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;
159 size_t length = 1 + strlen(keyname);
161 found_node = _vconf_keylist_headnode(keylist);
164 if(found_node->keyname == NULL) {
165 ERR("key node has null keyname");
169 if (!memcmp(keyname, found_node->keyname, length)) {
170 if (before_keynode) {
171 *before_keynode = temp_node;
176 temp_node = found_node;
177 found_node = _vconf_keynode_next(found_node);
183 * This function get Key name of the keynode.
184 * @param[in] keynode The Key
185 * @return Key Name of the keynode
187 API char *vconf_keynode_get_name(keynode_t *keynode)
189 retvm_if(keynode == NULL, NULL, "Invalid argument: keynode is NULL");
190 retvm_if(keynode->keyname == NULL, NULL, "The name of keynode is NULL");
192 return keynode->keyname;
196 * This function get value type of the keynode.
197 * @param[in] keynode The Key
198 * @return Type of the keynode
200 API int vconf_keynode_get_type(keynode_t *keynode)
202 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
204 return keynode->type;
207 API int vconf_keynode_get_int(keynode_t *keynode)
209 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
210 retvm_if(keynode->type != VCONF_TYPE_INT, VCONF_ERROR,
211 "The type(%d) of keynode(%s) is not INT", keynode->type, keynode->keyname);
213 return keynode->value.i;
216 API double vconf_keynode_get_dbl(keynode_t *keynode)
218 retvm_if(keynode == NULL, -1.0, "Invalid argument: keynode is NULL");
219 retvm_if(keynode->type != VCONF_TYPE_DOUBLE, -1.0,
220 "The type(%d) of keynode(%s) is not DBL", keynode->type, keynode->keyname);
222 return keynode->value.d;
226 * This function get Boolean value of the keynode.
227 * @param[in] keynode The Key
228 * @return Boolean value, -1 on error
230 API int vconf_keynode_get_bool(keynode_t *keynode)
232 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
233 retvm_if(keynode->type != VCONF_TYPE_BOOL, VCONF_ERROR,
234 "The type(%d) of keynode(%s) is not BOOL", keynode->type, keynode->keyname);
236 return !!(keynode->value.b);
240 * This function get String value of the keynode.
241 * @param[in] keynode The Key
242 * @return String value, NULL on error
244 API char *vconf_keynode_get_str(keynode_t *keynode)
246 retvm_if(keynode == NULL, NULL, "Invalid argument: keynode is NULL");
247 retvm_if(keynode->type != VCONF_TYPE_STRING, NULL,
248 "The type(%d) of keynode(%s) is not STR", keynode->type, keynode->keyname);
250 return keynode->value.s;
254 * Allocate, initialize and return a new Keylist object.
255 * @return The pointer of New keylist, NULL on error
257 API keylist_t *vconf_keylist_new(void)
260 keylist = calloc(1, sizeof(keylist_t));
266 * This function rewinds the KeyList internal cursor.
267 * @param[in] keylist Key List
268 * @return 0 on success, -1 on error
270 API int vconf_keylist_rewind(keylist_t *keylist)
272 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
274 keylist->cursor = NULL;
280 * A destructor for Keylist objects.
281 * @param[in] keylist Key List
282 * @return 0 on success, -1 on error
284 API int vconf_keylist_free(keylist_t *keylist)
286 keynode_t *keynode, *temp;
288 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
291 keynode = _vconf_keylist_headnode(keylist);
293 temp = _vconf_keynode_next(keynode);
294 _vconf_keynode_free(keynode);
303 * This function look for a Keynode contained in keylist that matches keyname.
304 * @param[in] keylist Key List
305 * @param[in] keyname Key to find
306 * @param[out] return_node pointer of keynode to set
307 * @return Type of the found key
310 vconf_keylist_lookup(keylist_t *keylist,
311 const char *keyname, keynode_t **return_node)
313 keynode_t *found_node;
315 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
316 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
317 retvm_if(return_node == NULL, VCONF_ERROR, "Invalid argument: return_node is NULL");
319 found_node = _vconf_keylist_lookup(keylist, keyname, NULL);
320 if (NULL == found_node)
324 *return_node = found_node;
325 return found_node->type;
329 * This function returns the next Key in a Keylist.
330 * Next key is known by the keylist internal cursor.
331 * @param[in] keylist Key List
332 * @return The next Keynode, NULL on error
334 API keynode_t *vconf_keylist_nextnode(keylist_t *keylist)
336 retvm_if(keylist == NULL, NULL, "Invalid argument: keylist is NULL");
339 keylist->cursor = _vconf_keynode_next(keylist->cursor);
341 keylist->cursor = keylist->head;
343 return keylist->cursor;
347 * This function appends a new Keynode included integer value to the keylist.
348 * If same keyname exist, the keynode will change.
349 * @param[in] keylist Key List
350 * @param[in] keyname Key
351 * @param[in] value The integer value
352 * @return Number of keynode included in the keylist, -1 on error
355 vconf_keylist_add_int(keylist_t *keylist, const char *keyname, const int value)
357 keynode_t *keynode = NULL, *addition = NULL;
359 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
360 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
362 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
363 _vconf_keynode_set_value_int(keynode, value);
366 if ((keynode = _vconf_keylist_headnode(keylist)))
367 while (_vconf_keynode_next(keynode))
368 keynode = _vconf_keynode_next(keynode);
370 addition = calloc(1, sizeof(keynode_t));
371 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
372 if (!_vconf_keynode_set_keyname(addition, keyname)) {
373 _vconf_keynode_set_value_int(addition, value);
374 if (keylist->head && NULL != keynode)
375 keynode->next = addition;
377 keylist->head = addition;
380 ERR("(maybe)not enought memory");
381 free(addition), addition = NULL;
389 * This function appends a new Keynode included boolean value to the keylist.
390 * If same keyname exist, the keynode will change.
391 * @param[in] keylist Key List
392 * @param[in] keyname Key
393 * @param[in] value The boolean value
394 * @return Number of keynode included in the keylist, -1 on error
397 vconf_keylist_add_bool(keylist_t *keylist, const char *keyname, const int value)
399 keynode_t *keynode = NULL, *addition = NULL;
401 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
402 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
404 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
405 _vconf_keynode_set_value_bool(keynode, value);
408 if ((keynode = _vconf_keylist_headnode(keylist)))
409 while (_vconf_keynode_next(keynode))
410 keynode = _vconf_keynode_next(keynode);
412 addition = calloc(1, sizeof(keynode_t));
413 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
414 if (!_vconf_keynode_set_keyname(addition, keyname)) {
415 _vconf_keynode_set_value_bool(addition, value);
416 if (keylist->head && NULL != keynode)
417 keynode->next = addition;
419 keylist->head = addition;
422 ERR("(maybe)not enought memory");
423 free(addition), addition = NULL;
431 * This function appends a new Keynode included double value to the keylist.
432 * If same keyname exist, the keynode will change.
433 * @param[in] keylist Key List
434 * @param[in] keyname Key
435 * @param[in] value The double value
436 * @return Number of keynode included in the keylist, -1 on error
439 vconf_keylist_add_dbl(keylist_t *keylist,
440 const char *keyname, const double value)
442 keynode_t *keynode = NULL, *addition = NULL;
444 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
445 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
447 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
448 _vconf_keynode_set_value_dbl(keynode, value);
451 if ((keynode = _vconf_keylist_headnode(keylist)))
452 while (_vconf_keynode_next(keynode))
453 keynode = _vconf_keynode_next(keynode);
455 addition = calloc(1, sizeof(keynode_t));
456 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
457 if (!_vconf_keynode_set_keyname(addition, keyname)) {
458 _vconf_keynode_set_value_dbl(addition, value);
459 if (keylist->head && NULL != keynode)
460 keynode->next = addition;
462 keylist->head = addition;
465 ERR("(maybe)not enought memory");
466 free(addition), addition = NULL;
474 * This function appends a new Keynode included string value to the keylist.
475 * If same keyname exist, the keynode will change.
476 * @param[in] keylist Key List
477 * @param[in] keyname Key
478 * @param[in] value The pointer of string value
479 * @return Number of keynode included in the keylist, -1 on error
482 vconf_keylist_add_str(keylist_t *keylist,
483 const char *keyname, const char *value)
485 keynode_t *keynode = NULL, *addition = NULL;
487 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
488 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
490 if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
491 if (VCONF_TYPE_STRING == keynode->type && keynode->value.s)
492 free(keynode->value.s);
493 _vconf_keynode_set_value_str(keynode, value);
496 if (NULL != (keynode = _vconf_keylist_headnode(keylist)))
497 while (_vconf_keynode_next(keynode))
498 keynode = _vconf_keynode_next(keynode);
500 addition = calloc(1, sizeof(keynode_t));
501 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
502 if (!_vconf_keynode_set_keyname(addition, keyname)) {
503 _vconf_keynode_set_value_str(addition, value);
504 if (keylist->head && NULL != keynode)
505 keynode->next = addition;
507 keylist->head = addition;
510 ERR("(maybe)not enought memory");
511 free(addition), addition = NULL;
519 * This function Appends a new Keynode to the keylist without value.
521 * @param[in] keylist Key List
522 * @param[in] keyname Key
523 * @return Number of keynode included in the keylist, -1 on error
525 API int vconf_keylist_add_null(keylist_t *keylist, const char *keyname)
527 keynode_t *keynode = NULL, *addition = NULL;
529 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
530 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
532 if (NULL != (keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
534 keynode->value.d = 0;
537 if ((keynode = _vconf_keylist_headnode(keylist)))
538 while (_vconf_keynode_next(keynode))
539 keynode = _vconf_keynode_next(keynode);
541 addition = calloc(1, sizeof(keynode_t));
542 retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
543 if (!_vconf_keynode_set_keyname(addition, keyname)) {
544 if (keylist->head && keynode)
545 keynode->next = addition;
547 keylist->head = addition;
550 ERR("(maybe)not enought memory");
551 free(addition), addition = NULL;
559 * This function remove the keynode that matches keyname.
560 * @param[in] keylist the keylist included the keyname
561 * @param[in] keyname key
562 * @return 0 on success, -1(Invalid parameter), -2(Not exist keyname in keylist) on error
564 API int vconf_keylist_del(keylist_t *keylist, const char *keyname)
566 keynode_t *found_node, *before_node = NULL;
568 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
569 retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
571 if ((found_node = _vconf_keylist_lookup(keylist, keyname, &before_node))) {
573 before_node->next = found_node->next;
575 /* requested key is headnode of keylist */
576 keylist->head = found_node->next;
579 _vconf_keynode_free(found_node);
587 int _vconf_get_key_prefix(const char *keyname, int *prefix)
589 if (strncmp(keyname, BACKEND_DB_PREFIX, strlen(BACKEND_DB_PREFIX)) == 0) {
590 *prefix = VCONF_BACKEND_DB;
591 } else if (0 == strncmp(keyname, BACKEND_FILE_PREFIX, strlen(BACKEND_FILE_PREFIX))) {
592 *prefix = VCONF_BACKEND_FILE;
593 } else if (0 == strncmp(keyname, BACKEND_MEMORY_PREFIX, strlen(BACKEND_MEMORY_PREFIX))) {
594 *prefix = VCONF_BACKEND_MEMORY;
596 ERR("Invalid argument: wrong prefix of key(%s)", keyname);
597 *prefix = VCONF_BACKEND_NULL;
598 return VCONF_ERROR_WRONG_PREFIX;
604 int _vconf_get_key_path(const char *keyname, char *path)
606 if (strncmp(keyname, BACKEND_DB_PREFIX, strlen(BACKEND_DB_PREFIX)) == 0) {
607 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_SYSTEM_DIR, keyname);
608 } else if (0 == strncmp(keyname, BACKEND_FILE_PREFIX, strlen(BACKEND_FILE_PREFIX))) {
609 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_SYSTEM_DIR, keyname);
610 } else if (0 == strncmp(keyname, BACKEND_MEMORY_PREFIX, strlen(BACKEND_MEMORY_PREFIX))) {
611 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_MEMORY_DIR, keyname);
613 ERR("Invalid argument: wrong prefix of key(%s)", keyname);
614 return VCONF_ERROR_WRONG_PREFIX;
620 #ifdef VCONF_USE_BACKUP_TRANSACTION
621 int _vconf_get_backup_path(const char *keyname, char *path)
623 char key_buf[VCONF_KEY_PATH_LEN] = {0, };
626 for(i = 0; i<VCONF_KEY_PATH_LEN-1 && keyname[i] != '\0' ; i++) {
627 if (keyname[i] == '/')
630 key_buf[i] = keyname[i];
633 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s%s%s", BACKEND_SYSTEM_DIR, BACKEND_DB_PREFIX, ".backup/", key_buf);
639 #ifndef DISABLE_RUNTIME_KEY_CREATION
640 static int _vconf_set_key_check_parent_dir(const char* path)
643 struct stat stat_info;
645 char path_buf[VCONF_KEY_PATH_LEN] = {0,};
648 mode_t dir_mode = 0664 | 0111;
650 parent = strrchr(path, '/');
651 strncpy(path_buf, path, parent-path);
652 path_buf[parent-path]=0;
654 exists = stat(path_buf,&stat_info);
656 if(mkdir(path_buf, dir_mode) != 0) {
657 if(errno == ENOENT) {
658 ret = _vconf_set_key_check_parent_dir((const char*)path_buf);
659 if(ret != VCONF_OK) return ret;
660 if(mkdir(path_buf, dir_mode) != 0) {
661 ERR("mkdir error(%d)", errno);
671 static int _vconf_set_key_creation(const char* path)
676 fd = open(path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
679 ERR("open(rdwr,create) error\n");
688 static int _vconf_set_file_lock(int fd, short type)
692 l.l_type = type; /*Do read Lock*/
693 l.l_start= 0; /*Start at begin*/
694 l.l_whence = SEEK_SET;
695 l.l_len = 0; /*Do it with whole file*/
697 return fcntl(fd, F_SETLKW, &l);
700 static int _vconf_set_read_lock(int fd)
702 return _vconf_set_file_lock(fd, F_RDLCK);
705 static int _vconf_set_write_lock(int fd)
707 return _vconf_set_file_lock(fd, F_WRLCK);
710 static int _vconf_set_unlock(int fd)
712 return _vconf_set_file_lock(fd, F_UNLCK);
715 #ifdef VCONF_USE_SQLFS_TRANSACTION
716 static void _vconf_acquire_transaction_delay(int ms)
718 struct timeval timeout;
719 timeout.tv_sec = ms / 1000 ;
720 timeout.tv_usec = 1000 * ( ms % 1000 );
722 select(0, 0, 0, 0, &timeout);
725 static int _vconf_db_begin_transaction()
728 VCONF_MOUNT_PATH_CHECK;
730 if(is_transaction == 0) {
733 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_start", &value, sizeof(value), 0) == -1)
735 //ERR("someone access vconf. retrying...(%d)", errno);
736 _vconf_acquire_transaction_delay(50);
737 goto transaction_retry;
748 static int _vconf_db_commit_transaction()
751 VCONF_MOUNT_PATH_CHECK;
753 retv_if(is_transaction <= 0, VCONF_ERROR);
755 if(is_transaction == 1) {
758 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_stop", &value, sizeof(value), 0) == -1)
760 //ERR("setxattr failed. retrying...(%d)", errno);
761 _vconf_acquire_transaction_delay(50);
762 goto transaction_retry;
773 static int _vconf_db_rollback_transaction()
776 VCONF_MOUNT_PATH_CHECK;
778 retv_if(is_transaction <= 0, VCONF_ERROR);
780 if(is_transaction == 1) {
783 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_rb", &value, sizeof(value), 0) == -1)
785 //ERR("setxattr failed. retrying...(%d)", errno);
786 _vconf_acquire_transaction_delay(50);
787 goto transaction_retry;
797 #endif //VCONF_USE_SQLFS_TRANSACTION
799 #ifdef VCONF_USE_BACKUP_TRANSACTION
801 static int _vconf_backup_check(char* vconf_path, char* backup_path)
806 char file_buf[BUF_LEN] = { 0, };
807 char err_buf[100] = { 0, };
808 int complete_mark = 0;
811 int is_recovered = 0;
814 if (access(vconf_path, F_OK) == -1 || access(backup_path, F_OK) == -1)
817 vconf_fd = open(vconf_path, O_WRONLY);
818 if (vconf_fd == -1) {
819 ERR("open %s failed", vconf_path);
820 ret = VCONF_ERROR_FILE_OPEN;
825 if(_vconf_set_write_lock(vconf_fd) == -1) {
826 ERR("set write lock %s failed", vconf_path);
827 ret = VCONF_ERROR_FILE_LOCK;
832 backup_fd = open(backup_path, O_RDONLY);
833 if (backup_fd == -1) {
834 ERR("open %s failed", backup_path);
835 ret = VCONF_ERROR_FILE_OPEN;
840 file_size = lseek(backup_fd, 0, SEEK_END);
841 if (file_size == -1) {
842 ERR("seek end %s failed", backup_path);
843 ret = VCONF_ERROR_FILE_SEEK;
846 } else if (file_size < FILE_ATOMIC_GUARANTEE_SIZE + VCONF_BACKUP_COMP_MARK_SIZE) {
850 if (lseek(backup_fd, 0, SEEK_SET) != 0) {
851 ERR("seek %s failed", backup_path);
852 ret = VCONF_ERROR_FILE_SEEK;
857 read_len = read(backup_fd, &complete_mark, sizeof(int));
858 if (read_len < sizeof(int))
861 if (complete_mark != VCONF_BACKUP_COMPLETE_MARK)
864 if (ftruncate(vconf_fd, 0) == -1) {
865 ERR("truncate %s failed", vconf_path);
866 ret = VCONF_ERROR_FILE_TRUNCATE;
871 while ( (read_len = read(backup_fd, file_buf, BUF_LEN )) >0) {
872 if(write(vconf_fd, file_buf, read_len) != read_len) {
873 ERR("write %s failed", backup_path);
874 ret = VCONF_ERROR_FILE_WRITE;
883 if(_vconf_set_unlock(vconf_fd)==-1) {
884 ERR("unset write lock %s failed", vconf_path);
885 ret = VCONF_ERROR_FILE_LOCK;
896 if(ret == VCONF_OK) {
897 if(remove(backup_path) == -1) {
898 ret = VCONF_ERROR_FILE_REMOVE;
903 if(ret != VCONF_OK) {
904 strerror_r(err_no, err_buf, 100);
905 ERR("_vconf_backup_check failed %d (%d / %s)\n", ret, err_no, err_buf);
906 } else if (is_recovered)
907 WARN("vconf(%s) successfully recovered and backup file is removed", vconf_path, backup_path);
909 WARN("vconf(%s)'s non-complete backup file is removed", vconf_path, backup_path);
914 static int _vconf_backup_write_str(char* backup_path, char* value)
917 char err_buf[100] = { 0, };
921 int complete_mark = VCONF_BACKUP_COMPLETE_MARK;
923 int vconf_type_str = VCONF_TYPE_STRING;
926 if( (backup_fd = open(backup_path, O_CREAT|O_EXCL|O_WRONLY, 0666)) == -1 ) {
927 ERR("open %s failed", backup_path);
928 ret = VCONF_ERROR_FILE_OPEN;
933 if ((result = write(backup_fd, (void *)&empty_mark, sizeof(int))) != sizeof(int)) {
934 ERR("write empty mark of %s failed %d", backup_path, result);
935 ret = VCONF_ERROR_FILE_WRITE;
940 if ((result = write(backup_fd, (void *)&vconf_type_str, sizeof(int))) != sizeof(int)) {
941 ERR("write type of %s failed %d", backup_path, result);
942 ret = VCONF_ERROR_FILE_WRITE;
947 write_len = strlen(value);
948 if((result = write(backup_fd, value, write_len)) != write_len) {
949 ERR("write %s failed %d", backup_path, result);
950 ret = VCONF_ERROR_FILE_WRITE;
956 if (fdatasync(backup_fd) == -1) {
957 ERR("sync %s failed", backup_path);
958 ret = VCONF_ERROR_FILE_SYNC;
963 if (lseek(backup_fd, 0, SEEK_SET) != 0) {
964 ERR("seek %s failed", backup_path);
965 ret = VCONF_ERROR_FILE_SEEK;
970 if((result = write(backup_fd, (void *)&complete_mark, sizeof(int))) != sizeof(int)) {
971 ERR("write complete mark of %s failed %d", backup_path, result);
972 ret = VCONF_ERROR_FILE_WRITE;
977 if (fdatasync(backup_fd) == -1) {
978 ERR("sync %s failed", backup_path);
979 ret = VCONF_ERROR_FILE_SYNC;
988 if(ret != VCONF_OK) {
989 strerror_r(err_no, err_buf, 100);
990 ERR("_vconf_backup_write_str failed %d (%d / %s)\n", ret, err_no, err_buf);
997 static int _vconf_backup_commit(char* backup_path)
1000 char err_buf[100] = { 0, };
1003 if(remove(backup_path) == -1) {
1004 ERR("remove %s failed", backup_path);
1005 ret = VCONF_ERROR_FILE_REMOVE;
1009 if(ret != VCONF_OK) {
1010 strerror_r(err_no, err_buf, 100);
1011 ERR("_vconf_backup_commit failed %d (%d / %s)\n", ret, err_no, err_buf);
1017 #endif // VCONF_USE_BACKUP_TRANSACTION
1019 static int _vconf_set_key_filesys(keynode_t *keynode, int prefix)
1021 char path[VCONF_KEY_PATH_LEN] = {0,};
1024 int func_ret = VCONF_OK;
1026 char err_buf[100] = { 0, };
1027 int is_write_error = 0;
1028 #ifdef VCONF_USE_BACKUP_TRANSACTION
1029 char backup_path[VCONF_KEY_PATH_LEN] = {0,};
1030 int is_backup_need = 0;
1036 ret = _vconf_get_key_path(keynode->keyname, path);
1037 retv_if(ret != VCONF_OK, ret);
1040 #ifdef VCONF_CHECK_IS_INITIALIZED
1041 if(prefix == VCONF_BACKEND_MEMORY && VCONF_NOT_INITIALIZED) {
1042 func_ret = VCONF_ERROR_NOT_INITIALIZED;
1047 #ifdef VCONF_USE_BACKUP_TRANSACTION
1048 if(prefix == VCONF_BACKEND_DB && keynode->type == VCONF_TYPE_STRING) {
1049 _vconf_get_backup_path(keynode->keyname, backup_path);
1050 ret = _vconf_backup_check(path, backup_path);
1051 if(ret != VCONF_OK) {
1059 if( (fp = fopen(path, "r+")) == NULL ) {
1060 func_ret = VCONF_ERROR_FILE_OPEN;
1065 #ifdef VCONF_USE_SQLFS_TRANSACTION
1066 if (prefix != VCONF_BACKEND_DB)
1069 ret = _vconf_set_write_lock(fileno(fp));
1071 func_ret = VCONF_ERROR_FILE_LOCK;
1077 #ifdef VCONF_USE_BACKUP_TRANSACTION
1078 if(prefix == VCONF_BACKEND_DB && keynode->type == VCONF_TYPE_STRING) {
1079 file_size = VCONF_TYPE_SIZE + strlen(keynode->value.s);
1080 if (file_size > FILE_ATOMIC_GUARANTEE_SIZE) {
1083 ret = _vconf_backup_write_str(backup_path, keynode->value.s);
1084 if(ret != VCONF_OK) {
1089 WARN("vconf backup file for(%s) is created. file size(%d)", path, file_size);
1094 if (ftruncate(fileno(fp), 0) == -1) {
1095 func_ret = VCONF_ERROR_FILE_TRUNCATE;
1100 /* write key type */
1101 ret = fwrite((void *)&(keynode->type), sizeof(int), 1, fp);
1109 func_ret = VCONF_ERROR_FILE_WRITE;
1113 /* write key value */
1114 switch(keynode->type)
1116 case VCONF_TYPE_INT:
1117 ret = fwrite((void *)&(keynode->value.i), sizeof(int), 1, fp);
1118 if(ret <= 0) is_write_error = 1;
1120 case VCONF_TYPE_DOUBLE:
1121 ret = fwrite((void *)&(keynode->value.d), sizeof(double), 1, fp);
1122 if(ret <= 0) is_write_error = 1;
1124 case VCONF_TYPE_BOOL:
1125 ret = fwrite((void *)&(keynode->value.b), sizeof(int), 1, fp);
1126 if(ret <= 0) is_write_error = 1;
1128 case VCONF_TYPE_STRING:
1129 ret = fprintf(fp,"%s",keynode->value.s);
1130 if(ret < strlen(keynode->value.s)) is_write_error = 1;
1131 //ret = fwrite((void *)keynode->value.s, sizeof(char), strlen(keynode->value.s), fp);
1134 func_ret = VCONF_ERROR_WRONG_TYPE;
1144 func_ret = VCONF_ERROR_FILE_WRITE;
1148 #ifdef VCONF_USE_SQLFS_TRANSACTION
1149 if(prefix == VCONF_BACKEND_FILE)
1151 if(prefix == VCONF_BACKEND_FILE || prefix == VCONF_BACKEND_DB)
1156 ret = fdatasync(fileno(fp));
1159 func_ret = VCONF_ERROR_FILE_SYNC;
1163 #ifdef VCONF_USE_BACKUP_TRANSACTION
1164 if (is_backup_need) {
1165 ret = _vconf_backup_commit(backup_path);
1166 if(ret != VCONF_OK) {
1175 #ifdef VCONF_USE_SQLFS_TRANSACTION
1176 if (prefix != VCONF_BACKEND_DB)
1179 ret = _vconf_set_unlock(fileno(fp));
1181 func_ret = VCONF_ERROR_FILE_LOCK;
1191 strerror_r(err_no, err_buf, 100);
1192 ERR("_vconf_set_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1198 static int _vconf_set_key(keynode_t *keynode)
1200 int func_ret = VCONF_OK;
1202 int is_busy_err = 0;
1207 ret = _vconf_get_key_prefix(keynode->keyname, &prefix);
1208 retv_if(ret != VCONF_OK, ret);
1210 #ifdef VCONF_USE_SQLFS_TRANSACTION
1211 if(prefix == VCONF_BACKEND_DB) {
1212 _vconf_db_begin_transaction();
1216 while((ret = _vconf_set_key_filesys(keynode, prefix)) != VCONF_OK)
1221 #ifdef VCONF_CHECK_INITIALIZED
1222 if(VCONF_NOT_INITIALIZED)
1224 ERR("%s : vconf is not initialized\n", keynode->keyname);
1227 else if(ret == VCONF_ERROR_FILE_OPEN)
1230 if(ret == VCONF_ERROR_FILE_OPEN)
1235 /* file is not exist, make path */
1236 #ifndef DISABLE_RUNTIME_KEY_CREATION
1240 char path[VCONF_KEY_PATH_LEN] = {0,};
1241 rc = _vconf_get_key_path(keynode->keyname, path);
1242 if(rc != VCONF_OK) {
1243 ERR("_vconf_get_key_path error");
1247 rc = _vconf_set_key_check_parent_dir(path);
1248 if(rc != VCONF_OK) {
1249 ERR("_vconf_set_key_check_parent_dir error : %s", path);
1253 rc = _vconf_set_key_creation(path);
1254 if(rc != VCONF_OK) {
1255 ERR("_vconf_set_key_creation error : %s", path);
1258 INFO("%s key is created", keynode->keyname);
1270 else if (ret == VCONF_ERROR_FILE_CHMOD)
1281 else if (ret == VCONF_ERROR_FILE_LOCK)
1294 else if (ret == VCONF_ERROR_FILE_WRITE)
1313 if ((is_busy_err == 1) && (retry < VCONF_ERROR_RETRY_CNT)) {
1314 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);
1315 usleep((retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1318 ERR("%s : write buf error(%d). break. (%d)\n", keynode->keyname, ret, retry);
1319 func_ret = VCONF_ERROR;
1324 #ifdef VCONF_USE_SQLFS_TRANSACTION
1325 if(prefix == VCONF_BACKEND_DB) {
1326 if(func_ret == VCONF_ERROR) {
1327 _vconf_db_rollback_transaction();
1329 _vconf_db_commit_transaction();
1338 * This function set the value of given keys
1339 * @param[in] keylist the keylist which should contain changed keys
1340 * @return 0 on success, -1 on error
1342 API int vconf_set(keylist_t *keylist)
1346 keynode_t *got_node;
1348 int func_ret = VCONF_OK;
1352 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
1354 INFO("vconf_set (%d)START", keylist->num);
1356 got_node = _vconf_keylist_headnode(keylist);
1358 retvm_if(got_node == NULL, VCONF_ERROR, "Invalid argument: headnode is NULL");
1360 ret = _vconf_get_key_prefix(got_node->keyname, &prefix);
1361 retv_if(ret != VCONF_OK, ret);
1363 #ifdef VCONF_USE_SQLFS_TRANSACTION
1364 if(prefix == VCONF_BACKEND_DB) {
1365 _vconf_db_begin_transaction();
1369 while (got_node != NULL) {
1370 ret = _vconf_set_key(got_node);
1371 if(ret != VCONF_OK) {
1372 func_ret = VCONF_ERROR;
1375 got_node = _vconf_keynode_next(got_node);
1378 #ifdef VCONF_USE_SQLFS_TRANSACTION
1379 if(prefix == VCONF_BACKEND_DB) {
1380 if(func_ret == VCONF_ERROR) {
1381 _vconf_db_rollback_transaction();
1383 _vconf_db_commit_transaction();
1393 API int vconf_sync_key(const char *in_key)
1398 char path[VCONF_KEY_PATH_LEN] = {0,};
1401 ret = _vconf_get_key_path(in_key, path);
1402 if(ret != VCONF_OK) return VCONF_ERROR;
1404 fd = open(path, O_RDWR);
1405 if(fd == -1) return VCONF_ERROR;
1416 * This function set the integer value of given key
1417 * @param[in] in_key key
1418 * @param[in] intval integer value to set
1419 * @return 0 on success, -1 on error
1421 API int vconf_set_int(const char *in_key, const int intval)
1425 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1427 int func_ret = VCONF_OK;
1429 keynode_t* pKeyNode = _vconf_keynode_new();
1430 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1432 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1433 if(func_ret != VCONF_OK) {
1434 _vconf_keynode_free(pKeyNode);
1435 ERR("set key name error");
1438 _vconf_keynode_set_value_int(pKeyNode, intval);
1440 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1441 ERR("vconf_set_int(%d) : %s(%d) error", getpid(), in_key, intval);
1442 func_ret = VCONF_ERROR;
1444 INFO("vconf_set_int(%d) : %s(%d) success", getpid(), in_key, intval);
1447 _vconf_keynode_free(pKeyNode);
1455 * This function set the boolean value of given key
1456 * @param[in] in_key key
1457 * @param[in] boolval boolean value to set
1458 (Integer value 1 is 'True', and 0 is 'False')
1459 * @return 0 on success, -1 on error
1461 API int vconf_set_bool(const char *in_key, const int boolval)
1465 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1467 int func_ret = VCONF_OK;
1468 keynode_t* pKeyNode = _vconf_keynode_new();
1469 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1471 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1472 if(func_ret != VCONF_OK) {
1473 _vconf_keynode_free(pKeyNode);
1474 ERR("set key name error");
1477 _vconf_keynode_set_value_bool(pKeyNode, boolval);
1479 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1480 ERR("vconf_set_bool(%d) : %s(%d) error", getpid(), in_key, boolval);
1481 func_ret = VCONF_ERROR;
1483 INFO("vconf_set_bool(%d) : %s(%d) success", getpid(), in_key, boolval);
1486 _vconf_keynode_free(pKeyNode);
1494 * This function set the double value of given key
1495 * @param[in] in_key key
1496 * @param[in] dblval double value to set
1497 * @return 0 on success, -1 on error
1499 API int vconf_set_dbl(const char *in_key, const double dblval)
1503 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1505 int func_ret = VCONF_OK;
1506 keynode_t* pKeyNode = _vconf_keynode_new();
1507 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1509 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1510 if(func_ret != VCONF_OK) {
1511 _vconf_keynode_free(pKeyNode);
1512 ERR("set key name error");
1515 _vconf_keynode_set_value_dbl(pKeyNode, dblval);
1517 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1518 ERR("vconf_set_dbl(%d) : %s(%f) error", getpid(), in_key, dblval);
1519 func_ret = VCONF_ERROR;
1521 INFO("vconf_set_dbl(%d) : %s(%f) success", getpid(), in_key, dblval);
1524 _vconf_keynode_free(pKeyNode);
1532 * This function set the string value of given key
1533 * @param[in] in_key key
1534 * @param[in] strval string value to set
1535 * @return 0 on success, -1 on error
1537 API int vconf_set_str(const char *in_key, const char *strval)
1541 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1542 retvm_if(strval == NULL, VCONF_ERROR, "Invalid argument: value is NULL");
1544 int func_ret = VCONF_OK;
1545 keynode_t* pKeyNode = _vconf_keynode_new();
1546 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1548 func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1549 if(func_ret != VCONF_OK) {
1550 _vconf_keynode_free(pKeyNode);
1551 ERR("set key name error");
1554 _vconf_keynode_set_value_str(pKeyNode, strval);
1556 if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1557 ERR("vconf_set_str(%d) : %s(%s) error", getpid(), in_key, strval);
1558 func_ret = VCONF_ERROR;
1560 INFO("vconf_set_str(%d) : %s(%s) success", getpid(), in_key, strval);
1563 _vconf_keynode_free(pKeyNode);
1571 #ifdef SUPPORT_ELEKTRA_VALUE_FORMAT
1572 /* keyFileUnserialize function of ELEKTRA */
1573 static int _vconf_get_key_elektra_format(keynode_t *keynode, FILE *fp)
1575 char version[10] = {0,};
1576 char type[5] = {0,};
1577 char comment[8] = {0,};
1578 char file_buf[BUF_LEN] = {0,};
1582 char err_buf[100] = { 0, };
1583 int func_ret = VCONF_OK;
1586 INFO("_vconf_get_key_elektra_format start");
1590 if (!fgets(version, sizeof(version), fp))
1597 func_ret = VCONF_ERROR_FILE_FGETS;
1600 if (strncmp(version,"RG",2)) {
1601 func_ret = VCONF_ERROR_WRONG_TYPE;
1605 if (!fgets(type, sizeof(type), fp))
1612 func_ret = VCONF_ERROR_FILE_FGETS;
1616 if (!fgets(comment, sizeof(comment), fp))
1623 func_ret = VCONF_ERROR_FILE_FGETS;
1627 while(fgets(file_buf, sizeof(file_buf), fp))
1630 value_size = value_size + strlen(file_buf);
1631 tmp = (char *) realloc(value, value_size);
1634 func_ret = VCONF_ERROR_NO_MEM;
1638 strncat(value, file_buf, strlen(file_buf));
1640 value_size = strlen(file_buf) + 1;
1641 value = (char *)malloc(value_size);
1643 func_ret = VCONF_ERROR_NO_MEM;
1646 memset(value, 0x00, value_size);
1647 strncpy(value, file_buf, strlen(file_buf));
1653 func_ret = VCONF_ERROR_FILE_FGETS;
1658 case VCONF_TYPE_INT:
1660 _vconf_keynode_set_value_int(keynode, atoi(value));
1663 case VCONF_TYPE_DOUBLE:
1665 _vconf_keynode_set_value_dbl(keynode, atof(value));
1668 case VCONF_TYPE_BOOL:
1670 _vconf_keynode_set_value_bool(keynode, atoi(value));
1673 case VCONF_TYPE_STRING:
1675 _vconf_keynode_set_value_str(keynode, value);
1680 func_ret = VCONF_ERROR_WRONG_VALUE;
1684 if(atoi(type) == VCONF_TYPE_STRING) {
1685 _vconf_keynode_set_value_str(keynode, "");
1687 func_ret = VCONF_ERROR_WRONG_VALUE;
1694 strerror_r(err_no, err_buf, 100);
1695 ERR("_vconf_set_key_filesys(%d/%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1698 if(value) free(value);
1704 static int _vconf_get_key_filesys(keynode_t *keynode, int prefix)
1706 char path[VCONF_KEY_PATH_LEN] = {0,};
1708 int func_ret = VCONF_OK;
1709 char err_buf[100] = { 0, };
1713 #ifdef VCONF_USE_BACKUP_TRANSACTION
1714 char backup_path[VCONF_KEY_PATH_LEN] = {0,};
1719 ret = _vconf_get_key_path(keynode->keyname, path);
1720 retv_if(ret != VCONF_OK, ret);
1722 #ifdef VCONF_CHECK_INITIALIZED
1723 if(prefix == VCONF_BACKEND_MEMORY && VCONF_NOT_INITIALIZED)
1725 func_ret = VCONF_ERROR_NOT_INITIALIZED;
1730 #ifdef VCONF_USE_BACKUP_TRANSACTION
1731 if(prefix == VCONF_BACKEND_DB) {
1732 _vconf_get_backup_path(keynode->keyname, backup_path);
1733 ret = _vconf_backup_check(path, backup_path);
1734 if(ret != VCONF_OK) {
1742 if( (fp = fopen(path, "r")) == NULL ) {
1743 func_ret = VCONF_ERROR_FILE_OPEN;
1748 #ifdef VCONF_USE_SQLFS_TRANSACTION
1749 if (prefix != VCONF_BACKEND_DB)
1752 ret = _vconf_set_read_lock(fileno(fp));
1754 func_ret = VCONF_ERROR_FILE_LOCK;
1760 /* read data type */
1761 if(!fread((void*)&type, sizeof(int), 1, fp)) {
1767 func_ret = VCONF_ERROR_FILE_FREAD;
1771 /* read data value */
1774 case VCONF_TYPE_INT:
1777 if(!fread((void*)&value_int, sizeof(int), 1, fp)) {
1783 func_ret = VCONF_ERROR_FILE_FREAD;
1786 _vconf_keynode_set_value_int(keynode, value_int);
1791 case VCONF_TYPE_DOUBLE:
1793 double value_dbl = 0;
1794 if(!fread((void*)&value_dbl, sizeof(double), 1, fp)) {
1800 func_ret = VCONF_ERROR_FILE_FREAD;
1803 _vconf_keynode_set_value_dbl(keynode, value_dbl);
1808 case VCONF_TYPE_BOOL:
1811 if(!fread((void*)&value_int, sizeof(int), 1, fp)) {
1817 func_ret = VCONF_ERROR_FILE_FREAD;
1820 _vconf_keynode_set_value_bool(keynode, value_int);
1825 case VCONF_TYPE_STRING:
1827 char file_buf[BUF_LEN] = {0,};
1831 while(fgets(file_buf, sizeof(file_buf), fp))
1834 value_size = value_size + strlen(file_buf);
1835 value = (char *) realloc(value, value_size);
1837 func_ret = VCONF_ERROR_NO_MEM;
1840 strncat(value, file_buf, strlen(file_buf));
1842 value_size = strlen(file_buf) + 1;
1843 value = (char *)malloc(value_size);
1845 func_ret = VCONF_ERROR_NO_MEM;
1848 memset(value, 0x00, value_size);
1849 strncpy(value, file_buf, strlen(file_buf));
1855 func_ret = VCONF_ERROR_FILE_FGETS;
1858 _vconf_keynode_set_value_str(keynode, value);
1860 _vconf_keynode_set_value_str(keynode, "");
1869 #ifdef SUPPORT_ELEKTRA_VALUE_FORMAT
1870 func_ret = _vconf_get_key_elektra_format(keynode, fp);
1872 func_ret = VCONF_ERROR_WRONG_TYPE;
1877 #ifdef VCONF_USE_SQLFS_TRANSACTION
1878 if (prefix != VCONF_BACKEND_DB)
1881 ret = _vconf_set_unlock(fileno(fp));
1883 func_ret = VCONF_ERROR_FILE_LOCK;
1894 strerror_r(err_no, err_buf, 100);
1895 ERR("_vconf_get_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1902 int _vconf_get_key(keynode_t *keynode)
1904 int func_ret = VCONF_OK;
1906 int is_busy_err = 0;
1910 ret = _vconf_get_key_prefix(keynode->keyname, &prefix);
1911 retv_if(ret != VCONF_OK, ret);
1913 #ifdef VCONF_USE_SQLFS_TRANSACTION
1914 if(prefix == VCONF_BACKEND_DB) {
1915 _vconf_db_begin_transaction();
1919 while((ret = _vconf_get_key_filesys(keynode, prefix)) != VCONF_OK)
1924 #ifdef VCONF_CHECK_INITIALIZED
1925 if(VCONF_NOT_INITIALIZED)
1927 ERR("%s : vconf is not initialized\n", keynode->keyname);
1930 else if(ret == VCONF_ERROR_FILE_OPEN)
1932 if(ret == VCONF_ERROR_FILE_OPEN)
1945 else if (ret == VCONF_ERROR_FILE_LOCK)
1958 else if (ret == VCONF_ERROR_FILE_FREAD)
1975 if ((is_busy_err == 1) && (retry < VCONF_ERROR_RETRY_CNT)) {
1976 ERR("%s : read buf error(%d). read will be retried(%d) , %d\n", keynode->keyname, ret, retry, (retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1977 usleep((retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1980 ERR("%s : read buf error(%d). break\n", keynode->keyname, ret);
1981 func_ret = VCONF_ERROR;
1986 #ifdef VCONF_USE_SQLFS_TRANSACTION
1987 if(prefix == VCONF_BACKEND_DB) {
1988 if(func_ret == VCONF_ERROR) {
1989 _vconf_db_rollback_transaction();
1991 _vconf_db_commit_transaction();
2000 static int _vconf_check_value_integrity(const void *value, int type)
2004 if ((type == VCONF_TYPE_STRING) && (value != NULL)) {
2008 if ((value) && (strlen(value) > 0)) {
2009 if ((type == VCONF_TYPE_INT) ||
2010 (type == VCONF_TYPE_BOOL)||
2011 (type == VCONF_TYPE_DOUBLE)) {
2012 while (*(((char *)value) + i) != '\0') {
2013 if ( !isdigit(*(((char *)value) + i)) ) {
2014 if ((type != VCONF_TYPE_BOOL) &&
2015 (*(((char *)value) + i) != '-')) {
2016 if ((type == VCONF_TYPE_DOUBLE) &&
2017 (*(((char *)value) + i) != '.')) {
2018 ERR("ERROR : vconf value is not digit.");
2029 ERR("ERROR : vconf value is NULL.");
2035 int _vconf_path_is_dir(char* path)
2037 struct stat entryInfo;
2039 if(lstat(path, &entryInfo) == 0 ) {
2040 if( S_ISDIR( entryInfo.st_mode ) ) {
2050 API int vconf_get(keylist_t *keylist, const char *dirpath, get_option_t option)
2053 struct dirent entry;
2054 struct dirent *result = NULL;
2055 char full_file_path[VCONF_KEY_PATH_LEN] = {0,};
2056 char file_path[VCONF_KEY_PATH_LEN] = {0,};
2057 char full_path[VCONF_KEY_PATH_LEN] = {0,};
2058 char err_buf[ERR_LEN] = {0,};
2065 keynode_t *temp_keynode;
2067 retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is null");
2068 retvm_if(dirpath == NULL, VCONF_ERROR, "Invalid argument: dirpath is null");
2070 temp_keynode = _vconf_keylist_headnode(keylist);
2072 if ((NULL != temp_keynode) && (VCONF_GET_KEY != option)) {
2073 ERR("Not support mode : Only VCONF_GET_KEY \
2074 option support To retrieve key with keylist");
2078 if(temp_keynode != NULL) {
2079 while(_vconf_keynode_next(temp_keynode)) {
2080 temp_keynode = _vconf_keynode_next(temp_keynode);
2084 ret = _vconf_get_key_path(dirpath, full_path);
2085 retvm_if(ret != VCONF_OK, ret, "Invalid argument: key is not valid");
2088 ret = _vconf_get_key_prefix(dirpath, &prefix);
2089 retv_if(ret != VCONF_OK, ret);
2091 #ifdef VCONF_USE_SQLFS_TRANSACTION
2092 if(prefix == VCONF_BACKEND_DB) {
2093 _vconf_db_begin_transaction();
2097 is_dir = _vconf_path_is_dir(full_path);
2099 if((dir=opendir(full_path)) == NULL) {
2100 strerror_r(errno, err_buf, ERR_LEN);
2101 ERR("ERROR : open directory(%s) fail(%s)", dirpath, err_buf);
2102 func_ret = VCONF_ERROR;
2106 if((readdir_r(dir, &entry, &result)) != 0) {
2107 strerror_r(errno, err_buf, ERR_LEN);
2108 ERR("ERROR : read directory(%s) fail(%s)", dirpath, err_buf);
2109 func_ret = VCONF_ERROR;
2112 while(result != NULL)
2114 if(( strcmp( entry.d_name, ".") == 0 ) || ( strcmp( entry.d_name, "..") == 0 )) {
2118 keynode_t* keynode = _vconf_keynode_new();
2119 if(keynode == NULL) {
2121 ERR("Invalid argument: key malloc fail");
2122 func_ret = VCONF_ERROR;
2126 snprintf(file_path, VCONF_KEY_PATH_LEN, "%s/%s", dirpath, entry.d_name);
2127 snprintf(full_file_path, VCONF_KEY_PATH_LEN, "%s/%s", full_path, entry.d_name);
2129 rc = _vconf_path_is_dir(full_file_path);
2130 if(rc != VCONF_ERROR) {
2133 if(option == VCONF_GET_KEY) {
2134 _vconf_keynode_free(keynode);
2137 _vconf_keynode_set_keyname(keynode, file_path);
2138 _vconf_keynode_set_dir(keynode);
2141 _vconf_keynode_set_keyname(keynode, file_path);
2142 _vconf_get_key(keynode);
2145 if (keylist->head && temp_keynode != NULL)
2147 temp_keynode->next = keynode;
2148 temp_keynode = _vconf_keynode_next(temp_keynode);
2151 keylist->head = keynode;
2152 temp_keynode = keylist->head;
2156 _vconf_keynode_free(keynode);
2158 memset(err_buf, 0x00, sizeof(err_buf));
2159 strerror_r(errno, err_buf, sizeof(err_buf));
2160 ERR("ERROR : get path(%s) fail(%s)", file_path, err_buf);
2161 func_ret = VCONF_ERROR;
2165 if((readdir_r(dir, &entry, &result)) != 0) {
2166 memset(err_buf, 0x00, sizeof(err_buf));
2167 strerror_r(errno, err_buf, sizeof(err_buf));
2168 ERR("ERROR : read directory(%s) fail(%s)", dirpath, err_buf);
2169 func_ret = VCONF_ERROR;
2173 if((closedir(dir)) != 0) {
2174 memset(err_buf, 0x00, sizeof(err_buf));
2175 strerror_r(errno, err_buf, sizeof(err_buf));
2176 ERR("ERROR : close directory(%s) fail(%s)", dirpath, err_buf);
2177 func_ret = VCONF_ERROR;
2179 } else if(is_dir == 0) {
2180 keynode_t* keynode = _vconf_keynode_new();
2181 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: key malloc fail");
2183 _vconf_keynode_set_keyname(keynode, dirpath);
2185 _vconf_get_key(keynode);
2187 if (keylist->head && temp_keynode != NULL) {
2188 temp_keynode->next = keynode;
2189 //temp_keynode = _vconf_keynode_next(temp_keynode);
2191 keylist->head = keynode;
2192 temp_keynode = keylist->head;
2196 func_ret = VCONF_ERROR;
2199 vconf_keylist_rewind(keylist);
2202 #ifdef VCONF_USE_SQLFS_TRANSACTION
2203 if(prefix == VCONF_BACKEND_DB) {
2204 if(func_ret == VCONF_ERROR) {
2205 _vconf_db_rollback_transaction();
2207 _vconf_db_commit_transaction();
2216 * This function get the integer value of given key
2217 * @param[in] in_key key
2218 * @param[out] intval output buffer
2219 * @return 0 on success, -1 on error
2221 API int vconf_get_int(const char *in_key, int *intval)
2225 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2226 retvm_if(intval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2228 int func_ret = VCONF_ERROR;
2229 keynode_t* pKeyNode = _vconf_keynode_new();
2230 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2232 _vconf_keynode_set_keyname(pKeyNode, in_key);
2234 if (_vconf_get_key(pKeyNode) != VCONF_OK)
2235 ERR("vconf_get_int(%d) : %s error", getpid(), in_key);
2237 *intval = pKeyNode->value.i;
2239 if(pKeyNode->type == VCONF_TYPE_INT) {
2240 INFO("vconf_get_int(%d) : %s(%d) success", getpid(), in_key, *intval);
2241 func_ret = VCONF_OK;
2243 ERR("The type(%d) of keynode(%s) is not INT", pKeyNode->type, pKeyNode->keyname);
2246 _vconf_keynode_free(pKeyNode);
2254 * This function get the boolean value of given key
2255 * @param[in] in_key key
2256 * @param[out] boolval output buffer
2257 * @return 0 on success, -1 on error
2259 API int vconf_get_bool(const char *in_key, int *boolval)
2263 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2264 retvm_if(boolval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2266 int func_ret = VCONF_ERROR;
2267 keynode_t* pKeyNode = _vconf_keynode_new();
2268 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2270 _vconf_keynode_set_keyname(pKeyNode, in_key);
2272 if (_vconf_get_key(pKeyNode) != VCONF_OK)
2273 ERR("vconf_get_bool(%d) : %s error", getpid(), in_key);
2275 *boolval = !!(pKeyNode->value.b);
2277 if(pKeyNode->type == VCONF_TYPE_BOOL) {
2278 INFO("vconf_get_bool(%d) : %s(%d) success", getpid(), in_key, *boolval);
2279 func_ret = VCONF_OK;
2281 ERR("The type(%d) of keynode(%s) is not BOOL", pKeyNode->type, pKeyNode->keyname);
2284 _vconf_keynode_free(pKeyNode);
2292 * This function get the double value of given key
2293 * @param[in] in_key key
2294 * @param[out] dblval output buffer
2295 * @return 0 on success, -1 on error
2297 API int vconf_get_dbl(const char *in_key, double *dblval)
2301 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2302 retvm_if(dblval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2304 int func_ret = VCONF_ERROR;
2305 keynode_t* pKeyNode = _vconf_keynode_new();
2306 retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2308 _vconf_keynode_set_keyname(pKeyNode, in_key);
2310 if (_vconf_get_key(pKeyNode) != VCONF_OK)
2311 ERR("vconf_get_dbl(%d) : %s error", getpid(), in_key);
2314 *dblval = pKeyNode->value.d;
2316 if(pKeyNode->type == VCONF_TYPE_DOUBLE) {
2317 INFO("vconf_get_dbl(%d) : %s(%f) success", getpid(), in_key, *dblval);
2318 func_ret = VCONF_OK;
2320 ERR("The type(%d) of keynode(%s) is not DBL", pKeyNode->type, pKeyNode->keyname);
2323 _vconf_keynode_free(pKeyNode);
2331 * This function get the string value of given key
2332 * @param[in] in_key key
2333 * @return pointer of key value on success, NULL on error
2335 API char *vconf_get_str(const char *in_key)
2339 retvm_if(in_key == NULL, NULL, "Invalid argument: key is null");
2341 keynode_t* pKeyNode = _vconf_keynode_new();
2342 retvm_if(pKeyNode == NULL, NULL, "key malloc fail");
2344 _vconf_keynode_set_keyname(pKeyNode, in_key);
2346 char *strval = NULL;
2347 char *tempstr = NULL;
2349 if (_vconf_get_key(pKeyNode) != VCONF_OK) {
2350 ERR("vconf_get_str(%d) : %s error", getpid(), in_key);
2353 if(pKeyNode->type == VCONF_TYPE_STRING)
2354 tempstr = pKeyNode->value.s;
2356 ERR("The type(%d) of keynode(%s) is not STR", pKeyNode->type, pKeyNode->keyname);
2359 strval = strdup(tempstr);
2360 INFO("vconf_get_str(%d) : %s(%s) success", getpid(), in_key, strval);
2363 _vconf_keynode_free(pKeyNode);
2371 * This function unset given key
2372 * @param[in] in_key key
2373 * @return 0 on success, -1 on error
2375 API int vconf_unset(const char *in_key)
2379 char path[VCONF_KEY_PATH_LEN] = {0,};
2381 int err_retry = VCONF_ERROR_RETRY_CNT;
2382 int func_ret = VCONF_OK;
2384 WARN("vconf_unset: %s. THIS API(vconf_unset) WILL BE DEPRECATED", in_key);
2386 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2388 ret = _vconf_get_key_path(in_key, path);
2389 retvm_if(ret != VCONF_OK, VCONF_ERROR, "Invalid argument: key is not valid");
2391 retvm_if(access(path, F_OK) == -1, VCONF_ERROR, "Error : key(%s) is not exist", in_key);
2396 ERR("vconf_unset error(%d) : %s", errno, in_key);
2397 func_ret = VCONF_ERROR;
2399 func_ret = VCONF_OK;
2402 } while(err_retry--);
2410 * This function unset given key recursively
2411 * @param[in] in_dir Directory name for removing
2412 * @return 0 on success, -1 on error
2414 API int vconf_unset_recursive(const char *in_dir)
2419 struct dirent entry;
2420 struct dirent *result = NULL;
2421 char fullpath[VCONF_KEY_PATH_LEN] = {0,};
2422 char dirpath[VCONF_KEY_PATH_LEN] = {0,};
2423 char err_buf[ERR_LEN] = {0,};
2428 WARN("vconf_unset_recursive: %s. THIS API(vconf_unset_recursive) WILL BE DEPRECATED", in_dir);
2430 retvm_if(in_dir == NULL, VCONF_ERROR, "Invalid argument: dir path is null");
2432 ret = _vconf_get_key_path(in_dir, dirpath);
2433 retvm_if(ret != VCONF_OK, VCONF_ERROR, "Invalid argument: key is not valid");
2435 if((dir=opendir(dirpath)) == NULL) {
2436 strerror_r(errno, err_buf, ERR_LEN);
2437 ERR("ERROR : open directory(%s) fail(%s)", in_dir, err_buf);
2441 if((readdir_r(dir, &entry, &result)) != 0) {
2442 strerror_r(errno, err_buf, ERR_LEN);
2443 ERR("ERROR : read directory(%s) fail(%s)", in_dir, err_buf);
2444 func_ret = VCONF_ERROR;
2447 while(result != NULL)
2449 if(( strcmp( entry.d_name, ".") == 0 ) || ( strcmp( entry.d_name, "..") == 0 )) {
2453 snprintf(fullpath,VCONF_KEY_PATH_LEN, "%s/%s", dirpath, entry.d_name);
2455 ret = _vconf_path_is_dir(fullpath);
2456 if(ret != VCONF_ERROR) {
2458 rc = vconf_unset_recursive(fullpath);
2459 if(rc == VCONF_ERROR)
2460 func_ret = VCONF_ERROR;
2463 rc = remove(fullpath);
2465 memset(err_buf, 0x00, sizeof(err_buf));
2466 strerror_r(errno, err_buf, sizeof(err_buf));
2467 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2468 func_ret = VCONF_ERROR;
2471 memset(err_buf, 0x00, sizeof(err_buf));
2472 strerror_r(errno, err_buf, sizeof(err_buf));
2473 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2474 func_ret = VCONF_ERROR;
2477 if((readdir_r(dir, &entry, &result)) != 0) {
2478 memset(err_buf, 0x00, sizeof(err_buf));
2479 strerror_r(errno, err_buf, sizeof(err_buf));
2480 ERR("ERROR : read directory(%s) fail(%s)", in_dir, err_buf);
2481 func_ret = VCONF_ERROR;
2485 if((closedir(dir)) != 0) {
2486 memset(err_buf, 0x00, sizeof(err_buf));
2487 strerror_r(errno, err_buf, sizeof(err_buf));
2488 ERR("ERROR : close directory(%s) fail(%s)", in_dir, err_buf);
2489 func_ret = VCONF_ERROR;
2492 if(func_ret == VCONF_OK) {
2493 if((remove(in_dir)) == -1) {
2494 memset(err_buf, 0x00, sizeof(err_buf));
2495 strerror_r(errno, err_buf, sizeof(err_buf));
2496 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2497 func_ret = VCONF_ERROR;
2505 API int vconf_notify_key_changed(const char *in_key, vconf_callback_fn cb, void *user_data)
2509 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2510 retvm_if(cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
2512 if (_vconf_kdb_add_notify(in_key, cb, user_data)) {
2513 ERR("vconf_notify_key_changed : key(%s) add notify fail", in_key);
2517 INFO("vconf_notify_key_changed : %s noti is added", in_key);
2524 API int vconf_ignore_key_changed(const char *in_key, vconf_callback_fn cb)
2528 retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2529 retvm_if(cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
2531 if (_vconf_kdb_del_notify(in_key, cb)) {
2532 ERR("vconf_ignore_key_changed() failed: key(%s)", in_key);
2536 INFO("vconf_ignore_key_changed : %s noti removed", in_key);
2543 API mode_t vconf_set_permission(mode_t mode)
2545 /* TODO: implement! */
2549 API int vconf_set_key_permission(const char *in_key, const mode_t mode)
2551 /* TODO: implement! */