4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hakjoo Ko <hakjoo.ko@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <glib-object.h>
28 #include "vconf-log.h"
32 #include <sys/types.h>
36 #include <tzplatform_config.h>
40 VCONFTOOL_TYPE_NO = 0x00,
41 VCONFTOOL_TYPE_STRING,
43 VCONFTOOL_TYPE_DOUBLE,
48 #define DB_PREFIX tzplatform_getenv(TZ_SYS_CONFIG)
49 #define FILE_PREFIX tzplatform_getenv(TZ_SYS_CONFIG)
50 #define MEMORY_INIT tzplatform_mkpath(TZ_SYS_CONFIG,"memory_init")
52 const char *BACKEND_DB_PREFIX = "db/";
53 const char *BACKEND_FILE_PREFIX = "file/";
54 const char *BACKEND_MEMORY_PREFIX = "memory/";
56 static char *guid = NULL;
57 static char *uid = NULL;
58 static char *vconf_type = NULL;
59 static int is_recursive = FALSE;
60 static int is_initialization = FALSE;
61 static int is_forced = FALSE;
62 static int get_num = 0;
64 static GOptionEntry entries[] = {
65 {"type", 't', 0, G_OPTION_ARG_STRING, &vconf_type, "type of value",
66 "int|bool|double|string"},
67 {"recursive", 'r', 0, G_OPTION_ARG_NONE, &is_recursive,
68 "retrieve keys recursively", NULL},
69 {"guid", 'g', 0, G_OPTION_ARG_STRING, &guid, "group permission", NULL},
70 {"uid", 'u', 0, G_OPTION_ARG_STRING, &uid, "user permission", NULL},
71 {"initialization", 'i', 0, G_OPTION_ARG_NONE, &is_initialization,
72 "memory backend initialization", NULL},
73 {"force", 'f', 0, G_OPTION_ARG_NONE, &is_forced,
74 "overwrite vconf values by force", NULL},
78 static void get_operation(char *input);
79 static void recursive_get(char *subDIR, int level);
80 static void print_keylist(keylist_t *keylist, keynode_t *temp_node, int level);
82 static void print_help(const char *cmd)
84 fprintf(stderr, "Usage:\n");
85 fprintf(stderr, "\n");
86 fprintf(stderr, "[Set vconf value]\n");
88 " %s set -t <TYPE> <KEY NAME> <VALUE> <OPTIONS>\n", cmd);
89 fprintf(stderr, " <TYPE>=int|bool|double|string\n");
90 fprintf(stderr, "\n");
92 " Ex) %s set -t string db/testapp/key1 \"This is test\" \n",
94 fprintf(stderr, "\n");
95 fprintf(stderr, " <OPTIONS>\n");
97 " -g <GUID> : Set Effective group id. The key's permission will be set to 0664.\n");
99 " Ex) %s set -t string db/testapp/key1 \"This is test\" -g 425\n",
102 " NOTE: -g and -u cannot be userd together. -u ignores -g option.\n");
103 fprintf(stderr, "\n");
105 " -u <UID> : Set Effective user id. The key's permission will be set to 0644.\n");
107 " Ex) %s set -t string db/testapp/key1 \"This is test\" -u 5000\n",
110 " NOTE: -g and -u cannot be userd together. -u ignores -g option.\n");
111 fprintf(stderr, "\n");
113 " -i : Install memory backend key into flash space for backup.\n");
115 " Ex) %s set -t string memory/testapp/key1 \"This is test\" -i\n",
117 fprintf(stderr, "\n");
119 " -f : Overwrite values by force, even when vconf values are already exist.\n");
120 fprintf(stderr, "\n");
121 fprintf(stderr, "[Get vconf value]\n");
122 fprintf(stderr, " %s get <OPTIONS> <KEY NAME>\n", cmd);
123 fprintf(stderr, "\n");
124 fprintf(stderr, " <OPTIONS>\n");
126 " -r : retrieve all keys included in sub-directorys \n");
127 fprintf(stderr, " Ex) %s get db/testapp/key1\n", cmd);
128 fprintf(stderr, " %s get db/testapp/\n", cmd);
129 fprintf(stderr, "\n");
130 fprintf(stderr, "[Unset vconf value]\n");
131 fprintf(stderr, " %s unset <KEY NAME>\n", cmd);
132 fprintf(stderr, "\n");
133 fprintf(stderr, " Ex) %s unset db/testapp/key1\n", cmd);
134 fprintf(stderr, "\n");
137 static int check_type(void)
140 if (!strncasecmp(vconf_type, "int", 3))
141 return VCONFTOOL_TYPE_INT;
142 else if (!strncasecmp(vconf_type, "string", 6))
143 return VCONFTOOL_TYPE_STRING;
144 else if (!strncasecmp(vconf_type, "double", 6))
145 return VCONFTOOL_TYPE_DOUBLE;
146 else if (!strncasecmp(vconf_type, "bool", 4))
147 return VCONFTOOL_TYPE_BOOL;
149 return VCONFTOOL_TYPE_NO;
152 static int __system(char * cmd)
157 if((cpid = fork()) < 0) {
170 execv(w[0], (char *const *)w);
177 if (waitpid(cpid, &status, 0) == -1) {
178 perror("waitpid failed");
181 if (WIFSIGNALED(status)) {
182 printf("signal(%d)\n", WTERMSIG(status));
183 perror("exit by signal");
186 if (!WIFEXITED(status)) {
187 perror("exit abnormally");
190 if (WIFEXITED(status) && WEXITSTATUS(status)) {
191 perror("child return error");
199 static void disable_invalid_char(char* src)
203 for(tmp = src; *tmp; ++tmp)
205 if( (*tmp == ';') || (*tmp == '|') )
207 fprintf(stderr,"invalid char is found\n");
213 static int check_file_path_mode(char* file_path)
215 char szCmd[BUFSIZE] = {0,};
223 "Error!\t Only root user can use '-g or -u' option\n");
230 /* Check file path */
231 if (access(file_path, F_OK) != 0) {
232 /* fprintf(stderr,"key does not exist\n"); */
234 char szPath[BUFSIZE] = { 0, };
235 char *pCh = strrchr(file_path, '/');
236 strncat(szPath, file_path, pCh - file_path);
237 /* fprintf(stderr, "szPath : %s\n", szPath); */
239 /* Check directory & create it */
240 if (access(szPath, F_OK) != 0) {
241 /* fprintf(stderr,"parent dir does not exist\n"); */
243 snprintf(szCmd, BUFSIZE, "/bin/mkdir %s -p --mode=775", szPath);
244 disable_invalid_char(szCmd);
245 if (__system(szCmd)) {
246 fprintf(stderr,"[%s:%d]Fail mkdir() szCmd=%s\n", __FILE__, __LINE__, szCmd);
250 snprintf(szCmd, BUFSIZE, "/bin/chgrp %s %s",tzplatform_getenv(TZ_SYS_USER_GROUP), szPath);
251 if (__system(szCmd)) {
252 fprintf(stderr,"[%s:%d]Fail chgrp() szCmd=%s\n", __FILE__, __LINE__, szCmd);
259 } else if (!is_forced) {
260 fprintf(stderr, "Key already exist. Use -f option to force update\n");
268 fd = open(file_path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
271 fprintf(stderr, "open(rdwr,create) error\n");
278 if((fd = open(file_path, O_RDONLY)) == -1) {
279 fprintf(stderr, "open(rdonly) error\n");
284 if (fchown(fd, atoi(uid), atoi(uid)) == -1) {
285 fprintf(stderr, "Error!\t Fail to fchown(%d)\n", errno);
290 if (-1 == fchown(fd, 0, atoi(guid))) {
291 fprintf(stderr, "Error!\t Fail to fchown()\n");
304 * there are three different types of vconf key back-end
306 * 2. sqlitefs based on sqlite3
307 * 3. tmpfs based on memory
308 * considering to that tmpfs is volatile so there should be a way
309 * to initialize key into permanent storage. That is the below function
310 * which copy memory back-end key to filesystem back-end, copy other back-end
311 * key to filesystem back-end just makes no sense.
313 static int copy_memory_key(char *pszKey, char *pszOrigin)
315 char szCmd[BUFSIZE] = { 0, };
316 char szPath[BUFSIZE] = { 0, };
317 char szFileName[BUFSIZE] = { 0, };
318 char *pCh = strrchr(pszKey, '/');
319 int nLen = strlen(pszKey);
321 /* only copy memory/ prefix key */
322 if (strncmp("memory/", pszKey, 7))
325 /* Get directory path and file name */
326 snprintf(szPath, BUFSIZE, "%s/", MEMORY_INIT);
327 strncat(szPath, pszKey, pCh - pszKey);
328 strncpy(szFileName, pszKey + (pCh - pszKey) + 1, nLen - (pCh - pszKey));
330 /* Check directory & create it */
331 if (0 != access(szPath, F_OK)) {
332 snprintf(szCmd, BUFSIZE, "mkdir %s -p --mode=755", szPath);
334 printf("[%s:%d]Fail mkdir() szCmd=%s\n", __FILE__,
340 strncat(szPath, "/", 1);
341 strncat(szPath, szFileName, strlen(szFileName));
342 memset(szCmd, 0x00, BUFSIZE);
343 snprintf(szCmd, BUFSIZE, "cp %s %s -r -p", pszOrigin, szPath);
345 printf("[%s:%d]Fail copy\n", __FILE__, __LINE__);
351 static int make_file_path(char *pszKey, char *pszBuf)
354 strncmp(pszKey, BACKEND_DB_PREFIX, strlen(BACKEND_DB_PREFIX))) {
355 snprintf(pszBuf, BUFSIZE, "%s/%s", DB_PREFIX, pszKey);
358 strncmp(pszKey, BACKEND_FILE_PREFIX,
359 strlen(BACKEND_FILE_PREFIX))) {
360 snprintf(pszBuf, BUFSIZE, "%s/%s", FILE_PREFIX, pszKey);
363 strncmp(pszKey, BACKEND_MEMORY_PREFIX,
364 strlen(BACKEND_MEMORY_PREFIX))) {
365 snprintf(pszBuf, BUFSIZE, "%s/%s", tzplatform_getenv(TZ_SYS_RUN), pszKey);
371 int main(int argc, char **argv)
374 char szFilePath[BUFSIZE] = { 0, };
375 char *psz_key = NULL;
377 GError *error = NULL;
378 GOptionContext *context;
381 context = g_option_context_new("- vconf library tool");
382 g_option_context_add_main_entries(context, entries, NULL);
383 g_option_context_set_help_enabled(context, FALSE);
384 g_option_context_set_ignore_unknown_options(context, TRUE);
386 if (!g_option_context_parse(context, &argc, &argv, &error)) {
387 g_print("option parsing failed: %s\n", error->message);
396 if (!strncmp(argv[1], "set", 3)) {
397 set_type = check_type();
398 if (argc < 4 || !set_type) {
403 if (make_file_path(argv[2], szFilePath)) {
404 fprintf(stderr, "Error!\t Bad prefix\n");
408 if (check_file_path_mode(szFilePath)) {
409 fprintf(stderr, "Error!\t create key %s\n", argv[2]);
414 case VCONFTOOL_TYPE_STRING:
415 vconf_set_str(argv[2], argv[3]);
417 case VCONFTOOL_TYPE_INT:
418 vconf_set_int(argv[2], atoi(argv[3]));
420 case VCONFTOOL_TYPE_DOUBLE:
421 vconf_set_dbl(argv[2], atof(argv[3]));
423 case VCONFTOOL_TYPE_BOOL:
424 vconf_set_bool(argv[2], !!atoi(argv[3]));
427 fprintf(stderr, "never reach");
432 /* Install memory backend key into flash space *******/
433 if (is_initialization) {
434 copy_memory_key(psz_key, szFilePath);
436 /* End memory backend key into flash space ***********/
438 } else if (!strncmp(argv[1], "get", 3)) {
440 get_operation(argv[2]);
443 } else if (!strncmp(argv[1], "unset", 5)) {
445 vconf_unset(argv[2]);
449 fprintf(stderr, "%s is a invalid command\n", argv[1]);
453 static void get_operation(char *input)
455 keylist_t *get_keylist;
456 keynode_t *temp_node;
459 get_keylist = vconf_keylist_new();
460 /* ParentDIR parameter of gconf_client_all_entries
461 can not include the last slash. */
462 if ('/' == input[strlen(input) - 1] && strlen(input) > 8)
463 input[strlen(input) - 1] = '\0';
465 vconf_get(get_keylist, input, VCONF_GET_ALL);
466 if (!(temp_node = vconf_keylist_nextnode(get_keylist))) {
467 test = strrchr(input, '/');
469 vconf_keylist_add_null(get_keylist, input);
470 if (test - input < 7)
474 vconf_get(get_keylist, input, VCONF_GET_KEY);
475 temp_node = vconf_keylist_nextnode(get_keylist);
477 fprintf(stderr, "Include at least one slash\"/\"\n");
478 vconf_keylist_free(get_keylist);
483 print_keylist(get_keylist, temp_node, 0);
487 vconf_keylist_free(get_keylist);
490 static void recursive_get(char *subDIR, int level)
492 keylist_t *get_keylist;
493 keynode_t *first_node;
495 get_keylist = vconf_keylist_new();
496 vconf_get(get_keylist, subDIR, VCONF_GET_ALL);
498 if ((first_node = vconf_keylist_nextnode(get_keylist))) {
499 print_keylist(get_keylist, first_node, level);
501 vconf_keylist_free(get_keylist);
504 static void print_keylist(keylist_t *keylist, keynode_t *temp_node, int level)
507 switch (vconf_keynode_get_type(temp_node))
510 printf("%s, value = %d (int)\n",
511 vconf_keynode_get_name(temp_node),
512 vconf_keynode_get_int(temp_node));
515 case VCONF_TYPE_BOOL:
516 printf("%s, value = %d (bool)\n",
517 vconf_keynode_get_name(temp_node),
518 vconf_keynode_get_bool(temp_node));
521 case VCONF_TYPE_DOUBLE:
522 printf("%s, value = %f (double)\n",
523 vconf_keynode_get_name(temp_node),
524 vconf_keynode_get_dbl(temp_node));
527 case VCONF_TYPE_STRING:
528 printf("%s, value = %s (string)\n",
529 vconf_keynode_get_name(temp_node),
530 vconf_keynode_get_str(temp_node));
534 printf("%s(Directory)\n",
535 vconf_keynode_get_name(temp_node));
537 recursive_get(vconf_keynode_get_name(temp_node),
541 /* fprintf(stderr, "Unknown Type(%d)\n", vconf_keynode_get_type(temp_node)); */
544 } while ((temp_node = vconf_keylist_nextnode(keylist)));