Openwrt UCI入门操作

1.UCI概述

UCI主要是一种对底层配置文件处理的一种方法。

用于OpenWrt整个系统的配置集中化。很多后台服务有自己的配置文件,并且配置文件格式都不相同,OpenWrt系统中需要开启各种服务,为了解决配置不兼容的问题,统一采用uci格式的配置文件。

首先我们要清楚UCI的结构,以/etc/config/network下面一个配置节点为例

Openwrt UCI入门操作_第1张图片

network整个文件的内容对应:配置文件包(package)

像上图这样一个配置节点我们称为:一个section,每个配置节点中包括配置类型、配置名、选项、值等信息。

以上图为例:interface我们叫做“配置类型”,mgnt我们叫做“配置名”,type、ip6assign等我们叫做选项(option)

它的默认访问路径为:/etc/config/下面的配置文件,

2.UCI命令

UCI命令支持通过UCI shell命令进行操作

常用的有uci show 、uci set 、uci get等 ,如uci show network

3.UCI-C使用方法

先来了解UCI结构的对应结构体:

UCI上下文结构体:贯穿查询、更改配置文件全过程

struct uci_context
{
    /* 配置文件包列表 */
    struct uci_list root;

    /* 解析上下文,只用于错误处理 */
    struct uci_parse_context *pctx;

    /* 后端导入导出 */
    struct uci_backend *backend;
    struct uci_list backends;

    /* uci 运行标识 */
    enum uci_flags flags;

    char *confdir;
    char *savedir;

    /* search path for delta files */
    struct uci_list delta_path;

    /* 私有数据 */
    int err;
    const char *func;
    jmp_buf trap;
    bool internal, nested;
    char *buf;
    int bufsz;
};

package对应的结构体如下(包结构体):它对应一个配置文件内容

struct uci_package

{

    struct uci_element e;

    struct uci_list sections;

    struct uci_context *ctx;

    bool has_delta;

    char *path;

    /* private: */

    struct uci_backend *backend;

    void *priv;

    int n_section;

    struct uci_list delta;

    struct uci_list saved_delta;

};

section对应的结构体(节结构体):它对应配置文件中的节

struct uci_section
{
    struct uci_element e;
    struct uci_list options;
    struct uci_package *package;
    bool anonymous;
    char *type;
};

option对应的结构体(选项结构体):对应配置文件里节中的 option 或者 list

struct uci_option
{
    struct uci_element e;
    struct uci_section *section;
    enum uci_option_type type;
    union {
        struct uci_list list;
        char *string;
    } v;
};

元素指针结构体:元素位置指针结构,用来查询并保存对应位置元素

struct uci_ptr
{
    enum uci_type target;
    enum {
        UCI_LOOKUP_DONE =    (1 << 0),
        UCI_LOOKUP_COMPLETE = (1 << 1),
        UCI_LOOKUP_EXTENDED = (1 << 2),
    } flags;

    struct uci_package *p;
    struct uci_section *s;
    struct uci_option *o;
    struct uci_element *last;

    const char *package;
    const char *section;
    const char *option;
    const char *value;
};

UCI 常用的C接口:

int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)	设置uci值

int uci_del_list(struct uci_context *ctx, struct uci_ptr *ptr)	删除list option

int uci_add_list(struct uci_context *ctx, struct uci_ptr *ptr)	增加list option

int uci_delete(struct uci_context *ctx, struct uci_ptr *ptr)	删除节点(option)

int uci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *str, bool extended)	     查询元素指针

int uci_rename(struct uci_context *ctx, struct uci_ptr *ptr)	
重命名节(option)

int uci_add_section(struct uci_context *ctx, struct uci_package *p, const char *type, 
struct uci_section **res)	                                    
添加一个节

struct uci_context *uci_alloc_context(void)	    分配上下文空间

void uci_free_context(struct uci_context *ctx)	  释放上下文空间

int uci_load(struct uci_context *ctx, const char *name, struct uci_package **package)	
加载配置到内存

int uci_set_confdir(struct uci_context *ctx, const char *dir)	
设置配置目录

int uci_commit(struct uci_context *ctx, struct uci_package **package, bool overwrite)	        
提交修改的值

struct uci_option *uci_lookup_option(struct uci_context *ctx, struct uci_section *s, const char *name)	  
查询option指针

const char *uci_lookup_option_string(struct uci_context *ctx, struct uci_section *s, const char *name)	  
获取一个option string值

struct uci_section *uci_lookup_section(struct uci_context *ctx, struct uci_package *p, const char *name)	 
查询package中的section

struct uci_package * uci_lookup_package(struct uci_context *ctx, const char *name)	
在上下文中获取package指针

C语言遍历配置文件实例:

struct uci_context *ctx = NULL;		
struct uci_package *pkg = NULL;
struct uci_element *emt = NULL;
char old_vid_option[64]={0};
char value[8] = {0};
int vlan_exist_flag = 0;

	ctx = uci_alloc_context();
    if (!ctx) {
        cw_log(LG_ERR, "SetLanTrunkInfo uci_alloc_context failed.");
        goto err;
    }
			
    if(UCI_OK != uci_load(ctx, "network", &pkg)){
		cw_log(LG_ERR, "SetLanTrunkInfo uci_load failed.");
    	goto err;
    }
    
	uci_foreach_element(&pkg->sections, emt)        //遍历这个配置文件下的每一个section
    {
        struct uci_section *s = uci_to_section(emt);    //获取每一个节点的指针
		if(s==NULL)
			continue;
		if(!strncmp("interface",s->type)){	//s->type为配置类型,s->e.name为配置节点名称
		/*自由发挥*/
		} 
    }


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

你可能感兴趣的:(开发语言,物联网)