From eef08e0770842f888e816c5fee9830a672b2e5c7 Mon Sep 17 00:00:00 2001 From: Amin Ben Ramdhane Date: Thu, 31 Dec 2020 13:14:48 +0100 Subject: [PATCH] bbf: remove the call to icwmp shell script --- bin/Makefile.am | 1 + configure.ac | 3 + dmdiagnostics.c | 125 ++++++++++++++++++++++++++++++++++++++++-- dmdiagnostics.h | 9 ++- dmoperate.c | 25 ++++----- dmoperate.h | 2 - libbbf_api/dmbbf.h | 8 ++- libbbf_api/dmcommon.c | 33 +++++++---- libbbf_api/dmcommon.h | 8 +++ libbbf_api/dmuci.c | 69 ++++++++++++++++++++++- libbbf_api/dmuci.h | 8 ++- 11 files changed, 249 insertions(+), 42 deletions(-) diff --git a/bin/Makefile.am b/bin/Makefile.am index aa028de8..cc41ca5e 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -141,6 +141,7 @@ libbbfdm_la_LIBADD = \ $(LIBTRACE_LIBS) \ $(LBLOBMSG_LIBS) \ $(LIBDLOPEN_LIBS) \ + $(LIBCURL_LIBS) \ -lbbf_api libbbfdm_la_CFLAGS+=-I../ diff --git a/configure.ac b/configure.ac index 5b9cc4a5..c33cf24a 100644 --- a/configure.ac +++ b/configure.ac @@ -78,6 +78,9 @@ AC_SUBST([LBLOBMSG_LIBS]) LIBDLOPEN_LIBS='-ldl' AC_SUBST([LIBDLOPEN_LIBS]) +LIBDLOPEN_LIBS='-lcurl' +AC_SUBST([LIBCURL_LIBS]) + AM_COND_IF([LOPENSSL], [ LIBOPENSSL_LIBS='-lssl' AC_SUBST([LIBOPENSSL_LIBS]) diff --git a/dmdiagnostics.c b/dmdiagnostics.c index 5579e5a3..6fb0abe6 100644 --- a/dmdiagnostics.c +++ b/dmdiagnostics.c @@ -9,6 +9,7 @@ * */ +#include #include #include "dmentry.h" #include "dmdiagnostics.h" @@ -71,6 +72,118 @@ void set_diagnostics_interface_option(struct dmctx *ctx, char *sec_name, char *v } } +static int download_file(const char *file_path, const char *url, const char *username, const char *password) +{ + int res_code = 0; + + CURL *curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_USERNAME, username); + curl_easy_setopt(curl, CURLOPT_PASSWORD, password); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, CURL_TIMEOUT); + + FILE *fp = fopen(file_path, "wb"); + if (fp) { + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + curl_easy_perform(curl); + fclose(fp); + } + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code); + curl_easy_cleanup(curl); + } + + return res_code; +} + +static int upload_file(const char *file_path, const char *url, const char *username, const char *password) +{ + int res_code = 0; + + CURL *curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_USERNAME, username); + curl_easy_setopt(curl, CURLOPT_PASSWORD, password); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, CURL_TIMEOUT); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + + FILE *fp = fopen(file_path, "rb"); + if (fp) { + curl_easy_setopt(curl, CURLOPT_READDATA, fp); + curl_easy_perform(curl); + fclose(fp); + } + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code); + curl_easy_cleanup(curl); + } + + return res_code; +} + +int bbf_config_backup(const char *url, const char *username, const char *password, char *config_name) +{ + int res = 0; + + // Export config file to backup file + if (dmuci_export_package(config_name, CONFIG_BACKUP)) { + res = -1; + goto end; + } + + // Upload config file + int res_code = upload_file(CONFIG_BACKUP, url, username, password); + if ((strncmp(url, HTTP_PROTO, strlen(HTTP_PROTO)) == 0 && res_code != 200) || + (strncmp(url, FTP_PROTO, strlen(FTP_PROTO)) == 0 && res_code != 226) || + (strncmp(url, HTTP_PROTO, strlen(HTTP_PROTO)) && strncmp(url, FTP_PROTO, strlen(FTP_PROTO)))) + res = -1; + +end: + // Remove temporary file + if (remove(CONFIG_BACKUP)) + res = -1; + + return res; +} + +int bbf_config_restore(const char *url, const char *username, const char *password, const char *size) +{ + int res = 0; + + // Check file size + if (size && *size) { + unsigned long file_size = strtoul(size, NULL, 10); + unsigned long fs_available_size = file_system_size("/tmp", FS_SIZE_AVAILABLE); + + if (fs_available_size < file_size) { + res = -1; + goto end; + } + } + + // Download config file + int res_code = download_file(CONFIG_RESTORE, url, username, password); + if ((strncmp(url, HTTP_PROTO, strlen(HTTP_PROTO)) == 0 && res_code != 200) || + (strncmp(url, FTP_PROTO, strlen(FTP_PROTO)) == 0 && res_code != 226) || + (strncmp(url, HTTP_PROTO, strlen(HTTP_PROTO)) && strncmp(url, FTP_PROTO, strlen(FTP_PROTO)))) { + res = -1; + goto end; + } + + // Apply config file + if (dmuci_import(NULL, CONFIG_RESTORE)) + res = -1; + +end: + // Remove temporary file + if (remove(CONFIG_RESTORE)) + res = -1; + + return res; +} + static void libtrace_cleanup(libtrace_t *trace, libtrace_packet_t *packet) { if (trace) @@ -468,8 +581,8 @@ int start_upload_download_diagnostic(int diagnostic_type, char *proto) } if ((url[0] == '\0') || - (strncmp(url, DOWNLOAD_UPLOAD_PROTOCOL_HTTP, strlen(DOWNLOAD_UPLOAD_PROTOCOL_HTTP)) != 0 && - strncmp(url, DOWNLOAD_UPLOAD_PROTOCOL_FTP, strlen(DOWNLOAD_UPLOAD_PROTOCOL_FTP)) != 0 && + (strncmp(url, HTTP_PROTO, strlen(HTTP_PROTO)) != 0 && + strncmp(url, FTP_PROTO, strlen(FTP_PROTO)) != 0 && strstr(url,"@") != NULL)) return -1; @@ -490,9 +603,9 @@ int start_upload_download_diagnostic(int diagnostic_type, char *proto) status = get_diagnostics_option("download", "DiagnosticState"); if (status && strcmp(status, "Complete") == 0) { memset(&diag_stats, 0, sizeof(diag_stats)); - if (strncmp(url, DOWNLOAD_UPLOAD_PROTOCOL_HTTP, strlen(DOWNLOAD_UPLOAD_PROTOCOL_HTTP)) == 0) + if (strncmp(url, HTTP_PROTO, strlen(HTTP_PROTO)) == 0) extract_stats(DOWNLOAD_DUMP_FILE, DIAGNOSTIC_HTTP, DOWNLOAD_DIAGNOSTIC); - if (strncmp(url, DOWNLOAD_UPLOAD_PROTOCOL_FTP, strlen(DOWNLOAD_UPLOAD_PROTOCOL_FTP)) == 0) + if (strncmp(url, FTP_PROTO, strlen(FTP_PROTO)) == 0) extract_stats(DOWNLOAD_DUMP_FILE, DIAGNOSTIC_FTP, DOWNLOAD_DIAGNOSTIC); } else if (status && strncmp(status, "Error_", strlen("Error_")) == 0) return -1; @@ -509,9 +622,9 @@ int start_upload_download_diagnostic(int diagnostic_type, char *proto) status = get_diagnostics_option("upload", "DiagnosticState"); if (status && strcmp(status, "Complete") == 0) { memset(&diag_stats, 0, sizeof(diag_stats)); - if (strncmp(url, DOWNLOAD_UPLOAD_PROTOCOL_HTTP, strlen(DOWNLOAD_UPLOAD_PROTOCOL_HTTP)) == 0) + if (strncmp(url, HTTP_PROTO, strlen(HTTP_PROTO)) == 0) extract_stats(UPLOAD_DUMP_FILE, DIAGNOSTIC_HTTP, UPLOAD_DIAGNOSTIC); - if (strncmp(url, DOWNLOAD_UPLOAD_PROTOCOL_FTP, strlen(DOWNLOAD_UPLOAD_PROTOCOL_FTP)) == 0) + if (strncmp(url, FTP_PROTO, strlen(FTP_PROTO)) == 0) extract_stats(UPLOAD_DUMP_FILE, DIAGNOSTIC_FTP, UPLOAD_DIAGNOSTIC); } else if (status && strncmp(status, "Error_", strlen("Error_")) == 0) return -1; diff --git a/dmdiagnostics.h b/dmdiagnostics.h index 1ec2c701..0d5efcfb 100644 --- a/dmdiagnostics.h +++ b/dmdiagnostics.h @@ -14,8 +14,8 @@ #include -#define DOWNLOAD_UPLOAD_PROTOCOL_HTTP "http://" -#define DOWNLOAD_UPLOAD_PROTOCOL_FTP "ftp://" +#define HTTP_PROTO "http://" +#define FTP_PROTO "ftp://" #define default_date_format "AAAA-MM-JJTHH:MM:SS.000000Z" #define default_date_size sizeof(default_date_format) + 1 #define FTP_SIZE_RESPONSE "213" @@ -23,7 +23,10 @@ #define FTP_TRANSFERT_COMPLETE "226 Transfer" #define FTP_RETR_REQUEST "RETR" #define FTP_STOR_REQUEST "STOR" +#define CURL_TIMEOUT 10 #define DMMAP_DIAGNOSTIGS "dmmap_diagnostics" +#define CONFIG_RESTORE "/tmp/bbf_config_restore" +#define CONFIG_BACKUP "/tmp/bbf_config_backup" struct diagnostic_stats { @@ -58,5 +61,7 @@ void set_diagnostics_option(char *sec_name, char *option, char *value); void init_diagnostics_operation(char *sec_name, char *operation_path); void set_diagnostics_interface_option(struct dmctx *ctx, char *sec_name, char *value); int start_upload_download_diagnostic(int diagnostic_type, char *proto); +int bbf_config_backup(const char *url, const char *username, const char *password, char *config_name); +int bbf_config_restore(const char *url, const char *username, const char *password, const char *size); #endif diff --git a/dmoperate.c b/dmoperate.c index 2b8910f0..a2a7ebe6 100644 --- a/dmoperate.c +++ b/dmoperate.c @@ -235,10 +235,10 @@ static opr_ret_t vendor_conf_backup(struct dmctx *dmctx, char *path, json_object fserver.user = dmjson_get_value(input, 1, "Username"); fserver.pass = dmjson_get_value(input, 1, "Password"); - dmcmd("/bin/sh", 7, ICWMP_SCRIPT, "upload", fserver.url, VCF_FILE_TYPE, fserver.user, fserver.pass, vcf_name); + int res = bbf_config_backup(fserver.url, fserver.user, fserver.pass, vcf_name); dmfree(vcf_name); - return SUCCESS; + return res ? FAIL : SUCCESS; } static opr_ret_t vendor_conf_restore(struct dmctx *dmctx, char *path, json_object *input) @@ -254,12 +254,9 @@ static opr_ret_t vendor_conf_restore(struct dmctx *dmctx, char *path, json_objec fserver.pass = dmjson_get_value(input, 1, "Password"); file_size = dmjson_get_value(input, 1, "FileSize"); - dmcmd("/bin/sh", 7, ICWMP_SCRIPT, "download", fserver.url, file_size, VCF_FILE_TYPE, fserver.user, fserver.pass); + int res = bbf_config_restore(fserver.url, fserver.user, fserver.pass, file_size); - if (0 == dmcmd_no_wait("/bin/sh", 4, ICWMP_SCRIPT, "apply", "download", VCF_FILE_TYPE)) - return SUCCESS; - else - return FAIL; + return res ? FAIL : SUCCESS; } static void fill_wireless_scan_results(struct dmctx *dmctx, char *radio) @@ -348,7 +345,7 @@ static opr_ret_t ip_diagnostics_ipping(struct dmctx *dmctx, char *path, json_obj // Commit and Free uci_ctx_bbfdm commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - dmcmd("/bin/sh", 3, IPPING_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp":"usp"); + dmcmd("/bin/sh", 3, IPPING_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp" : "usp"); // Allocate uci_ctx_bbfdm dmuci_init_bbfdm(); @@ -406,7 +403,7 @@ static opr_ret_t ip_diagnostics_traceroute(struct dmctx *dmctx, char *path, json // Commit and Free uci_ctx_bbfdm commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - dmcmd("/bin/sh", 3, TRACEROUTE_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp":"usp"); + dmcmd("/bin/sh", 3, TRACEROUTE_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp" : "usp"); // Allocate uci_ctx_bbfdm dmuci_init_bbfdm(); @@ -458,7 +455,7 @@ static opr_ret_t ip_diagnostics_download(struct dmctx *dmctx, char *path, json_o set_diagnostics_option("download", "NumberOfConnections", download.num_of_connections); set_diagnostics_option("download", "EnablePerConnection", download.enable_per_connection_results); - if (start_upload_download_diagnostic(DOWNLOAD_DIAGNOSTIC, bbfdatamodel_type == BBFDM_CWMP ? "cwmp":"usp") == -1) + if (start_upload_download_diagnostic(DOWNLOAD_DIAGNOSTIC, bbfdatamodel_type == BBFDM_CWMP ? "cwmp" : "usp") == -1) return FAIL; download.romtime = get_diagnostics_option("download", "ROMtime"); @@ -518,7 +515,7 @@ static opr_ret_t ip_diagnostics_upload(struct dmctx *dmctx, char *path, json_obj set_diagnostics_option("upload", "NumberOfConnections", upload.num_of_connections); set_diagnostics_option("upload", "EnablePerConnection", upload.enable_per_connection_results); - if (start_upload_download_diagnostic(UPLOAD_DIAGNOSTIC, bbfdatamodel_type == BBFDM_CWMP ? "cwmp":"usp") == -1) + if (start_upload_download_diagnostic(UPLOAD_DIAGNOSTIC, bbfdatamodel_type == BBFDM_CWMP ? "cwmp" : "usp") == -1) return FAIL; upload.romtime = get_diagnostics_option("upload", "ROMtime"); @@ -585,7 +582,7 @@ static opr_ret_t ip_diagnostics_udpecho(struct dmctx *dmctx, char *path, json_ob // Commit and Free uci_ctx_bbfdm commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - dmcmd("/bin/sh", 3, UDPECHO_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp":"usp"); + dmcmd("/bin/sh", 3, UDPECHO_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp" : "usp"); // Allocate uci_ctx_bbfdm dmuci_init_bbfdm(); @@ -636,7 +633,7 @@ static opr_ret_t ip_diagnostics_serverselection(struct dmctx *dmctx, char *path, // Commit and Free uci_ctx_bbfdm commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - dmcmd("/bin/sh", 3, SERVERSELECTION_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp":"usp"); + dmcmd("/bin/sh", 3, SERVERSELECTION_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp" : "usp"); // Allocate uci_ctx_bbfdm dmuci_init_bbfdm(); @@ -680,7 +677,7 @@ static opr_ret_t ip_diagnostics_nslookup(struct dmctx *dmctx, char *path, json_o // Commit and Free uci_ctx_bbfdm commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - dmcmd("/bin/sh", 3, NSLOOKUP_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp":"usp"); + dmcmd("/bin/sh", 3, NSLOOKUP_PATH, "run", bbfdatamodel_type == BBFDM_CWMP ? "cwmp" : "usp"); // Allocate uci_ctx_bbfdm dmuci_init_bbfdm(); diff --git a/dmoperate.h b/dmoperate.h index 0faf6edb..45fd4578 100644 --- a/dmoperate.h +++ b/dmoperate.h @@ -21,8 +21,6 @@ #define SYSTEM_UBUS_PATH "system" #define NETWORK_INTERFACE_UBUS_PATH "network.interface" -#define ICWMP_SCRIPT "/usr/sbin/icwmp" -#define VCF_FILE_TYPE "3 Vendor Configuration File" extern struct op_cmd *dynamic_operate; diff --git a/libbbf_api/dmbbf.h b/libbbf_api/dmbbf.h index 029f8f02..3c1242b3 100644 --- a/libbbf_api/dmbbf.h +++ b/libbbf_api/dmbbf.h @@ -447,9 +447,11 @@ static inline void trace_empty_func() } #if TRACE_TYPE == 2 #define TRACE(MESSAGE, ...) do { \ - fprintf(stderr, "TRACE: %s@%s:%d " MESSAGE, __FUNCTION__,__FILE__,__LINE__, ##__VA_ARGS__); \ - fprintf(stderr, "\n"); \ - fflush(stderr); \ + FILE *fp = fopen("/tmp/bbfdm.log", "a"); \ + if (fp) { \ + fprintf(fp, "%s@%s:%d: " MESSAGE, __func__, __FILE__, __LINE__, ##__VA_ARGS__); \ + fclose(fp); \ + } \ } while(0) #elif TRACE_TYPE == 1 #define TRACE(MESSAGE, ...) printf(MESSAGE, ## __VA_ARGS__) diff --git a/libbbf_api/dmcommon.c b/libbbf_api/dmcommon.c index 1e4e9f3a..8f9a0763 100644 --- a/libbbf_api/dmcommon.c +++ b/libbbf_api/dmcommon.c @@ -1455,30 +1455,39 @@ bool folder_exists(const char *path) { struct stat buffer; - if (stat(path, &buffer) == 0 && S_ISDIR(buffer.st_mode)) - return true; - else - return false; + return (stat(path, &buffer) == 0 && S_ISDIR(buffer.st_mode)); } bool file_exists(const char *path) { struct stat buffer; - if(stat(path, &buffer) == 0) - return true; - else - return false; + return stat(path, &buffer) == 0; } bool is_regular_file(const char *path) { struct stat buffer; - if (stat(path, &buffer) == 0 && S_ISREG(buffer.st_mode)) - return true; - else - return false; + return (stat(path, &buffer) == 0 && S_ISREG(buffer.st_mode)); +} + +unsigned long file_system_size(const char *path, const enum fs_size_type_enum type) +{ + struct statvfs vfs; + + statvfs(path, &vfs); + + switch (type) { + case FS_SIZE_TOTAL: + return vfs.f_blocks * vfs.f_frsize; + case FS_SIZE_AVAILABLE: + return vfs.f_bavail * vfs.f_frsize; + case FS_SIZE_USED: + return (vfs.f_blocks - vfs.f_bfree) * vfs.f_frsize; + default: + return -1; + } } int get_base64char_value(char b64) diff --git a/libbbf_api/dmcommon.h b/libbbf_api/dmcommon.h index 08d0aaa1..1fe3022f 100644 --- a/libbbf_api/dmcommon.h +++ b/libbbf_api/dmcommon.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -156,6 +157,12 @@ do { \ if (mpp) close (mpp); \ } while (0) +enum fs_size_type_enum { + FS_SIZE_TOTAL, + FS_SIZE_AVAILABLE, + FS_SIZE_USED, +}; + #define IPPING_PATH "/usr/share/bbfdm/functions/ipping_launch" #define IPPING_STOP DMCMD("/bin/sh", 2, IPPING_PATH, "stop"); #define DOWNLOAD_DIAGNOSTIC_PATH "/usr/share/bbfdm/functions/download_launch" @@ -280,6 +287,7 @@ char *decode64(char *enc); bool folder_exists(const char *path); bool file_exists(const char *path); bool is_regular_file(const char *path); +unsigned long file_system_size(const char *path, const enum fs_size_type_enum type); char *stringToHex(char *text, int length); char *replace_char(char *str, char find, char replace); void sync_dmmap_bool_to_uci_list(struct uci_section *s, char *section, char *value, bool b); diff --git a/libbbf_api/dmuci.c b/libbbf_api/dmuci.c index 1bba6da6..60dd597e 100644 --- a/libbbf_api/dmuci.c +++ b/libbbf_api/dmuci.c @@ -288,6 +288,73 @@ end: return o; } +/**** UCI IMPORT *****/ +int dmuci_import(char *package_name, const char *input_path) +{ + struct uci_package *package = NULL; + struct uci_element *e; + int ret = 0; + + FILE *input = fopen(input_path, "r"); + if (!input) + return -1; + + if (uci_import(uci_ctx, input, package_name, &package, (package_name != NULL)) != UCI_OK) { + ret = -1; + goto end; + } + + uci_foreach_element(&uci_ctx->root, e) { + struct uci_package *p = uci_to_package(e); + if (uci_commit(uci_ctx, &p, true) != UCI_OK) + ret = -1; + } + +end: + fclose(input); + + return ret; +} + +/**** UCI EXPORT *****/ +int dmuci_export_package(char *package, const char *output_path) +{ + struct uci_ptr ptr = {0}; + int ret = 0; + + FILE *out = fopen(output_path, "a"); + if (!out) + return -1; + + if (uci_lookup_ptr(uci_ctx, &ptr, package, true) != UCI_OK) { + ret = -1; + goto end; + } + + if (uci_export(uci_ctx, out, ptr.p, true) != UCI_OK) + ret = -1; + +end: + fclose(out); + + return ret; +} + +int dmuci_export(const char *output_path) +{ + char **configs = NULL; + char **p; + + if ((uci_list_configs(uci_ctx, &configs) != UCI_OK) || !configs) + return -1; + + for (p = configs; *p; p++) + dmuci_export_package(*p, output_path); + + free(configs); + return 0; +} + /**** UCI COMMIT *****/ int dmuci_commit_package(char *package) { @@ -363,7 +430,7 @@ end: } /**** UCI REVERT *****/ -static int dmuci_revert_package(char *package) +int dmuci_revert_package(char *package) { struct uci_ptr ptr = {0}; diff --git a/libbbf_api/dmuci.h b/libbbf_api/dmuci.h index 62f01c69..af22dd6b 100644 --- a/libbbf_api/dmuci.h +++ b/libbbf_api/dmuci.h @@ -318,8 +318,14 @@ char *dmuci_list_to_string(struct uci_list *list, char *delimitor); void uci_add_list_to_list(struct uci_list *addlist, struct uci_list *list); void free_all_list_package_change(struct list_head *clist); int dmuci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value); +int dmuci_import(char *package_name, const char *input_path); +int dmuci_export_package(char *package, const char *output_path); +int dmuci_export(const char *output_path); +int dmuci_commit_package(char *package); int dmuci_commit(void); +int dmuci_save_package(char *package); int dmuci_save(void); +int dmuci_revert_package(char *package); int dmuci_revert(void); int dmuci_change_packages(struct list_head *clist); @@ -342,8 +348,6 @@ int dmuci_add_list_value_by_section(struct uci_section *s, char *option, char *v int dmuci_del_list_value_by_section(struct uci_section *s, char *option, char *value); int dmuci_rename_section_by_section(struct uci_section *s, char *value); struct uci_section *dmuci_walk_section(char *package, char *stype, void *arg1, void *arg2, int cmp , int (*filter)(struct uci_section *s, void *value), struct uci_section *prev_section, int walk); -int dmuci_commit_package(char *package); -int dmuci_save_package(char *package); int dmuci_get_option_value_string_bbfdm(char *package, char *section, char *option, char **value); char *dmuci_set_value_bbfdm(char *package, char *section, char *option, char *value);