查看: 193|回复: 0

[教程] 【转】C代码调用uci的API读openwrt配置文件指南

[复制链接]

582

主题

3

好友

1万

积分

翰林

Rank: 7Rank: 7Rank: 7

  • TA的每日心情
    擦汗
    2014-2-12 10:49
  • 签到天数: 150 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2017-7-24 14:36:43 |显示全部楼层
    实战背景

    倘若我们自己写了一个应用程序,也想用uci来集中化管理配置该应用的配置文件,怎么办呢?
    看了arvik的上一篇博客后相信新手能很快的使用uci对某个配置文件进行配置,只是如何让我们的应用程序读取配置文件内容呢,本篇arvik将解答这个问题。

    简单的基本关系图解

    这里画一个图让大家大致了解配置文件的内容和uci的几个基本结构之间的对应关系。(例举文件为uhttpd的配置文件)

    20160226201126987.jpg

    几个结构体

    struct uci_package: 包结构体。它对应一个配置文件内容

    1. struct uci_package
    2. {
    3.     struct uci_element e;
    4.     struct uci_list sections;
    5.     struct uci_context *ctx;
    6.     bool has_delta;
    7.     char *path;

    8.     /* private: */
    9.     struct uci_backend *backend;
    10.     void *priv;
    11.     int n_section;
    12.     struct uci_list delta;
    13.     struct uci_list saved_delta;
    14. };
    复制代码
    struct uci_section:节结构体,它对应配置文件中的节
    1. struct uci_section
    2. {
    3.     struct uci_element e;
    4.     struct uci_list options;
    5.     struct uci_package *package;
    6.     bool anonymous;
    7.     char *type;
    8. };
    复制代码
    struct uci_option:选项结构体,它对应配置文件里节中的option或者list
    1. struct uci_option
    2. {
    3.     struct uci_element e;
    4.     struct uci_section *section;
    5.     enum uci_option_type type;
    6.     union {
    7.         struct uci_list list;
    8.         char *string;
    9.     } v;
    10. };
    复制代码
    struct uci_ptr:元素位置指针结构,用来查询并保存对应位置元素
    1. struct uci_ptr
    2. {
    3.     enum uci_type target;
    4.     enum {
    5.         UCI_LOOKUP_DONE =     (1 << 0),
    6.         UCI_LOOKUP_COMPLETE = (1 << 1),
    7.         UCI_LOOKUP_EXTENDED = (1 << 2),
    8.     } flags;

    9.     struct uci_package *p;
    10.     struct uci_section *s;
    11.     struct uci_option *o;
    12.     struct uci_element *last;

    13.     const char *package;
    14.     const char *section;
    15.     const char *option;
    16.     const char *value;
    17. };
    复制代码
    struct uci_context: uci上下文结构,贯穿查询、更改配置文件全过程。
    1. struct uci_context
    2. {
    3.     /* 配置文件包列表 */
    4.     struct uci_list root;

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

    7.     /* 后端导入导出 */
    8.     struct uci_backend *backend;
    9.     struct uci_list backends;

    10.     /* uci 运行标识 */
    11.     enum uci_flags flags;

    12.     char *confdir;
    13.     char *savedir;

    14.     /* search path for delta files */
    15.     struct uci_list delta_path;

    16.     /* 私有数据 */
    17.     int err;
    18.     const char *func;
    19.     jmp_buf trap;
    20.     bool internal, nested;
    21.     char *buf;
    22.     int bufsz;
    23. };
    复制代码
    几个基本API函数

    uci_alloc_context:动态申请一个uci上下文结构

    1. struct uci_context *uci_alloc_context(void);
    复制代码
    uci_free_contex:释放由uci_alloc_context申请的uci上下文结构且包括它的所有数据
    1. void uci_free_context(struct uci_context *ctx);
    复制代码
    uci_lookup_ptr:由给定的元组查找元素。填充ptr结构体中的p,s,o,last
    1. /**
    2. * uci_lookup_ptr: 分离一个uci元组字符串且查找对应元素树
    3. * @ctx: uci context结构体指针
    4. * @ptr: 存放元素查询结果的结构体指针
    5. * @str: 待查找的uci元组字符串
    6. * @extended: 允许扩展语法查询
    7. *
    8. *如果extended被设为ture,则uci_lookup_ptr支持下列扩展语法:
    9. *
    10. *例子:
    11. *   network.@interface[0].ifname ('ifname' option of the first interface section)
    12. *   network.@interface[-1]       (last interface section)
    13. * Note: 有必要的话uci_lookup_ptr将会自动加载配置文件包
    14. * @str 不能是一个const类型指针,它在使用的过程中将会被更改且用于将字符串填写到@ptr中,因此
    15. * 它只要@ptr还在使用,它就必须是可用的
    16. *
    17. * 这个函数在指定包元组的的字符串未被找到时返回UCI_ERR_NOTFOUND,否则返回UCI_OK
    18. *
    19. * 记住在查找其他部分失败的情况,如果它们同样被指定,包括section和option,同样会返回UCI_OK,
    20. * 但是ptr->flags * UCI_LOOKUP_COMPLETE标志位不会被置位
    21. */
    22. int uci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *str, bool extended);
    复制代码

    只需由以上3个API就可以对一个uci标准配置文件进行简单的读取了。

    代码实战

    下面就写一个实例代码试试吧

    1. /***********************************
    2. author:arvik
    3. email:1216601195@qq.com
    4. csdn:http://blog.csdn.net/u012819339
    5. ************************************/
    6. #include <stdio.h>
    7. #include <string.h>
    8. #include <stdlib.h>
    9. #include "uci.h"

    10. int main()
    11. {
    12.     struct uci_context *c;
    13.     struct uci_ptr p;
    14.     char *a = strdup("arvik_testconfig.main.home");

    15.     c = uci_alloc_context();
    16.     if(UCI_OK != uci_lookup_ptr(c, &p, a, true))
    17.     {
    18.         uci_perror(c, "no found!\n");
    19.         return -1;
    20.     }

    21.     printf("%s\n", p.o->v.string);
    22.     uci_free_context(c);
    23.     free(a);

    24.     return(0);
    25. }
    复制代码
    效果:
    1. root@OpenWrt:/# arvik_uci_test
    2. /www
    复制代码
    运行截图
    TIM截图20170724143615.png

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /3 下一条

    手机版|爱板网 |网站地图  

    GMT+8, 2017-9-26 11:50 , Processed in 0.409159 second(s), 11 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部