PTREL 471:Merge from tizen2.2 branch from git repository framework/appfw/vconf
[platform/core/appfw/vconf.git] / vconf.c
1 /*
2  * libslp-setting
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hakjoo Ko <hakjoo.ko@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <stdlib.h>
23 #include <limits.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include "vconf-internals.h"
28 #include <dirent.h>
29 #include <sys/stat.h>
30 #include <sys/xattr.h>
31 #include <ctype.h>
32
33 #ifndef API
34 #define API __attribute__ ((visibility("default")))
35 #endif
36
37 #define VCONF_ERROR_RETRY_CNT 20
38 #define VCONF_ERROR_RETRY_SLEEP_UTIME 10000
39
40 #ifdef VCONF_USE_SQLFS_TRANSACTION
41 int IN_SBOX=0;
42
43 #define VCONF_MOUNT_PATH "/opt/var/kdb/db"
44 #define VCONF_MOUNT_PATH_CHECK \
45 do{\
46         if(!IN_SBOX) \
47       IN_SBOX = access("/opt/var/kdb/kdb_first_boot", F_OK) + 2; \
48         if(2==IN_SBOX) return 0;\
49 }while(0)
50
51 __thread int is_transaction;
52 #endif
53
54 #ifdef VCONF_TIMECHECK
55 double correction, startT;
56
57 double set_start_time(void)
58 {
59         struct timeval tv;
60         double curtime;
61
62         gettimeofday(&tv, NULL);
63         curtime = tv.tv_sec * 1000 + (double)tv.tv_usec / 1000;
64         return curtime;
65 }
66
67 double exec_time(double start)
68 {
69         double end = set_start_time();
70         return (end - start - correction);
71 }
72
73 int init_time(void)
74 {
75         double temp_t;
76         temp_t = set_start_time();
77         correction = exec_time(temp_t);
78
79         return 0;
80 }
81 #endif
82
83 int _vconf_keynode_set_keyname(keynode_t *keynode, const char *keyname)
84 {
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");
88         return VCONF_OK;
89 }
90
91 static inline void _vconf_keynode_set_dir(keynode_t *keynode)
92 {
93         keynode->type = VCONF_TYPE_DIR;
94 }
95
96 static inline void _vconf_keynode_set_value_int(keynode_t *keynode, const int value)
97 {
98         keynode->type = VCONF_TYPE_INT;
99         keynode->value.i = value;
100 }
101
102 static inline void _vconf_keynode_set_value_bool(keynode_t *keynode, const int value)
103 {
104         keynode->type = VCONF_TYPE_BOOL;
105         keynode->value.b = !!value;
106 }
107
108 static inline void _vconf_keynode_set_value_dbl(keynode_t *keynode, const double value)
109 {
110         keynode->type = VCONF_TYPE_DOUBLE;
111         keynode->value.d = value;
112 }
113
114 static inline void _vconf_keynode_set_value_str(keynode_t *keynode, const char *value)
115 {
116         keynode->type = VCONF_TYPE_STRING;
117         keynode->value.s = strdup(value);
118 }
119
120 inline void _vconf_keynode_set_null(keynode_t *keynode)
121 {
122         keynode->type = VCONF_TYPE_NONE;
123         //keynode->value.d = NULL;
124 }
125
126 static inline keynode_t *_vconf_keynode_next(keynode_t *keynode)
127 {
128         return keynode->next;
129 }
130
131 inline keynode_t *_vconf_keynode_new(void)
132 {
133         keynode_t *keynode;
134         keynode = calloc(1, sizeof(keynode_t));
135
136         return keynode;
137 }
138
139 inline void _vconf_keynode_free(keynode_t *keynode)
140 {
141         if(keynode) {
142                 if (keynode->keyname)
143                         free(keynode->keyname);
144                 if (keynode->type == VCONF_TYPE_STRING && keynode->value.s)
145                         free(keynode->value.s);
146                 free(keynode);
147         }
148 }
149
150 static inline keynode_t *_vconf_keylist_headnode(keylist_t *keylist)
151 {
152         return keylist->head;
153 }
154
155 static keynode_t *_vconf_keylist_lookup(keylist_t *keylist, const char *keyname,
156                                  keynode_t **before_keynode)
157 {
158         keynode_t *found_node, *temp_node = NULL;
159
160         found_node = _vconf_keylist_headnode(keylist);
161
162         while (found_node) {
163                 if(found_node->keyname == NULL) {
164                         ERR("key node has null keyname");
165                         return NULL;
166                 }
167
168                 if (!strncmp(keyname, found_node->keyname, strlen(keyname))) {
169                         if (before_keynode) {
170                                         *before_keynode = temp_node;
171                         }
172                         return found_node;
173                 }
174
175                 temp_node = found_node;
176                 found_node = _vconf_keynode_next(found_node);
177         }
178         return NULL;
179 }
180
181 /*
182  * This function get Key name of the keynode.
183  * @param[in] keynode The Key
184  * @return Key Name of the keynode
185  */
186 API char *vconf_keynode_get_name(keynode_t *keynode)
187 {
188         retvm_if(keynode == NULL, NULL, "Invalid argument: keynode is NULL");
189         retvm_if(keynode->keyname == NULL, NULL, "The name of keynode is NULL");
190
191         return keynode->keyname;
192 }
193
194 /*
195  * This function get value type of the keynode.
196  * @param[in] keynode The Key
197  * @return Type of the keynode
198  */
199 API int vconf_keynode_get_type(keynode_t *keynode)
200 {
201         retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
202
203         return keynode->type;
204 }
205
206 API int vconf_keynode_get_int(keynode_t *keynode)
207 {
208         retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
209         retvm_if(keynode->type != VCONF_TYPE_INT, VCONF_ERROR,
210                  "The type(%d) of keynode(%s) is not INT", keynode->type, keynode->keyname);
211
212         return keynode->value.i;
213 }
214
215 API double vconf_keynode_get_dbl(keynode_t *keynode)
216 {
217         retvm_if(keynode == NULL, -1.0, "Invalid argument: keynode is NULL");
218         retvm_if(keynode->type != VCONF_TYPE_DOUBLE, -1.0,
219                  "The type(%d) of keynode(%s) is not DBL", keynode->type, keynode->keyname);
220
221         return keynode->value.d;
222 }
223
224 /*
225  * This function get Boolean value of the keynode.
226  * @param[in] keynode The Key
227  * @return Boolean value, -1 on error
228  */
229 API int vconf_keynode_get_bool(keynode_t *keynode)
230 {
231         retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: keynode is NULL");
232         retvm_if(keynode->type != VCONF_TYPE_BOOL, VCONF_ERROR,
233                  "The type(%d) of keynode(%s) is not BOOL", keynode->type, keynode->keyname);
234
235         return !!(keynode->value.b);
236 }
237
238 /*
239  * This function get String value of the keynode.
240  * @param[in] keynode The Key
241  * @return String value, NULL on error
242  */
243 API char *vconf_keynode_get_str(keynode_t *keynode)
244 {
245         retvm_if(keynode == NULL, NULL, "Invalid argument: keynode is NULL");
246         retvm_if(keynode->type != VCONF_TYPE_STRING, NULL,
247                 "The type(%d) of keynode(%s) is not STR", keynode->type, keynode->keyname);
248
249         return keynode->value.s;
250 }
251
252 /*
253  * Allocate, initialize and return a new Keylist object.
254  * @return The pointer of New keylist, NULL on error
255  */
256 API keylist_t *vconf_keylist_new(void)
257 {
258         keylist_t *keylist;
259         keylist = calloc(1, sizeof(keylist_t));
260
261         return keylist;
262 }
263
264 /*
265  * This function rewinds the KeyList internal cursor.
266  * @param[in] keylist Key List
267  * @return 0 on success, -1 on error
268  */
269 API int vconf_keylist_rewind(keylist_t *keylist)
270 {
271         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
272
273         keylist->cursor = NULL;
274
275         return 0;
276 }
277
278 /*
279  * A destructor for Keylist objects.
280  * @param[in] keylist Key List
281  * @return 0 on success, -1 on error
282  */
283 API int vconf_keylist_free(keylist_t *keylist)
284 {
285         keynode_t *keynode, *temp;
286
287         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
288
289         if (keylist->num) {
290                 keynode = _vconf_keylist_headnode(keylist);
291                 while (keynode) {
292                         temp = _vconf_keynode_next(keynode);
293                         _vconf_keynode_free(keynode);
294                         keynode = temp;
295                 }
296         }
297         free(keylist);
298         return 0;
299 }
300
301 /*
302  * This function look for a Keynode contained in keylist that matches keyname.
303  * @param[in] keylist Key List
304  * @param[in] keyname Key to find
305  * @param[out] return_node pointer of keynode to set
306  * @return Type of the found key
307  */
308 API int
309 vconf_keylist_lookup(keylist_t *keylist,
310                      const char *keyname, keynode_t **return_node)
311 {
312         keynode_t *found_node;
313
314         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
315         retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
316         retvm_if(return_node == NULL, VCONF_ERROR, "Invalid argument: return_node is NULL");
317
318         found_node = _vconf_keylist_lookup(keylist, keyname, NULL);
319         if (NULL == found_node)
320                 return 0;
321
322         if (return_node)
323                 *return_node = found_node;
324         return found_node->type;
325 }
326
327 /*
328  * This function returns the next Key in a Keylist.
329  * Next key is known by the keylist internal cursor.
330  * @param[in] keylist Key List
331  * @return The next Keynode, NULL on error
332  */
333 API keynode_t *vconf_keylist_nextnode(keylist_t *keylist)
334 {
335         retvm_if(keylist == NULL, NULL, "Invalid argument: keylist is NULL");
336
337         if (keylist->cursor)
338                 keylist->cursor = _vconf_keynode_next(keylist->cursor);
339         else
340                 keylist->cursor = keylist->head;
341
342         return keylist->cursor;
343 }
344
345 /*
346  * This function appends a new Keynode included integer value to the keylist.
347  * If same keyname exist, the keynode will change.
348  * @param[in] keylist Key List
349  * @param[in] keyname Key
350  * @param[in] value The integer value
351  * @return Number of keynode included in the keylist, -1 on error
352  */
353 API int
354 vconf_keylist_add_int(keylist_t *keylist, const char *keyname, const int value)
355 {
356         keynode_t *keynode = NULL, *addition = NULL;
357
358         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
359         retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
360
361         if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
362                 _vconf_keynode_set_value_int(keynode, value);
363                 return keylist->num;
364         }
365         if ((keynode = _vconf_keylist_headnode(keylist)))
366                 while (_vconf_keynode_next(keynode))
367                         keynode = _vconf_keynode_next(keynode);
368
369         addition = calloc(1, sizeof(keynode_t));
370         retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
371         if (!_vconf_keynode_set_keyname(addition, keyname)) {
372                 _vconf_keynode_set_value_int(addition, value);
373                 if (keylist->head && NULL != keynode)
374                         keynode->next = addition;
375                 else
376                         keylist->head = addition;
377                 keylist->num += 1;
378         } else {
379                 ERR("(maybe)not enought memory");
380                 free(addition), addition = NULL;
381                 return VCONF_ERROR;
382         }
383
384         return keylist->num;
385 }
386
387 /*
388  * This function appends a new Keynode included boolean value to the keylist.
389  * If same keyname exist, the keynode will change.
390  * @param[in] keylist Key List
391  * @param[in] keyname Key
392  * @param[in] value The boolean value
393  * @return Number of keynode included in the keylist, -1 on error
394  */
395 API int
396 vconf_keylist_add_bool(keylist_t *keylist, const char *keyname, const int value)
397 {
398         keynode_t *keynode = NULL, *addition = NULL;
399
400         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
401         retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
402
403         if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
404                 _vconf_keynode_set_value_bool(keynode, value);
405                 return keylist->num;
406         }
407         if ((keynode = _vconf_keylist_headnode(keylist)))
408                 while (_vconf_keynode_next(keynode))
409                         keynode = _vconf_keynode_next(keynode);
410
411         addition = calloc(1, sizeof(keynode_t));
412         retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
413         if (!_vconf_keynode_set_keyname(addition, keyname)) {
414                 _vconf_keynode_set_value_bool(addition, value);
415                 if (keylist->head && NULL != keynode)
416                         keynode->next = addition;
417                 else
418                         keylist->head = addition;
419                 keylist->num += 1;
420         } else {
421                 ERR("(maybe)not enought memory");
422                 free(addition), addition = NULL;
423                 return VCONF_ERROR;
424         }
425
426         return keylist->num;
427 }
428
429 /*
430  * This function appends a new Keynode included double value to the keylist.
431  * If same keyname exist, the keynode will change.
432  * @param[in] keylist Key List
433  * @param[in] keyname Key
434  * @param[in] value The double value
435  * @return Number of keynode included in the keylist, -1 on error
436  */
437 API int
438 vconf_keylist_add_dbl(keylist_t *keylist,
439                       const char *keyname, const double value)
440 {
441         keynode_t *keynode = NULL, *addition = NULL;
442
443         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
444         retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
445
446         if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
447                 _vconf_keynode_set_value_dbl(keynode, value);
448                 return keylist->num;
449         }
450         if ((keynode = _vconf_keylist_headnode(keylist)))
451                 while (_vconf_keynode_next(keynode))
452                         keynode = _vconf_keynode_next(keynode);
453
454         addition = calloc(1, sizeof(keynode_t));
455         retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
456         if (!_vconf_keynode_set_keyname(addition, keyname)) {
457                 _vconf_keynode_set_value_dbl(addition, value);
458                 if (keylist->head && NULL != keynode)
459                         keynode->next = addition;
460                 else
461                         keylist->head = addition;
462                 keylist->num += 1;
463         } else {
464                 ERR("(maybe)not enought memory");
465                 free(addition), addition = NULL;
466                 return VCONF_ERROR;
467         }
468
469         return keylist->num;
470 }
471
472 /*
473  * This function appends a new Keynode included string value to the keylist.
474  * If same keyname exist, the keynode will change.
475  * @param[in] keylist Key List
476  * @param[in] keyname Key
477  * @param[in] value The pointer of string value
478  * @return Number of keynode included in the keylist, -1 on error
479  */
480 API int
481 vconf_keylist_add_str(keylist_t *keylist,
482                       const char *keyname, const char *value)
483 {
484         keynode_t *keynode = NULL, *addition = NULL;
485
486         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
487         retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
488
489         if ((keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
490                 if (VCONF_TYPE_STRING == keynode->type && keynode->value.s)
491                         free(keynode->value.s);
492                 _vconf_keynode_set_value_str(keynode, value);
493                 return keylist->num;
494         }
495         if (NULL != (keynode = _vconf_keylist_headnode(keylist)))
496                 while (_vconf_keynode_next(keynode))
497                         keynode = _vconf_keynode_next(keynode);
498
499         addition = calloc(1, sizeof(keynode_t));
500         retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
501         if (!_vconf_keynode_set_keyname(addition, keyname)) {
502                 _vconf_keynode_set_value_str(addition, value);
503                 if (keylist->head && NULL != keynode)
504                         keynode->next = addition;
505                 else
506                         keylist->head = addition;
507                 keylist->num += 1;
508         } else {
509                 ERR("(maybe)not enought memory");
510                 free(addition), addition = NULL;
511                 return VCONF_ERROR;
512         }
513
514         return keylist->num;
515 }
516
517 /*
518  * This function Appends a new Keynode to the keylist without value.
519  * Use on vconf_get()
520  * @param[in] keylist Key List
521  * @param[in] keyname Key
522  * @return Number of keynode included in the keylist, -1 on error
523  */
524 API int vconf_keylist_add_null(keylist_t *keylist, const char *keyname)
525 {
526         keynode_t *keynode = NULL, *addition = NULL;
527
528         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
529         retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
530
531         if (NULL != (keynode = _vconf_keylist_lookup(keylist, keyname, NULL))) {
532                 keynode->type = 0;
533                 keynode->value.d = 0;
534                 return keylist->num;
535         }
536         if ((keynode = _vconf_keylist_headnode(keylist)))
537                 while (_vconf_keynode_next(keynode))
538                         keynode = _vconf_keynode_next(keynode);
539
540         addition = calloc(1, sizeof(keynode_t));
541         retvm_if(addition == NULL, VCONF_ERROR, "(maybe)not enought memory");
542         if (!_vconf_keynode_set_keyname(addition, keyname)) {
543                 if (keylist->head && keynode)
544                         keynode->next = addition;
545                 else
546                         keylist->head = addition;
547                 keylist->num += 1;
548         } else {
549                 ERR("(maybe)not enought memory");
550                 free(addition), addition = NULL;
551                 return VCONF_ERROR;
552         }
553
554         return keylist->num;
555 }
556
557 /*
558  * This function remove the keynode that matches keyname.
559  * @param[in] keylist the keylist included the keyname
560  * @param[in] keyname key
561  * @return 0 on success, -1(Invalid parameter), -2(Not exist keyname in keylist) on error
562  */
563 API int vconf_keylist_del(keylist_t *keylist, const char *keyname)
564 {
565         keynode_t *found_node, *before_node = NULL;
566
567         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
568         retvm_if(keyname == NULL, VCONF_ERROR, "Invalid argument: keyname is NULL");
569
570         if ((found_node = _vconf_keylist_lookup(keylist, keyname, &before_node))) {
571                 if(before_node) {
572                         before_node->next = found_node->next;
573                 } else {
574                         /* requested key is headnode of keylist */
575                         keylist->head = found_node->next;
576                 }
577
578                 _vconf_keynode_free(found_node);
579         } else
580                 return VCONF_ERROR;
581
582         return VCONF_OK;
583 }
584
585
586 int _vconf_get_key_prefix(const char *keyname, int *prefix)
587 {
588         if (strncmp(keyname, BACKEND_DB_PREFIX, strlen(BACKEND_DB_PREFIX)) == 0) {
589                 *prefix = VCONF_BACKEND_DB;
590         } else if (0 == strncmp(keyname, BACKEND_FILE_PREFIX, strlen(BACKEND_FILE_PREFIX))) {
591                 *prefix = VCONF_BACKEND_FILE;
592         } else if (0 == strncmp(keyname, BACKEND_MEMORY_PREFIX, strlen(BACKEND_MEMORY_PREFIX))) {
593                 *prefix = VCONF_BACKEND_MEMORY;
594         } else {
595                 ERR("Invalid argument: wrong prefix of key(%s)", keyname);
596                 *prefix = VCONF_BACKEND_NULL;
597                 return VCONF_ERROR_WRONG_PREFIX;
598         }
599
600         return VCONF_OK;
601 }
602
603 int _vconf_get_key_path(const char *keyname, char *path)
604 {
605         if (strncmp(keyname, BACKEND_DB_PREFIX, strlen(BACKEND_DB_PREFIX)) == 0) {
606                 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_SYSTEM_DIR, keyname);
607         } else if (0 == strncmp(keyname, BACKEND_FILE_PREFIX, strlen(BACKEND_FILE_PREFIX))) {
608                 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_SYSTEM_DIR, keyname);
609         } else if (0 == strncmp(keyname, BACKEND_MEMORY_PREFIX, strlen(BACKEND_MEMORY_PREFIX))) {
610                 snprintf(path, VCONF_KEY_PATH_LEN, "%s%s", BACKEND_MEMORY_DIR, keyname);
611         } else {
612                 ERR("Invalid argument: wrong prefix of key(%s)", keyname);
613                 return VCONF_ERROR_WRONG_PREFIX;
614         }
615
616         return VCONF_OK;
617 }
618
619 #ifdef VCONF_USE_BACKUP_TRANSACTION
620 int _vconf_get_backup_path(const char *keyname, char *path)
621 {
622         char key_buf[VCONF_KEY_PATH_LEN] = {0, };
623         int i;
624
625         for(i = 0; i<VCONF_KEY_PATH_LEN-1 && keyname[i] != '\0' ; i++) {
626                 if (keyname[i] == '/')
627                         key_buf[i] = '$';
628                 else
629                         key_buf[i] = keyname[i];
630         }
631
632         snprintf(path, VCONF_KEY_PATH_LEN, "%s%s%s%s", BACKEND_SYSTEM_DIR, BACKEND_DB_PREFIX, ".backup/", key_buf);
633
634         return VCONF_OK;
635 }
636 #endif
637
638 #ifndef DISABLE_RUNTIME_KEY_CREATION
639 static int _vconf_set_key_check_parent_dir(const char* path)
640 {
641         int exists = 0;
642         struct stat stat_info;
643         char* parent;
644         char path_buf[VCONF_KEY_PATH_LEN] = {0,};
645         int ret = 0;
646
647         mode_t dir_mode =  0664 | 0111;
648
649         parent = strrchr(path, '/');
650         strncpy(path_buf, path, parent-path);
651         path_buf[parent-path]=0;
652
653         exists = stat(path_buf,&stat_info);
654         if(exists){
655                 if(mkdir(path_buf, dir_mode) != 0) {
656                         if(errno == ENOENT) {
657                                 ret = _vconf_set_key_check_parent_dir((const char*)path_buf);
658                                 if(ret != VCONF_OK) return ret;
659                                 if(mkdir(path_buf, dir_mode) != 0) {
660                                         ERR("mkdir error(%d)", errno);
661                                         return VCONF_ERROR;
662                                 }
663                         }
664                 }
665         }
666
667         return VCONF_OK;
668 }
669
670 static int _vconf_set_key_creation(const char* path)
671 {
672         int fd;
673         mode_t temp;
674         temp = umask(0000);
675         fd = open(path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
676         umask(temp);
677         if(fd == -1) {
678                 ERR("open(rdwr,create) error\n");
679                 return VCONF_ERROR;
680         }
681         close(fd);
682
683         return VCONF_OK;
684 }
685 #endif
686
687 static int _vconf_set_file_lock(int fd, short type)
688 {
689         struct flock l;
690
691         l.l_type = type; /*Do read Lock*/
692         l.l_start= 0;       /*Start at begin*/
693         l.l_whence = SEEK_SET;
694         l.l_len = 0;        /*Do it with whole file*/
695
696         return fcntl(fd, F_SETLKW, &l);
697 }
698
699 static int _vconf_set_read_lock(int fd)
700 {
701         return _vconf_set_file_lock(fd, F_RDLCK);
702 }
703
704 static int _vconf_set_write_lock(int fd)
705 {
706         return _vconf_set_file_lock(fd, F_WRLCK);
707 }
708
709 static int _vconf_set_unlock(int fd)
710 {
711         return _vconf_set_file_lock(fd, F_UNLCK);
712 }
713
714 #ifdef VCONF_USE_SQLFS_TRANSACTION
715 static void _vconf_acquire_transaction_delay(int ms)
716 {
717     struct timeval timeout;
718     timeout.tv_sec = ms / 1000 ;
719     timeout.tv_usec = 1000 * ( ms % 1000 );
720
721     select(0, 0, 0, 0, &timeout);
722 }
723
724 static int _vconf_db_begin_transaction()
725 {
726         pid_t value;
727         VCONF_MOUNT_PATH_CHECK;
728
729         if(is_transaction == 0) {
730                 value = getpid();
731 transaction_retry:
732                 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_start", &value, sizeof(value), 0) == -1)
733                 {
734                         //ERR("someone access vconf. retrying...(%d)", errno);
735                         _vconf_acquire_transaction_delay(50);
736                         goto transaction_retry;
737                 } else {
738                         is_transaction++;
739                 }
740         } else {
741                 is_transaction++;
742         }
743
744         return VCONF_OK;
745 }
746
747 static int _vconf_db_commit_transaction()
748 {
749         pid_t value;
750         VCONF_MOUNT_PATH_CHECK;
751
752         retv_if(is_transaction <= 0, VCONF_ERROR);
753
754         if(is_transaction == 1) {
755                 value = getpid();
756 transaction_retry:
757                 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_stop", &value, sizeof(value), 0) == -1)
758                 {
759                         //ERR("setxattr failed. retrying...(%d)", errno);
760                         _vconf_acquire_transaction_delay(50);
761                         goto transaction_retry;
762                 } else {
763                         is_transaction = 0;
764                 }
765         } else {
766                 is_transaction--;
767         }
768
769         return 0;
770 }
771
772 static int _vconf_db_rollback_transaction()
773 {
774         pid_t value;
775         VCONF_MOUNT_PATH_CHECK;
776
777         retv_if(is_transaction <= 0, VCONF_ERROR);
778
779         if(is_transaction == 1) {
780                 value = getpid();
781 transaction_retry:
782                 if(setxattr(VCONF_MOUNT_PATH, "full_db_transaction_rb", &value, sizeof(value), 0) == -1)
783                 {
784                         //ERR("setxattr failed. retrying...(%d)", errno);
785                         _vconf_acquire_transaction_delay(50);
786                         goto transaction_retry;
787                 } else {
788                         is_transaction = 0;
789                 }
790         } else {
791                 is_transaction --;
792         }
793
794         return 0;
795 }
796 #endif //VCONF_USE_SQLFS_TRANSACTION
797
798 #ifdef VCONF_USE_BACKUP_TRANSACTION
799
800 static int _vconf_backup_check(char* vconf_path, char* backup_path)
801 {
802         int ret = VCONF_OK;
803         int vconf_fd = -1;
804         int backup_fd = -1;
805         char file_buf[BUF_LEN] = { 0, };
806         char err_buf[100] = { 0, };
807         int complete_mark = 0;
808         int read_len;
809         int err_no = 0;
810         int is_recovered = 0;
811         int file_size;
812
813         if (access(vconf_path, F_OK) == -1 || access(backup_path, F_OK) == -1)
814                 return ret;
815
816         vconf_fd = open(vconf_path, O_WRONLY);
817         if (vconf_fd == -1) {
818                 ERR("open %s failed", vconf_path);
819                 ret = VCONF_ERROR_FILE_OPEN;
820                 err_no = errno;
821                 goto out_close;
822         }
823
824         if(_vconf_set_write_lock(vconf_fd) == -1) {
825                 ERR("set write lock %s failed", vconf_path);
826                 ret = VCONF_ERROR_FILE_LOCK;
827                 err_no = errno;
828                 goto out_close;
829         }
830
831         backup_fd = open(backup_path, O_RDONLY);
832         if (backup_fd == -1) {
833                 ERR("open %s failed", backup_path);
834                 ret = VCONF_ERROR_FILE_OPEN;
835                 err_no = errno;
836                 goto out_unlock;
837         }
838
839         file_size = lseek(backup_fd, 0, SEEK_END);
840         if (file_size == -1) {
841                 ERR("seek end %s failed", backup_path);
842                 ret = VCONF_ERROR_FILE_SEEK;
843                 err_no = errno;
844                 goto out_unlock;
845         } else if (file_size < FILE_ATOMIC_GUARANTEE_SIZE + VCONF_BACKUP_COMP_MARK_SIZE) {
846                 goto out_unlock;
847         }
848
849         if (lseek(backup_fd, 0, SEEK_SET) != 0) {
850                 ERR("seek %s failed", backup_path);
851                 ret = VCONF_ERROR_FILE_SEEK;
852                 err_no = errno;
853                 goto out_unlock;
854         }
855
856         read_len = read(backup_fd, &complete_mark, sizeof(int));
857         if (read_len < sizeof(int))
858                 goto out_unlock;
859
860         if (complete_mark != VCONF_BACKUP_COMPLETE_MARK)
861                 goto out_unlock;
862
863         if (ftruncate(vconf_fd, 0) == -1) {
864                 ERR("truncate %s failed", vconf_path);
865                 ret = VCONF_ERROR_FILE_TRUNCATE;
866                 err_no = errno;
867                 goto out_unlock;
868         }
869
870         while ( (read_len = read(backup_fd, file_buf, BUF_LEN )) >0) {
871                 if(write(vconf_fd, file_buf, read_len) != read_len) {
872                         ERR("write %s failed", backup_path);
873                         ret = VCONF_ERROR_FILE_WRITE;
874                         err_no = errno;
875                         goto out_unlock;
876                 }
877         }
878
879         is_recovered = 1;
880
881 out_unlock :
882         if(_vconf_set_unlock(vconf_fd)==-1) {
883                 ERR("unset write lock %s failed", vconf_path);
884                 ret = VCONF_ERROR_FILE_LOCK;
885                 err_no = errno;
886                 goto out_close;
887         }
888
889 out_close:
890         if (vconf_fd != -1)
891                 close(vconf_fd);
892         if(backup_fd != -1)
893                 close(backup_fd);
894
895         if(ret == VCONF_OK) {
896                 if(remove(backup_path) == -1) {
897                         ret = VCONF_ERROR_FILE_REMOVE;
898                         err_no = errno;
899                 }
900         }
901
902         if(ret != VCONF_OK) {
903                 strerror_r(err_no, err_buf, 100);
904                 ERR("_vconf_backup_check failed %d (%d / %s)\n", ret, err_no, err_buf);
905         } else if (is_recovered)
906                 WARN("vconf(%s) successfully recovered and backup file is removed", vconf_path, backup_path);
907         else
908                 WARN("vconf(%s)'s non-complete backup file is removed", vconf_path, backup_path);
909
910         return ret;
911 }
912
913 static int _vconf_backup_write_str(char* backup_path, char* value)
914 {
915         int ret = VCONF_OK;
916         char err_buf[100] = { 0, };
917         int err_no = 0;
918         int backup_fd = -1;
919         int write_len = 0;
920         int complete_mark = VCONF_BACKUP_COMPLETE_MARK;
921         int empty_mark = 0;
922         int vconf_type_str = VCONF_TYPE_STRING;
923         int result;
924
925         if( (backup_fd = open(backup_path, O_CREAT|O_EXCL|O_WRONLY, 0666)) == -1 ) {
926                 ERR("open %s failed", backup_path);
927                 ret = VCONF_ERROR_FILE_OPEN;
928                 err_no = errno;
929                 goto out_close;
930         }
931
932         if ((result = write(backup_fd, (void *)&empty_mark, sizeof(int))) != sizeof(int)) {
933                 ERR("write empty mark of %s failed %d", backup_path, result);
934                 ret = VCONF_ERROR_FILE_WRITE;
935                 err_no = errno;
936                 goto out_close;
937         }
938
939         if ((result = write(backup_fd, (void *)&vconf_type_str, sizeof(int))) != sizeof(int)) {
940                 ERR("write type of %s failed %d", backup_path, result);
941                 ret = VCONF_ERROR_FILE_WRITE;
942                 err_no = errno;
943                 goto out_close;
944         }
945
946         write_len = strlen(value);
947         if((result = write(backup_fd, value, write_len)) != write_len) {
948                 ERR("write %s failed %d", backup_path, result);
949                 ret = VCONF_ERROR_FILE_WRITE;
950                 err_no = errno;
951                 goto out_close;
952
953         }
954
955         if (fdatasync(backup_fd) == -1) {
956                 ERR("sync %s failed", backup_path);
957                 ret = VCONF_ERROR_FILE_SYNC;
958                 err_no = errno;
959                 goto out_close;
960         }
961
962         if (lseek(backup_fd, 0, SEEK_SET) != 0) {
963                 ERR("seek %s failed", backup_path);
964                 ret = VCONF_ERROR_FILE_SEEK;
965                 err_no = errno;
966                 goto out_close;
967         }
968
969         if((result = write(backup_fd, (void *)&complete_mark, sizeof(int))) != sizeof(int)) {
970                 ERR("write complete mark of %s failed %d", backup_path, result);
971                 ret = VCONF_ERROR_FILE_WRITE;
972                 err_no = errno;
973                 goto out_close;
974         }
975
976         if (fdatasync(backup_fd) == -1) {
977                 ERR("sync %s failed", backup_path);
978                 ret = VCONF_ERROR_FILE_SYNC;
979                 err_no = errno;
980                 goto out_close;
981         }
982
983 out_close:
984         if(backup_fd != -1)
985                 close(backup_fd);
986
987         if(ret != VCONF_OK) {
988                 strerror_r(err_no, err_buf, 100);
989                 ERR("_vconf_backup_write_str failed %d (%d / %s)\n", ret, err_no, err_buf);
990         }
991
992         return ret;
993
994 }
995
996 static int _vconf_backup_commit(char* backup_path)
997 {
998         int ret = VCONF_OK;
999         char err_buf[100] = { 0, };
1000         int err_no = 0;
1001
1002         if(remove(backup_path) == -1) {
1003                 ERR("remove %s failed", backup_path);
1004                 ret = VCONF_ERROR_FILE_REMOVE;
1005                 err_no = errno;
1006         }
1007
1008         if(ret != VCONF_OK) {
1009                 strerror_r(err_no, err_buf, 100);
1010                 ERR("_vconf_backup_commit failed %d (%d / %s)\n", ret, err_no, err_buf);
1011         }
1012
1013         return ret;
1014
1015 }
1016 #endif // VCONF_USE_BACKUP_TRANSACTION
1017
1018 static int _vconf_set_key_filesys(keynode_t *keynode, int prefix)
1019 {
1020         char path[VCONF_KEY_PATH_LEN] = {0,};
1021         FILE *fp = NULL;
1022         int ret = -1;
1023         int func_ret = VCONF_OK;
1024         int err_no = 0;
1025         char err_buf[100] = { 0, };
1026         int is_write_error = 0;
1027 #ifdef VCONF_USE_BACKUP_TRANSACTION
1028         char backup_path[VCONF_KEY_PATH_LEN] = {0,};
1029         int is_backup_need = 0;
1030         int file_size = 0;
1031 #endif
1032
1033         errno = 0;
1034
1035         ret = _vconf_get_key_path(keynode->keyname, path);
1036         retv_if(ret != VCONF_OK, ret);
1037
1038
1039 #ifdef VCONF_CHECK_IS_INITIALIZED
1040         if(prefix == VCONF_BACKEND_MEMORY && VCONF_NOT_INITIALIZED) {
1041                 func_ret = VCONF_ERROR_NOT_INITIALIZED;
1042                 goto out_return;
1043         }
1044 #endif
1045
1046 #ifdef VCONF_USE_BACKUP_TRANSACTION
1047         if(prefix == VCONF_BACKEND_DB && keynode->type == VCONF_TYPE_STRING) {
1048                 _vconf_get_backup_path(keynode->keyname, backup_path);
1049                 ret = _vconf_backup_check(path, backup_path);
1050                 if(ret != VCONF_OK) {
1051                         func_ret = ret;
1052                         err_no = errno;
1053                         goto out_return;
1054                 }
1055         }
1056 #endif
1057
1058         if( (fp = fopen(path, "r+")) == NULL ) {
1059                 func_ret = VCONF_ERROR_FILE_OPEN;
1060                 err_no = errno;
1061                 goto out_return;
1062         }
1063
1064 #ifdef VCONF_USE_SQLFS_TRANSACTION
1065         if (prefix != VCONF_BACKEND_DB)
1066 #endif
1067         {
1068                 ret = _vconf_set_write_lock(fileno(fp));
1069                 if(ret == -1) {
1070                         func_ret = VCONF_ERROR_FILE_LOCK;
1071                         err_no = errno;
1072                         goto out_close;
1073                 }
1074         }
1075
1076 #ifdef VCONF_USE_BACKUP_TRANSACTION
1077         if(prefix == VCONF_BACKEND_DB && keynode->type == VCONF_TYPE_STRING) {
1078                 file_size = VCONF_TYPE_SIZE + strlen(keynode->value.s);
1079                 if (file_size > FILE_ATOMIC_GUARANTEE_SIZE) {
1080                         is_backup_need = 1;
1081
1082                         ret = _vconf_backup_write_str(backup_path, keynode->value.s);
1083                         if(ret != VCONF_OK) {
1084                                 func_ret = ret;
1085                                 err_no = errno;
1086                                 goto out_unlock;
1087                         } else
1088                                 WARN("vconf backup file for(%s) is created. file size(%d)", path, file_size);
1089                 }
1090         }
1091 #endif
1092
1093         if (ftruncate(fileno(fp), 0) == -1) {
1094                 func_ret = VCONF_ERROR_FILE_TRUNCATE;
1095                 err_no = errno;
1096                 goto out_unlock;
1097         }
1098
1099         /* write key type */
1100         ret = fwrite((void *)&(keynode->type), sizeof(int), 1, fp);
1101         if(ret <= 0)
1102         {
1103                 if(errno) {
1104                         err_no = errno;
1105                 } else {
1106                         errno = EAGAIN;
1107                 }
1108                 func_ret = VCONF_ERROR_FILE_WRITE;
1109                 goto out_unlock;
1110         }
1111
1112         /* write key value */
1113         switch(keynode->type)
1114         {
1115                 case VCONF_TYPE_INT:
1116                         ret = fwrite((void *)&(keynode->value.i), sizeof(int), 1, fp);
1117                         if(ret <= 0) is_write_error = 1;
1118                         break;
1119                 case VCONF_TYPE_DOUBLE:
1120                         ret = fwrite((void *)&(keynode->value.d), sizeof(double), 1, fp);
1121                         if(ret <= 0) is_write_error = 1;
1122                         break;
1123                 case VCONF_TYPE_BOOL:
1124                         ret = fwrite((void *)&(keynode->value.b), sizeof(int), 1, fp);
1125                         if(ret <= 0) is_write_error = 1;
1126                         break;
1127                 case VCONF_TYPE_STRING:
1128                         ret = fprintf(fp,"%s",keynode->value.s);
1129                         if(ret < strlen(keynode->value.s)) is_write_error = 1;
1130                         //ret = fwrite((void *)keynode->value.s, sizeof(char), strlen(keynode->value.s), fp);
1131                         break;
1132                 default :
1133                         func_ret = VCONF_ERROR_WRONG_TYPE;
1134                         goto out_unlock;
1135         }
1136         if(is_write_error)
1137         {
1138                 if(errno) {
1139                         err_no = errno;
1140                 } else {
1141                         errno = EAGAIN;
1142                 }
1143                 func_ret = VCONF_ERROR_FILE_WRITE;
1144                 goto out_unlock;
1145         }
1146
1147 #ifdef VCONF_USE_SQLFS_TRANSACTION
1148         if(prefix == VCONF_BACKEND_FILE)
1149 #else
1150         if(prefix == VCONF_BACKEND_FILE || prefix == VCONF_BACKEND_DB)
1151 #endif
1152         {
1153                 fflush(fp);
1154
1155                 ret = fdatasync(fileno(fp));
1156                 if(ret == -1) {
1157                         err_no = errno;
1158                         func_ret = VCONF_ERROR_FILE_SYNC;
1159                 }
1160         }
1161
1162 #ifdef VCONF_USE_BACKUP_TRANSACTION
1163         if (is_backup_need) {
1164                 ret = _vconf_backup_commit(backup_path);
1165                 if(ret != VCONF_OK) {
1166                         func_ret = ret;
1167                         err_no = errno;
1168                         goto out_unlock;
1169                 }
1170         }
1171 #endif
1172
1173 out_unlock :
1174 #ifdef VCONF_USE_SQLFS_TRANSACTION
1175         if (prefix != VCONF_BACKEND_DB)
1176 #endif
1177         {
1178                 ret = _vconf_set_unlock(fileno(fp));
1179                 if(ret == -1) {
1180                         func_ret = VCONF_ERROR_FILE_LOCK;
1181                         err_no = errno;
1182                         goto out_close;
1183                 }
1184         }
1185 out_close :
1186         fclose(fp);
1187
1188 out_return :
1189         if(err_no != 0) {
1190                 strerror_r(err_no, err_buf, 100);
1191                 ERR("_vconf_set_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1192         }
1193
1194         return func_ret;
1195 }
1196
1197 static int _vconf_set_key(keynode_t *keynode)
1198 {
1199         int func_ret = VCONF_OK;
1200         int ret = 0;
1201         int is_busy_err = 0;
1202         int retry = -1;
1203         int prefix = 0;
1204         int rc = 0;
1205
1206         ret = _vconf_get_key_prefix(keynode->keyname, &prefix);
1207         retv_if(ret != VCONF_OK, ret);
1208
1209 #ifdef VCONF_USE_SQLFS_TRANSACTION
1210         if(prefix == VCONF_BACKEND_DB) {
1211                 _vconf_db_begin_transaction();
1212         }
1213 #endif
1214
1215         while((ret = _vconf_set_key_filesys(keynode, prefix)) != VCONF_OK)
1216         {
1217                 is_busy_err = 0;
1218                 retry++;
1219
1220 #ifdef VCONF_CHECK_INITIALIZED
1221                 if(VCONF_NOT_INITIALIZED)
1222                 {
1223                         ERR("%s : vconf is not initialized\n", keynode->keyname);
1224                         is_busy_err = 1;
1225                 }
1226                 else if(ret == VCONF_ERROR_FILE_OPEN)
1227 #else
1228
1229                 if(ret == VCONF_ERROR_FILE_OPEN)
1230 #endif
1231                 {
1232                         switch (errno)
1233                         {
1234                                 /* file is not exist, make path */
1235 #ifndef DISABLE_RUNTIME_KEY_CREATION
1236                                 case EFAULT :
1237                                 case ENOENT :
1238                                 {
1239                                         char path[VCONF_KEY_PATH_LEN] = {0,};
1240                                         rc = _vconf_get_key_path(keynode->keyname, path);
1241                                         if(rc != VCONF_OK) {
1242                                                 ERR("_vconf_get_key_path error");
1243                                                 break;
1244                                         }
1245
1246                                         rc = _vconf_set_key_check_parent_dir(path);
1247                                         if(rc != VCONF_OK) {
1248                                                 ERR("_vconf_set_key_check_parent_dir error : %s", path);
1249                                                 break;
1250                                         }
1251
1252                                         rc = _vconf_set_key_creation(path);
1253                                         if(rc != VCONF_OK) {
1254                                                 ERR("_vconf_set_key_creation error : %s", path);
1255                                                 break;
1256                                         }
1257                                         INFO("%s key is created", keynode->keyname);
1258                                 }
1259 #endif
1260                                 case EAGAIN :
1261                                 case EMFILE :
1262                                 case ENFILE :
1263                                 case ETXTBSY :
1264                                 {
1265                                         is_busy_err = 1;
1266                                 }
1267                         }
1268                 }
1269                 else if (ret == VCONF_ERROR_FILE_CHMOD)
1270                 {
1271                         switch (errno)
1272                         {
1273                                 case EINTR :
1274                                 case EBADF :
1275                                 {
1276                                         is_busy_err = 1;
1277                                 }
1278                         }
1279                 }
1280                 else if (ret == VCONF_ERROR_FILE_LOCK)
1281                 {
1282                         switch (errno)
1283                         {
1284                                 case EBADF :
1285                                 case EACCES :
1286                                 case EAGAIN :
1287                                 case ENOLCK :
1288                                 {
1289                                         is_busy_err = 1;
1290                                 }
1291                         }
1292                 }
1293                 else if (ret == VCONF_ERROR_FILE_WRITE)
1294                 {
1295                         switch (errno)
1296                         {
1297                                 case 0 :
1298                                 case EAGAIN :
1299                                 case EINTR :
1300                                 case EIO :
1301                                 case ENOMEM :
1302                                 {
1303                                         is_busy_err = 1;
1304                                 }
1305                         }
1306                 }
1307                 else
1308                 {
1309                         is_busy_err = 0;
1310                 }
1311
1312                 if ((is_busy_err == 1) && (retry < VCONF_ERROR_RETRY_CNT)) {
1313                         ERR("%s : write buf error(%d). write will be retried(%d) , usleep time : %d\n", keynode->keyname, ret, retry, (retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1314                         usleep((retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1315                         continue;
1316                 } else {
1317                         ERR("%s : write buf error(%d). break. (%d)\n", keynode->keyname, ret, retry);
1318                         func_ret = VCONF_ERROR;
1319                         break;
1320                 }
1321         }
1322
1323 #ifdef VCONF_USE_SQLFS_TRANSACTION
1324         if(prefix == VCONF_BACKEND_DB) {
1325                 if(func_ret == VCONF_ERROR) {
1326                         _vconf_db_rollback_transaction();
1327                 } else {
1328                         _vconf_db_commit_transaction();
1329                 }
1330         }
1331 #endif
1332
1333         return func_ret;
1334 }
1335
1336 /*
1337  * This function set the value of given keys
1338  * @param[in] keylist the keylist which should contain changed keys
1339  * @return 0 on success, -1 on error
1340  */
1341 API int vconf_set(keylist_t *keylist)
1342 {
1343         START_TIME_CHECK
1344
1345         keynode_t *got_node;
1346
1347         int func_ret = VCONF_OK;
1348         int ret = 0;
1349         int prefix = 0;
1350
1351         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is NULL");
1352
1353         INFO("vconf_set (%d)START", keylist->num);
1354
1355         got_node = _vconf_keylist_headnode(keylist);
1356
1357         retvm_if(got_node == NULL, VCONF_ERROR, "Invalid argument: headnode is NULL");
1358
1359         ret = _vconf_get_key_prefix(got_node->keyname, &prefix);
1360         retv_if(ret != VCONF_OK, ret);
1361
1362 #ifdef VCONF_USE_SQLFS_TRANSACTION
1363         if(prefix == VCONF_BACKEND_DB) {
1364                 _vconf_db_begin_transaction();
1365         }
1366 #endif
1367
1368         while (got_node != NULL) {
1369                 ret = _vconf_set_key(got_node);
1370                 if(ret != VCONF_OK) {
1371                         func_ret = VCONF_ERROR;
1372                 }
1373
1374                 got_node = _vconf_keynode_next(got_node);
1375         }
1376
1377 #ifdef VCONF_USE_SQLFS_TRANSACTION
1378         if(prefix == VCONF_BACKEND_DB) {
1379                 if(func_ret == VCONF_ERROR) {
1380                         _vconf_db_rollback_transaction();
1381                 } else {
1382                         _vconf_db_commit_transaction();
1383                 }
1384         }
1385 #endif
1386
1387         END_TIME_CHECK
1388
1389         return func_ret;
1390 }
1391
1392 API int vconf_sync_key(const char *in_key)
1393 {
1394         START_TIME_CHECK
1395
1396         int fd;
1397         char path[VCONF_KEY_PATH_LEN] = {0,};
1398         int ret = -1;
1399
1400         ret = _vconf_get_key_path(in_key, path);
1401         if(ret != VCONF_OK) return VCONF_ERROR;
1402
1403         fd = open(path, O_RDWR);
1404         if(fd == -1) return VCONF_ERROR;
1405
1406         fsync(fd);
1407         close(fd);
1408
1409         END_TIME_CHECK
1410
1411         return 0;
1412 }
1413
1414 /*
1415  * This function set the integer value of given key
1416  * @param[in]   in_key  key
1417  * @param[in]   intval integer value to set
1418  * @return 0 on success, -1 on error
1419  */
1420 API int vconf_set_int(const char *in_key, const int intval)
1421 {
1422         START_TIME_CHECK
1423
1424         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1425
1426         int func_ret = VCONF_OK;
1427
1428         keynode_t* pKeyNode = _vconf_keynode_new();
1429         retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1430
1431         func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1432         if(func_ret != VCONF_OK) {
1433                 _vconf_keynode_free(pKeyNode);
1434                 ERR("set key name error");
1435                 return VCONF_ERROR;
1436         }
1437         _vconf_keynode_set_value_int(pKeyNode, intval);
1438
1439         if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1440                 ERR("vconf_set_int(%d) : %s(%d) error", getpid(), in_key, intval);
1441                 func_ret = VCONF_ERROR;
1442         } else{
1443                 INFO("vconf_set_int(%d) : %s(%d) success", getpid(), in_key, intval);
1444         }
1445
1446         _vconf_keynode_free(pKeyNode);
1447
1448         END_TIME_CHECK
1449
1450         return func_ret;
1451 }
1452
1453 /*
1454 * This function set the boolean value of given key
1455 * @param[in]    in_key  key
1456 * @param[in]    boolval boolean value to set
1457                 (Integer value 1 is 'True', and 0 is 'False')
1458 * @return 0 on success, -1 on error
1459 */
1460 API int vconf_set_bool(const char *in_key, const int boolval)
1461 {
1462         START_TIME_CHECK
1463
1464         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1465
1466         int func_ret = VCONF_OK;
1467         keynode_t* pKeyNode = _vconf_keynode_new();
1468         retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1469
1470         func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1471         if(func_ret != VCONF_OK) {
1472                 _vconf_keynode_free(pKeyNode);
1473                 ERR("set key name error");
1474                 return VCONF_ERROR;
1475         }
1476         _vconf_keynode_set_value_bool(pKeyNode, boolval);
1477
1478         if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1479                 ERR("vconf_set_bool(%d) : %s(%d) error", getpid(), in_key, boolval);
1480                 func_ret = VCONF_ERROR;
1481         } else {
1482                 INFO("vconf_set_bool(%d) : %s(%d) success", getpid(), in_key, boolval);
1483         }
1484
1485         _vconf_keynode_free(pKeyNode);
1486
1487         END_TIME_CHECK
1488
1489         return func_ret;
1490 }
1491
1492 /*
1493  * This function set the double value of given key
1494  * @param[in]   in_key  key
1495  * @param[in]   dblval double value to set
1496  * @return 0 on success, -1 on error
1497  */
1498 API int vconf_set_dbl(const char *in_key, const double dblval)
1499 {
1500         START_TIME_CHECK
1501
1502         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1503
1504         int func_ret = VCONF_OK;
1505         keynode_t* pKeyNode = _vconf_keynode_new();
1506         retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1507
1508         func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1509         if(func_ret != VCONF_OK) {
1510                 _vconf_keynode_free(pKeyNode);
1511                 ERR("set key name error");
1512                 return VCONF_ERROR;
1513         }
1514         _vconf_keynode_set_value_dbl(pKeyNode, dblval);
1515
1516         if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1517                 ERR("vconf_set_dbl(%d) : %s(%f) error", getpid(), in_key, dblval);
1518                 func_ret = VCONF_ERROR;
1519         } else {
1520                 INFO("vconf_set_dbl(%d) : %s(%f) success", getpid(), in_key, dblval);
1521         }
1522
1523         _vconf_keynode_free(pKeyNode);
1524
1525         END_TIME_CHECK
1526
1527         return func_ret;
1528 }
1529
1530 /*
1531  * This function set the string value of given key
1532  * @param[in]   in_key  key
1533  * @param[in]   strval string value to set
1534  * @return 0 on success, -1 on error
1535  */
1536 API int vconf_set_str(const char *in_key, const char *strval)
1537 {
1538         START_TIME_CHECK
1539
1540         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
1541         retvm_if(strval == NULL, VCONF_ERROR, "Invalid argument: value is NULL");
1542
1543         int func_ret = VCONF_OK;
1544         keynode_t* pKeyNode = _vconf_keynode_new();
1545         retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
1546
1547         func_ret = _vconf_keynode_set_keyname(pKeyNode, in_key);
1548         if(func_ret != VCONF_OK) {
1549                 _vconf_keynode_free(pKeyNode);
1550                 ERR("set key name error");
1551                 return VCONF_ERROR;
1552         }
1553         _vconf_keynode_set_value_str(pKeyNode, strval);
1554
1555         if (_vconf_set_key(pKeyNode) != VCONF_OK) {
1556                 ERR("vconf_set_str(%d) : %s(%s) error", getpid(), in_key, strval);
1557                 func_ret = VCONF_ERROR;
1558         } else {
1559                 INFO("vconf_set_str(%d) : %s(%s) success", getpid(), in_key, strval);
1560         }
1561
1562         _vconf_keynode_free(pKeyNode);
1563
1564         END_TIME_CHECK
1565
1566         return func_ret;
1567 }
1568
1569
1570 #ifdef SUPPORT_ELEKTRA_VALUE_FORMAT
1571 /* keyFileUnserialize function of ELEKTRA */
1572 static int _vconf_get_key_elektra_format(keynode_t *keynode, FILE *fp)
1573 {
1574         char version[10] = {0,};
1575         char type[5] = {0,};
1576         char comment[8] = {0,};
1577         char file_buf[BUF_LEN] = {0,};
1578         char *value = NULL;
1579         int value_size = 0;
1580         int err_no = 0;
1581         char err_buf[100] = { 0, };
1582         int func_ret = VCONF_OK;
1583         char tmp;
1584
1585         INFO("_vconf_get_key_elektra_format start");
1586
1587         rewind(fp);
1588
1589         if (!fgets(version, sizeof(version), fp))
1590         {
1591                 if(ferror(fp)) {
1592                         err_no = errno;
1593                 } else {
1594                         err_no = EAGAIN;
1595                 }
1596                 func_ret = VCONF_ERROR_FILE_FGETS;
1597                 goto out_return;
1598         }
1599         if (strncmp(version,"RG",2)) {
1600                 func_ret = VCONF_ERROR_WRONG_TYPE;
1601                 goto out_return;
1602         }
1603
1604         if (!fgets(type, sizeof(type), fp))
1605         {
1606                 if(ferror(fp)) {
1607                         err_no = errno;
1608                 } else {
1609                         err_no = EAGAIN;
1610                 }
1611                 func_ret = VCONF_ERROR_FILE_FGETS;
1612                 goto out_return;
1613         }
1614
1615         if (!fgets(comment, sizeof(comment), fp))
1616         {
1617                 if(ferror(fp)) {
1618                         err_no = errno;
1619                 } else {
1620                         err_no = EAGAIN;
1621                 }
1622                 func_ret = VCONF_ERROR_FILE_FGETS;
1623                 goto out_return;
1624         }
1625
1626         while(fgets(file_buf, sizeof(file_buf), fp))
1627         {
1628                 if(value) {
1629                         value_size = value_size + strlen(file_buf);
1630                         tmp = (char *) realloc(value, value_size);
1631                         if(!tmp) {
1632                                 free(value);
1633                                 func_ret = VCONF_ERROR_NO_MEM;
1634                                 break;
1635                         }
1636                         value = tmp;
1637                         strncat(value, file_buf, strlen(file_buf));
1638                 } else {
1639                         value_size = strlen(file_buf) + 1;
1640                         value = (char *)malloc(value_size);
1641                         if(value == NULL) {
1642                                 func_ret = VCONF_ERROR_NO_MEM;
1643                                 break;
1644                         }
1645                         memset(value, 0x00, value_size);
1646                         strncpy(value, file_buf, strlen(file_buf));
1647                 }
1648         }
1649
1650         if(ferror(fp)) {
1651                 err_no = errno;
1652                 func_ret = VCONF_ERROR_FILE_FGETS;
1653         } else {
1654                 if(value) {
1655                         switch(atoi(type))
1656                         {
1657                                 case VCONF_TYPE_INT:
1658                                 {
1659                                         _vconf_keynode_set_value_int(keynode, atoi(value));
1660                                         break;
1661                                 }
1662                                 case VCONF_TYPE_DOUBLE:
1663                                 {
1664                                         _vconf_keynode_set_value_dbl(keynode, atof(value));
1665                                         break;
1666                                 }
1667                                 case VCONF_TYPE_BOOL:
1668                                 {
1669                                         _vconf_keynode_set_value_bool(keynode, atoi(value));
1670                                         break;
1671                                 }
1672                                 case VCONF_TYPE_STRING:
1673                                 {
1674                                         _vconf_keynode_set_value_str(keynode, value);
1675                                         break;
1676                                 }
1677                                 default :
1678                                 {
1679                                         func_ret = VCONF_ERROR_WRONG_VALUE;
1680                                 }
1681                         }
1682                 } else {
1683                         if(atoi(type) == VCONF_TYPE_STRING) {
1684                                 _vconf_keynode_set_value_str(keynode, "");
1685                         } else {
1686                                 func_ret = VCONF_ERROR_WRONG_VALUE;
1687                         }
1688                 }
1689         }
1690
1691 out_return :
1692         if(err_no != 0) {
1693                 strerror_r(err_no, err_buf, 100);
1694                 ERR("_vconf_set_key_filesys(%d/%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1695         }
1696
1697         if(value) free(value);
1698
1699         return func_ret;
1700 }
1701 #endif
1702
1703 static int _vconf_get_key_filesys(keynode_t *keynode, int prefix)
1704 {
1705         char path[VCONF_KEY_PATH_LEN] = {0,};
1706         int ret = -1;
1707         int func_ret = VCONF_OK;
1708         char err_buf[100] = { 0, };
1709         int err_no = 0;
1710         int type = 0;
1711         FILE *fp = NULL;
1712 #ifdef VCONF_USE_BACKUP_TRANSACTION
1713         char backup_path[VCONF_KEY_PATH_LEN] = {0,};
1714 #endif
1715
1716         errno = 0;
1717
1718         ret = _vconf_get_key_path(keynode->keyname, path);
1719         retv_if(ret != VCONF_OK, ret);
1720
1721 #ifdef VCONF_CHECK_INITIALIZED
1722         if(prefix == VCONF_BACKEND_MEMORY && VCONF_NOT_INITIALIZED)
1723         {
1724                 func_ret = VCONF_ERROR_NOT_INITIALIZED;
1725                 goto out_return;
1726         }
1727 #endif
1728
1729 #ifdef VCONF_USE_BACKUP_TRANSACTION
1730         if(prefix == VCONF_BACKEND_DB) {
1731                 _vconf_get_backup_path(keynode->keyname, backup_path);
1732                 ret = _vconf_backup_check(path, backup_path);
1733                 if(ret != VCONF_OK) {
1734                         func_ret = ret;
1735                         err_no = errno;
1736                         goto out_return;
1737                 }
1738         }
1739 #endif
1740
1741         if( (fp = fopen(path, "r")) == NULL ) {
1742                 func_ret = VCONF_ERROR_FILE_OPEN;
1743                 err_no = errno;
1744                 goto out_return;
1745         }
1746
1747 #ifdef VCONF_USE_SQLFS_TRANSACTION
1748         if (prefix != VCONF_BACKEND_DB)
1749 #endif
1750         {
1751                 ret = _vconf_set_read_lock(fileno(fp));
1752                 if(ret == -1) {
1753                         func_ret = VCONF_ERROR_FILE_LOCK;
1754                         err_no = errno;
1755                         goto out_close;
1756                 }
1757         }
1758
1759         /* read data type */
1760         if(!fread((void*)&type, sizeof(int), 1, fp)) {
1761                 if(ferror(fp)) {
1762                         err_no = errno;
1763                 } else {
1764                         errno = EAGAIN;
1765                 }
1766                 func_ret = VCONF_ERROR_FILE_FREAD;
1767                 goto out_unlock;
1768         }
1769
1770         /* read data value */
1771         switch(type)
1772         {
1773                 case VCONF_TYPE_INT:
1774                 {
1775                         int value_int = 0;
1776                         if(!fread((void*)&value_int, sizeof(int), 1, fp)) {
1777                                 if(ferror(fp)) {
1778                                         err_no = errno;
1779                                 } else {
1780                                         errno = EAGAIN;
1781                                 }
1782                                 func_ret = VCONF_ERROR_FILE_FREAD;
1783                                 goto out_unlock;
1784                         } else {
1785                                 _vconf_keynode_set_value_int(keynode, value_int);
1786                         }
1787
1788                         break;
1789                 }
1790                 case VCONF_TYPE_DOUBLE:
1791                 {
1792                         double value_dbl = 0;
1793                         if(!fread((void*)&value_dbl, sizeof(double), 1, fp)) {
1794                                 if(ferror(fp)) {
1795                                         err_no = errno;
1796                                 } else {
1797                                         errno = EAGAIN;
1798                                 }
1799                                 func_ret = VCONF_ERROR_FILE_FREAD;
1800                                 goto out_unlock;
1801                         } else {
1802                                 _vconf_keynode_set_value_dbl(keynode, value_dbl);
1803                         }
1804
1805                         break;
1806                 }
1807                 case VCONF_TYPE_BOOL:
1808                 {
1809                         int value_int = 0;
1810                         if(!fread((void*)&value_int, sizeof(int), 1, fp)) {
1811                                 if(ferror(fp)) {
1812                                         err_no = errno;
1813                                 } else {
1814                                         errno = EAGAIN;
1815                                 }
1816                                 func_ret = VCONF_ERROR_FILE_FREAD;
1817                                 goto out_unlock;
1818                         } else {
1819                                 _vconf_keynode_set_value_bool(keynode, value_int);
1820                         }
1821
1822                         break;
1823                 }
1824                 case VCONF_TYPE_STRING:
1825                 {
1826                         char file_buf[BUF_LEN] = {0,};
1827                         char *value = NULL;
1828                         int value_size = 0;
1829
1830                         while(fgets(file_buf, sizeof(file_buf), fp))
1831                         {
1832                                 if(value) {
1833                                         value_size = value_size + strlen(file_buf);
1834                                         value = (char *) realloc(value, value_size);
1835                                         if(value == NULL) {
1836                                                 func_ret = VCONF_ERROR_NO_MEM;
1837                                                 break;
1838                                         }
1839                                         strncat(value, file_buf, strlen(file_buf));
1840                                 } else {
1841                                         value_size = strlen(file_buf) + 1;
1842                                         value = (char *)malloc(value_size);
1843                                         if(value == NULL) {
1844                                                 func_ret = VCONF_ERROR_NO_MEM;
1845                                                 break;
1846                                         }
1847                                         memset(value, 0x00, value_size);
1848                                         strncpy(value, file_buf, strlen(file_buf));
1849                                 }
1850                         }
1851
1852                         if(ferror(fp)) {
1853                                 err_no = errno;
1854                                 func_ret = VCONF_ERROR_FILE_FGETS;
1855                         } else {
1856                                 if(value) {
1857                                         _vconf_keynode_set_value_str(keynode, value);
1858                                 } else {
1859                                         _vconf_keynode_set_value_str(keynode, "");
1860                                 }
1861                         }
1862                         if(value)
1863                                 free(value);
1864
1865                         break;
1866                 }
1867                 default :
1868 #ifdef SUPPORT_ELEKTRA_VALUE_FORMAT
1869                         func_ret = _vconf_get_key_elektra_format(keynode, fp);
1870 #else
1871                         func_ret = VCONF_ERROR_WRONG_TYPE;
1872 #endif
1873         }
1874
1875 out_unlock :
1876 #ifdef VCONF_USE_SQLFS_TRANSACTION
1877         if (prefix != VCONF_BACKEND_DB)
1878 #endif
1879         {
1880                 ret = _vconf_set_unlock(fileno(fp));
1881                 if(ret == -1) {
1882                         func_ret = VCONF_ERROR_FILE_LOCK;
1883                         err_no = errno;
1884                         goto out_close;
1885                 }
1886         }
1887
1888 out_close :
1889         fclose(fp);
1890
1891 out_return :
1892         if(err_no != 0) {
1893                 strerror_r(err_no, err_buf, 100);
1894                 ERR("_vconf_get_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
1895         }
1896
1897         return func_ret;
1898 }
1899
1900
1901 int _vconf_get_key(keynode_t *keynode)
1902 {
1903         int func_ret = VCONF_OK;
1904         int ret = 0;
1905         int is_busy_err = 0;
1906         int retry = -1;
1907         int prefix = 0;
1908
1909         ret = _vconf_get_key_prefix(keynode->keyname, &prefix);
1910         retv_if(ret != VCONF_OK, ret);
1911
1912 #ifdef VCONF_USE_SQLFS_TRANSACTION
1913         if(prefix == VCONF_BACKEND_DB) {
1914                 _vconf_db_begin_transaction();
1915         }
1916 #endif
1917
1918         while((ret = _vconf_get_key_filesys(keynode, prefix)) != VCONF_OK)
1919         {
1920                 is_busy_err = 0;
1921                 retry++;
1922
1923 #ifdef VCONF_CHECK_INITIALIZED
1924                 if(VCONF_NOT_INITIALIZED)
1925                 {
1926                         ERR("%s : vconf is not initialized\n", keynode->keyname);
1927                         is_busy_err = 1;
1928                 }
1929                 else if(ret == VCONF_ERROR_FILE_OPEN)
1930 #else
1931                 if(ret == VCONF_ERROR_FILE_OPEN)
1932 #endif
1933                 {
1934                         switch (errno)
1935                         {
1936                                 case EAGAIN :
1937                                 case EMFILE :
1938                                 case ETXTBSY :
1939                                 {
1940                                         is_busy_err = 1;
1941                                 }
1942                         }
1943                 }
1944                 else if (ret == VCONF_ERROR_FILE_LOCK)
1945                 {
1946                         switch (errno)
1947                         {
1948                                 case EBADF :
1949                                 case EACCES :
1950                                 case EAGAIN :
1951                                 case ENOLCK :
1952                                 {
1953                                         is_busy_err = 1;
1954                                 }
1955                         }
1956                 }
1957                 else if (ret == VCONF_ERROR_FILE_FREAD)
1958                 {
1959                         switch (errno)
1960                         {
1961                                 case EAGAIN :
1962                                 case EINTR :
1963                                 case EIO :
1964                                 {
1965                                         is_busy_err = 1;
1966                                 }
1967                         }
1968                 }
1969                 else
1970                 {
1971                         is_busy_err = 0;
1972                 }
1973
1974                 if ((is_busy_err == 1) && (retry < VCONF_ERROR_RETRY_CNT)) {
1975                         ERR("%s : read buf error(%d). read will be retried(%d) , %d\n", keynode->keyname, ret, retry, (retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1976                         usleep((retry)*VCONF_ERROR_RETRY_SLEEP_UTIME);
1977                         continue;
1978                 } else {
1979                         ERR("%s : read buf error(%d). break\n",  keynode->keyname, ret);
1980                         func_ret = VCONF_ERROR;
1981                         break;
1982                 }
1983         }
1984
1985 #ifdef VCONF_USE_SQLFS_TRANSACTION
1986         if(prefix == VCONF_BACKEND_DB) {
1987                 if(func_ret == VCONF_ERROR) {
1988                         _vconf_db_rollback_transaction();
1989                 } else {
1990                         _vconf_db_commit_transaction();
1991                 }
1992         }
1993 #endif
1994
1995         return func_ret;
1996 }
1997
1998 /*
1999 static int _vconf_check_value_integrity(const void *value, int type)
2000 {
2001         int i = 0;
2002
2003         if ((type == VCONF_TYPE_STRING) && (value != NULL)) {
2004                 return 0;
2005         }
2006
2007         if ((value) && (strlen(value) > 0)) {
2008                 if ((type == VCONF_TYPE_INT) ||
2009                         (type == VCONF_TYPE_BOOL)||
2010                         (type == VCONF_TYPE_DOUBLE)) {
2011                         while (*(((char *)value) + i) != '\0') {
2012                                 if ( !isdigit(*(((char *)value) + i)) ) {
2013                                         if ((type != VCONF_TYPE_BOOL) &&
2014                                                 (*(((char *)value) + i) != '-')) {
2015                                                 if ((type == VCONF_TYPE_DOUBLE) &&
2016                                                         (*(((char *)value) + i) != '.')) {
2017                                                         ERR("ERROR : vconf value is not digit.");
2018                                                         return -1;
2019                                                 }
2020                                         }
2021                                 }
2022                                 i++;
2023                         }
2024                 }
2025
2026                 return 0;
2027         } else {
2028                 ERR("ERROR : vconf value is NULL.");
2029                 return -2;
2030         }
2031 }
2032 */
2033
2034 int _vconf_path_is_dir(char* path)
2035 {
2036         struct stat entryInfo;
2037
2038         if(lstat(path, &entryInfo) == 0 ) {
2039                 if( S_ISDIR( entryInfo.st_mode ) ) {
2040                         return 1;
2041                 } else {
2042                         return 0;
2043                 }
2044         } else {
2045                 return VCONF_ERROR;
2046         }
2047 }
2048
2049 API int vconf_get(keylist_t *keylist, const char *dirpath, get_option_t option)
2050 {
2051         DIR *dir = NULL;
2052         struct dirent entry;
2053         struct dirent *result = NULL;
2054         char full_file_path[VCONF_KEY_PATH_LEN] = {0,};
2055         char file_path[VCONF_KEY_PATH_LEN] = {0,};
2056         char full_path[VCONF_KEY_PATH_LEN] = {0,};
2057         char err_buf[ERR_LEN] = {0,};
2058         int rc = 0;
2059         int func_ret = 0;
2060         int ret = 0;
2061         int is_dir = 0;
2062         int prefix = 0;
2063
2064         keynode_t *temp_keynode;
2065
2066         retvm_if(keylist == NULL, VCONF_ERROR, "Invalid argument: keylist is null");
2067         retvm_if(dirpath == NULL, VCONF_ERROR, "Invalid argument: dirpath is null");
2068
2069         temp_keynode = _vconf_keylist_headnode(keylist);
2070
2071         if ((NULL != temp_keynode) && (VCONF_GET_KEY != option)) {
2072                 ERR("Not support mode : Only VCONF_GET_KEY \
2073                 option support To retrieve key with keylist");
2074                 return VCONF_ERROR;
2075         }
2076
2077         if(temp_keynode != NULL) {
2078                 while(_vconf_keynode_next(temp_keynode)) {
2079                         temp_keynode = _vconf_keynode_next(temp_keynode);
2080                 }
2081         }
2082
2083         ret = _vconf_get_key_path(dirpath, full_path);
2084         retvm_if(ret != VCONF_OK, ret, "Invalid argument: key is not valid");
2085
2086
2087         ret = _vconf_get_key_prefix(dirpath, &prefix);
2088         retv_if(ret != VCONF_OK, ret);
2089
2090 #ifdef VCONF_USE_SQLFS_TRANSACTION
2091         if(prefix == VCONF_BACKEND_DB) {
2092                 _vconf_db_begin_transaction();
2093         }
2094 #endif
2095
2096         is_dir = _vconf_path_is_dir(full_path);
2097         if(is_dir == 1) {
2098                 if((dir=opendir(full_path)) == NULL) {
2099                         strerror_r(errno, err_buf, ERR_LEN);
2100                         ERR("ERROR : open directory(%s) fail(%s)", dirpath, err_buf);
2101                         func_ret = VCONF_ERROR;
2102                         goto out_unlock;
2103                 }
2104
2105                 if((readdir_r(dir, &entry, &result)) != 0) {
2106                         strerror_r(errno, err_buf, ERR_LEN);
2107                         ERR("ERROR : read directory(%s) fail(%s)", dirpath, err_buf);
2108                         func_ret = VCONF_ERROR;
2109                 }
2110
2111                 while(result != NULL)
2112                 {
2113                         if(( strcmp( entry.d_name, ".") == 0 ) || ( strcmp( entry.d_name, "..") == 0 )) {
2114                             goto NEXT;
2115                         }
2116
2117                         keynode_t* keynode = _vconf_keynode_new();
2118                         if(keynode == NULL) {
2119                                 closedir(dir);
2120                                 ERR("Invalid argument: key malloc fail");
2121                                 func_ret = VCONF_ERROR;
2122                                 goto out_unlock;
2123                         }
2124
2125                         snprintf(file_path, VCONF_KEY_PATH_LEN, "%s/%s", dirpath, entry.d_name);
2126                         snprintf(full_file_path, VCONF_KEY_PATH_LEN, "%s/%s", full_path, entry.d_name);
2127
2128                         rc = _vconf_path_is_dir(full_file_path);
2129                         if(rc != VCONF_ERROR) {
2130                                 if(rc == 1) {
2131                                         /* directory */
2132                                         if(option == VCONF_GET_KEY) {
2133                                                 _vconf_keynode_free(keynode);
2134                                                 goto NEXT;
2135                                         } else {
2136                                                 _vconf_keynode_set_keyname(keynode, file_path);
2137                                                 _vconf_keynode_set_dir(keynode);
2138                                         }
2139                                 } else {
2140                                         _vconf_keynode_set_keyname(keynode, file_path);
2141                                         _vconf_get_key(keynode);
2142                                 }
2143
2144                                 if (keylist->head && temp_keynode != NULL)
2145                                 {
2146                                         temp_keynode->next = keynode;
2147                                         temp_keynode = _vconf_keynode_next(temp_keynode);
2148                                 }
2149                                 else {
2150                                         keylist->head = keynode;
2151                                         temp_keynode = keylist->head;
2152                                 }
2153                                 keylist->num += 1;
2154                         } else {
2155                                 _vconf_keynode_free(keynode);
2156
2157                                 memset(err_buf, 0x00, sizeof(err_buf));
2158                                 strerror_r(errno, err_buf, sizeof(err_buf));
2159                                 ERR("ERROR : get path(%s) fail(%s)", file_path, err_buf);
2160                                 func_ret = VCONF_ERROR;
2161                         }
2162
2163         NEXT:
2164                         if((readdir_r(dir, &entry, &result)) != 0) {
2165                                 memset(err_buf, 0x00, sizeof(err_buf));
2166                                 strerror_r(errno, err_buf, sizeof(err_buf));
2167                                 ERR("ERROR : read directory(%s) fail(%s)", dirpath, err_buf);
2168                                 func_ret = VCONF_ERROR;
2169                         }
2170                 }
2171
2172                 if((closedir(dir)) != 0) {
2173                         memset(err_buf, 0x00, sizeof(err_buf));
2174                         strerror_r(errno, err_buf, sizeof(err_buf));
2175                         ERR("ERROR : close directory(%s) fail(%s)", dirpath, err_buf);
2176                         func_ret = VCONF_ERROR;
2177                 }
2178         } else if(is_dir == 0) {
2179                 keynode_t* keynode = _vconf_keynode_new();
2180                 retvm_if(keynode == NULL, VCONF_ERROR, "Invalid argument: key malloc fail");
2181
2182                 _vconf_keynode_set_keyname(keynode, dirpath);
2183
2184                 _vconf_get_key(keynode);
2185
2186                 if (keylist->head && temp_keynode != NULL) {
2187                         temp_keynode->next = keynode;
2188                         //temp_keynode = _vconf_keynode_next(temp_keynode);
2189                 } else {
2190                         keylist->head = keynode;
2191                         temp_keynode = keylist->head;
2192                 }
2193                 keylist->num += 1;
2194         } else {
2195                 func_ret = VCONF_ERROR;
2196                 goto out_unlock;
2197         }
2198         vconf_keylist_rewind(keylist);
2199
2200 out_unlock:
2201 #ifdef VCONF_USE_SQLFS_TRANSACTION
2202         if(prefix == VCONF_BACKEND_DB) {
2203                 if(func_ret == VCONF_ERROR) {
2204                         _vconf_db_rollback_transaction();
2205                 } else {
2206                         _vconf_db_commit_transaction();
2207                 }
2208         }
2209 #endif
2210
2211         return func_ret;
2212 }
2213
2214 /*
2215  * This function get the integer value of given key
2216  * @param[in]   in_key  key
2217  * @param[out]  intval output buffer
2218  * @return 0 on success, -1 on error
2219  */
2220 API int vconf_get_int(const char *in_key, int *intval)
2221 {
2222         START_TIME_CHECK
2223
2224         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2225         retvm_if(intval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2226
2227         int func_ret = VCONF_ERROR;
2228         keynode_t* pKeyNode = _vconf_keynode_new();
2229         retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2230
2231         _vconf_keynode_set_keyname(pKeyNode, in_key);
2232
2233         if (_vconf_get_key(pKeyNode) != VCONF_OK)
2234                 ERR("vconf_get_int(%d) : %s error", getpid(), in_key);
2235         else {
2236                 *intval = pKeyNode->value.i;
2237
2238                 if(pKeyNode->type == VCONF_TYPE_INT) {
2239                         INFO("vconf_get_int(%d) : %s(%d) success", getpid(), in_key, *intval);
2240                         func_ret = VCONF_OK;
2241                 } else
2242                         ERR("The type(%d) of keynode(%s) is not INT", pKeyNode->type, pKeyNode->keyname);
2243         }
2244
2245         _vconf_keynode_free(pKeyNode);
2246
2247         END_TIME_CHECK
2248
2249         return func_ret;
2250 }
2251
2252 /*
2253  * This function get the boolean value of given key
2254  * @param[in]   in_key  key
2255  * @param[out]  boolval output buffer
2256  * @return 0 on success, -1 on error
2257  */
2258 API int vconf_get_bool(const char *in_key, int *boolval)
2259 {
2260         START_TIME_CHECK
2261
2262         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2263         retvm_if(boolval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2264
2265         int func_ret = VCONF_ERROR;
2266         keynode_t* pKeyNode = _vconf_keynode_new();
2267         retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2268
2269         _vconf_keynode_set_keyname(pKeyNode, in_key);
2270
2271         if (_vconf_get_key(pKeyNode) != VCONF_OK)
2272                 ERR("vconf_get_bool(%d) : %s error", getpid(), in_key);
2273         else {
2274                 *boolval = !!(pKeyNode->value.b);
2275
2276                 if(pKeyNode->type == VCONF_TYPE_BOOL) {
2277                         INFO("vconf_get_bool(%d) : %s(%d) success", getpid(), in_key, *boolval);
2278                         func_ret = VCONF_OK;
2279                 } else
2280                         ERR("The type(%d) of keynode(%s) is not BOOL", pKeyNode->type, pKeyNode->keyname);
2281         }
2282
2283         _vconf_keynode_free(pKeyNode);
2284
2285         END_TIME_CHECK
2286
2287         return func_ret;
2288 }
2289
2290 /*
2291  * This function get the double value of given key
2292  * @param[in]   in_key  key
2293  * @param[out]  dblval output buffer
2294  * @return 0 on success, -1 on error
2295  */
2296 API int vconf_get_dbl(const char *in_key, double *dblval)
2297 {
2298         START_TIME_CHECK
2299
2300         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2301         retvm_if(dblval == NULL, VCONF_ERROR, "Invalid argument: output buffer is null");
2302
2303         int func_ret = VCONF_ERROR;
2304         keynode_t* pKeyNode = _vconf_keynode_new();
2305         retvm_if(pKeyNode == NULL, VCONF_ERROR, "key malloc fail");
2306
2307         _vconf_keynode_set_keyname(pKeyNode, in_key);
2308
2309         if (_vconf_get_key(pKeyNode) != VCONF_OK)
2310                 ERR("vconf_get_dbl(%d) : %s error", getpid(), in_key);
2311         else {
2312
2313                 *dblval = pKeyNode->value.d;
2314
2315                 if(pKeyNode->type == VCONF_TYPE_DOUBLE) {
2316                         INFO("vconf_get_dbl(%d) : %s(%f) success", getpid(), in_key, *dblval);
2317                         func_ret = VCONF_OK;
2318                 } else
2319                         ERR("The type(%d) of keynode(%s) is not DBL", pKeyNode->type, pKeyNode->keyname);
2320         }
2321
2322         _vconf_keynode_free(pKeyNode);
2323
2324         END_TIME_CHECK
2325
2326         return func_ret;
2327 }
2328
2329 /*
2330  * This function get the string value of given key
2331  * @param[in]   in_key  key
2332  * @return pointer of key value on success, NULL on error
2333  */
2334 API char *vconf_get_str(const char *in_key)
2335 {
2336         START_TIME_CHECK
2337
2338         retvm_if(in_key == NULL, NULL, "Invalid argument: key is null");
2339
2340         keynode_t* pKeyNode = _vconf_keynode_new();
2341         retvm_if(pKeyNode == NULL, NULL, "key malloc fail");
2342
2343         _vconf_keynode_set_keyname(pKeyNode, in_key);
2344
2345         char *strval = NULL;
2346         char *tempstr = NULL;
2347
2348         if (_vconf_get_key(pKeyNode) != VCONF_OK) {
2349                 ERR("vconf_get_str(%d) : %s error", getpid(), in_key);
2350         } else {
2351
2352                 if(pKeyNode->type == VCONF_TYPE_STRING)
2353                         tempstr = pKeyNode->value.s;
2354                 else
2355                         ERR("The type(%d) of keynode(%s) is not STR", pKeyNode->type, pKeyNode->keyname);
2356
2357                 if(tempstr)
2358                         strval = strdup(tempstr);
2359                 INFO("vconf_get_str(%d) : %s(%s) success", getpid(), in_key, strval);
2360         }
2361
2362         _vconf_keynode_free(pKeyNode);
2363
2364         END_TIME_CHECK
2365
2366         return strval;
2367 }
2368
2369 /*
2370  * This function unset given key
2371  * @param[in]   in_key  key
2372  * @return 0 on success, -1 on error
2373  */
2374 API int vconf_unset(const char *in_key)
2375 {
2376         START_TIME_CHECK
2377
2378         char path[VCONF_KEY_PATH_LEN] = {0,};
2379         int ret = -1;
2380         int err_retry = VCONF_ERROR_RETRY_CNT;
2381         int func_ret = VCONF_OK;
2382
2383         WARN("vconf_unset: %s. THIS API(vconf_unset) WILL BE DEPRECATED", in_key);
2384
2385         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2386
2387         ret = _vconf_get_key_path(in_key, path);
2388         retvm_if(ret != VCONF_OK, VCONF_ERROR, "Invalid argument: key is not valid");
2389
2390         retvm_if(access(path, F_OK) == -1, VCONF_ERROR, "Error : key(%s) is not exist", in_key);
2391
2392         do {
2393                 ret = remove(path);
2394                 if(ret == -1) {
2395                         ERR("vconf_unset error(%d) : %s", errno, in_key);
2396                         func_ret = VCONF_ERROR;
2397                 } else {
2398                         func_ret = VCONF_OK;
2399                         break;
2400                 }
2401         } while(err_retry--);
2402
2403         END_TIME_CHECK
2404
2405         return func_ret;
2406 }
2407
2408 /*
2409  * This function unset given key recursively
2410  * @param[in]   in_dir  Directory name for removing
2411  * @return 0 on success, -1 on error
2412  */
2413 API int vconf_unset_recursive(const char *in_dir)
2414 {
2415         START_TIME_CHECK
2416
2417         DIR *dir = NULL;
2418         struct dirent entry;
2419         struct dirent *result = NULL;
2420         char fullpath[VCONF_KEY_PATH_LEN] = {0,};
2421         char dirpath[VCONF_KEY_PATH_LEN] = {0,};
2422         char err_buf[ERR_LEN] = {0,};
2423         int rc = 0;
2424         int func_ret = 0;
2425         int ret = 0;
2426
2427         WARN("vconf_unset_recursive: %s. THIS API(vconf_unset_recursive) WILL BE DEPRECATED", in_dir);
2428
2429         retvm_if(in_dir == NULL, VCONF_ERROR, "Invalid argument: dir path is null");
2430
2431         ret = _vconf_get_key_path(in_dir, dirpath);
2432         retvm_if(ret != VCONF_OK, VCONF_ERROR, "Invalid argument: key is not valid");
2433
2434         if((dir=opendir(dirpath)) == NULL) {
2435                 strerror_r(errno, err_buf, ERR_LEN);
2436                 ERR("ERROR : open directory(%s) fail(%s)", in_dir, err_buf);
2437                 return VCONF_ERROR;
2438         }
2439
2440         if((readdir_r(dir, &entry, &result)) != 0) {
2441                 strerror_r(errno, err_buf, ERR_LEN);
2442                 ERR("ERROR : read directory(%s) fail(%s)", in_dir, err_buf);
2443                 func_ret = VCONF_ERROR;
2444         }
2445
2446         while(result != NULL)
2447         {
2448                 if(( strcmp( entry.d_name, ".") == 0 ) || ( strcmp( entry.d_name, "..") == 0 )) {
2449                     goto NEXT;
2450                 }
2451
2452                 snprintf(fullpath,VCONF_KEY_PATH_LEN, "%s/%s", dirpath, entry.d_name);
2453
2454                 ret = _vconf_path_is_dir(fullpath);
2455                 if(ret != VCONF_ERROR) {
2456                         if(ret == 1) {
2457                                 rc = vconf_unset_recursive(fullpath);
2458                                 if(rc == VCONF_ERROR)
2459                                         func_ret = VCONF_ERROR;
2460                         }
2461
2462                         rc = remove(fullpath);
2463                         if(rc == -1) {
2464                                 memset(err_buf, 0x00, sizeof(err_buf));
2465                                 strerror_r(errno, err_buf, sizeof(err_buf));
2466                                 ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2467                                 func_ret = VCONF_ERROR;
2468                         }
2469                 } else {
2470                         memset(err_buf, 0x00, sizeof(err_buf));
2471                         strerror_r(errno, err_buf, sizeof(err_buf));
2472                         ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2473                         func_ret = VCONF_ERROR;
2474                 }
2475 NEXT:
2476                 if((readdir_r(dir, &entry, &result)) != 0) {
2477                         memset(err_buf, 0x00, sizeof(err_buf));
2478                         strerror_r(errno, err_buf, sizeof(err_buf));
2479                         ERR("ERROR : read directory(%s) fail(%s)", in_dir, err_buf);
2480                         func_ret = VCONF_ERROR;
2481                 }
2482         }
2483
2484         if((closedir(dir)) != 0) {
2485                 memset(err_buf, 0x00, sizeof(err_buf));
2486                 strerror_r(errno, err_buf, sizeof(err_buf));
2487                 ERR("ERROR : close directory(%s) fail(%s)", in_dir, err_buf);
2488                 func_ret = VCONF_ERROR;
2489         }
2490 #if 0
2491         if(func_ret == VCONF_OK) {
2492                 if((remove(in_dir)) == -1) {
2493                         memset(err_buf, 0x00, sizeof(err_buf));
2494                         strerror_r(errno, err_buf, sizeof(err_buf));
2495                         ERR("ERROR : remove path(%s) fail(%s)", in_dir, err_buf);
2496                         func_ret = VCONF_ERROR;
2497                 }
2498         }
2499 #endif
2500
2501         return func_ret;
2502 }
2503
2504 API int vconf_notify_key_changed(const char *in_key, vconf_callback_fn cb, void *user_data)
2505 {
2506         START_TIME_CHECK
2507
2508         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2509         retvm_if(cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
2510
2511         if (_vconf_kdb_add_notify(in_key, cb, user_data)) {
2512                 ERR("vconf_notify_key_changed : key(%s) add notify fail", in_key);
2513                 return VCONF_ERROR;
2514         }
2515
2516         INFO("vconf_notify_key_changed : %s noti is added", in_key);
2517
2518         END_TIME_CHECK
2519
2520         return VCONF_OK;
2521 }
2522
2523 API int vconf_ignore_key_changed(const char *in_key, vconf_callback_fn cb)
2524 {
2525         START_TIME_CHECK
2526
2527         retvm_if(in_key == NULL, VCONF_ERROR, "Invalid argument: key is null");
2528         retvm_if(cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
2529
2530         if (_vconf_kdb_del_notify(in_key, cb)) {
2531                 ERR("vconf_ignore_key_changed() failed: key(%s)", in_key);
2532                 return VCONF_ERROR;
2533         }
2534
2535         INFO("vconf_ignore_key_changed : %s noti removed", in_key);
2536
2537         END_TIME_CHECK
2538
2539         return VCONF_OK;
2540 }
2541
2542 API mode_t vconf_set_permission(mode_t mode)
2543 {
2544         /* TODO: implement! */
2545         return mode;
2546 }
2547
2548 API int vconf_set_key_permission(const char *in_key, const mode_t mode)
2549 {
2550         /* TODO: implement! */
2551         return 0;
2552 }
2553