X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuci.git;a=blobdiff_plain;f=cli.c;h=36ef6e5d1cbbedbd3baa07d8a11f4dbd7dd27db2;hp=16306ff845c449b4180fb340c19dfec7f7ed97ec;hb=00d91c8ca4a5d35d5c3706d0042f0e57cefa3d12;hpb=cbe26a83fc4756b9919ac72ace53a6a9556e80f7 diff --git a/cli.c b/cli.c index 16306ff..36ef6e5 100644 --- a/cli.c +++ b/cli.c @@ -26,6 +26,7 @@ static enum { CLI_FLAG_QUIET = (1 << 1), CLI_FLAG_NOCOMMIT = (1 << 2), CLI_FLAG_BATCH = (1 << 3), + CLI_FLAG_SHOW_EXT = (1 << 4), } flags; static FILE *input; @@ -50,8 +51,68 @@ enum { CMD_HELP, }; +struct uci_type_list { + unsigned int idx; + const char *name; + struct uci_type_list *next; +}; + +static struct uci_type_list *type_list = NULL; +static char *typestr = NULL; +static const char *cur_section_ref = NULL; + static int uci_cmd(int argc, char **argv); +static void +uci_reset_typelist(void) +{ + struct uci_type_list *type; + while (type_list != NULL) { + type = type_list; + type_list = type_list->next; + free(type); + } + if (typestr) { + free(typestr); + typestr = NULL; + } + cur_section_ref = NULL; +} + +static char * +uci_lookup_section_ref(struct uci_section *s) +{ + struct uci_type_list *ti = type_list; + int maxlen; + + if (!s->anonymous || !(flags & CLI_FLAG_SHOW_EXT)) + return s->e.name; + + /* look up in section type list */ + while (ti) { + if (strcmp(ti->name, s->type) == 0) + break; + ti = ti->next; + } + if (!ti) { + ti = malloc(sizeof(struct uci_type_list)); + memset(ti, 0, sizeof(struct uci_type_list)); + ti->next = type_list; + type_list = ti; + ti->name = s->type; + } + + maxlen = strlen(s->type) + 1 + 2 + 10; + if (!typestr) { + typestr = malloc(maxlen); + } else { + typestr = realloc(typestr, maxlen); + } + sprintf(typestr, "@%s[%d]", ti->name, ti->idx); + ti->idx++; + return typestr; +} + static void uci_usage(void) { fprintf(stderr, @@ -83,6 +144,7 @@ static void uci_usage(void) "\t-q quiet mode (don't print error messages)\n" "\t-s force strict mode (stop on parser errors, default)\n" "\t-S disable strict mode\n" + "\t-X do not use extended syntax on 'show'\n" "\n", appname ); @@ -122,20 +184,21 @@ static void uci_show_option(struct uci_option *o) { printf("%s.%s.%s=", o->section->package->e.name, - o->section->e.name, + (cur_section_ref ? cur_section_ref : o->section->e.name), o->e.name); uci_show_value(o); } -static void uci_show_section(struct uci_section *p) +static void uci_show_section(struct uci_section *s) { struct uci_element *e; - const char *cname, *sname; + const char *cname; + const char *sname; - cname = p->package->e.name; - sname = p->e.name; - printf("%s.%s=%s\n", cname, sname, p->type); - uci_foreach_element(&p->options, e) { + cname = s->package->e.name; + sname = (cur_section_ref ? cur_section_ref : s->e.name); + printf("%s.%s=%s\n", cname, sname, s->type); + uci_foreach_element(&s->options, e) { uci_show_option(uci_to_option(e)); } } @@ -144,9 +207,13 @@ static void uci_show_package(struct uci_package *p) { struct uci_element *e; + uci_reset_typelist(); uci_foreach_element( &p->sections, e) { - uci_show_section(uci_to_section(e)); + struct uci_section *s = uci_to_section(e); + cur_section_ref = uci_lookup_section_ref(s); + uci_show_section(s); } + uci_reset_typelist(); } static void uci_show_changes(struct uci_package *p) @@ -179,53 +246,43 @@ static void uci_show_changes(struct uci_package *p) static int package_cmd(int cmd, char *tuple) { - struct uci_package *p; - struct uci_section *s; struct uci_element *e = NULL; + struct uci_ptr ptr; - if (uci_lookup_ext(ctx, &e, tuple) != UCI_OK) { + if (uci_lookup_ptr(ctx, &ptr, tuple, true) != UCI_OK) { cli_perror(); return 1; } - switch(e->type) { - case UCI_TYPE_PACKAGE: - p = uci_to_package(e); - break; - case UCI_TYPE_SECTION: - s = uci_to_section(e); - p = s->package; - break; - case UCI_TYPE_OPTION: - s = uci_to_option(e)->section; - p = s->package; - break; - default: - return 0; - } + e = ptr.last; switch(cmd) { case CMD_CHANGES: - uci_show_changes(p); + uci_show_changes(ptr.p); break; case CMD_COMMIT: if (flags & CLI_FLAG_NOCOMMIT) return 0; - if (uci_commit(ctx, &p, false) != UCI_OK) + if (uci_commit(ctx, &ptr.p, false) != UCI_OK) cli_perror(); break; case CMD_EXPORT: - uci_export(ctx, stdout, p, true); + uci_export(ctx, stdout, ptr.p, true); break; case CMD_SHOW: + if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) { + ctx->err = UCI_ERR_NOTFOUND; + cli_perror(); + return 1; + } switch(e->type) { case UCI_TYPE_PACKAGE: - uci_show_package(p); + uci_show_package(ptr.p); break; case UCI_TYPE_SECTION: - uci_show_section(uci_to_section(e)); + uci_show_section(ptr.s); break; case UCI_TYPE_OPTION: - uci_show_option(uci_to_option(e)); + uci_show_option(ptr.o); break; default: /* should not happen */ @@ -234,7 +291,7 @@ static int package_cmd(int cmd, char *tuple) break; } - uci_unload(ctx, p); + uci_unload(ctx, ptr.p); return 0; } @@ -335,74 +392,35 @@ done: static int uci_do_section_cmd(int cmd, int argc, char **argv) { - struct uci_package *p = NULL; - struct uci_section *s = NULL; - struct uci_element *e = NULL; - struct uci_option *o = NULL; - char *section = NULL; - char *option = NULL; - char *value = NULL; + struct uci_element *e; + struct uci_ptr ptr; int ret = UCI_OK; - char *str; if (argc != 2) return 255; - value = strchr(argv[1], '='); - if (value) { - *value = 0; - value++; - if (!uci_validate_text(value)) - return 1; - } - - if (value && (cmd != CMD_SET) && (cmd != CMD_ADD_LIST) && (cmd != CMD_RENAME)) - return 1; - - do { - str = strchr(argv[1], '.'); /* look up section part */ - if (!str) - break; - - str++; - str = strchr(str, '.'); /* look up option part */ - if (!str) - break; - - /* separate option from the rest of the pointer */ - *str = 0; - option = str + 1; - } while (0); - - if (uci_lookup_ext(ctx, &e, argv[1]) != UCI_OK) { + if (uci_lookup_ptr(ctx, &ptr, argv[1], true) != UCI_OK) { cli_perror(); return 1; } - switch(e->type) { - case UCI_TYPE_PACKAGE: - p = uci_to_package(e); - break; - case UCI_TYPE_SECTION: - s = uci_to_section(e); - break; - default: + if (ptr.value && (cmd != CMD_SET) && (cmd != CMD_ADD_LIST) && (cmd != CMD_RENAME)) return 1; - } - if (s) { - section = s->e.name; - p = s->package; - } + e = ptr.last; switch(cmd) { case CMD_GET: + if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) { + ctx->err = UCI_ERR_NOTFOUND; + cli_perror(); + return 1; + } switch(e->type) { case UCI_TYPE_SECTION: - printf("%s\n", s->type); + printf("%s\n", ptr.s->type); break; case UCI_TYPE_OPTION: - o = uci_to_option(e); - uci_show_value(o); + uci_show_value(ptr.o); break; default: break; @@ -410,19 +428,19 @@ static int uci_do_section_cmd(int cmd, int argc, char **argv) /* throw the value to stdout */ break; case CMD_RENAME: - ret = uci_rename(ctx, p, section, option, value); + ret = uci_rename(ctx, &ptr); break; case CMD_REVERT: - ret = uci_revert(ctx, &p, section, option); + ret = uci_revert(ctx, &ptr); break; case CMD_SET: - ret = uci_set(ctx, p, section, option, value, NULL); + ret = uci_set(ctx, &ptr); break; case CMD_ADD_LIST: - ret = uci_add_list(ctx, p, section, option, value, NULL); + ret = uci_add_list(ctx, &ptr); break; case CMD_DEL: - ret = uci_delete(ctx, p, section, option); + ret = uci_delete(ctx, &ptr); break; } @@ -432,7 +450,7 @@ static int uci_do_section_cmd(int cmd, int argc, char **argv) /* save changes, but don't commit them yet */ if (ret == UCI_OK) - ret = uci_save(ctx, p); + ret = uci_save(ctx, ptr.p); if (ret != UCI_OK) { cli_perror(); @@ -489,6 +507,7 @@ static int uci_batch(void) { int ret = 0; + flags |= CLI_FLAG_BATCH; while (!feof(input)) { struct uci_element *e, *tmp; @@ -503,6 +522,8 @@ static int uci_batch(void) uci_unload(ctx, uci_to_package(e)); } } + flags &= ~CLI_FLAG_BATCH; + return 0; } @@ -529,7 +550,8 @@ static int uci_cmd(int argc, char **argv) cmd = CMD_RENAME; else if (!strcasecmp(argv[0], "revert")) cmd = CMD_REVERT; - else if (!strcasecmp(argv[0], "del")) + else if (!strcasecmp(argv[0], "del") || + !strcasecmp(argv[0], "delete")) cmd = CMD_DEL; else if (!strcasecmp(argv[0], "import")) cmd = CMD_IMPORT; @@ -572,6 +594,7 @@ int main(int argc, char **argv) int ret; int c; + flags = CLI_FLAG_SHOW_EXT; appname = argv[0]; input = stdin; ctx = uci_alloc_context(); @@ -580,7 +603,7 @@ int main(int argc, char **argv) return 1; } - while((c = getopt(argc, argv, "c:d:f:mnNp:P:sSq")) != -1) { + while((c = getopt(argc, argv, "c:d:f:mnNp:P:sSqX")) != -1) { switch(c) { case 'c': uci_set_confdir(ctx, optarg); @@ -622,6 +645,9 @@ int main(int argc, char **argv) case 'q': flags |= CLI_FLAG_QUIET; break; + case 'X': + flags &= ~CLI_FLAG_SHOW_EXT; + break; default: uci_usage(); return 0;