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\n");
		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\n", option);
		my_uciDestroy(ctx);
		return -1;
	}

	strcpy(md5_wireless, value);
	printf("md5_wireless is %s\n", 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\n");
		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\n", 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\n");
		return -1;
	}

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

	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\n", 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\n");
		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;
}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM