uci基本应用法

本文是根据代码实践以及查看别人的文章总结出来的内容,旨在今后使用时能快速上手,以应用目的为主。主要讲解的是关于uci的一些基本配置方法,主要涉及section和option,对list等一些复杂的配置暂时不包括,但是在看别人文章的时候发现以下文章讲的内容很全面,这里给出链接,以便今后对本文不涉及的内容做查询。
https://blog.csdn.net/qq_41453285/article/details/102527800

uci简介

统一配置接口(Unified Configuration Interface,UCI),是OpenWrt成功的关键技术之一,已经移植支持数千个软件。它采用纯文本文件来保存配置,并提供命令行和C语言编程调用接口进行管理。

uci结构

匿名section,如图一
config <section type>
<option type> <option value>

命名section,如图二
config <section type> <section name>
<option type> <option value>

config指的是配置文件的名字。

<section type>指的是配置section的类型,比如图中的wifi-iface和wifi-device。

<section name>指的是配置section的名称(别名),比如图中的“wifi0”和“wifi1”和“wifi2”等。这一项是可选的,如果没有这一项就是匿名section,针对这样的section是如何进行配置的呢,稍后的配置步骤中会有解答。

<option type>指的是配置选项(其实就是section的一种属性),从图中可以看出,option是属于section其中的,比如图中的“index”和“tyepe”这类的属性值。

<option value>指的是配置选项对应数据值,比如图中的“3”和“ath3”之类的值,<option value>和<option type>之间以空格分隔,<option value>通常都是字符串格式保存在配置文件中。

PS:命名规范就是字母数字下划线,尽量如此做,当然有更广泛的允许,此处不多说。

图一 图二

uci命令行使用

命令行总结

将一些常用的操作命令整理在如下表格:

操作 命令 说明
uci add test aNewSection 增加<section type> aNewSection
uci set test.@aNewSection[0].aNewOption=1 这里虽然使用的命令是uci set,但是因为set的对象是原本没有的option,所以是增加一个option的功能,增加的option要求一定要已经存在对应的section。在之前的section中增加
uci delete test.@aNewSection[0].aNewOption0 删除一个<option type>
uci delete test.@aNewSection[0] 删除一个<section type>,请注意这里删除section之后,连带section下的所有option都会被删除。
uci get test.@aNewSection[0].aNewOption0 查看某个<option type>的<option value>
uci show test.@aNewSection[0].aNewOption0 查看某个<option type>这一行项目
uci get test.@aNewSection[0] 查看某个<section type>
uci show test.@aNewSection[0] 查看某个<section type>具体项目值
uci rename test.@aNewSection[0]=aNewSection0 对匿名section重命名
uci rename test.aNewSection0.aNewOption=aNewOption0 对option重命名
uci set test.aNewSection0.aNewOption0=2 这里使用的命令是uci set,因为set的对象是原本已经有的option,修改

注意:

1.section新建一定是匿名的,之后可以rename为它添加上名字。

2.任何的修改uci文件操作(增删改)都必须最后使用“uci commit <config>”命令使文件修改生效。

3.另外附上一些其他的uci命令用法,其中uci delete <config> 这个命令我试过,意思是删除一个配置文件(I guess),但是无论如何都无法删除,一直显示Invalid command。

uci命令行使用效果

实验基础:在/etc/config/目录下新建一个test文件,文件中已经写入了6个section,内容如图:

运行“增”命令

uci add test aNewSection
uci set test.@aNewSection[0].aNewOption=1
uci commit test

运行结果

运行“改”命令:

uci rename test.@aNewSection[0]=aNewSection0
uci rename test.aNewSection0.aNewOption=aNewOption0
uci set test.aNewSection0.aNewOption0=2
uci commit test

运行结果

运行“查”命令:

uci get test.@aNewSection[0].aNewOption0
uci show test.@aNewSection[0].aNewOption0
uci get test.@aNewSection[0]
uci show test.@aNewSection[0]

运行结果

运行“删”命令

uci delete test.@aNewSection[0].aNewOption0
uci delete test.@aNewSection[0]
uci commit test

运行结果



删除之后整个section都没有了。

这里可以看到如果删除第一个(index是0)section,后一个就会变成第一个(index是0),此时wifi-iface的section只有2个,如果删除第三个wifi-iface(index是2),就会报出无效参数的错误。

uci接口代码使用

接口总结

原生uci接口在文章开头的链接中可以找到,这里列出的是为了以后方便使用封装之后的接口。

函数名称 函数原型 函数说明
my_uciInit struct uci_context *my_uciInit() 初始化并分配一个ctx
my_uciDestroy int my_uciDestroy(struct uci_context *ctx) 释放一个ctx空间
my_uciAddSection int my_uciAddSection(struct uci_context *ctx, const char *package, const char *sectionName) 添加一个section
my_uciSet int my_uciSet(struct uci_context *ctx, char *package, char *option, char *value) 添加或者修改一个option
my_uciGet int my_uciGet(struct uci_context *ctx, char *package, char *option, char *value) 获取一个option的值
my_uciCommit int my_uciCommit(struct uci_context *ctx, char *package) 提交修改config
my_uciDelete int my_uciDelete(struct uci_context *ctx, char *package, char *option) 删除一个section或者删除一个option
uci_foreach_element uci_foreach_element(struct uci_section *, struct uci_element *) 原生遍历函数,注意不能在这个函数范围内做删除操作

