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 #define VCONF_NOT_INITIALIZED (access("/tmp/vconf-initialized", F_OK) == -1)
42 #ifdef VCONF_USE_SQLFS_TRANSACTION
45 #define VCONF_MOUNT_PATH "/opt/var/kdb/db"
46 #define VCONF_MOUNT_PATH_CHECK \
49 IN_SBOX = access("/opt/var/kdb/kdb_first_boot", F_OK) + 2; \
50 if(2==IN_SBOX) return 0;\
53 __thread int is_transaction;
56 #ifdef VCONF_TIMECHECK
57 double correction, startT;
59 double set_start_time(void)
64 gettimeofday(&tv, NULL);
65 curtime = tv.tv_sec * 1000 + (double)tv.tv_usec / 1000;
69 double exec_time(double start)
71 double end = set_start_time();
72 return (end - start - correction);
78 temp_t = set_start_time();
79 correction = exec_time(temp_t);
85 int _vconf_keynode_set_keyname(keynode_t *keynode, const char *keyname)
87 if (keynode->keyname) free(keynode->keyname);
88 keynode->keyname = strndup(keyname, VCONF_KEY_PATH_LEN);
89 retvm_if(keynode->keyname == NULL, VCONF_ERROR, "strndup Fails");
93 static inline void _vconf_keynode_set_dir(keynode_t *keynode)
95 keynode->type = VCONF_TYPE_DIR;
98 static inline void _vconf_keynode_set_value_int(keynode_t *keynode, const int value)
100 keynode->type = VCONF_TYPE_INT;
101 keynode->value.i = value;
104 static inline void _vconf_keynode_set_value_bool(keynode_t *keynode, const int value)
106 keynode->type = VCONF_TYPE_BOOL;
107 keynode->value.b = !!value;
110 static inline void _vconf_keynode_set_value_dbl(keynode_t *keynode, const double value)
112 keynode->type = VCONF_TYPE_DOUBLE;
113 keynode->value.d = value;
116 static inline void _vconf_keynode_set_value_str(keynode_t *keynode, const char *value)
118 keynode->type = VCONF_TYPE_STRING;
119 keynode->value.s = strdup(value);
122 inline void _vconf_keynode_set_null(keynode_t *keynode)
124 keynode->type = VCONF_TYPE_NONE;
125 //keynode->value.d = NULL;
128 static inline keynode_t *_vconf_keynode_next(keynode_t *keynode)
130 return keynode->next;
133 inline keynode_t *_vconf_keynode_new(void)
136 keynode = calloc(1, sizeof(keynode_t));
141 inline void _vconf_keynode_free(keynode_t *keynode)
144 if (keynode->keyname)
145 free(keynode->keyname);
146 if (keynode->type == VCONF_TYPE_STRING && keynode->value.s)
147 free(keynode->value.s);
152 static inline keynode_t *_vconf_keylist_headnode(keylist_t *keylist)
154 return keylist->head;
157 static keynode_t *_vconf_keylist_lookup(keylist_t *keylist, const char *keyname,
158 keynode_t **before_keynode)
160 keynode_t *found_node, *temp_node = NULL;
162 found_node = _vconf_keylist_headnode(keylist);
165 if(found_node->keyname == NULL) {
166 ERR("key node has null keyname");
170 if (!strncmp(keyname, found_node->keyname, strlen(keyname))) {
171 if (before_keynode) {
172 *before_keynode = temp_node;
177 temp_node = found_node;
178 found_node = _vconf_keynode_next(found_node);
184 * This function get Key name of the keynode.
185 * @param[in] keynode The Key
186 * @return Key Name of the keynode
188 API char *vconf_keynode_get_name(keynode_t *keynode)
190 retvm_if(keynode == NULL, NULL, "Invalid argument: keynode is NULL");
191 retvm_if(keynode->keyname == NULL, NULL, "The name of keynode is NULL");
193 return keynode->keyname;
197 * This function get value type of the keynode.
198 * @param[in] keynode The Key
199 * @return Type of the keynode
201 API int vconf_keynode_get_type(keynode_t *keynode)
203 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
205 return keynode->type;
208 API int vconf_keynode_get_int(keynode_t *keynode)
210 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
211 retvm_if(keynode->type != VCONF_TYPE_INT, VCONF_ERROR,
212 "The type(%d) of keynode(%s) is not INT", keynode->type, keynode->keyname);
214 return keynode->value.i;
217 API double vconf_keynode_get_dbl(keynode_t *keynode)
219 retvm_if(keynode == NULL, -1.0, "Invalid argument: keynode is NULL");
220 retvm_if(keynode->type != VCONF_TYPE_DOUBLE, -1.0,
221 "The type(%d) of keynode(%s) is not DBL", keynode->type, keynode->keyname);
223 return keynode->value.d;
227 * This function get Boolean value of the keynode.
228 * @param[in] keynode The Key
229 * @return Boolean value, -1 on error
231 API int vconf_keynode_get_bool(keynode_t *keynode)
233 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
234 retvm_if(keynode->type != VCONF_TYPE_BOOL, VCONF_ERROR,
235 "The type(%d) of keynode(%s) is not BOOL", keynode->type, keynode->keyname);
237 return !!(keynode->value.b);
241 * This function get String value of the keynode.
242 * @param[in] keynode The Key
243 * @return String value, NULL on error
245 API char *vconf_keynode_get_str(keynode_t *keynode)
247 retvm_if(keynode == NULL, NULL, "Invalid argument: keynode is NULL");
248 retvm_if(keynode->type != VCONF_TYPE_STRING, NULL,
249 "The type(%d) of keynode(%s) is not STR", keynode->type, keynode->keyname);
251 return keynode->value.s;
255 * Allocate, initialize and return a new Keylist object.
256 * @return The pointer of New keylist, NULL on error
258 API keylist_t *vconf_keylist_new(void)
261 keylist = calloc(1, sizeof(keylist_t));
267 * This function rewinds the KeyList internal cursor.
268 * @param[in] keylist Key List
269 * @return 0 on success, -1 on error
271 API int vconf_keylist_rewind(keylist_t *keylist)
273 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
275 keylist->cursor = NULL;
281 * A destructor for Keylist objects.
282 * @param[in] keylist Key List
283 * @return 0 on success, -1 on error
285 API int vconf_keylist_free(keylist_t *keylist)
287 keynode_t *keynode, *temp;
289 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
292 keynode = _vconf_keylist_headnode(keylist);
294 temp = _vconf_keynode_next(keynode);
295 _vconf_keynode_free(keynode);
304 * This function look for a Keynode contained in keylist that matches keyname.
305 * @param[in] keylist Key List
306 * @param[in] keyname Key to find
307 * @param[out] return_node pointer of keynode to set
308 * @return Type of the found key
311 vconf_keylist_lookup(keylist_t *keylist,
312 const char *keyname, keynode_t **return_node)
314 keynode_t *found_node;
316 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
317 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
318 retvm_if(return_node == NULL, VCONF_ERROR, "Invalid argument: return_node is NULL");
320 found_node = _vconf_keylist_lookup(keylist, keyname, NULL);
321 if (NULL == found_node)
325 *return_node = found_node;
326 return found_node->type;
330 * This function returns the next Key in a Keylist.
331 * Next key is known by the keylist internal cursor.
332 * @param[in] keylist Key List
333 * @return The next Keynode, NULL on error
335 API keynode_t *vconf_keylist_nextnode(keylist_t *keylist)
337 retvm_if(keylist == NULL, NULL, "Invalid argument: keylist is NULL");
340 keylist->cursor = _vconf_keynode_next(keylist->cursor);
342 keylist->cursor = keylist->head;
344 return keylist->cursor;
348 * This function appends a new Keynode included integer value to the keylist.
349 * If same keyname exist, the keynode will change.
350 * @param[in] keylist Key List
351 * @param[in] keyname Key
352 * @param[in] value The integer value
353 * @return Number of keynode included in the keylist, -1 on error
356 vconf_keylist_add_int(keylist_t *keylist, const char *keyname, const int value)
358 keynode_t *keynode = NULL, *addition = NULL;
360 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
361 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
363 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
364 _vconf_keynode_set_value_int(keynode, value);
367 if ((keynode = _vconf_keylist_headnode(keylist)))
368 while (_vconf_keynode_next(keynode))
369 keynode = _vconf_keynode_next(keynode);
371 addition = calloc(1, sizeof(keynode_t));
372 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
373 if (!_vconf_keynode_set_keyname(addition, keyname)) {
374 _vconf_keynode_set_value_int(addition, value);
375 if (keylist->head && NULL != keynode)
376 keynode->next = addition;
378 keylist->head = addition;
381 ERR("(maybe)not enought memory");
382 free(addition), addition = NULL;
390 * This function appends a new Keynode included boolean value to the keylist.
391 * If same keyname exist, the keynode will change.
392 * @param[in] keylist Key List
393 * @param[in] keyname Key
394 * @param[in] value The boolean value
395 * @return Number of keynode included in the keylist, -1 on error
398 vconf_keylist_add_bool(keylist_t *keylist, const char *keyname, const int value)
400 keynode_t *keynode = NULL, *addition = NULL;
402 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
403 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
405 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
406 _vconf_keynode_set_value_bool(keynode, value);
409 if ((keynode = _vconf_keylist_headnode(keylist)))
410 while (_vconf_keynode_next(keynode))
411 keynode = _vconf_keynode_next(keynode);
413 addition = calloc(1, sizeof(keynode_t));
414 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
415 if (!_vconf_keynode_set_keyname(addition, keyname)) {
416 _vconf_keynode_set_value_bool(addition, value);
417 if (keylist->head && NULL != keynode)
418 keynode->next = addition;
420 keylist->head = addition;
423 ERR("(maybe)not enought memory");
424 free(addition), addition = NULL;
432 * This function appends a new Keynode included double value to the keylist.
433 * If same keyname exist, the keynode will change.
434 * @param[in] keylist Key List
435 * @param[in] keyname Key
436 * @param[in] value The double value
437 * @return Number of keynode included in the keylist, -1 on error
440 vconf_keylist_add_dbl(keylist_t *keylist,
441 const char *keyname, const double value)
443 keynode_t *keynode = NULL, *addition = NULL;
445 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
446 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
448 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
449 _vconf_keynode_set_value_dbl(keynode, value);
452 if ((keynode = _vconf_keylist_headnode(keylist)))
453 while (_vconf_keynode_next(keynode))
454 keynode = _vconf_keynode_next(keynode);
456 addition = calloc(1, sizeof(keynode_t));
457 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
458 if (!_vconf_keynode_set_keyname(addition, keyname)) {
459 _vconf_keynode_set_value_dbl(addition, value);
460 if (keylist->head && NULL != keynode)
461 keynode->next = addition;
463 keylist->head = addition;
466 ERR("(maybe)not enought memory");
467 free(addition), addition = NULL;
475 * This function appends a new Keynode included string value to the keylist.
476 * If same keyname exist, the keynode will change.
477 * @param[in] keylist Key List
478 * @param[in] keyname Key
479 * @param[in] value The pointer of string value
480 * @return Number of keynode included in the keylist, -1 on error
483 vconf_keylist_add_str(keylist_t *keylist,
484 const char *keyname, const char *value)
486 keynode_t *keynode = NULL, *addition = NULL;
488 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
489 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
491 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
492 if (VCONF_TYPE_STRING == keynode->type && keynode->value.s)
493 free(keynode->value.s);
494 _vconf_keynode_set_value_str(keynode, value);
497 if (NULL != (keynode = _vconf_keylist_headnode(keylist)))
498 while (_vconf_keynode_next(keynode))
499 keynode = _vconf_keynode_next(keynode);
501 addition = calloc(1, sizeof(keynode_t));
502 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
503 if (!_vconf_keynode_set_keyname(addition, keyname)) {
504 _vconf_keynode_set_value_str(addition, value);
505 if (keylist->head && NULL != keynode)
506 keynode->next = addition;
508 keylist->head = addition;
511 ERR("(maybe)not enought memory");
512 free(addition), addition = NULL;
520 * This function Appends a new Keynode to the keylist without value.
522 * @param[in] keylist Key List
523 * @param[in] keyname Key
524 * @return Number of keynode included in the keylist, -1 on error
526 API int vconf_keylist_add_null(keylist_t *keylist, const char *keyname)
528 keynode_t *keynode = NULL, *addition = NULL;
530 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
531 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
533 if (NULL != (keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
535 keynode->value.d = 0;
538 if ((keynode = _vconf_keylist_headnode(keylist)))
539 while (_vconf_keynode_next(keynode))
540 keynode = _vconf_keynode_next(keynode);
542 addition = calloc(1, sizeof(keynode_t));
543 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
544 if (!_vconf_keynode_set_keyname(addition, keyname)) {
545 if (keylist->head && keynode)
546 keynode->next = addition;
548 keylist->head = addition;
551 ERR("(maybe)not enought memory");
552 free(addition), addition = NULL;
560 * This function remove the keynode that matches keyname.
561 * @param[in] keylist the keylist included the keyname
562 * @param[in] keyname key
563 * @return 0 on success, -1(Invalid parameter), -2(Not exist keyname in keylist) on error
565 API int vconf_keylist_del(keylist_t *keylist, const char *keyname)
567 keynode_t *found_node, *before_node = NULL;
569 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
570 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
572 if ((found_node = _vconf_keylist_lookup(keylist, keyname, &before_node))) {
574 before_node->next = found_node->next;
576 /* requested key is headnode of keylist */
577 keylist->head = found_node->next;
580 _vconf_keynode_free(found_node);
588 int _vconf_get_key_prefix(const char *keyname, int *prefix)
590 if (strncmp(keyname, BACKEND_DB_PREFIX, strlen(BACKEND_DB_PREFIX)) == 0) {
591 *prefix = VCONF_BACKEND_DB;
592 } else if (0 == strncmp(keyname, BACKEND_FILE_PREFIX, strlen(BACKEND_FILE_PREFIX))) {
593 *prefix = VCONF_BACKEND_FILE;
594 } else if (0 == strncmp(keyname, BACKEND_MEMORY_PREFIX, strlen(BACKEND_MEMORY_PREFIX))) {
595 *prefix = VCONF_BACKEND_MEMORY;
597 ERR("Invalid argument: wrong prefix of key(%s)", keyname);
598 *prefix = VCONF_BACKEND_NULL;
599 return VCONF_ERROR_WRONG_PREFIX;
605 int _vconf_get_key_path(const char *keyname, char *path)
607 if (strncmp(keyname, BACKEND_DB_PREFIX, strlen(BACKEND_DB_PREFIX)) == 0) {
608 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_SYSTEM_DIR, keyname);
609 } else if (0 == strncmp(keyname, BACKEND_FILE_PREFIX, strlen(BACKEND_FILE_PREFIX))) {
610 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_SYSTEM_DIR, keyname);
611 } else if (0 == strncmp(keyname, BACKEND_MEMORY_PREFIX, strlen(BACKEND_MEMORY_PREFIX))) {
612 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_MEMORY_DIR, keyname);
614 ERR("Invalid argument: wrong prefix of key(%s)", keyname);
615 return VCONF_ERROR_WRONG_PREFIX;
621 #ifdef VCONF_USE_BACKUP_TRANSACTION
622 int _vconf_get_backup_path(const char *keyname, char *path)
624 char key_buf[VCONF_KEY_PATH_LEN] = {0, };
627 for(i = 0; i<VCONF_KEY_PATH_LEN-1 && keyname[i] != '\0' ; i++) {
628 if (keyname[i] == '/')
631 key_buf[i] = keyname[i];
634 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s%s%s", BACKEND_SYSTEM_DIR, BACKEND_DB_PREFIX, ".backup/", key_buf);
640 #ifndef DISABLE_RUNTIME_KEY_CREATION
641 static int _vconf_set_key_check_parent_dir(const char* path)
644 struct stat stat_info;
646 char path_buf[VCONF_KEY_PATH_LEN] = {0,};
649 mode_t dir_mode = 0664 | 0111;
651 parent = strrchr(path, '/');
652 strncpy(path_buf, path, parent-path);
653 path_buf[parent-path]=0;
655 exists = stat(path_buf,&stat_info);
657 if(mkdir(path_buf, dir_mode) != 0) {
658 if(errno == ENOENT) {
659 ret = _vconf_set_key_check_parent_dir((const char*)path_buf);
660 if(ret != VCONF_OK) return ret;
661 if(mkdir(path_buf, dir_mode) != 0) {
662 ERR("mkdir error(%d)", errno);
672 static int _vconf_set_key_creation(const char* path)
677 fd = open(path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
680 ERR("open(rdwr,create) error\n");
689 static int _vconf_set_file_lock(int fd, short type)
693 l.l_type = type; /*Do read Lock*/
694 l.l_start= 0; /*Start at begin*/
695 l.l_whence = SEEK_SET;
696 l.l_len = 0; /*Do it with whole file*/
698 return fcntl(fd, F_SETLKW, &l);
701 static int _vconf_set_read_lock(int fd)
703 return _vconf_set_file_lock(fd, F_RDLCK);
706 static int _vconf_set_write_lock(int fd)
708 return _vconf_set_file_lock(fd, F_WRLCK);
711 static int _vconf_set_unlock(int fd)
713 return _vconf_set_file_lock(fd, F_UNLCK);
716 #ifdef VCONF_USE_SQLFS_TRANSACTION
717 static void _vconf_acquire_transaction_delay(int ms)
719 struct timeval timeout;
720 timeout.tv_sec = ms / 1000 ;
721 timeout.tv_usec = 1000 * ( ms % 1000 );
723 select(0, 0, 0, 0, &timeout);
726 static int _vconf_db_begin_transaction()
729 VCONF_MOUNT_PATH_CHECK;
731 if(is_transaction == 0) {
734 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_start", &value, sizeof(value), 0) == -1)
736 //ERR("someone access vconf. retrying...(%d)", errno);
737 _vconf_acquire_transaction_delay(50);
738 goto transaction_retry;
749 static int _vconf_db_commit_transaction()
752 VCONF_MOUNT_PATH_CHECK;
754 retv_if(is_transaction <= 0, VCONF_ERROR);
756 if(is_transaction == 1) {
759 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_stop", &value, sizeof(value), 0) == -1)
761 //ERR("setxattr failed. retrying...(%d)", errno);
762 _vconf_acquire_transaction_delay(50);
763 goto transaction_retry;
774 static int _vconf_db_rollback_transaction()
777 VCONF_MOUNT_PATH_CHECK;
779 retv_if(is_transaction <= 0, VCONF_ERROR);
781 if(is_transaction == 1) {
784 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_rb", &value, sizeof(value), 0) == -1)
786 //ERR("setxattr failed. retrying...(%d)", errno);
787 _vconf_acquire_transaction_delay(50);
788 goto transaction_retry;
798 #endif //VCONF_USE_SQLFS_TRANSACTION
800 #ifdef VCONF_USE_BACKUP_TRANSACTION
802 static int _vconf_backup_check(char* vconf_path, char* backup_path)
807 char file_buf[BUF_LEN] = { 0, };
808 char err_buf[100] = { 0, };
809 int complete_mark = 0;
812 int is_recovered = 0;
815 if (access(vconf_path, F_OK) == -1 || access(backup_path, F_OK) == -1)
818 vconf_fd = open(vconf_path, O_WRONLY);
819 if (vconf_fd == -1) {
820 ERR("open %s failed", vconf_path);
821 ret = VCONF_ERROR_FILE_OPEN;
826 if(_vconf_set_write_lock(vconf_fd) == -1) {
827 ERR("set write lock %s failed", vconf_path);
828 ret = VCONF_ERROR_FILE_LOCK;
833 backup_fd = open(backup_path, O_RDONLY);
834 if (backup_fd == -1) {
835 ERR("open %s failed", backup_path);
836 ret = VCONF_ERROR_FILE_OPEN;
841 file_size = lseek(backup_fd, 0, SEEK_END);
842 if (file_size == -1) {
843 ERR("seek end %s failed", backup_path);
844 ret = VCONF_ERROR_FILE_SEEK;
847 } else if (file_size < FILE_ATOMIC_GUARANTEE_SIZE + VCONF_BACKUP_COMP_MARK_SIZE) {
851 if (lseek(backup_fd, 0, SEEK_SET) != 0) {
852 ERR("seek %s failed", backup_path);
853 ret = VCONF_ERROR_FILE_SEEK;
858 read_len = read(backup_fd, &complete_mark, sizeof(int));
859 if (read_len < sizeof(int))
862 if (complete_mark != VCONF_BACKUP_COMPLETE_MARK)
865 if (ftruncate(vconf_fd, 0) == -1) {
866 ERR("truncate %s failed", vconf_path);
867 ret = VCONF_ERROR_FILE_TRUNCATE;
872 while ( (read_len = read(backup_fd, file_buf, BUF_LEN )) >0) {
873 if(write(vconf_fd, file_buf, read_len) != read_len) {
874 ERR("write %s failed", backup_path);
875 ret = VCONF_ERROR_FILE_WRITE;
884 if(_vconf_set_unlock(vconf_fd)==-1) {
885 ERR("unset write lock %s failed", vconf_path);
886 ret = VCONF_ERROR_FILE_LOCK;
897 if(ret == VCONF_OK) {
898 if(remove(backup_path) == -1) {
899 ret = VCONF_ERROR_FILE_REMOVE;
904 if(ret != VCONF_OK) {
905 strerror_r(err_no, err_buf, 100);
906 ERR("_vconf_backup_check failed %d (%d / %s)\n", ret, err_no, err_buf);
907 } else if (is_recovered)
908 WARN("vconf(%s) successfully recovered and backup file is removed", vconf_path, backup_path);
910 WARN("vconf(%s)'s non-complete backup file is removed", vconf_path, backup_path);
915 static int _vconf_backup_write_str(char* backup_path, char* value)
918 char err_buf[100] = { 0, };
922 int complete_mark = VCONF_BACKUP_COMPLETE_MARK;
924 int vconf_type_str = VCONF_TYPE_STRING;
927 if( (backup_fd = open(backup_path, O_CREAT|O_EXCL|O_WRONLY, 0666)) == -1 ) {
928 ERR("open %s failed", backup_path);
929 ret = VCONF_ERROR_FILE_OPEN;
934 if ((result = write(backup_fd, (void *)&empty_mark, sizeof(int))) != sizeof(int)) {
935 ERR("write empty mark of %s failed %d", backup_path, result);
936 ret = VCONF_ERROR_FILE_WRITE;
941 if ((result = write(backup_fd, (void *)&vconf_type_str, sizeof(int))) != sizeof(int)) {
942 ERR("write type of %s failed %d", backup_path, result);
943 ret = VCONF_ERROR_FILE_WRITE;
948 write_len = strlen(value);
949 if((result = write(backup_fd, value, write_len)) != write_len) {
950 ERR("write %s failed %d", backup_path, result);
951 ret = VCONF_ERROR_FILE_WRITE;
957 if (fdatasync(backup_fd) == -1) {
958 ERR("sync %s failed", backup_path);
959 ret = VCONF_ERROR_FILE_SYNC;
964 if (lseek(backup_fd, 0, SEEK_SET) != 0) {
965 ERR("seek %s failed", backup_path);
966 ret = VCONF_ERROR_FILE_SEEK;
971 if((result = write(backup_fd, (void *)&complete_mark, sizeof(int))) != sizeof(int)) {
972 ERR("write complete mark of %s failed %d", backup_path, result);
973 ret = VCONF_ERROR_FILE_WRITE;
978 if (fdatasync(backup_fd) == -1) {
979 ERR("sync %s failed", backup_path);
980 ret = VCONF_ERROR_FILE_SYNC;
989 if(ret != VCONF_OK) {
990 strerror_r(err_no, err_buf, 100);
991 ERR("_vconf_backup_write_str failed %d (%d / %s)\n", ret, err_no, err_buf);
998 static int _vconf_backup_commit(char* backup_path)
1001 char err_buf[100] = { 0, };
1004 if(remove(backup_path) == -1) {
1005 ERR("remove %s failed", backup_path);
1006 ret = VCONF_ERROR_FILE_REMOVE;
1010 if(ret != VCONF_OK) {
1011 strerror_r(err_no, err_buf, 100);
1012 ERR("_vconf_backup_commit failed %d (%d / %s)\n", ret, err_no, err_buf);
1018 #endif // VCONF_USE_BACKUP_TRANSACTION
1020 static int _vconf_set_key_filesys(keynode_t *keynode, int prefix)
1022 char path[VCONF_KEY_PATH_LEN] = {0,};
1025 int func_ret = VCONF_OK;
1027 char err_buf[100] = { 0, };
1028 int is_write_error = 0;
1029 #ifdef VCONF_USE_BACKUP_TRANSACTION
1030 char backup_path[VCONF_KEY_PATH_LEN] = {0,};
1031 int is_backup_need = 0;
1037 ret = _vconf_get_key_path(keynode->keyname, path);
1038 retv_if(ret != VCONF_OK, ret);
1040 if(prefix == VCONF_BACKEND_MEMORY && VCONF_NOT_INITIALIZED) {
1041 func_ret = VCONF_ERROR_NOT_INITIALIZED;
1045 #ifdef VCONF_USE_BACKUP_TRANSACTION
1046 if(prefix == VCONF_BACKEND_DB && keynode->type == VCONF_TYPE_STRING) {
1047 _vconf_get_backup_path(keynode->keyname, backup_path);
1048 ret = _vconf_backup_check(path, backup_path);
1049 if(ret != VCONF_OK) {
1057 if( (fp = fopen(path, "r+")) == NULL ) {
1058 func_ret = VCONF_ERROR_FILE_OPEN;
1063 #ifdef VCONF_USE_SQLFS_TRANSACTION
1064 if (prefix != VCONF_BACKEND_DB)
1067 ret = _vconf_set_write_lock(fileno(fp));
1069 func_ret = VCONF_ERROR_FILE_LOCK;
1075 #ifdef VCONF_USE_BACKUP_TRANSACTION
1076 if(prefix == VCONF_BACKEND_DB && keynode->type == VCONF_TYPE_STRING) {
1077 file_size = VCONF_TYPE_SIZE + strlen(keynode->value.s);
1078 if (file_size > FILE_ATOMIC_GUARANTEE_SIZE) {
1081 ret = _vconf_backup_write_str(backup_path, keynode->value.s);
1082 if(ret != VCONF_OK) {
1087 WARN("vconf backup file for(%s) is created. file size(%d)", path, file_size);
1092 if (ftruncate(fileno(fp), 0) == -1) {
1093 func_ret = VCONF_ERROR_FILE_TRUNCATE;
1098 /* write key type */
1099 ret = fwrite((void *)&(keynode->type), sizeof(int), 1, fp);
1107 func_ret = VCONF_ERROR_FILE_WRITE;
1111 /* write key value */
1112 switch(keynode->type)
1114 case VCONF_TYPE_INT:
1115 ret = fwrite((void *)&(keynode->value.i), sizeof(int), 1, fp);
1116 if(ret <= 0) is_write_error = 1;
1118 case VCONF_TYPE_DOUBLE:
1119 ret = fwrite((void *)&(keynode->value.d), sizeof(double), 1, fp);
1120 if(ret <= 0) is_write_error = 1;
1122 case VCONF_TYPE_BOOL:
1123 ret = fwrite((void *)&(keynode->value.b), sizeof(int), 1, fp);
1124 if(ret <= 0) is_write_error = 1;
1126 case VCONF_TYPE_STRING:
1127 ret = fprintf(fp,"%s",keynode->value.s);
1128 if(ret < strlen(keynode->value.s)) is_write_error = 1;
1129 //ret = fwrite((void *)keynode->value.s, sizeof(char), strlen(keynode->value.s), fp);
1132 func_ret = VCONF_ERROR_WRONG_TYPE;
1142 func_ret = VCONF_ERROR_FILE_WRITE;
1146 #ifdef VCONF_USE_SQLFS_TRANSACTION
1147 if(prefix == VCONF_BACKEND_FILE)
1149 if(prefix == VCONF_BACKEND_FILE || prefix == VCONF_BACKEND_DB)
1154 ret = fdatasync(fileno(fp));
1157 func_ret = VCONF_ERROR_FILE_SYNC;
1161 #ifdef VCONF_USE_BACKUP_TRANSACTION
1162 if (is_backup_need) {
1163 ret = _vconf_backup_commit(backup_path);
1164 if(ret != VCONF_OK) {
1173 #ifdef VCONF_USE_SQLFS_TRANSACTION
1174 if (prefix != VCONF_BACKEND_DB)
1177 ret = _vconf_set_unlock(fileno(fp));
1179 func_ret = VCONF_ERROR_FILE_LOCK;
1189 strerror_r(err_no, err_buf, 100);
1190 ERR("_vconf_set_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1196 static int _vconf_set_key(keynode_t *keynode)
1198 int func_ret = VCONF_OK;
1200 int is_busy_err = 0;
1205 ret = _vconf_get_key_prefix(keynode->keyname, &prefix);
1206 retv_if(ret != VCONF_OK, ret);
1208 #ifdef VCONF_USE_SQLFS_TRANSACTION
1209 if(prefix == VCONF_BACKEND_DB) {
1210 _vconf_db_begin_transaction();
1214 while((ret = _vconf_set_key_filesys(keynode, prefix)) != VCONF_OK)
1219 if(VCONF_NOT_INITIALIZED)
1221 ERR("%s : vconf is not initialized\n", keynode->keyname);
1224 else if(ret == VCONF_ERROR_FILE_OPEN)
1228 /* file is not exist, make path */
1229 #ifndef DISABLE_RUNTIME_KEY_CREATION
1233 char path[VCONF_KEY_PATH_LEN] = {0,};
1234 rc = _vconf_get_key_path(keynode->keyname, path);
1235 if(rc != VCONF_OK) {
1236 ERR("_vconf_get_key_path error");
1240 rc = _vconf_set_key_check_parent_dir(path);
1241 if(rc != VCONF_OK) {
1242 ERR("_vconf_set_key_check_parent_dir error : %s", path);
1246 rc = _vconf_set_key_creation(path);
1247 if(rc != VCONF_OK) {
1248 ERR("_vconf_set_key_creation error : %s", path);
1251 INFO("%s key is created", keynode->keyname);
1263 else if (ret == VCONF_ERROR_FILE_CHMOD)
1274 else if (ret == VCONF_ERROR_FILE_LOCK)
1287 else if (ret == VCONF_ERROR_FILE_WRITE)
1306 if ((is_busy_err == 1) && (retry < VCONF_ERROR_RETRY_CNT)) {
1307 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);
1308 usleep((retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1311 ERR("%s : write buf error(%d). break. (%d)\n", keynode->keyname, ret, retry);
1312 func_ret = VCONF_ERROR;
1317 #ifdef VCONF_USE_SQLFS_TRANSACTION
1318 if(prefix == VCONF_BACKEND_DB) {
1319 if(func_ret == VCONF_ERROR) {
1320 _vconf_db_rollback_transaction();
1322 _vconf_db_commit_transaction();
1331 * This function set the value of given keys
1332 * @param[in] keylist the keylist which should contain changed keys
1333 * @return 0 on success, -1 on error
1335 API int vconf_set(keylist_t *keylist)
1339 keynode_t *got_node;
1341 int func_ret = VCONF_OK;
1345 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
1347 INFO("vconf_set (%d)START", keylist->num);
1349 got_node = _vconf_keylist_headnode(keylist);
1351 retvm_if(got_node == NULL, VCONF_ERROR, "Invalid argument: headnode is NULL");
1353 ret = _vconf_get_key_prefix(got_node->keyname, &prefix);
1354 retv_if(ret != VCONF_OK, ret);
1356 #ifdef VCONF_USE_SQLFS_TRANSACTION
1357 if(prefix == VCONF_BACKEND_DB) {
1358 _vconf_db_begin_transaction();
1362 while (got_node != NULL) {
1363 ret = _vconf_set_key(got_node);
1364 if(ret != VCONF_OK) {
1365 func_ret = VCONF_ERROR;
1368 got_node = _vconf_keynode_next(got_node);
1371 #ifdef VCONF_USE_SQLFS_TRANSACTION
1372 if(prefix == VCONF_BACKEND_DB) {
1373 if(func_ret == VCONF_ERROR) {
1374 _vconf_db_rollback_transaction();
1376 _vconf_db_commit_transaction();
1386 API int vconf_sync_key(const char *in_key)
1391 char path[VCONF_KEY_PATH_LEN] = {0,};
1394 ret = _vconf_get_key_path(in_key, path);
1395 if(ret != VCONF_OK) return VCONF_ERROR;
1397 fd = open(path, O_RDWR);
1398 if(fd == -1) return VCONF_ERROR;
1409 * This function set the integer value of given key
1410 * @param[in] in_key key
1411 * @param[in] intval integer value to set
1412 * @return 0 on success, -1 on error
1414 API int vconf_set_int(const char *in_key, const int intval)
1418 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1420 int func_ret = VCONF_OK;
1422 keynode_t* pKeyNode = _vconf_keynode_new();
1423 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1425 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1426 if(func_ret != VCONF_OK) {
1427 _vconf_keynode_free(pKeyNode);
1428 ERR("set key name error");
1431 _vconf_keynode_set_value_int(pKeyNode, intval);
1433 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1434 ERR("vconf_set_int(%d) : %s(%d) error", getpid(), in_key, intval);
1435 func_ret = VCONF_ERROR;
1437 INFO("vconf_set_int(%d) : %s(%d) success", getpid(), in_key, intval);
1440 _vconf_keynode_free(pKeyNode);
1448 * This function set the boolean value of given key
1449 * @param[in] in_key key
1450 * @param[in] boolval boolean value to set
1451 (Integer value 1 is 'True', and 0 is 'False')
1452 * @return 0 on success, -1 on error
1454 API int vconf_set_bool(const char *in_key, const int boolval)
1458 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1460 int func_ret = VCONF_OK;
1461 keynode_t* pKeyNode = _vconf_keynode_new();
1462 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1464 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1465 if(func_ret != VCONF_OK) {
1466 _vconf_keynode_free(pKeyNode);
1467 ERR("set key name error");
1470 _vconf_keynode_set_value_bool(pKeyNode, boolval);
1472 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1473 ERR("vconf_set_bool(%d) : %s(%d) error", getpid(), in_key, boolval);
1474 func_ret = VCONF_ERROR;
1476 INFO("vconf_set_bool(%d) : %s(%d) success", getpid(), in_key, boolval);
1479 _vconf_keynode_free(pKeyNode);
1487 * This function set the double value of given key
1488 * @param[in] in_key key
1489 * @param[in] dblval double value to set
1490 * @return 0 on success, -1 on error
1492 API int vconf_set_dbl(const char *in_key, const double dblval)
1496 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1498 int func_ret = VCONF_OK;
1499 keynode_t* pKeyNode = _vconf_keynode_new();
1500 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1502 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1503 if(func_ret != VCONF_OK) {
1504 _vconf_keynode_free(pKeyNode);
1505 ERR("set key name error");
1508 _vconf_keynode_set_value_dbl(pKeyNode, dblval);
1510 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1511 ERR("vconf_set_dbl(%d) : %s(%f) error", getpid(), in_key, dblval);
1512 func_ret = VCONF_ERROR;
1514 INFO("vconf_set_dbl(%d) : %s(%f) success", getpid(), in_key, dblval);
1517 _vconf_keynode_free(pKeyNode);
1525 * This function set the string value of given key
1526 * @param[in] in_key key
1527 * @param[in] strval string value to set
1528 * @return 0 on success, -1 on error
1530 API int vconf_set_str(const char *in_key, const char *strval)
1534 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1535 retvm_if(strval == NULL, VCONF_ERROR, "Invalid argument: value is NULL");
1537 int func_ret = VCONF_OK;
1538 keynode_t* pKeyNode = _vconf_keynode_new();
1539 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1541 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1542 if(func_ret != VCONF_OK) {
1543 _vconf_keynode_free(pKeyNode);
1544 ERR("set key name error");
1547 _vconf_keynode_set_value_str(pKeyNode, strval);
1549 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1550 ERR("vconf_set_str(%d) : %s(%s) error", getpid(), in_key, strval);
1551 func_ret = VCONF_ERROR;
1553 INFO("vconf_set_str(%d) : %s(%s) success", getpid(), in_key, strval);
1556 _vconf_keynode_free(pKeyNode);
1564 #ifdef SUPPORT_ELEKTRA_VALUE_FORMAT
1565 /* keyFileUnserialize function of ELEKTRA */
1566 static int _vconf_get_key_elektra_format(keynode_t *keynode, FILE *fp)
1568 char version[10] = {0,};
1569 char type[5] = {0,};
1570 char comment[8] = {0,};
1571 char file_buf[BUF_LEN] = {0,};
1575 char err_buf[100] = { 0, };
1576 int func_ret = VCONF_OK;
1579 INFO("_vconf_get_key_elektra_format start");
1583 if (!fgets(version, sizeof(version), fp))
1590 func_ret = VCONF_ERROR_FILE_FGETS;
1593 if (strncmp(version,"RG",2)) {
1594 func_ret = VCONF_ERROR_WRONG_TYPE;
1598 if (!fgets(type, sizeof(type), fp))
1605 func_ret = VCONF_ERROR_FILE_FGETS;
1609 if (!fgets(comment, sizeof(comment), fp))
1616 func_ret = VCONF_ERROR_FILE_FGETS;
1620 while(fgets(file_buf, sizeof(file_buf), fp))
1623 value_size = value_size + strlen(file_buf);
1624 tmp = (char *) realloc(value, value_size);
1627 func_ret = VCONF_ERROR_NO_MEM;
1631 strncat(value, file_buf, strlen(file_buf));
1633 value_size = strlen(file_buf) + 1;
1634 value = (char *)malloc(value_size);
1636 func_ret = VCONF_ERROR_NO_MEM;
1639 memset(value, 0x00, value_size);
1640 strncpy(value, file_buf, strlen(file_buf));
1646 func_ret = VCONF_ERROR_FILE_FGETS;
1651 case VCONF_TYPE_INT:
1653 _vconf_keynode_set_value_int(keynode, atoi(value));
1656 case VCONF_TYPE_DOUBLE:
1658 _vconf_keynode_set_value_dbl(keynode, atof(value));
1661 case VCONF_TYPE_BOOL:
1663 _vconf_keynode_set_value_bool(keynode, atoi(value));
1666 case VCONF_TYPE_STRING:
1668 _vconf_keynode_set_value_str(keynode, value);
1673 func_ret = VCONF_ERROR_WRONG_VALUE;
1677 if(atoi(type) == VCONF_TYPE_STRING) {
1678 _vconf_keynode_set_value_str(keynode, "");
1680 func_ret = VCONF_ERROR_WRONG_VALUE;
1687 strerror_r(err_no, err_buf, 100);
1688 ERR("_vconf_set_key_filesys(%d/%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1691 if(value) free(value);
1697 static int _vconf_get_key_filesys(keynode_t *keynode, int prefix)
1699 char path[VCONF_KEY_PATH_LEN] = {0,};
1701 int func_ret = VCONF_OK;
1702 char err_buf[100] = { 0, };
1706 #ifdef VCONF_USE_BACKUP_TRANSACTION
1707 char backup_path[VCONF_KEY_PATH_LEN] = {0,};
1712 ret = _vconf_get_key_path(keynode->keyname, path);
1713 retv_if(ret != VCONF_OK, ret);
1715 if(prefix == VCONF_BACKEND_MEMORY && VCONF_NOT_INITIALIZED)
1717 func_ret = VCONF_ERROR_NOT_INITIALIZED;
1721 #ifdef VCONF_USE_BACKUP_TRANSACTION
1722 if(prefix == VCONF_BACKEND_DB) {
1723 _vconf_get_backup_path(keynode->keyname, backup_path);
1724 ret = _vconf_backup_check(path, backup_path);
1725 if(ret != VCONF_OK) {
1733 if( (fp = fopen(path, "r")) == NULL ) {
1734 func_ret = VCONF_ERROR_FILE_OPEN;
1739 #ifdef VCONF_USE_SQLFS_TRANSACTION
1740 if (prefix != VCONF_BACKEND_DB)
1743 ret = _vconf_set_read_lock(fileno(fp));
1745 func_ret = VCONF_ERROR_FILE_LOCK;
1751 /* read data type */
1752 if(!fread((void*)&type, sizeof(int), 1, fp)) {
1758 func_ret = VCONF_ERROR_FILE_FREAD;
1762 /* read data value */
1765 case VCONF_TYPE_INT:
1768 if(!fread((void*)&value_int, sizeof(int), 1, fp)) {
1774 func_ret = VCONF_ERROR_FILE_FREAD;
1777 _vconf_keynode_set_value_int(keynode, value_int);
1782 case VCONF_TYPE_DOUBLE:
1784 double value_dbl = 0;
1785 if(!fread((void*)&value_dbl, sizeof(double), 1, fp)) {
1791 func_ret = VCONF_ERROR_FILE_FREAD;
1794 _vconf_keynode_set_value_dbl(keynode, value_dbl);
1799 case VCONF_TYPE_BOOL:
1802 if(!fread((void*)&value_int, sizeof(int), 1, fp)) {
1808 func_ret = VCONF_ERROR_FILE_FREAD;
1811 _vconf_keynode_set_value_bool(keynode, value_int);
1816 case VCONF_TYPE_STRING:
1818 char file_buf[BUF_LEN] = {0,};
1822 while(fgets(file_buf, sizeof(file_buf), fp))
1825 value_size = value_size + strlen(file_buf);
1826 value = (char *) realloc(value, value_size);
1828 func_ret = VCONF_ERROR_NO_MEM;
1831 strncat(value, file_buf, strlen(file_buf));
1833 value_size = strlen(file_buf) + 1;
1834 value = (char *)malloc(value_size);
1836 func_ret = VCONF_ERROR_NO_MEM;
1839 memset(value, 0x00, value_size);
1840 strncpy(value, file_buf, strlen(file_buf));
1846 func_ret = VCONF_ERROR_FILE_FGETS;
1849 _vconf_keynode_set_value_str(keynode, value);
1851 _vconf_keynode_set_value_str(keynode, "");
1860 #ifdef SUPPORT_ELEKTRA_VALUE_FORMAT
1861 func_ret = _vconf_get_key_elektra_format(keynode, fp);
1863 func_ret = VCONF_ERROR_WRONG_TYPE;
1868 #ifdef VCONF_USE_SQLFS_TRANSACTION
1869 if (prefix != VCONF_BACKEND_DB)
1872 ret = _vconf_set_unlock(fileno(fp));
1874 func_ret = VCONF_ERROR_FILE_LOCK;
1885 strerror_r(err_no, err_buf, 100);
1886 ERR("_vconf_get_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1893 int _vconf_get_key(keynode_t *keynode)
1895 int func_ret = VCONF_OK;
1897 int is_busy_err = 0;
1901 ret = _vconf_get_key_prefix(keynode->keyname, &prefix);
1902 retv_if(ret != VCONF_OK, ret);
1904 #ifdef VCONF_USE_SQLFS_TRANSACTION
1905 if(prefix == VCONF_BACKEND_DB) {
1906 _vconf_db_begin_transaction();
1910 while((ret = _vconf_get_key_filesys(keynode, prefix)) != VCONF_OK)
1915 if(VCONF_NOT_INITIALIZED)
1917 ERR("%s : vconf is not initialized\n", keynode->keyname);
1920 else if(ret == VCONF_ERROR_FILE_OPEN)
1932 else if (ret == VCONF_ERROR_FILE_LOCK)
1945 else if (ret == VCONF_ERROR_FILE_FREAD)
1962 if ((is_busy_err == 1) && (retry < VCONF_ERROR_RETRY_CNT)) {
1963 ERR("%s : read buf error(%d). read will be retried(%d) , %d\n", keynode->keyname, ret, retry, (retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1964 usleep((retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1967 ERR("%s : read buf error(%d). break\n", keynode->keyname, ret);
1968 func_ret = VCONF_ERROR;
1973 #ifdef VCONF_USE_SQLFS_TRANSACTION
1974 if(prefix == VCONF_BACKEND_DB) {
1975 if(func_ret == VCONF_ERROR) {
1976 _vconf_db_rollback_transaction();
1978 _vconf_db_commit_transaction();
1987 static int _vconf_check_value_integrity(const void *value, int type)
1991 if ((type == VCONF_TYPE_STRING) && (value != NULL)) {
1995 if ((value) && (strlen(value) > 0)) {
1996 if ((type == VCONF_TYPE_INT) ||
1997 (type == VCONF_TYPE_BOOL)||
1998 (type == VCONF_TYPE_DOUBLE)) {
1999 while (*(((char *)value) + i) != '\0') {
2000 if ( !isdigit(*(((char *)value) + i)) ) {
2001 if ((type != VCONF_TYPE_BOOL) &&
2002 (*(((char *)value) + i) != '-')) {
2003 if ((type == VCONF_TYPE_DOUBLE) &&
2004 (*(((char *)value) + i) != '.')) {
2005 ERR("ERROR : vconf value is not digit.");
2016 ERR("ERROR : vconf value is NULL.");
2022 int _vconf_path_is_dir(char* path)
2024 struct stat entryInfo;
2026 if(lstat(path, &entryInfo) == 0 ) {
2027 if( S_ISDIR( entryInfo.st_mode ) ) {
2037 API int vconf_get(keylist_t *keylist, const char *dirpath, get_option_t option)
2040 struct dirent entry;
2041 struct dirent *result = NULL;
2042 char full_file_path[VCONF_KEY_PATH_LEN] = {0,};
2043 char file_path[VCONF_KEY_PATH_LEN] = {0,};
2044 char full_path[VCONF_KEY_PATH_LEN] = {0,};
2045 char err_buf[ERR_LEN] = {0,};
2052 keynode_t *temp_keynode;
2054 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is null");
2055 retvm_if(dirpath == NULL, VCONF_ERROR, "Invalid argument: dirpath is null");
2057 temp_keynode = _vconf_keylist_headnode(keylist);
2059 if ((NULL != temp_keynode) && (VCONF_GET_KEY != option)) {
2060 ERR("Not support mode : Only VCONF_GET_KEY \
2061 option support To retrieve key with keylist");
2065 if(temp_keynode != NULL) {
2066 while(_vconf_keynode_next(temp_keynode)) {
2067 temp_keynode = _vconf_keynode_next(temp_keynode);
2071 ret = _vconf_get_key_path(dirpath, full_path);
2072 retvm_if(ret != VCONF_OK, ret, "Invalid argument: key is not valid");
2075 ret = _vconf_get_key_prefix(dirpath, &prefix);
2076 retv_if(ret != VCONF_OK, ret);
2078 #ifdef VCONF_USE_SQLFS_TRANSACTION
2079 if(prefix == VCONF_BACKEND_DB) {
2080 _vconf_db_begin_transaction();
2084 is_dir = _vconf_path_is_dir(full_path);
2086 if((dir=opendir(full_path)) == NULL) {
2087 strerror_r(errno, err_buf, ERR_LEN);
2088 ERR("ERROR : open directory(%s) fail(%s)", dirpath, err_buf);
2089 func_ret = VCONF_ERROR;
2093 if((readdir_r(dir, &entry, &result)) != 0) {
2094 strerror_r(errno, err_buf, ERR_LEN);
2095 ERR("ERROR : read directory(%s) fail(%s)", dirpath, err_buf);
2096 func_ret = VCONF_ERROR;
2099 while(result != NULL)
2101 if(( strcmp( entry.d_name, ".") == 0 ) || ( strcmp( entry.d_name, "..") == 0 )) {
2105 keynode_t* keynode = _vconf_keynode_new();
2106 if(keynode == NULL) {
2108 ERR("Invalid argument: key malloc fail");
2109 func_ret = VCONF_ERROR;
2113 snprintf(file_path, VCONF_KEY_PATH_LEN, "%s/%s", dirpath, entry.d_name);
2114 snprintf(full_file_path, VCONF_KEY_PATH_LEN, "%s/%s", full_path, entry.d_name);
2116 rc = _vconf_path_is_dir(full_file_path);
2117 if(rc != VCONF_ERROR) {
2120 if(option == VCONF_GET_KEY) {
2121 _vconf_keynode_free(keynode);
2124 _vconf_keynode_set_keyname(keynode, file_path);
2125 _vconf_keynode_set_dir(keynode);
2128 _vconf_keynode_set_keyname(keynode, file_path);
2129 _vconf_get_key(keynode);
2132 if (keylist->head && temp_keynode != NULL)
2134 temp_keynode->next = keynode;
2135 temp_keynode = _vconf_keynode_next(temp_keynode);
2138 keylist->head = keynode;
2139 temp_keynode = keylist->head;
2143 _vconf_keynode_free(keynode);
2145 memset(err_buf, 0x00, sizeof(err_buf));
2146 strerror_r(errno, err_buf, sizeof(err_buf));
2147 ERR("ERROR : get path(%s) fail(%s)", file_path, err_buf);
2148 func_ret = VCONF_ERROR;
2152 if((readdir_r(dir, &entry, &result)) != 0) {
2153 memset(err_buf, 0x00, sizeof(err_buf));
2154 strerror_r(errno, err_buf, sizeof(err_buf));
2155 ERR("ERROR : read directory(%s) fail(%s)", dirpath, err_buf);
2156 func_ret = VCONF_ERROR;
2160 if((closedir(dir)) != 0) {
2161 memset(err_buf, 0x00, sizeof(err_buf));
2162 strerror_r(errno, err_buf, sizeof(err_buf));
2163 ERR("ERROR : close directory(%s) fail(%s)", dirpath, err_buf);
2164 func_ret = VCONF_ERROR;
2166 } else if(is_dir == 0) {
2167 keynode_t* keynode = _vconf_keynode_new();
2168 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: key malloc fail");
2170 _vconf_keynode_set_keyname(keynode, dirpath);
2172 _vconf_get_key(keynode);
2174 if (keylist->head && temp_keynode != NULL) {
2175 temp_keynode->next = keynode;
2176 //temp_keynode = _vconf_keynode_next(temp_keynode);
2178 keylist->head = keynode;
2179 temp_keynode = keylist->head;
2183 func_ret = VCONF_ERROR;
2186 vconf_keylist_rewind(keylist);
2189 #ifdef VCONF_USE_SQLFS_TRANSACTION
2190 if(prefix == VCONF_BACKEND_DB) {
2191 if(func_ret == VCONF_ERROR) {
2192 _vconf_db_rollback_transaction();
2194 _vconf_db_commit_transaction();
2203 * This function get the integer value of given key
2204 * @param[in] in_key key
2205 * @param[out] intval output buffer
2206 * @return 0 on success, -1 on error
2208 API int vconf_get_int(const char *in_key, int *intval)
2212 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2213 retvm_if(intval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2215 int func_ret = VCONF_ERROR;
2216 keynode_t* pKeyNode = _vconf_keynode_new();
2217 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2219 _vconf_keynode_set_keyname(pKeyNode, in_key);
2221 if (_vconf_get_key(pKeyNode) != VCONF_OK)
2222 ERR("vconf_get_int(%d) : %s error", getpid(), in_key);
2224 *intval = pKeyNode->value.i;
2226 if(pKeyNode->type == VCONF_TYPE_INT) {
2227 INFO("vconf_get_int(%d) : %s(%d) success", getpid(), in_key, *intval);
2228 func_ret = VCONF_OK;
2230 ERR("The type(%d) of keynode(%s) is not INT", pKeyNode->type, pKeyNode->keyname);
2233 _vconf_keynode_free(pKeyNode);
2241 * This function get the boolean value of given key
2242 * @param[in] in_key key
2243 * @param[out] boolval output buffer
2244 * @return 0 on success, -1 on error
2246 API int vconf_get_bool(const char *in_key, int *boolval)
2250 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2251 retvm_if(boolval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2253 int func_ret = VCONF_ERROR;
2254 keynode_t* pKeyNode = _vconf_keynode_new();
2255 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2257 _vconf_keynode_set_keyname(pKeyNode, in_key);
2259 if (_vconf_get_key(pKeyNode) != VCONF_OK)
2260 ERR("vconf_get_bool(%d) : %s error", getpid(), in_key);
2262 *boolval = !!(pKeyNode->value.b);
2264 if(pKeyNode->type == VCONF_TYPE_BOOL) {
2265 INFO("vconf_get_bool(%d) : %s(%d) success", getpid(), in_key, *boolval);
2266 func_ret = VCONF_OK;
2268 ERR("The type(%d) of keynode(%s) is not BOOL", pKeyNode->type, pKeyNode->keyname);
2271 _vconf_keynode_free(pKeyNode);
2279 * This function get the double value of given key
2280 * @param[in] in_key key
2281 * @param[out] dblval output buffer
2282 * @return 0 on success, -1 on error
2284 API int vconf_get_dbl(const char *in_key, double *dblval)
2288 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2289 retvm_if(dblval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2291 int func_ret = VCONF_ERROR;
2292 keynode_t* pKeyNode = _vconf_keynode_new();
2293 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2295 _vconf_keynode_set_keyname(pKeyNode, in_key);
2297 if (_vconf_get_key(pKeyNode) != VCONF_OK)
2298 ERR("vconf_get_dbl(%d) : %s error", getpid(), in_key);
2301 *dblval = pKeyNode->value.d;
2303 if(pKeyNode->type == VCONF_TYPE_DOUBLE) {
2304 INFO("vconf_get_dbl(%d) : %s(%f) success", getpid(), in_key, *dblval);
2305 func_ret = VCONF_OK;
2307 ERR("The type(%d) of keynode(%s) is not DBL", pKeyNode->type, pKeyNode->keyname);
2310 _vconf_keynode_free(pKeyNode);
2318 * This function get the string value of given key
2319 * @param[in] in_key key
2320 * @return pointer of key value on success, NULL on error
2322 API char *vconf_get_str(const char *in_key)
2326 retvm_if(in_key == NULL, NULL, "Invalid argument: key is null");
2328 keynode_t* pKeyNode = _vconf_keynode_new();
2329 retvm_if(pKeyNode == NULL, NULL, "key malloc fail");
2331 _vconf_keynode_set_keyname(pKeyNode, in_key);
2333 char *strval = NULL;
2334 char *tempstr = NULL;
2336 if (_vconf_get_key(pKeyNode) != VCONF_OK) {
2337 ERR("vconf_get_str(%d) : %s error", getpid(), in_key);
2340 if(pKeyNode->type == VCONF_TYPE_STRING)
2341 tempstr = pKeyNode->value.s;
2343 ERR("The type(%d) of keynode(%s) is not STR", pKeyNode->type, pKeyNode->keyname);
2346 strval = strdup(tempstr);
2347 INFO("vconf_get_str(%d) : %s(%s) success", getpid(), in_key, strval);
2350 _vconf_keynode_free(pKeyNode);
2358 * This function unset given key
2359 * @param[in] in_key key
2360 * @return 0 on success, -1 on error
2362 API int vconf_unset(const char *in_key)
2366 char path[VCONF_KEY_PATH_LEN] = {0,};
2368 int err_retry = VCONF_ERROR_RETRY_CNT;
2369 int func_ret = VCONF_OK;
2371 WARN("vconf_unset: %s. THIS API(vconf_unset) WILL BE DEPRECATED", in_key);
2373 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2375 ret = _vconf_get_key_path(in_key, path);
2376 retvm_if(ret != VCONF_OK, VCONF_ERROR, "Invalid argument: key is not valid");
2378 retvm_if(access(path, F_OK) == -1, VCONF_ERROR, "Error : key(%s) is not exist", in_key);
2383 ERR("vconf_unset error(%d) : %s", errno, in_key);
2384 func_ret = VCONF_ERROR;
2386 func_ret = VCONF_OK;
2389 } while(err_retry--);
2397 * This function unset given key recursively
2398 * @param[in] in_dir Directory name for removing
2399 * @return 0 on success, -1 on error
2401 API int vconf_unset_recursive(const char *in_dir)
2406 struct dirent entry;
2407 struct dirent *result = NULL;
2408 char fullpath[VCONF_KEY_PATH_LEN] = {0,};
2409 char dirpath[VCONF_KEY_PATH_LEN] = {0,};
2410 char err_buf[ERR_LEN] = {0,};
2415 WARN("vconf_unset_recursive: %s. THIS API(vconf_unset_recursive) WILL BE DEPRECATED", in_dir);
2417 retvm_if(in_dir == NULL, VCONF_ERROR, "Invalid argument: dir path is null");
2419 ret = _vconf_get_key_path(in_dir, dirpath);
2420 retvm_if(ret != VCONF_OK, VCONF_ERROR, "Invalid argument: key is not valid");
2422 if((dir=opendir(dirpath)) == NULL) {
2423 strerror_r(errno, err_buf, ERR_LEN);
2424 ERR("ERROR : open directory(%s) fail(%s)", in_dir, err_buf);
2428 if((readdir_r(dir, &entry, &result)) != 0) {
2429 strerror_r(errno, err_buf, ERR_LEN);
2430 ERR("ERROR : read directory(%s) fail(%s)", in_dir, err_buf);
2431 func_ret = VCONF_ERROR;
2434 while(result != NULL)
2436 if(( strcmp( entry.d_name, ".") == 0 ) || ( strcmp( entry.d_name, "..") == 0 )) {
2440 snprintf(fullpath,VCONF_KEY_PATH_LEN, "%s/%s", dirpath, entry.d_name);
2442 ret = _vconf_path_is_dir(fullpath);
2443 if(ret != VCONF_ERROR) {
2445 rc = vconf_unset_recursive(fullpath);
2446 if(rc == VCONF_ERROR)
2447 func_ret = VCONF_ERROR;
2450 rc = remove(fullpath);
2452 memset(err_buf, 0x00, sizeof(err_buf));
2453 strerror_r(errno, err_buf, sizeof(err_buf));
2454 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2455 func_ret = VCONF_ERROR;
2458 memset(err_buf, 0x00, sizeof(err_buf));
2459 strerror_r(errno, err_buf, sizeof(err_buf));
2460 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2461 func_ret = VCONF_ERROR;
2464 if((readdir_r(dir, &entry, &result)) != 0) {
2465 memset(err_buf, 0x00, sizeof(err_buf));
2466 strerror_r(errno, err_buf, sizeof(err_buf));
2467 ERR("ERROR : read directory(%s) fail(%s)", in_dir, err_buf);
2468 func_ret = VCONF_ERROR;
2472 if((closedir(dir)) != 0) {
2473 memset(err_buf, 0x00, sizeof(err_buf));
2474 strerror_r(errno, err_buf, sizeof(err_buf));
2475 ERR("ERROR : close directory(%s) fail(%s)", in_dir, err_buf);
2476 func_ret = VCONF_ERROR;
2479 if(func_ret == VCONF_OK) {
2480 if((remove(in_dir)) == -1) {
2481 memset(err_buf, 0x00, sizeof(err_buf));
2482 strerror_r(errno, err_buf, sizeof(err_buf));
2483 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2484 func_ret = VCONF_ERROR;
2492 API int vconf_notify_key_changed(const char *in_key, vconf_callback_fn cb, void *user_data)
2496 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2497 retvm_if(cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
2499 if (_vconf_kdb_add_notify(in_key, cb, user_data)) {
2500 ERR("vconf_notify_key_changed : key(%s) add notify fail", in_key);
2504 INFO("vconf_notify_key_changed : %s noti is added", in_key);
2511 API int vconf_ignore_key_changed(const char *in_key, vconf_callback_fn cb)
2515 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2516 retvm_if(cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
2518 if (_vconf_kdb_del_notify(in_key, cb)) {
2519 ERR("vconf_ignore_key_changed() failed: key(%s)", in_key);
2523 INFO("vconf_ignore_key_changed : %s noti removed", in_key);
2530 API mode_t vconf_set_permission(mode_t mode)
2532 /* TODO: implement! */
2536 API int vconf_set_key_permission(const char *in_key, const mode_t mode)
2538 /* TODO: implement! */