参考https://blog.csdn.net/KOBE_ZERO/article/details/51496761, 测试了以下使用libuci 读写配置文件, 读程序没问题,但写入程序不成功。函数摘录如下:
struct uci_context * ctx = uci_alloc_context(); //申请上下文
struct uci_ptr ptr ={
.package = "config",
.section = "servver",
.option = "value",
.value = "256",
};
uci_set(_ctx,&ptr); //写入配置
uci_commit(_ctx, &ptr.p, false); //提交保存更改
uci_unload(_ctx,ptr.p); //卸载包
uci_free_context(ctx); //释放上下文
uci_set, uci_commit ,uci_unload返回值都是失败, 分别是3,2,2, 折腾好久,找不到原因。
网上搜索到一篇关于libuci库中的结构体的文章: https://blog.csdn.net/KOBE_ZERO/article/details/51496761
注意到结构体,以下四个成员都是const, 说明uci_set函数第二个ptr参数肯定是做输入用下面给一个遍历所由配置项目的函数, 在https://blog.csdn.net/KOBE_ZERO/article/details/51496761提供代码上改的:
#define UCI_CONFIG_FILE "testconfig" //不带路径, 目录为默认目录/etc/config/
int dump_config()
{
char* value;
struct uci_element *e, *e1;
struct uci_package * pkg = NULL;
struct uci_context * ctx = NULL;
do{
ctx = uci_alloc_context(); // 申请一个UCI上下文.
if(!ctx) break;
if(UCI_OK != uci_load(ctx, UCI_CONFIG_FILE, &pkg)) break;
/*遍历UCI的每一个节*/
uci_foreach_element(&pkg->sections, e){
struct uci_section *s = uci_to_section(e);
printf("config\t %s\t %s\t \n", s->type, e->name);
// 将一个 element 转换为 section类型, 如果节点有名字,则 s->anonymous 为 false.
// 此时通过 s->e->name 来获取.
// 此时 您可以通过 uci_lookup_option()来获取 当前节下的一个值.
if (NULL != (value = uci_lookup_option_string(ctx, s, "ipaddr")))
{
// printf("uci_element.name=%s, ipaddr = %s\n", e->name, value);
// char* ip = strdup(value); //如果您想持有该变量值,一定要拷贝一份。当 pkg销毁后value的内存会被释放。
}
{
uci_foreach_element(&s->options, e1){
struct uci_option *opt = uci_to_option(e1);
if(UCI_TYPE_STRING == opt->type)
printf("\t option %s %s\t \n", opt->e.name, opt->v.string);
else if(UCI_TYPE_LIST == opt->type){
uci_foreach_element(&opt->v.list, e2){
printf("\t list %s %s\t \n", opt->e.name, e2->name);
}
}
}
}
uci_unload(ctx, pkg); // 释放 pkg
uci_free_context(ctx);
return 0;
}while(0);
cleanup:
if(pkg) uci_unload(ctx, pkg); // 释放 pkg
if(ctx) uci_free_context(ctx);
ctx = NULL;
return -1;
}
一点补充说明:
uci配置有两种:option和list, 配置文件中出现key重复的option, 则以最后一个option为准;配置文件中出现key重复的list, 则全部keyvalue组成一个数组提供个应用程序使用。 配置的例子:
config rule
option name 'alice'
option name 'bob' -----以后一个为准
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'