From b5a0cbc4885ade0ed9ceb5e25335b80a042dd02c Mon Sep 17 00:00:00 2001 From: NADAL Jean-Baptiste Date: Mon, 12 Dec 2016 20:35:57 +0100 Subject: [PATCH] bump uci version 2016-07-04 --- src/3P/uci/.gitignore | 13 + src/3P/uci/CMakeLists.txt | 47 + src/3P/uci/blob.c | 238 ++++ src/3P/uci/cli.c | 777 ++++++++++++ src/3P/uci/delta.c | 513 ++++++++ src/3P/uci/file.c | 932 +++++++++++++++ src/3P/uci/libuci.c | 234 ++++ src/3P/uci/list.c | 733 ++++++++++++ src/3P/uci/lua/CMakeLists.txt | 51 + src/3P/uci/lua/uci.c | 999 ++++++++++++++++ src/3P/uci/parse.c | 130 +++ src/3P/uci/sh/uci.sh | 178 +++ src/3P/uci/test/README | 34 + src/3P/uci/test/config/network | 25 + .../test/references/add_list_changes.result | 4 + .../test/references/add_list_config.result | 6 + .../uci/test/references/add_list_show.result | 3 + src/3P/uci/test/references/add_section.result | 1 + .../uci/test/references/batch_comments.result | 9 + src/3P/uci/test/references/batch_set.result | 9 + .../cli.options.delta.commit.result | 5 + .../cli.options.delta.export.result | 5 + .../test/references/del_list_config.result | 5 + .../del_list_multiline_config.result | 4 + src/3P/uci/test/references/export.data | 11 + src/3P/uci/test/references/export.result | 12 + src/3P/uci/test/references/get.data | 2 + src/3P/uci/test/references/get_multiline.data | 5 + src/3P/uci/test/references/get_parsing.data | 5 + src/3P/uci/test/references/import.data | 12 + src/3P/uci/test/references/import.result | 11 + .../uci/test/references/revert_option.result | 3 + .../references/revert_option_multiline.result | 2 + .../uci/test/references/revert_section.result | 0 .../test/references/set_existing_option.data | 2 + .../references/set_existing_option.result | 1 + .../set_existing_option_multiline.result | 2 + .../test/references/set_named_section.result | 1 + .../references/set_nonexisting_option.data | 1 + .../references/set_nonexisting_option.result | 1 + .../set_nonexisting_option_multiline.result | 2 + src/3P/uci/test/references/set_parsing.data | 2 + .../references/set_parsing_multiline.data | 2 + src/3P/uci/test/references/show_parsing.data | 2 + .../references/show_parsing_multiline.data | 20 + .../show_parsing_multiline_option.result | 12 + .../show_parsing_multiline_package.result | 18 + .../show_parsing_multiline_section.result | 16 + .../test/references/ucimap_example_1.result | 15 + .../test/references/ucimap_example_2.result | 14 + src/3P/uci/test/shunit2/shunit2 | 1040 +++++++++++++++++ src/3P/uci/test/tests.d/000_import | 5 + src/3P/uci/test/tests.d/010_export | 14 + src/3P/uci/test/tests.d/020_get | 47 + src/3P/uci/test/tests.d/030_set | 46 + src/3P/uci/test/tests.d/040_add | 8 + src/3P/uci/test/tests.d/050_show | 45 + src/3P/uci/test/tests.d/060_batch | 43 + src/3P/uci/test/tests.d/070_revert | 47 + src/3P/uci/test/tests.d/080_list | 52 + src/3P/uci/test/tests.d/090_cli_options | 46 + src/3P/uci/test/tests.sh | 78 ++ src/3P/uci/uci.h | 696 +++++++++++ src/3P/uci/uci_blob.h | 42 + src/3P/uci/uci_config.h.in | 2 + src/3P/uci/uci_internal.h | 258 ++++ src/3P/uci/ucimap.c | 922 +++++++++++++++ src/3P/uci/ucimap.h | 323 +++++ src/3P/uci/util.c | 254 ++++ 69 files changed, 9097 insertions(+) create mode 100644 src/3P/uci/.gitignore create mode 100644 src/3P/uci/CMakeLists.txt create mode 100644 src/3P/uci/blob.c create mode 100644 src/3P/uci/cli.c create mode 100644 src/3P/uci/delta.c create mode 100644 src/3P/uci/file.c create mode 100644 src/3P/uci/libuci.c create mode 100644 src/3P/uci/list.c create mode 100644 src/3P/uci/lua/CMakeLists.txt create mode 100644 src/3P/uci/lua/uci.c create mode 100644 src/3P/uci/parse.c create mode 100755 src/3P/uci/sh/uci.sh create mode 100644 src/3P/uci/test/README create mode 100644 src/3P/uci/test/config/network create mode 100644 src/3P/uci/test/references/add_list_changes.result create mode 100644 src/3P/uci/test/references/add_list_config.result create mode 100644 src/3P/uci/test/references/add_list_show.result create mode 100644 src/3P/uci/test/references/add_section.result create mode 100644 src/3P/uci/test/references/batch_comments.result create mode 100644 src/3P/uci/test/references/batch_set.result create mode 100644 src/3P/uci/test/references/cli.options.delta.commit.result create mode 100644 src/3P/uci/test/references/cli.options.delta.export.result create mode 100644 src/3P/uci/test/references/del_list_config.result create mode 100644 src/3P/uci/test/references/del_list_multiline_config.result create mode 100644 src/3P/uci/test/references/export.data create mode 100644 src/3P/uci/test/references/export.result create mode 100644 src/3P/uci/test/references/get.data create mode 100644 src/3P/uci/test/references/get_multiline.data create mode 100644 src/3P/uci/test/references/get_parsing.data create mode 100644 src/3P/uci/test/references/import.data create mode 100644 src/3P/uci/test/references/import.result create mode 100644 src/3P/uci/test/references/revert_option.result create mode 100644 src/3P/uci/test/references/revert_option_multiline.result create mode 100644 src/3P/uci/test/references/revert_section.result create mode 100644 src/3P/uci/test/references/set_existing_option.data create mode 100644 src/3P/uci/test/references/set_existing_option.result create mode 100644 src/3P/uci/test/references/set_existing_option_multiline.result create mode 100644 src/3P/uci/test/references/set_named_section.result create mode 100644 src/3P/uci/test/references/set_nonexisting_option.data create mode 100644 src/3P/uci/test/references/set_nonexisting_option.result create mode 100644 src/3P/uci/test/references/set_nonexisting_option_multiline.result create mode 100644 src/3P/uci/test/references/set_parsing.data create mode 100644 src/3P/uci/test/references/set_parsing_multiline.data create mode 100644 src/3P/uci/test/references/show_parsing.data create mode 100644 src/3P/uci/test/references/show_parsing_multiline.data create mode 100644 src/3P/uci/test/references/show_parsing_multiline_option.result create mode 100644 src/3P/uci/test/references/show_parsing_multiline_package.result create mode 100644 src/3P/uci/test/references/show_parsing_multiline_section.result create mode 100644 src/3P/uci/test/references/ucimap_example_1.result create mode 100644 src/3P/uci/test/references/ucimap_example_2.result create mode 100644 src/3P/uci/test/shunit2/shunit2 create mode 100644 src/3P/uci/test/tests.d/000_import create mode 100644 src/3P/uci/test/tests.d/010_export create mode 100644 src/3P/uci/test/tests.d/020_get create mode 100644 src/3P/uci/test/tests.d/030_set create mode 100644 src/3P/uci/test/tests.d/040_add create mode 100644 src/3P/uci/test/tests.d/050_show create mode 100644 src/3P/uci/test/tests.d/060_batch create mode 100644 src/3P/uci/test/tests.d/070_revert create mode 100644 src/3P/uci/test/tests.d/080_list create mode 100644 src/3P/uci/test/tests.d/090_cli_options create mode 100644 src/3P/uci/test/tests.sh create mode 100644 src/3P/uci/uci.h create mode 100644 src/3P/uci/uci_blob.h create mode 100644 src/3P/uci/uci_config.h.in create mode 100644 src/3P/uci/uci_internal.h create mode 100644 src/3P/uci/ucimap.c create mode 100644 src/3P/uci/ucimap.h create mode 100644 src/3P/uci/util.c diff --git a/src/3P/uci/.gitignore b/src/3P/uci/.gitignore new file mode 100644 index 00000000..0407feb4 --- /dev/null +++ b/src/3P/uci/.gitignore @@ -0,0 +1,13 @@ +Makefile +CMakeCache.txt +CMakeFiles +*.cmake +*.o +*.a +*.so +*.dylib +install_manifest.txt + +uci +uci_config.h +test/save diff --git a/src/3P/uci/CMakeLists.txt b/src/3P/uci/CMakeLists.txt new file mode 100644 index 00000000..a900a156 --- /dev/null +++ b/src/3P/uci/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 2.6) + +PROJECT(uci C) + +SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -g3 -I. -DUCI_PREFIX="${CMAKE_INSTALL_PREFIX}") + +OPTION(UCI_DEBUG "debugging support" OFF) +OPTION(UCI_DEBUG_TYPECAST "typecast debugging support" OFF) +OPTION(BUILD_LUA "build Lua binding" ON) + +IF(BUILD_STATIC) + FIND_LIBRARY(ubox_library NAMES ubox.a) +ELSE(BUILD_STATIC) + FIND_LIBRARY(ubox_library NAMES ubox) +ENDIF(BUILD_STATIC) + +FIND_PATH(ubox_include_dir libubox/usock.h) + +CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/uci_config.h.in ${CMAKE_SOURCE_DIR}/uci_config.h ) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${ubox_include_dir}) + +SET(LIB_SOURCES libuci.c file.c util.c delta.c parse.c blob.c) + +ADD_LIBRARY(uci SHARED ${LIB_SOURCES}) +TARGET_LINK_LIBRARIES(uci ${ubox_library}) +SET_TARGET_PROPERTIES(uci PROPERTIES OUTPUT_NAME uci) + +ADD_EXECUTABLE(cli cli.c) +SET_TARGET_PROPERTIES(cli PROPERTIES OUTPUT_NAME uci) +TARGET_LINK_LIBRARIES(cli uci) + +ADD_LIBRARY(ucimap STATIC ucimap.c) + +ADD_SUBDIRECTORY(lua) + +INSTALL(FILES uci.h uci_config.h uci_blob.h ucimap.h + DESTINATION include +) + +INSTALL(TARGETS uci cli + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin +) + diff --git a/src/3P/uci/blob.c b/src/3P/uci/blob.c new file mode 100644 index 00000000..c8e5dc90 --- /dev/null +++ b/src/3P/uci/blob.c @@ -0,0 +1,238 @@ +/* + * blob.c - uci <-> blobmsg conversion layer + * Copyright (C) 2012-2013 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ +#include +#include +#include + +#include +#include "uci.h" +#include "uci_blob.h" + +static bool +uci_attr_to_blob(struct blob_buf *b, const char *str, + const char *name, enum blobmsg_type type) +{ + char *err; + int intval; + long long llval; + + switch (type) { + case BLOBMSG_TYPE_STRING: + blobmsg_add_string(b, name, str); + break; + case BLOBMSG_TYPE_BOOL: + if (!strcmp(str, "true") || !strcmp(str, "1")) + intval = 1; + else if (!strcmp(str, "false") || !strcmp(str, "0")) + intval = 0; + else + return false; + + blobmsg_add_u8(b, name, intval); + break; + case BLOBMSG_TYPE_INT32: + intval = strtol(str, &err, 0); + if (*err) + return false; + + blobmsg_add_u32(b, name, intval); + break; + case BLOBMSG_TYPE_INT64: + llval = strtoll(str, &err, 0); + if (*err) + return false; + + blobmsg_add_u64(b, name, llval); + break; + default: + return false; + } + return true; +} + +static void +uci_array_to_blob(struct blob_buf *b, struct uci_option *o, + enum blobmsg_type type) +{ + struct uci_element *e; + char *str, *next, *word; + + if (o->type == UCI_TYPE_LIST) { + uci_foreach_element(&o->v.list, e) { + uci_attr_to_blob(b, e->name, NULL, type); + } + return; + } + + str = strdup(o->v.string); + next = str; + + while ((word = strsep(&next, " \t")) != NULL) { + if (!*word) + continue; + + uci_attr_to_blob(b, word, NULL, type); + } + + free(str); +} + +static int +__uci_element_to_blob(struct blob_buf *b, struct uci_element *e, + const struct uci_blob_param_list *p) +{ + const struct blobmsg_policy *attr = NULL; + struct uci_option *o = uci_to_option(e); + unsigned int types = 0; + void *array; + int i, ret = 0; + + for (i = 0; i < p->n_params; i++) { + attr = &p->params[i]; + + if (strcmp(attr->name, e->name) != 0) + continue; + + if (attr->type > BLOBMSG_TYPE_LAST) + continue; + + if (types & (1 << attr->type)) + continue; + + types |= 1 << attr->type; + + if (attr->type == BLOBMSG_TYPE_ARRAY) { + int element_type = 0; + + if (p->info) + element_type = p->info[i].type; + + if (!element_type) + element_type = BLOBMSG_TYPE_STRING; + + array = blobmsg_open_array(b, attr->name); + uci_array_to_blob(b, o, element_type); + blobmsg_close_array(b, array); + ret++; + continue; + } + + if (o->type == UCI_TYPE_LIST) + continue; + + ret += uci_attr_to_blob(b, o->v.string, attr->name, attr->type); + } + return ret; +} + +static int +__uci_to_blob(struct blob_buf *b, struct uci_section *s, + const struct uci_blob_param_list *p) +{ + struct uci_element *e; + int ret = 0; + + uci_foreach_element(&s->options, e) + ret += __uci_element_to_blob(b, e, p); + + return ret; +} + +int +uci_to_blob(struct blob_buf *b, struct uci_section *s, + const struct uci_blob_param_list *p) +{ + int ret = 0; + int i; + + ret += __uci_to_blob(b, s, p); + for (i = 0; i < p->n_next; i++) + ret += uci_to_blob(b, s, p->next[i]); + + return ret; +} + +bool +uci_blob_diff(struct blob_attr **tb1, struct blob_attr **tb2, + const struct uci_blob_param_list *config, unsigned long *diff) +{ + bool ret = false; + int i; + + for (i = 0; i < config->n_params; i++) { + if (!tb1[i] && !tb2[i]) + continue; + + if (!!tb1[i] != !!tb2[i]) + goto mark; + + if (blob_len(tb1[i]) != blob_len(tb2[i])) + goto mark; + + if (memcmp(tb1[i], tb2[i], blob_raw_len(tb1[i])) != 0) + goto mark; + + continue; + +mark: + ret = true; + if (diff) + bitfield_set(diff, i); + else + return ret; + } + + return ret; +} + + +static bool +__uci_blob_check_equal(struct blob_attr *c1, struct blob_attr *c2, + const struct uci_blob_param_list *config) +{ + struct blob_attr **tb1, **tb2; + + if (!!c1 ^ !!c2) + return false; + + if (!c1 && !c2) + return true; + + tb1 = alloca(config->n_params * sizeof(struct blob_attr *)); + blobmsg_parse(config->params, config->n_params, tb1, + blob_data(c1), blob_len(c1)); + + tb2 = alloca(config->n_params * sizeof(struct blob_attr *)); + blobmsg_parse(config->params, config->n_params, tb2, + blob_data(c2), blob_len(c2)); + + return !uci_blob_diff(tb1, tb2, config, NULL); +} + +bool +uci_blob_check_equal(struct blob_attr *c1, struct blob_attr *c2, + const struct uci_blob_param_list *config) +{ + int i; + + if (!__uci_blob_check_equal(c1, c2, config)) + return false; + + for (i = 0; i < config->n_next; i++) { + if (!__uci_blob_check_equal(c1, c2, config->next[i])) + return false; + } + + return true; +} diff --git a/src/3P/uci/cli.c b/src/3P/uci/cli.c new file mode 100644 index 00000000..f8b45dba --- /dev/null +++ b/src/3P/uci/cli.c @@ -0,0 +1,777 @@ +/* + * cli - Command Line Interface for the Unified Configuration Interface + * Copyright (C) 2008 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include "uci.h" + +#define MAX_ARGS 4 /* max command line arguments for batch mode */ + +static const char *delimiter = " "; +static const char *appname; +static enum { + CLI_FLAG_MERGE = (1 << 0), + 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; + +static struct uci_context *ctx; +enum { + /* section cmds */ + CMD_GET, + CMD_SET, + CMD_ADD_LIST, + CMD_DEL_LIST, + CMD_DEL, + CMD_RENAME, + CMD_REVERT, + CMD_REORDER, + /* package cmds */ + CMD_SHOW, + CMD_CHANGES, + CMD_EXPORT, + CMD_COMMIT, + /* other cmds */ + CMD_ADD, + CMD_IMPORT, + 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; + char *ret; + int maxlen; + + if (!(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)); + if (!ti) + return NULL; + memset(ti, 0, sizeof(struct uci_type_list)); + ti->next = type_list; + type_list = ti; + ti->name = s->type; + } + + if (s->anonymous) { + maxlen = strlen(s->type) + 1 + 2 + 10; + if (!typestr) { + typestr = malloc(maxlen); + } else { + typestr = realloc(typestr, maxlen); + } + + if (typestr) + sprintf(typestr, "@%s[%d]", ti->name, ti->idx); + + ret = typestr; + } else { + ret = s->e.name; + } + + ti->idx++; + + return ret; +} + +static void uci_usage(void) +{ + fprintf(stderr, + "Usage: %s [] []\n\n" + "Commands:\n" + "\tbatch\n" + "\texport []\n" + "\timport []\n" + "\tchanges []\n" + "\tcommit []\n" + "\tadd \n" + "\tadd_list .
.