实战背景
倘若我们自己写了一个应用程序,也想用uci来集中化管理配置该应用的配置文件,怎么办呢?
看了arvik的上一篇博客后相信新手能很快的使用uci对某个配置文件进行配置,只是如何让我们的应用程序读取配置文件内容呢,本篇arvik将解答这个问题。 简单的基本关系图解这里画一个图让大家大致了解配置文件的内容和uci的几个基本结构之间的对应关系。(例举文件为uhttpd的配置文件)
几个结构体struct uci_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;
- };
复制代码 struct uci_section:节结构体,它对应配置文件中的节- struct uci_section
- {
- struct uci_element e;
- struct uci_list options;
- struct uci_package *package;
- bool anonymous;
- char *type;
- };
复制代码 struct uci_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:元素位置指针结构,用来查询并保存对应位置元素- 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;
- };
-
复制代码 struct uci_context: 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;
- };
复制代码 几个基本API函数uci_alloc_context:动态申请一个uci上下文结构 - struct uci_context *uci_alloc_context(void);
复制代码 uci_free_contex:释放由uci_alloc_context申请的uci上下文结构且包括它的所有数据- void uci_free_context(struct uci_context *ctx);
复制代码 uci_lookup_ptr:由给定的元组查找元素。填充ptr结构体中的p,s,o,last- /**
- * uci_lookup_ptr: 分离一个uci元组字符串且查找对应元素树
- * @ctx: uci context结构体指针
- * @ptr: 存放元素查询结果的结构体指针
- * @str: 待查找的uci元组字符串
- * @extended: 允许扩展语法查询
- *
- *如果extended被设为ture,则uci_lookup_ptr支持下列扩展语法:
- *
- *例子:
- * network.@interface[0].ifname ('ifname' option of the first interface section)
- * network.@interface[-1] (last interface section)
- * Note: 有必要的话uci_lookup_ptr将会自动加载配置文件包
- * @str 不能是一个const类型指针,它在使用的过程中将会被更改且用于将字符串填写到@ptr中,因此
- * 它只要@ptr还在使用,它就必须是可用的
- *
- * 这个函数在指定包元组的的字符串未被找到时返回UCI_ERR_NOTFOUND,否则返回UCI_OK
- *
- * 记住在查找其他部分失败的情况,如果它们同样被指定,包括section和option,同样会返回UCI_OK,
- * 但是ptr->flags * UCI_LOOKUP_COMPLETE标志位不会被置位
- */
- int uci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *str, bool extended);
复制代码 只需由以上3个API就可以对一个uci标准配置文件进行简单的读取了。 代码实战下面就写一个实例代码试试吧 - /***********************************
- author:arvik
- email:1216601195@qq.com
- csdn:http://blog.csdn.net/u012819339
- ************************************/
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "uci.h"
- int main()
- {
- struct uci_context *c;
- struct uci_ptr p;
- char *a = strdup("arvik_testconfig.main.home");
- c = uci_alloc_context();
- if(UCI_OK != uci_lookup_ptr(c, &p, a, true))
- {
- uci_perror(c, "no found!\n");
- return -1;
- }
- printf("%s\n", p.o->v.string);
- uci_free_context(c);
- free(a);
- return(0);
- }
复制代码 效果:- root@OpenWrt:/# arvik_uci_test
- /www
复制代码 运行截图
|