【智能路由器】C代码调用uci的API读openwrt配置文件指南

来源:互联网 发布:海航进出口公司 知乎 编辑:程序博客网 时间:2024/06/06 04:03

【智能路由器】系列文章连接
http://blog.csdn.net/u012819339/article/category/5803489


上篇博客讲解了命令行下uci的使用方法,本篇博客arvik将简单剖析uci部分源码,带领大家使用c语言调用uci的API来读取配置文件。

实战背景

倘若我们自己写了一个应用程序,也想用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:由给定的元组查找元素

/** * 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:arvikemail:1216601195@qq.comcsdn: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

运行截图:
这里写图片描述


【智能路由器】系列文章连接
http://blog.csdn.net/u012819339/article/category/5803489

2 0
原创粉丝点击