4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hakjoo Ko <hakjoo.ko@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include "vconf-internals.h"
30 #include <sys/xattr.h>
34 #define API __attribute__ ((visibility("default")))
37 #define VCONF_ERROR_RETRY_CNT 20
38 #define VCONF_ERROR_RETRY_SLEEP_UTIME 10000
40 #ifdef VCONF_USE_SQLFS_TRANSACTION
43 #define VCONF_MOUNT_PATH "/opt/var/kdb/db"
44 #define VCONF_MOUNT_PATH_CHECK \
47 IN_SBOX = access("/opt/var/kdb/kdb_first_boot", F_OK) + 2; \
48 if(2==IN_SBOX) return 0;\
51 __thread int is_transaction;
54 #ifdef VCONF_TIMECHECK
55 double correction, startT;
57 double set_start_time(void)
62 gettimeofday(&tv, NULL);
63 curtime = tv.tv_sec * 1000 + (double)tv.tv_usec / 1000;
67 double exec_time(double start)
69 double end = set_start_time();
70 return (end - start - correction);
76 temp_t = set_start_time();
77 correction = exec_time(temp_t);
83 int _vconf_keynode_set_keyname(keynode_t *keynode, const char *keyname)
85 if (keynode->keyname) free(keynode->keyname);
86 keynode->keyname = strndup(keyname, VCONF_KEY_PATH_LEN);
87 retvm_if(keynode->keyname == NULL, VCONF_ERROR, "strndup Fails");
91 static inline void _vconf_keynode_set_dir(keynode_t *keynode)
93 keynode->type = VCONF_TYPE_DIR;
96 static inline void _vconf_keynode_set_value_int(keynode_t *keynode, const int value)
98 keynode->type = VCONF_TYPE_INT;
99 keynode->value.i = value;
102 static inline void _vconf_keynode_set_value_bool(keynode_t *keynode, const int value)
104 keynode->type = VCONF_TYPE_BOOL;
105 keynode->value.b = !!value;
108 static inline void _vconf_keynode_set_value_dbl(keynode_t *keynode, const double value)
110 keynode->type = VCONF_TYPE_DOUBLE;
111 keynode->value.d = value;
114 static inline void _vconf_keynode_set_value_str(keynode_t *keynode, const char *value)
116 keynode->type = VCONF_TYPE_STRING;
117 keynode->value.s = strdup(value);
120 inline void _vconf_keynode_set_null(keynode_t *keynode)
122 keynode->type = VCONF_TYPE_NONE;
123 //keynode->value.d = NULL;
126 static inline keynode_t *_vconf_keynode_next(keynode_t *keynode)
128 return keynode->next;
131 inline keynode_t *_vconf_keynode_new(void)
134 keynode = calloc(1, sizeof(keynode_t));
139 inline void _vconf_keynode_free(keynode_t *keynode)
142 if (keynode->keyname)
143 free(keynode->keyname);
144 if (keynode->type == VCONF_TYPE_STRING && keynode->value.s)
145 free(keynode->value.s);
150 static inline keynode_t *_vconf_keylist_headnode(keylist_t *keylist)
152 return keylist->head;
155 static keynode_t *_vconf_keylist_lookup(keylist_t *keylist, const char *keyname,
156 keynode_t **before_keynode)
158 keynode_t *found_node, *temp_node = NULL;
160 found_node = _vconf_keylist_headnode(keylist);
163 if(found_node->keyname == NULL) {
164 ERR("key node has null keyname");
168 if (!strncmp(keyname, found_node->keyname, strlen(keyname))) {
169 if (before_keynode) {
170 *before_keynode = temp_node;
175 temp_node = found_node;
176 found_node = _vconf_keynode_next(found_node);
182 * This function get Key name of the keynode.
183 * @param[in] keynode The Key
184 * @return Key Name of the keynode
186 API char *vconf_keynode_get_name(keynode_t *keynode)
188 retvm_if(keynode == NULL, NULL, "Invalid argument: keynode is NULL");
189 retvm_if(keynode->keyname == NULL, NULL, "The name of keynode is NULL");
191 return keynode->keyname;
195 * This function get value type of the keynode.
196 * @param[in] keynode The Key
197 * @return Type of the keynode
199 API int vconf_keynode_get_type(keynode_t *keynode)
201 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
203 return keynode->type;
206 API int vconf_keynode_get_int(keynode_t *keynode)
208 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
209 retvm_if(keynode->type != VCONF_TYPE_INT, VCONF_ERROR,
210 "The type(%d) of keynode(%s) is not INT", keynode->type, keynode->keyname);
212 return keynode->value.i;
215 API double vconf_keynode_get_dbl(keynode_t *keynode)
217 retvm_if(keynode == NULL, -1.0, "Invalid argument: keynode is NULL");
218 retvm_if(keynode->type != VCONF_TYPE_DOUBLE, -1.0,
219 "The type(%d) of keynode(%s) is not DBL", keynode->type, keynode->keyname);
221 return keynode->value.d;
225 * This function get Boolean value of the keynode.
226 * @param[in] keynode The Key
227 * @return Boolean value, -1 on error
229 API int vconf_keynode_get_bool(keynode_t *keynode)
231 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
232 retvm_if(keynode->type != VCONF_TYPE_BOOL, VCONF_ERROR,
233 "The type(%d) of keynode(%s) is not BOOL", keynode->type, keynode->keyname);
235 return !!(keynode->value.b);
239 * This function get String value of the keynode.
240 * @param[in] keynode The Key
241 * @return String value, NULL on error
243 API char *vconf_keynode_get_str(keynode_t *keynode)
245 retvm_if(keynode == NULL, NULL, "Invalid argument: keynode is NULL");
246 retvm_if(keynode->type != VCONF_TYPE_STRING, NULL,
247 "The type(%d) of keynode(%s) is not STR", keynode->type, keynode->keyname);
249 return keynode->value.s;
253 * Allocate, initialize and return a new Keylist object.
254 * @return The pointer of New keylist, NULL on error
256 API keylist_t *vconf_keylist_new(void)
259 keylist = calloc(1, sizeof(keylist_t));
265 * This function rewinds the KeyList internal cursor.
266 * @param[in] keylist Key List
267 * @return 0 on success, -1 on error
269 API int vconf_keylist_rewind(keylist_t *keylist)
271 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
273 keylist->cursor = NULL;
279 * A destructor for Keylist objects.
280 * @param[in] keylist Key List
281 * @return 0 on success, -1 on error
283 API int vconf_keylist_free(keylist_t *keylist)
285 keynode_t *keynode, *temp;
287 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
290 keynode = _vconf_keylist_headnode(keylist);
292 temp = _vconf_keynode_next(keynode);
293 _vconf_keynode_free(keynode);
302 * This function look for a Keynode contained in keylist that matches keyname.
303 * @param[in] keylist Key List
304 * @param[in] keyname Key to find
305 * @param[out] return_node pointer of keynode to set
306 * @return Type of the found key
309 vconf_keylist_lookup(keylist_t *keylist,
310 const char *keyname, keynode_t **return_node)
312 keynode_t *found_node;
314 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
315 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
316 retvm_if(return_node == NULL, VCONF_ERROR, "Invalid argument: return_node is NULL");
318 found_node = _vconf_keylist_lookup(keylist, keyname, NULL);
319 if (NULL == found_node)
323 *return_node = found_node;
324 return found_node->type;
328 * This function returns the next Key in a Keylist.
329 * Next key is known by the keylist internal cursor.
330 * @param[in] keylist Key List
331 * @return The next Keynode, NULL on error
333 API keynode_t *vconf_keylist_nextnode(keylist_t *keylist)
335 retvm_if(keylist == NULL, NULL, "Invalid argument: keylist is NULL");
338 keylist->cursor = _vconf_keynode_next(keylist->cursor);
340 keylist->cursor = keylist->head;
342 return keylist->cursor;
346 * This function appends a new Keynode included integer value to the keylist.
347 * If same keyname exist, the keynode will change.
348 * @param[in] keylist Key List
349 * @param[in] keyname Key
350 * @param[in] value The integer value
351 * @return Number of keynode included in the keylist, -1 on error
354 vconf_keylist_add_int(keylist_t *keylist, const char *keyname, const int value)
356 keynode_t *keynode = NULL, *addition = NULL;
358 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
359 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
361 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
362 _vconf_keynode_set_value_int(keynode, value);
365 if ((keynode = _vconf_keylist_headnode(keylist)))
366 while (_vconf_keynode_next(keynode))
367 keynode = _vconf_keynode_next(keynode);
369 addition = calloc(1, sizeof(keynode_t));
370 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
371 if (!_vconf_keynode_set_keyname(addition, keyname)) {
372 _vconf_keynode_set_value_int(addition, value);
373 if (keylist->head && NULL != keynode)
374 keynode->next = addition;
376 keylist->head = addition;
379 ERR("(maybe)not enought memory");
380 free(addition), addition = NULL;
388 * This function appends a new Keynode included boolean value to the keylist.
389 * If same keyname exist, the keynode will change.
390 * @param[in] keylist Key List
391 * @param[in] keyname Key
392 * @param[in] value The boolean value
393 * @return Number of keynode included in the keylist, -1 on error
396 vconf_keylist_add_bool(keylist_t *keylist, const char *keyname, const int value)
398 keynode_t *keynode = NULL, *addition = NULL;
400 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
401 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
403 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
404 _vconf_keynode_set_value_bool(keynode, value);
407 if ((keynode = _vconf_keylist_headnode(keylist)))
408 while (_vconf_keynode_next(keynode))
409 keynode = _vconf_keynode_next(keynode);
411 addition = calloc(1, sizeof(keynode_t));
412 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
413 if (!_vconf_keynode_set_keyname(addition, keyname)) {
414 _vconf_keynode_set_value_bool(addition, value);
415 if (keylist->head && NULL != keynode)
416 keynode->next = addition;
418 keylist->head = addition;
421 ERR("(maybe)not enought memory");
422 free(addition), addition = NULL;
430 * This function appends a new Keynode included double value to the keylist.
431 * If same keyname exist, the keynode will change.
432 * @param[in] keylist Key List
433 * @param[in] keyname Key
434 * @param[in] value The double value
435 * @return Number of keynode included in the keylist, -1 on error
438 vconf_keylist_add_dbl(keylist_t *keylist,
439 const char *keyname, const double value)
441 keynode_t *keynode = NULL, *addition = NULL;
443 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
444 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
446 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
447 _vconf_keynode_set_value_dbl(keynode, value);
450 if ((keynode = _vconf_keylist_headnode(keylist)))
451 while (_vconf_keynode_next(keynode))
452 keynode = _vconf_keynode_next(keynode);
454 addition = calloc(1, sizeof(keynode_t));
455 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
456 if (!_vconf_keynode_set_keyname(addition, keyname)) {
457 _vconf_keynode_set_value_dbl(addition, value);
458 if (keylist->head && NULL != keynode)
459 keynode->next = addition;
461 keylist->head = addition;
464 ERR("(maybe)not enought memory");
465 free(addition), addition = NULL;
473 * This function appends a new Keynode included string value to the keylist.
474 * If same keyname exist, the keynode will change.
475 * @param[in] keylist Key List
476 * @param[in] keyname Key
477 * @param[in] value The pointer of string value
478 * @return Number of keynode included in the keylist, -1 on error
481 vconf_keylist_add_str(keylist_t *keylist,
482 const char *keyname, const char *value)
484 keynode_t *keynode = NULL, *addition = NULL;
486 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
487 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
489 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
490 if (VCONF_TYPE_STRING == keynode->type && keynode->value.s)
491 free(keynode->value.s);
492 _vconf_keynode_set_value_str(keynode, value);
495 if (NULL != (keynode = _vconf_keylist_headnode(keylist)))
496 while (_vconf_keynode_next(keynode))
497 keynode = _vconf_keynode_next(keynode);
499 addition = calloc(1, sizeof(keynode_t));
500 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
501 if (!_vconf_keynode_set_keyname(addition, keyname)) {
502 _vconf_keynode_set_value_str(addition, value);
503 if (keylist->head && NULL != keynode)
504 keynode->next = addition;
506 keylist->head = addition;
509 ERR("(maybe)not enought memory");
510 free(addition), addition = NULL;
518 * This function Appends a new Keynode to the keylist without value.
520 * @param[in] keylist Key List
521 * @param[in] keyname Key
522 * @return Number of keynode included in the keylist, -1 on error
524 API int vconf_keylist_add_null(keylist_t *keylist, const char *keyname)
526 keynode_t *keynode = NULL, *addition = NULL;
528 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
529 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
531 if (NULL != (keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
533 keynode->value.d = 0;
536 if ((keynode = _vconf_keylist_headnode(keylist)))
537 while (_vconf_keynode_next(keynode))
538 keynode = _vconf_keynode_next(keynode);
540 addition = calloc(1, sizeof(keynode_t));
541 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
542 if (!_vconf_keynode_set_keyname(addition, keyname)) {
543 if (keylist->head && keynode)
544 keynode->next = addition;
546 keylist->head = addition;
549 ERR("(maybe)not enought memory");
550 free(addition), addition = NULL;
558 * This function remove the keynode that matches keyname.
559 * @param[in] keylist the keylist included the keyname
560 * @param[in] keyname key
561 * @return 0 on success, -1(Invalid parameter), -2(Not exist keyname in keylist) on error
563 API int vconf_keylist_del(keylist_t *keylist, const char *keyname)
565 keynode_t *found_node, *before_node = NULL;
567 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
568 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
570 if ((found_node = _vconf_keylist_lookup(keylist, keyname, &before_node))) {
572 before_node->next = found_node->next;
574 /* requested key is headnode of keylist */
575 keylist->head = found_node->next;
578 _vconf_keynode_free(found_node);
586 int _vconf_get_key_prefix(const char *keyname, int *prefix)
588 if (strncmp(keyname, BACKEND_DB_PREFIX, strlen(BACKEND_DB_PREFIX)) == 0) {
589 *prefix = VCONF_BACKEND_DB;
590 } else if (0 == strncmp(keyname, BACKEND_FILE_PREFIX, strlen(BACKEND_FILE_PREFIX))) {
591 *prefix = VCONF_BACKEND_FILE;
592 } else if (0 == strncmp(keyname, BACKEND_MEMORY_PREFIX, strlen(BACKEND_MEMORY_PREFIX))) {
593 *prefix = VCONF_BACKEND_MEMORY;
595 ERR("Invalid argument: wrong prefix of key(%s)", keyname);
596 *prefix = VCONF_BACKEND_NULL;
597 return VCONF_ERROR_WRONG_PREFIX;
603 int _vconf_get_key_path(const char *keyname, char *path)
605 if (strncmp(keyname, BACKEND_DB_PREFIX, strlen(BACKEND_DB_PREFIX)) == 0) {
606 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_SYSTEM_DIR, keyname);
607 } else if (0 == strncmp(keyname, BACKEND_FILE_PREFIX, strlen(BACKEND_FILE_PREFIX))) {
608 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_SYSTEM_DIR, keyname);
609 } else if (0 == strncmp(keyname, BACKEND_MEMORY_PREFIX, strlen(BACKEND_MEMORY_PREFIX))) {
610 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_MEMORY_DIR, keyname);
612 ERR("Invalid argument: wrong prefix of key(%s)", keyname);
613 return VCONF_ERROR_WRONG_PREFIX;
619 #ifdef VCONF_USE_BACKUP_TRANSACTION
620 int _vconf_get_backup_path(const char *keyname, char *path)
622 char key_buf[VCONF_KEY_PATH_LEN] = {0, };
625 for(i = 0; i<VCONF_KEY_PATH_LEN-1 && keyname[i] != '\0' ; i++) {
626 if (keyname[i] == '/')
629 key_buf[i] = keyname[i];
632 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s%s%s", BACKEND_SYSTEM_DIR, BACKEND_DB_PREFIX, ".backup/", key_buf);
638 #ifndef DISABLE_RUNTIME_KEY_CREATION
639 static int _vconf_set_key_check_parent_dir(const char* path)
642 struct stat stat_info;
644 char path_buf[VCONF_KEY_PATH_LEN] = {0,};
647 mode_t dir_mode = 0664 | 0111;
649 parent = strrchr(path, '/');
650 strncpy(path_buf, path, parent-path);
651 path_buf[parent-path]=0;
653 exists = stat(path_buf,&stat_info);
655 if(mkdir(path_buf, dir_mode) != 0) {
656 if(errno == ENOENT) {
657 ret = _vconf_set_key_check_parent_dir((const char*)path_buf);
658 if(ret != VCONF_OK) return ret;
659 if(mkdir(path_buf, dir_mode) != 0) {
660 ERR("mkdir error(%d)", errno);
670 static int _vconf_set_key_creation(const char* path)
675 fd = open(path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
678 ERR("open(rdwr,create) error\n");
687 static int _vconf_set_file_lock(int fd, short type)
691 l.l_type = type; /*Do read Lock*/
692 l.l_start= 0; /*Start at begin*/
693 l.l_whence = SEEK_SET;
694 l.l_len = 0; /*Do it with whole file*/
696 return fcntl(fd, F_SETLKW, &l);
699 static int _vconf_set_read_lock(int fd)
701 return _vconf_set_file_lock(fd, F_RDLCK);
704 static int _vconf_set_write_lock(int fd)
706 return _vconf_set_file_lock(fd, F_WRLCK);
709 static int _vconf_set_unlock(int fd)
711 return _vconf_set_file_lock(fd, F_UNLCK);
714 #ifdef VCONF_USE_SQLFS_TRANSACTION
715 static void _vconf_acquire_transaction_delay(int ms)
717 struct timeval timeout;
718 timeout.tv_sec = ms / 1000 ;
719 timeout.tv_usec = 1000 * ( ms % 1000 );
721 select(0, 0, 0, 0, &timeout);
724 static int _vconf_db_begin_transaction()
727 VCONF_MOUNT_PATH_CHECK;
729 if(is_transaction == 0) {
732 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_start", &value, sizeof(value), 0) == -1)
734 //ERR("someone access vconf. retrying...(%d)", errno);
735 _vconf_acquire_transaction_delay(50);
736 goto transaction_retry;
747 static int _vconf_db_commit_transaction()
750 VCONF_MOUNT_PATH_CHECK;
752 retv_if(is_transaction <= 0, VCONF_ERROR);
754 if(is_transaction == 1) {
757 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_stop", &value, sizeof(value), 0) == -1)
759 //ERR("setxattr failed. retrying...(%d)", errno);
760 _vconf_acquire_transaction_delay(50);
761 goto transaction_retry;
772 static int _vconf_db_rollback_transaction()
775 VCONF_MOUNT_PATH_CHECK;
777 retv_if(is_transaction <= 0, VCONF_ERROR);
779 if(is_transaction == 1) {
782 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_rb", &value, sizeof(value), 0) == -1)
784 //ERR("setxattr failed. retrying...(%d)", errno);
785 _vconf_acquire_transaction_delay(50);
786 goto transaction_retry;
796 #endif //VCONF_USE_SQLFS_TRANSACTION
798 #ifdef VCONF_USE_BACKUP_TRANSACTION
800 static int _vconf_backup_check(char* vconf_path, char* backup_path)
805 char file_buf[BUF_LEN] = { 0, };
806 char err_buf[100] = { 0, };
807 int complete_mark = 0;
810 int is_recovered = 0;
813 if (access(vconf_path, F_OK) == -1 || access(backup_path, F_OK) == -1)
816 vconf_fd = open(vconf_path, O_WRONLY);
817 if (vconf_fd == -1) {
818 ERR("open %s failed", vconf_path);
819 ret = VCONF_ERROR_FILE_OPEN;
824 if(_vconf_set_write_lock(vconf_fd) == -1) {
825 ERR("set write lock %s failed", vconf_path);
826 ret = VCONF_ERROR_FILE_LOCK;
831 backup_fd = open(backup_path, O_RDONLY);
832 if (backup_fd == -1) {
833 ERR("open %s failed", backup_path);
834 ret = VCONF_ERROR_FILE_OPEN;
839 file_size = lseek(backup_fd, 0, SEEK_END);
840 if (file_size == -1) {
841 ERR("seek end %s failed", backup_path);
842 ret = VCONF_ERROR_FILE_SEEK;
845 } else if (file_size < FILE_ATOMIC_GUARANTEE_SIZE + VCONF_BACKUP_COMP_MARK_SIZE) {
849 if (lseek(backup_fd, 0, SEEK_SET) != 0) {
850 ERR("seek %s failed", backup_path);
851 ret = VCONF_ERROR_FILE_SEEK;
856 read_len = read(backup_fd, &complete_mark, sizeof(int));
857 if (read_len < sizeof(int))
860 if (complete_mark != VCONF_BACKUP_COMPLETE_MARK)
863 if (ftruncate(vconf_fd, 0) == -1) {
864 ERR("truncate %s failed", vconf_path);
865 ret = VCONF_ERROR_FILE_TRUNCATE;
870 while ( (read_len = read(backup_fd, file_buf, BUF_LEN )) >0) {
871 if(write(vconf_fd, file_buf, read_len) != read_len) {
872 ERR("write %s failed", backup_path);
873 ret = VCONF_ERROR_FILE_WRITE;
882 if(_vconf_set_unlock(vconf_fd)==-1) {
883 ERR("unset write lock %s failed", vconf_path);
884 ret = VCONF_ERROR_FILE_LOCK;
895 if(ret == VCONF_OK) {
896 if(remove(backup_path) == -1) {
897 ret = VCONF_ERROR_FILE_REMOVE;
902 if(ret != VCONF_OK) {
903 strerror_r(err_no, err_buf, 100);
904 ERR("_vconf_backup_check failed %d (%d / %s)\n", ret, err_no, err_buf);
905 } else if (is_recovered)
906 WARN("vconf(%s) successfully recovered and backup file is removed", vconf_path, backup_path);
908 WARN("vconf(%s)'s non-complete backup file is removed", vconf_path, backup_path);
913 static int _vconf_backup_write_str(char* backup_path, char* value)
916 char err_buf[100] = { 0, };
920 int complete_mark = VCONF_BACKUP_COMPLETE_MARK;
922 int vconf_type_str = VCONF_TYPE_STRING;
925 if( (backup_fd = open(backup_path, O_CREAT|O_EXCL|O_WRONLY, 0666)) == -1 ) {
926 ERR("open %s failed", backup_path);
927 ret = VCONF_ERROR_FILE_OPEN;
932 if ((result = write(backup_fd, (void *)&empty_mark, sizeof(int))) != sizeof(int)) {
933 ERR("write empty mark of %s failed %d", backup_path, result);
934 ret = VCONF_ERROR_FILE_WRITE;
939 if ((result = write(backup_fd, (void *)&vconf_type_str, sizeof(int))) != sizeof(int)) {
940 ERR("write type of %s failed %d", backup_path, result);
941 ret = VCONF_ERROR_FILE_WRITE;
946 write_len = strlen(value);
947 if((result = write(backup_fd, value, write_len)) != write_len) {
948 ERR("write %s failed %d", backup_path, result);
949 ret = VCONF_ERROR_FILE_WRITE;
955 if (fdatasync(backup_fd) == -1) {
956 ERR("sync %s failed", backup_path);
957 ret = VCONF_ERROR_FILE_SYNC;
962 if (lseek(backup_fd, 0, SEEK_SET) != 0) {
963 ERR("seek %s failed", backup_path);
964 ret = VCONF_ERROR_FILE_SEEK;
969 if((result = write(backup_fd, (void *)&complete_mark, sizeof(int))) != sizeof(int)) {
970 ERR("write complete mark of %s failed %d", backup_path, result);
971 ret = VCONF_ERROR_FILE_WRITE;
976 if (fdatasync(backup_fd) == -1) {
977 ERR("sync %s failed", backup_path);
978 ret = VCONF_ERROR_FILE_SYNC;
987 if(ret != VCONF_OK) {
988 strerror_r(err_no, err_buf, 100);
989 ERR("_vconf_backup_write_str failed %d (%d / %s)\n", ret, err_no, err_buf);
996 static int _vconf_backup_commit(char* backup_path)
999 char err_buf[100] = { 0, };
1002 if(remove(backup_path) == -1) {
1003 ERR("remove %s failed", backup_path);
1004 ret = VCONF_ERROR_FILE_REMOVE;
1008 if(ret != VCONF_OK) {
1009 strerror_r(err_no, err_buf, 100);
1010 ERR("_vconf_backup_commit failed %d (%d / %s)\n", ret, err_no, err_buf);
1016 #endif // VCONF_USE_BACKUP_TRANSACTION
1018 static int _vconf_set_key_filesys(keynode_t *keynode, int prefix)
1020 char path[VCONF_KEY_PATH_LEN] = {0,};
1023 int func_ret = VCONF_OK;
1025 char err_buf[100] = { 0, };
1026 int is_write_error = 0;
1027 #ifdef VCONF_USE_BACKUP_TRANSACTION
1028 char backup_path[VCONF_KEY_PATH_LEN] = {0,};
1029 int is_backup_need = 0;
1035 ret = _vconf_get_key_path(keynode->keyname, path);
1036 retv_if(ret != VCONF_OK, ret);
1039 #ifdef VCONF_CHECK_IS_INITIALIZED
1040 if(prefix == VCONF_BACKEND_MEMORY && VCONF_NOT_INITIALIZED) {
1041 func_ret = VCONF_ERROR_NOT_INITIALIZED;
1046 #ifdef VCONF_USE_BACKUP_TRANSACTION
1047 if(prefix == VCONF_BACKEND_DB && keynode->type == VCONF_TYPE_STRING) {
1048 _vconf_get_backup_path(keynode->keyname, backup_path);
1049 ret = _vconf_backup_check(path, backup_path);
1050 if(ret != VCONF_OK) {
1058 if( (fp = fopen(path, "r+")) == NULL ) {
1059 func_ret = VCONF_ERROR_FILE_OPEN;
1064 #ifdef VCONF_USE_SQLFS_TRANSACTION
1065 if (prefix != VCONF_BACKEND_DB)
1068 ret = _vconf_set_write_lock(fileno(fp));
1070 func_ret = VCONF_ERROR_FILE_LOCK;
1076 #ifdef VCONF_USE_BACKUP_TRANSACTION
1077 if(prefix == VCONF_BACKEND_DB && keynode->type == VCONF_TYPE_STRING) {
1078 file_size = VCONF_TYPE_SIZE + strlen(keynode->value.s);
1079 if (file_size > FILE_ATOMIC_GUARANTEE_SIZE) {
1082 ret = _vconf_backup_write_str(backup_path, keynode->value.s);
1083 if(ret != VCONF_OK) {
1088 WARN("vconf backup file for(%s) is created. file size(%d)", path, file_size);
1093 if (ftruncate(fileno(fp), 0) == -1) {
1094 func_ret = VCONF_ERROR_FILE_TRUNCATE;
1099 /* write key type */
1100 ret = fwrite((void *)&(keynode->type), sizeof(int), 1, fp);
1108 func_ret = VCONF_ERROR_FILE_WRITE;
1112 /* write key value */
1113 switch(keynode->type)
1115 case VCONF_TYPE_INT:
1116 ret = fwrite((void *)&(keynode->value.i), sizeof(int), 1, fp);
1117 if(ret <= 0) is_write_error = 1;
1119 case VCONF_TYPE_DOUBLE:
1120 ret = fwrite((void *)&(keynode->value.d), sizeof(double), 1, fp);
1121 if(ret <= 0) is_write_error = 1;
1123 case VCONF_TYPE_BOOL:
1124 ret = fwrite((void *)&(keynode->value.b), sizeof(int), 1, fp);
1125 if(ret <= 0) is_write_error = 1;
1127 case VCONF_TYPE_STRING:
1128 ret = fprintf(fp,"%s",keynode->value.s);
1129 if(ret < strlen(keynode->value.s)) is_write_error = 1;
1130 //ret = fwrite((void *)keynode->value.s, sizeof(char), strlen(keynode->value.s), fp);
1133 func_ret = VCONF_ERROR_WRONG_TYPE;
1143 func_ret = VCONF_ERROR_FILE_WRITE;
1147 #ifdef VCONF_USE_SQLFS_TRANSACTION
1148 if(prefix == VCONF_BACKEND_FILE)
1150 if(prefix == VCONF_BACKEND_FILE || prefix == VCONF_BACKEND_DB)
1155 ret = fdatasync(fileno(fp));
1158 func_ret = VCONF_ERROR_FILE_SYNC;
1162 #ifdef VCONF_USE_BACKUP_TRANSACTION
1163 if (is_backup_need) {
1164 ret = _vconf_backup_commit(backup_path);
1165 if(ret != VCONF_OK) {
1174 #ifdef VCONF_USE_SQLFS_TRANSACTION
1175 if (prefix != VCONF_BACKEND_DB)
1178 ret = _vconf_set_unlock(fileno(fp));
1180 func_ret = VCONF_ERROR_FILE_LOCK;
1190 strerror_r(err_no, err_buf, 100);
1191 ERR("_vconf_set_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1197 static int _vconf_set_key(keynode_t *keynode)
1199 int func_ret = VCONF_OK;
1201 int is_busy_err = 0;
1206 ret = _vconf_get_key_prefix(keynode->keyname, &prefix);
1207 retv_if(ret != VCONF_OK, ret);
1209 #ifdef VCONF_USE_SQLFS_TRANSACTION
1210 if(prefix == VCONF_BACKEND_DB) {
1211 _vconf_db_begin_transaction();
1215 while((ret = _vconf_set_key_filesys(keynode, prefix)) != VCONF_OK)
1220 #ifdef VCONF_CHECK_INITIALIZED
1221 if(VCONF_NOT_INITIALIZED)
1223 ERR("%s : vconf is not initialized\n", keynode->keyname);
1226 else if(ret == VCONF_ERROR_FILE_OPEN)
1229 if(ret == VCONF_ERROR_FILE_OPEN)
1234 /* file is not exist, make path */
1235 #ifndef DISABLE_RUNTIME_KEY_CREATION
1239 char path[VCONF_KEY_PATH_LEN] = {0,};
1240 rc = _vconf_get_key_path(keynode->keyname, path);
1241 if(rc != VCONF_OK) {
1242 ERR("_vconf_get_key_path error");
1246 rc = _vconf_set_key_check_parent_dir(path);
1247 if(rc != VCONF_OK) {
1248 ERR("_vconf_set_key_check_parent_dir error : %s", path);
1252 rc = _vconf_set_key_creation(path);
1253 if(rc != VCONF_OK) {
1254 ERR("_vconf_set_key_creation error : %s", path);
1257 INFO("%s key is created", keynode->keyname);
1269 else if (ret == VCONF_ERROR_FILE_CHMOD)
1280 else if (ret == VCONF_ERROR_FILE_LOCK)
1293 else if (ret == VCONF_ERROR_FILE_WRITE)
1312 if ((is_busy_err == 1) && (retry < VCONF_ERROR_RETRY_CNT)) {
1313 ERR("%s : write buf error(%d). write will be retried(%d) , usleep time : %d\n", keynode->keyname, ret, retry, (retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1314 usleep((retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1317 ERR("%s : write buf error(%d). break. (%d)\n", keynode->keyname, ret, retry);
1318 func_ret = VCONF_ERROR;
1323 #ifdef VCONF_USE_SQLFS_TRANSACTION
1324 if(prefix == VCONF_BACKEND_DB) {
1325 if(func_ret == VCONF_ERROR) {
1326 _vconf_db_rollback_transaction();
1328 _vconf_db_commit_transaction();
1337 * This function set the value of given keys
1338 * @param[in] keylist the keylist which should contain changed keys
1339 * @return 0 on success, -1 on error
1341 API int vconf_set(keylist_t *keylist)
1345 keynode_t *got_node;
1347 int func_ret = VCONF_OK;
1351 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
1353 INFO("vconf_set (%d)START", keylist->num);
1355 got_node = _vconf_keylist_headnode(keylist);
1357 retvm_if(got_node == NULL, VCONF_ERROR, "Invalid argument: headnode is NULL");
1359 ret = _vconf_get_key_prefix(got_node->keyname, &prefix);
1360 retv_if(ret != VCONF_OK, ret);
1362 #ifdef VCONF_USE_SQLFS_TRANSACTION
1363 if(prefix == VCONF_BACKEND_DB) {
1364 _vconf_db_begin_transaction();
1368 while (got_node != NULL) {
1369 ret = _vconf_set_key(got_node);
1370 if(ret != VCONF_OK) {
1371 func_ret = VCONF_ERROR;
1374 got_node = _vconf_keynode_next(got_node);
1377 #ifdef VCONF_USE_SQLFS_TRANSACTION
1378 if(prefix == VCONF_BACKEND_DB) {
1379 if(func_ret == VCONF_ERROR) {
1380 _vconf_db_rollback_transaction();
1382 _vconf_db_commit_transaction();
1392 API int vconf_sync_key(const char *in_key)
1397 char path[VCONF_KEY_PATH_LEN] = {0,};
1400 ret = _vconf_get_key_path(in_key, path);
1401 if(ret != VCONF_OK) return VCONF_ERROR;
1403 fd = open(path, O_RDWR);
1404 if(fd == -1) return VCONF_ERROR;
1415 * This function set the integer value of given key
1416 * @param[in] in_key key
1417 * @param[in] intval integer value to set
1418 * @return 0 on success, -1 on error
1420 API int vconf_set_int(const char *in_key, const int intval)
1424 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1426 int func_ret = VCONF_OK;
1428 keynode_t* pKeyNode = _vconf_keynode_new();
1429 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1431 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1432 if(func_ret != VCONF_OK) {
1433 _vconf_keynode_free(pKeyNode);
1434 ERR("set key name error");
1437 _vconf_keynode_set_value_int(pKeyNode, intval);
1439 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1440 ERR("vconf_set_int(%d) : %s(%d) error", getpid(), in_key, intval);
1441 func_ret = VCONF_ERROR;
1443 INFO("vconf_set_int(%d) : %s(%d) success", getpid(), in_key, intval);
1446 _vconf_keynode_free(pKeyNode);
1454 * This function set the boolean value of given key
1455 * @param[in] in_key key
1456 * @param[in] boolval boolean value to set
1457 (Integer value 1 is 'True', and 0 is 'False')
1458 * @return 0 on success, -1 on error
1460 API int vconf_set_bool(const char *in_key, const int boolval)
1464 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1466 int func_ret = VCONF_OK;
1467 keynode_t* pKeyNode = _vconf_keynode_new();
1468 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1470 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1471 if(func_ret != VCONF_OK) {
1472 _vconf_keynode_free(pKeyNode);
1473 ERR("set key name error");
1476 _vconf_keynode_set_value_bool(pKeyNode, boolval);
1478 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1479 ERR("vconf_set_bool(%d) : %s(%d) error", getpid(), in_key, boolval);
1480 func_ret = VCONF_ERROR;
1482 INFO("vconf_set_bool(%d) : %s(%d) success", getpid(), in_key, boolval);
1485 _vconf_keynode_free(pKeyNode);
1493 * This function set the double value of given key
1494 * @param[in] in_key key
1495 * @param[in] dblval double value to set
1496 * @return 0 on success, -1 on error
1498 API int vconf_set_dbl(const char *in_key, const double dblval)
1502 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1504 int func_ret = VCONF_OK;
1505 keynode_t* pKeyNode = _vconf_keynode_new();
1506 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1508 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1509 if(func_ret != VCONF_OK) {
1510 _vconf_keynode_free(pKeyNode);
1511 ERR("set key name error");
1514 _vconf_keynode_set_value_dbl(pKeyNode, dblval);
1516 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1517 ERR("vconf_set_dbl(%d) : %s(%f) error", getpid(), in_key, dblval);
1518 func_ret = VCONF_ERROR;
1520 INFO("vconf_set_dbl(%d) : %s(%f) success", getpid(), in_key, dblval);
1523 _vconf_keynode_free(pKeyNode);
1531 * This function set the string value of given key
1532 * @param[in] in_key key
1533 * @param[in] strval string value to set
1534 * @return 0 on success, -1 on error
1536 API int vconf_set_str(const char *in_key, const char *strval)
1540 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1541 retvm_if(strval == NULL, VCONF_ERROR, "Invalid argument: value is NULL");
1543 int func_ret = VCONF_OK;
1544 keynode_t* pKeyNode = _vconf_keynode_new();
1545 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1547 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1548 if(func_ret != VCONF_OK) {
1549 _vconf_keynode_free(pKeyNode);
1550 ERR("set key name error");
1553 _vconf_keynode_set_value_str(pKeyNode, strval);
1555 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1556 ERR("vconf_set_str(%d) : %s(%s) error", getpid(), in_key, strval);
1557 func_ret = VCONF_ERROR;
1559 INFO("vconf_set_str(%d) : %s(%s) success", getpid(), in_key, strval);
1562 _vconf_keynode_free(pKeyNode);
1570 #ifdef SUPPORT_ELEKTRA_VALUE_FORMAT
1571 /* keyFileUnserialize function of ELEKTRA */
1572 static int _vconf_get_key_elektra_format(keynode_t *keynode, FILE *fp)
1574 char version[10] = {0,};
1575 char type[5] = {0,};
1576 char comment[8] = {0,};
1577 char file_buf[BUF_LEN] = {0,};
1581 char err_buf[100] = { 0, };
1582 int func_ret = VCONF_OK;
1585 INFO("_vconf_get_key_elektra_format start");
1589 if (!fgets(version, sizeof(version), fp))
1596 func_ret = VCONF_ERROR_FILE_FGETS;
1599 if (strncmp(version,"RG",2)) {
1600 func_ret = VCONF_ERROR_WRONG_TYPE;
1604 if (!fgets(type, sizeof(type), fp))
1611 func_ret = VCONF_ERROR_FILE_FGETS;
1615 if (!fgets(comment, sizeof(comment), fp))
1622 func_ret = VCONF_ERROR_FILE_FGETS;
1626 while(fgets(file_buf, sizeof(file_buf), fp))
1629 value_size = value_size + strlen(file_buf);
1630 tmp = (char *) realloc(value, value_size);
1633 func_ret = VCONF_ERROR_NO_MEM;
1637 strncat(value, file_buf, strlen(file_buf));
1639 value_size = strlen(file_buf) + 1;
1640 value = (char *)malloc(value_size);
1642 func_ret = VCONF_ERROR_NO_MEM;
1645 memset(value, 0x00, value_size);
1646 strncpy(value, file_buf, strlen(file_buf));
1652 func_ret = VCONF_ERROR_FILE_FGETS;
1657 case VCONF_TYPE_INT:
1659 _vconf_keynode_set_value_int(keynode, atoi(value));
1662 case VCONF_TYPE_DOUBLE:
1664 _vconf_keynode_set_value_dbl(keynode, atof(value));
1667 case VCONF_TYPE_BOOL:
1669 _vconf_keynode_set_value_bool(keynode, atoi(value));
1672 case VCONF_TYPE_STRING:
1674 _vconf_keynode_set_value_str(keynode, value);
1679 func_ret = VCONF_ERROR_WRONG_VALUE;
1683 if(atoi(type) == VCONF_TYPE_STRING) {
1684 _vconf_keynode_set_value_str(keynode, "");
1686 func_ret = VCONF_ERROR_WRONG_VALUE;
1693 strerror_r(err_no, err_buf, 100);
1694 ERR("_vconf_set_key_filesys(%d/%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1697 if(value) free(value);
1703 static int _vconf_get_key_filesys(keynode_t *keynode, int prefix)
1705 char path[VCONF_KEY_PATH_LEN] = {0,};
1707 int func_ret = VCONF_OK;
1708 char err_buf[100] = { 0, };
1712 #ifdef VCONF_USE_BACKUP_TRANSACTION
1713 char backup_path[VCONF_KEY_PATH_LEN] = {0,};
1718 ret = _vconf_get_key_path(keynode->keyname, path);
1719 retv_if(ret != VCONF_OK, ret);
1721 #ifdef VCONF_CHECK_INITIALIZED
1722 if(prefix == VCONF_BACKEND_MEMORY && VCONF_NOT_INITIALIZED)
1724 func_ret = VCONF_ERROR_NOT_INITIALIZED;
1729 #ifdef VCONF_USE_BACKUP_TRANSACTION
1730 if(prefix == VCONF_BACKEND_DB) {
1731 _vconf_get_backup_path(keynode->keyname, backup_path);
1732 ret = _vconf_backup_check(path, backup_path);
1733 if(ret != VCONF_OK) {
1741 if( (fp = fopen(path, "r")) == NULL ) {
1742 func_ret = VCONF_ERROR_FILE_OPEN;
1747 #ifdef VCONF_USE_SQLFS_TRANSACTION
1748 if (prefix != VCONF_BACKEND_DB)
1751 ret = _vconf_set_read_lock(fileno(fp));
1753 func_ret = VCONF_ERROR_FILE_LOCK;
1759 /* read data type */
1760 if(!fread((void*)&type, sizeof(int), 1, fp)) {
1766 func_ret = VCONF_ERROR_FILE_FREAD;
1770 /* read data value */
1773 case VCONF_TYPE_INT:
1776 if(!fread((void*)&value_int, sizeof(int), 1, fp)) {
1782 func_ret = VCONF_ERROR_FILE_FREAD;
1785 _vconf_keynode_set_value_int(keynode, value_int);
1790 case VCONF_TYPE_DOUBLE:
1792 double value_dbl = 0;
1793 if(!fread((void*)&value_dbl, sizeof(double), 1, fp)) {
1799 func_ret = VCONF_ERROR_FILE_FREAD;
1802 _vconf_keynode_set_value_dbl(keynode, value_dbl);
1807 case VCONF_TYPE_BOOL:
1810 if(!fread((void*)&value_int, sizeof(int), 1, fp)) {
1816 func_ret = VCONF_ERROR_FILE_FREAD;
1819 _vconf_keynode_set_value_bool(keynode, value_int);
1824 case VCONF_TYPE_STRING:
1826 char file_buf[BUF_LEN] = {0,};
1830 while(fgets(file_buf, sizeof(file_buf), fp))
1833 value_size = value_size + strlen(file_buf);
1834 value = (char *) realloc(value, value_size);
1836 func_ret = VCONF_ERROR_NO_MEM;
1839 strncat(value, file_buf, strlen(file_buf));
1841 value_size = strlen(file_buf) + 1;
1842 value = (char *)malloc(value_size);
1844 func_ret = VCONF_ERROR_NO_MEM;
1847 memset(value, 0x00, value_size);
1848 strncpy(value, file_buf, strlen(file_buf));
1854 func_ret = VCONF_ERROR_FILE_FGETS;
1857 _vconf_keynode_set_value_str(keynode, value);
1859 _vconf_keynode_set_value_str(keynode, "");
1868 #ifdef SUPPORT_ELEKTRA_VALUE_FORMAT
1869 func_ret = _vconf_get_key_elektra_format(keynode, fp);
1871 func_ret = VCONF_ERROR_WRONG_TYPE;
1876 #ifdef VCONF_USE_SQLFS_TRANSACTION
1877 if (prefix != VCONF_BACKEND_DB)
1880 ret = _vconf_set_unlock(fileno(fp));
1882 func_ret = VCONF_ERROR_FILE_LOCK;
1893 strerror_r(err_no, err_buf, 100);
1894 ERR("_vconf_get_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1901 int _vconf_get_key(keynode_t *keynode)
1903 int func_ret = VCONF_OK;
1905 int is_busy_err = 0;
1909 ret = _vconf_get_key_prefix(keynode->keyname, &prefix);
1910 retv_if(ret != VCONF_OK, ret);
1912 #ifdef VCONF_USE_SQLFS_TRANSACTION
1913 if(prefix == VCONF_BACKEND_DB) {
1914 _vconf_db_begin_transaction();
1918 while((ret = _vconf_get_key_filesys(keynode, prefix)) != VCONF_OK)
1923 #ifdef VCONF_CHECK_INITIALIZED
1924 if(VCONF_NOT_INITIALIZED)
1926 ERR("%s : vconf is not initialized\n", keynode->keyname);
1929 else if(ret == VCONF_ERROR_FILE_OPEN)
1931 if(ret == VCONF_ERROR_FILE_OPEN)
1944 else if (ret == VCONF_ERROR_FILE_LOCK)
1957 else if (ret == VCONF_ERROR_FILE_FREAD)
1974 if ((is_busy_err == 1) && (retry < VCONF_ERROR_RETRY_CNT)) {
1975 ERR("%s : read buf error(%d). read will be retried(%d) , %d\n", keynode->keyname, ret, retry, (retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1976 usleep((retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1979 ERR("%s : read buf error(%d). break\n", keynode->keyname, ret);
1980 func_ret = VCONF_ERROR;
1985 #ifdef VCONF_USE_SQLFS_TRANSACTION
1986 if(prefix == VCONF_BACKEND_DB) {
1987 if(func_ret == VCONF_ERROR) {
1988 _vconf_db_rollback_transaction();
1990 _vconf_db_commit_transaction();
1999 static int _vconf_check_value_integrity(const void *value, int type)
2003 if ((type == VCONF_TYPE_STRING) && (value != NULL)) {
2007 if ((value) && (strlen(value) > 0)) {
2008 if ((type == VCONF_TYPE_INT) ||
2009 (type == VCONF_TYPE_BOOL)||
2010 (type == VCONF_TYPE_DOUBLE)) {
2011 while (*(((char *)value) + i) != '\0') {
2012 if ( !isdigit(*(((char *)value) + i)) ) {
2013 if ((type != VCONF_TYPE_BOOL) &&
2014 (*(((char *)value) + i) != '-')) {
2015 if ((type == VCONF_TYPE_DOUBLE) &&
2016 (*(((char *)value) + i) != '.')) {
2017 ERR("ERROR : vconf value is not digit.");
2028 ERR("ERROR : vconf value is NULL.");
2034 int _vconf_path_is_dir(char* path)
2036 struct stat entryInfo;
2038 if(lstat(path, &entryInfo) == 0 ) {
2039 if( S_ISDIR( entryInfo.st_mode ) ) {
2049 API int vconf_get(keylist_t *keylist, const char *dirpath, get_option_t option)
2052 struct dirent entry;
2053 struct dirent *result = NULL;
2054 char full_file_path[VCONF_KEY_PATH_LEN] = {0,};
2055 char file_path[VCONF_KEY_PATH_LEN] = {0,};
2056 char full_path[VCONF_KEY_PATH_LEN] = {0,};
2057 char err_buf[ERR_LEN] = {0,};
2064 keynode_t *temp_keynode;
2066 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is null");
2067 retvm_if(dirpath == NULL, VCONF_ERROR, "Invalid argument: dirpath is null");
2069 temp_keynode = _vconf_keylist_headnode(keylist);
2071 if ((NULL != temp_keynode) && (VCONF_GET_KEY != option)) {
2072 ERR("Not support mode : Only VCONF_GET_KEY \
2073 option support To retrieve key with keylist");
2077 if(temp_keynode != NULL) {
2078 while(_vconf_keynode_next(temp_keynode)) {
2079 temp_keynode = _vconf_keynode_next(temp_keynode);
2083 ret = _vconf_get_key_path(dirpath, full_path);
2084 retvm_if(ret != VCONF_OK, ret, "Invalid argument: key is not valid");
2087 ret = _vconf_get_key_prefix(dirpath, &prefix);
2088 retv_if(ret != VCONF_OK, ret);
2090 #ifdef VCONF_USE_SQLFS_TRANSACTION
2091 if(prefix == VCONF_BACKEND_DB) {
2092 _vconf_db_begin_transaction();
2096 is_dir = _vconf_path_is_dir(full_path);
2098 if((dir=opendir(full_path)) == NULL) {
2099 strerror_r(errno, err_buf, ERR_LEN);
2100 ERR("ERROR : open directory(%s) fail(%s)", dirpath, err_buf);
2101 func_ret = VCONF_ERROR;
2105 if((readdir_r(dir, &entry, &result)) != 0) {
2106 strerror_r(errno, err_buf, ERR_LEN);
2107 ERR("ERROR : read directory(%s) fail(%s)", dirpath, err_buf);
2108 func_ret = VCONF_ERROR;
2111 while(result != NULL)
2113 if(( strcmp( entry.d_name, ".") == 0 ) || ( strcmp( entry.d_name, "..") == 0 )) {
2117 keynode_t* keynode = _vconf_keynode_new();
2118 if(keynode == NULL) {
2120 ERR("Invalid argument: key malloc fail");
2121 func_ret = VCONF_ERROR;
2125 snprintf(file_path, VCONF_KEY_PATH_LEN, "%s/%s", dirpath, entry.d_name);
2126 snprintf(full_file_path, VCONF_KEY_PATH_LEN, "%s/%s", full_path, entry.d_name);
2128 rc = _vconf_path_is_dir(full_file_path);
2129 if(rc != VCONF_ERROR) {
2132 if(option == VCONF_GET_KEY) {
2133 _vconf_keynode_free(keynode);
2136 _vconf_keynode_set_keyname(keynode, file_path);
2137 _vconf_keynode_set_dir(keynode);
2140 _vconf_keynode_set_keyname(keynode, file_path);
2141 _vconf_get_key(keynode);
2144 if (keylist->head && temp_keynode != NULL)
2146 temp_keynode->next = keynode;
2147 temp_keynode = _vconf_keynode_next(temp_keynode);
2150 keylist->head = keynode;
2151 temp_keynode = keylist->head;
2155 _vconf_keynode_free(keynode);
2157 memset(err_buf, 0x00, sizeof(err_buf));
2158 strerror_r(errno, err_buf, sizeof(err_buf));
2159 ERR("ERROR : get path(%s) fail(%s)", file_path, err_buf);
2160 func_ret = VCONF_ERROR;
2164 if((readdir_r(dir, &entry, &result)) != 0) {
2165 memset(err_buf, 0x00, sizeof(err_buf));
2166 strerror_r(errno, err_buf, sizeof(err_buf));
2167 ERR("ERROR : read directory(%s) fail(%s)", dirpath, err_buf);
2168 func_ret = VCONF_ERROR;
2172 if((closedir(dir)) != 0) {
2173 memset(err_buf, 0x00, sizeof(err_buf));
2174 strerror_r(errno, err_buf, sizeof(err_buf));
2175 ERR("ERROR : close directory(%s) fail(%s)", dirpath, err_buf);
2176 func_ret = VCONF_ERROR;
2178 } else if(is_dir == 0) {
2179 keynode_t* keynode = _vconf_keynode_new();
2180 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: key malloc fail");
2182 _vconf_keynode_set_keyname(keynode, dirpath);
2184 _vconf_get_key(keynode);
2186 if (keylist->head && temp_keynode != NULL) {
2187 temp_keynode->next = keynode;
2188 //temp_keynode = _vconf_keynode_next(temp_keynode);
2190 keylist->head = keynode;
2191 temp_keynode = keylist->head;
2195 func_ret = VCONF_ERROR;
2198 vconf_keylist_rewind(keylist);
2201 #ifdef VCONF_USE_SQLFS_TRANSACTION
2202 if(prefix == VCONF_BACKEND_DB) {
2203 if(func_ret == VCONF_ERROR) {
2204 _vconf_db_rollback_transaction();
2206 _vconf_db_commit_transaction();
2215 * This function get the integer value of given key
2216 * @param[in] in_key key
2217 * @param[out] intval output buffer
2218 * @return 0 on success, -1 on error
2220 API int vconf_get_int(const char *in_key, int *intval)
2224 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2225 retvm_if(intval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2227 int func_ret = VCONF_ERROR;
2228 keynode_t* pKeyNode = _vconf_keynode_new();
2229 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2231 _vconf_keynode_set_keyname(pKeyNode, in_key);
2233 if (_vconf_get_key(pKeyNode) != VCONF_OK)
2234 ERR("vconf_get_int(%d) : %s error", getpid(), in_key);
2236 *intval = pKeyNode->value.i;
2238 if(pKeyNode->type == VCONF_TYPE_INT) {
2239 INFO("vconf_get_int(%d) : %s(%d) success", getpid(), in_key, *intval);
2240 func_ret = VCONF_OK;
2242 ERR("The type(%d) of keynode(%s) is not INT", pKeyNode->type, pKeyNode->keyname);
2245 _vconf_keynode_free(pKeyNode);
2253 * This function get the boolean value of given key
2254 * @param[in] in_key key
2255 * @param[out] boolval output buffer
2256 * @return 0 on success, -1 on error
2258 API int vconf_get_bool(const char *in_key, int *boolval)
2262 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2263 retvm_if(boolval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2265 int func_ret = VCONF_ERROR;
2266 keynode_t* pKeyNode = _vconf_keynode_new();
2267 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2269 _vconf_keynode_set_keyname(pKeyNode, in_key);
2271 if (_vconf_get_key(pKeyNode) != VCONF_OK)
2272 ERR("vconf_get_bool(%d) : %s error", getpid(), in_key);
2274 *boolval = !!(pKeyNode->value.b);
2276 if(pKeyNode->type == VCONF_TYPE_BOOL) {
2277 INFO("vconf_get_bool(%d) : %s(%d) success", getpid(), in_key, *boolval);
2278 func_ret = VCONF_OK;
2280 ERR("The type(%d) of keynode(%s) is not BOOL", pKeyNode->type, pKeyNode->keyname);
2283 _vconf_keynode_free(pKeyNode);
2291 * This function get the double value of given key
2292 * @param[in] in_key key
2293 * @param[out] dblval output buffer
2294 * @return 0 on success, -1 on error
2296 API int vconf_get_dbl(const char *in_key, double *dblval)
2300 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2301 retvm_if(dblval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2303 int func_ret = VCONF_ERROR;
2304 keynode_t* pKeyNode = _vconf_keynode_new();
2305 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2307 _vconf_keynode_set_keyname(pKeyNode, in_key);
2309 if (_vconf_get_key(pKeyNode) != VCONF_OK)
2310 ERR("vconf_get_dbl(%d) : %s error", getpid(), in_key);
2313 *dblval = pKeyNode->value.d;
2315 if(pKeyNode->type == VCONF_TYPE_DOUBLE) {
2316 INFO("vconf_get_dbl(%d) : %s(%f) success", getpid(), in_key, *dblval);
2317 func_ret = VCONF_OK;
2319 ERR("The type(%d) of keynode(%s) is not DBL", pKeyNode->type, pKeyNode->keyname);
2322 _vconf_keynode_free(pKeyNode);
2330 * This function get the string value of given key
2331 * @param[in] in_key key
2332 * @return pointer of key value on success, NULL on error
2334 API char *vconf_get_str(const char *in_key)
2338 retvm_if(in_key == NULL, NULL, "Invalid argument: key is null");
2340 keynode_t* pKeyNode = _vconf_keynode_new();
2341 retvm_if(pKeyNode == NULL, NULL, "key malloc fail");
2343 _vconf_keynode_set_keyname(pKeyNode, in_key);
2345 char *strval = NULL;
2346 char *tempstr = NULL;
2348 if (_vconf_get_key(pKeyNode) != VCONF_OK) {
2349 ERR("vconf_get_str(%d) : %s error", getpid(), in_key);
2352 if(pKeyNode->type == VCONF_TYPE_STRING)
2353 tempstr = pKeyNode->value.s;
2355 ERR("The type(%d) of keynode(%s) is not STR", pKeyNode->type, pKeyNode->keyname);
2358 strval = strdup(tempstr);
2359 INFO("vconf_get_str(%d) : %s(%s) success", getpid(), in_key, strval);
2362 _vconf_keynode_free(pKeyNode);
2370 * This function unset given key
2371 * @param[in] in_key key
2372 * @return 0 on success, -1 on error
2374 API int vconf_unset(const char *in_key)
2378 char path[VCONF_KEY_PATH_LEN] = {0,};
2380 int err_retry = VCONF_ERROR_RETRY_CNT;
2381 int func_ret = VCONF_OK;
2383 WARN("vconf_unset: %s. THIS API(vconf_unset) WILL BE DEPRECATED", in_key);
2385 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2387 ret = _vconf_get_key_path(in_key, path);
2388 retvm_if(ret != VCONF_OK, VCONF_ERROR, "Invalid argument: key is not valid");
2390 retvm_if(access(path, F_OK) == -1, VCONF_ERROR, "Error : key(%s) is not exist", in_key);
2395 ERR("vconf_unset error(%d) : %s", errno, in_key);
2396 func_ret = VCONF_ERROR;
2398 func_ret = VCONF_OK;
2401 } while(err_retry--);
2409 * This function unset given key recursively
2410 * @param[in] in_dir Directory name for removing
2411 * @return 0 on success, -1 on error
2413 API int vconf_unset_recursive(const char *in_dir)
2418 struct dirent entry;
2419 struct dirent *result = NULL;
2420 char fullpath[VCONF_KEY_PATH_LEN] = {0,};
2421 char dirpath[VCONF_KEY_PATH_LEN] = {0,};
2422 char err_buf[ERR_LEN] = {0,};
2427 WARN("vconf_unset_recursive: %s. THIS API(vconf_unset_recursive) WILL BE DEPRECATED", in_dir);
2429 retvm_if(in_dir == NULL, VCONF_ERROR, "Invalid argument: dir path is null");
2431 ret = _vconf_get_key_path(in_dir, dirpath);
2432 retvm_if(ret != VCONF_OK, VCONF_ERROR, "Invalid argument: key is not valid");
2434 if((dir=opendir(dirpath)) == NULL) {
2435 strerror_r(errno, err_buf, ERR_LEN);
2436 ERR("ERROR : open directory(%s) fail(%s)", in_dir, err_buf);
2440 if((readdir_r(dir, &entry, &result)) != 0) {
2441 strerror_r(errno, err_buf, ERR_LEN);
2442 ERR("ERROR : read directory(%s) fail(%s)", in_dir, err_buf);
2443 func_ret = VCONF_ERROR;
2446 while(result != NULL)
2448 if(( strcmp( entry.d_name, ".") == 0 ) || ( strcmp( entry.d_name, "..") == 0 )) {
2452 snprintf(fullpath,VCONF_KEY_PATH_LEN, "%s/%s", dirpath, entry.d_name);
2454 ret = _vconf_path_is_dir(fullpath);
2455 if(ret != VCONF_ERROR) {
2457 rc = vconf_unset_recursive(fullpath);
2458 if(rc == VCONF_ERROR)
2459 func_ret = VCONF_ERROR;
2462 rc = remove(fullpath);
2464 memset(err_buf, 0x00, sizeof(err_buf));
2465 strerror_r(errno, err_buf, sizeof(err_buf));
2466 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2467 func_ret = VCONF_ERROR;
2470 memset(err_buf, 0x00, sizeof(err_buf));
2471 strerror_r(errno, err_buf, sizeof(err_buf));
2472 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2473 func_ret = VCONF_ERROR;
2476 if((readdir_r(dir, &entry, &result)) != 0) {
2477 memset(err_buf, 0x00, sizeof(err_buf));
2478 strerror_r(errno, err_buf, sizeof(err_buf));
2479 ERR("ERROR : read directory(%s) fail(%s)", in_dir, err_buf);
2480 func_ret = VCONF_ERROR;
2484 if((closedir(dir)) != 0) {
2485 memset(err_buf, 0x00, sizeof(err_buf));
2486 strerror_r(errno, err_buf, sizeof(err_buf));
2487 ERR("ERROR : close directory(%s) fail(%s)", in_dir, err_buf);
2488 func_ret = VCONF_ERROR;
2491 if(func_ret == VCONF_OK) {
2492 if((remove(in_dir)) == -1) {
2493 memset(err_buf, 0x00, sizeof(err_buf));
2494 strerror_r(errno, err_buf, sizeof(err_buf));
2495 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2496 func_ret = VCONF_ERROR;
2504 API int vconf_notify_key_changed(const char *in_key, vconf_callback_fn cb, void *user_data)
2508 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2509 retvm_if(cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
2511 if (_vconf_kdb_add_notify(in_key, cb, user_data)) {
2512 ERR("vconf_notify_key_changed : key(%s) add notify fail", in_key);
2516 INFO("vconf_notify_key_changed : %s noti is added", in_key);
2523 API int vconf_ignore_key_changed(const char *in_key, vconf_callback_fn cb)
2527 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2528 retvm_if(cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
2530 if (_vconf_kdb_del_notify(in_key, cb)) {
2531 ERR("vconf_ignore_key_changed() failed: key(%s)", in_key);
2535 INFO("vconf_ignore_key_changed : %s noti removed", in_key);
2542 API mode_t vconf_set_permission(mode_t mode)
2544 /* TODO: implement! */
2548 API int vconf_set_key_permission(const char *in_key, const mode_t mode)
2550 /* TODO: implement! */