接口使用实例

test_uci_foreach_element


int test_uci_foreach_element()
{
	struct uci_context * ctx = NULL;
	struct uci_package * pkg = NULL;
	struct uci_element *e = NULL;
	const char *value = NULL;

	
	ctx = uci_alloc_context();
	if (UCI_OK != uci_load(ctx, "wireless", &pkg))
	{
		uci_free_context(ctx);
		return -1;
	}

	uci_foreach_element(&pkg->sections, e)
	{
		struct uci_section *s = uci_to_section(e);
			
		if (0 == strncmp("wifi-iface", s->type, 10))
		{
			int enabled = 0;
			int vap_index = -1;
			char ssid[128] = {0};

			value = uci_lookup_option_string(ctx, s, "index");
			if (NULL != value)
			{
				vap_index = atoi(value);
			}

			value = uci_lookup_option_string(ctx, s, "enabled");
			if (NULL != value)
			{
				enabled = atoi(value);
			}
			
			value = uci_lookup_option_string(ctx, s, "ssid");
			if (NULL != value)
			{
				strcpy(ssid, value);
			}

		}
	}
	
	uci_unload(ctx, pkg);
	uci_free_context(ctx);

	return 0;
}


test_my_uciGet


/* uci get my_config_file.@global[0].md5_wireless */
int test_my_uciGet(char *md5_wireless)
{
	int ret;
	char option[128] = {0};
	char value[128] = {0};
	
	struct uci_context *ctx = NULL;
	ctx = my_uciInit();
	if (ctx == NULL)
	{
		printf("uci init error
");
		return -1;
	}

	snprintf(option, sizeof(option), "@global[0].md5_wireless");
	ret = my_uciGet(ctx, "wifison", option , value);
	if (ret != 0)
	{
		printf("uci get %s failed
", option);
		my_uciDestroy(ctx);
		return -1;
	}

	strcpy(md5_wireless, value);
	printf("md5_wireless is %s
", md5_wireless);
	my_uciDestroy(ctx);
	return 0;
}


test_my_uciSet


/* uci set my_config_file.@global[0].md5_wireless */
int test_my_uciSet(char *md5_wireless)
{
	int ret;
	char option[128] = {0};
	
	struct uci_context *ctx = NULL;
	ctx = my_uciInit();
	if (ctx == NULL)
	{
		printf("uci init error
");
		return -1;
	}

	snprintf(option, sizeof(option), "@global[0].md5_wireless");
	ret = my_uciSet(ctx, "wifison", option, md5_wireless);
	if (ret != 0)
	{
		printf("uci set %s failed
", option);
		my_uciCommit(ctx, "wifison");
		my_uciDestroy(ctx);
		return -1;
	}

	my_uciCommit(ctx, "wifison");
	my_uciDestroy(ctx);
	return 0;
}


test_my_uciAddSection


/* uci add my_config_file blacklist */
/* uci set my_config_file.@blacklist[0].macaddr */
int test_my_uciAddSection(char *macaddr)
{
	char option[128] = {0};
	char data[128] = {0};
	struct uci_context *ctx = NULL;
	int ret;
	ctx = my_uciInit();
	if (ctx == NULL)
	{
		printf("uci init error
");
		return -1;
	}

	ret = my_uciAddSection(ctx, "my_config_file", "blacklist");
	if (ret != 0)
	{
		printf("uci add section failed
");
	}

	snprintf(option, sizeof(option), "@blacklist[%d].macaddr", blacklist_num);
	snprintf(data, sizeof(data), "%s", macaddr);
	ret = my_uciSet(ctx, "my_config_file", option , data);
	if (ret != 0)
	{
		printf("uci set %s failed
", option);
	}

	my_uciCommit(ctx, "my_config_file");
	my_uciDestroy(ctx);
	return 0;
}


test_my_uciDelete_section


/* uci delete my_config_file.ath%d */
int test_my_uciDelete_section(void)
{
	int i;

	struct uci_context *ctx = NULL;
	int ret;
	ctx = my_uciInit();
	if (ctx == NULL)
	{
		printf("uci init error
");
		return -1;
	}
		
	for (i = 0; i < VAP_MAX_NUM * RADIO_MAX_NUM; i ++)
	{
		char sectionName[128] = {0};
		snprintf(sectionName, sizeof(sectionName), "ath%d", i);
		ret = my_uciDelete(ctx, "my_config_file", sectionName);
		if (ret != 0)
		{
			continue;
		}
	}
	my_uciCommit(ctx, "my_config_file");
	my_uciDestroy(ctx);

	return 0;
}


原文地址:https://www.cnblogs.com/y-c-y/p/14664203.html