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