OpenWRT UCI API的使用

2023-11-03

OpenWRT UCI API的使用

UCI 是OpenWRT为实现配置集中化而引入的一个软件包, 通过修改UCI,可以实现对OpenWRT的绝对部分配置的修改.LUCI(OpenWRT 的WEB配置界面)也是通过读UCI配置文件的操作来实现用户对路由的配置的。通过掌握UCI的API的使用,可以方便地将您的软件的配置接口集成到LUCI中.


LUCI配置文件简介



LUCI的配置文件一般存储在 /etc/config目录下。比如网络配置文件则是 /etc/config/network 无线的配置文件是 /etc/config/wireless. 跟多配置文件的含义参考官方 WIKI


基本概念



UCI上下文: struct uci_context *
包(Package): 一个包对应一个UCI格式的文件.类型是 struct uci_package *
节(Section): 一个配置文件的节点. 类型是 struct uci_list *
值(Value):一个节下面可能包含多个值 一个值具有一个名字.
UCI配置文件的基本操作.


首先您需要引入头文件



#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <uci.h>


static struct uci_context * ctx = NULL; //定义一个UCI上下文的静态变量.
/*********************************************
*   载入配置文件,并遍历Section.
*/
bool load_config()
{
    struct uci_package * pkg = NULL;
    struct uci_element *e;


    ctx = uci_alloc_context(); // 申请一个UCI上下文.
    if (UCI_OK != uci_load(ctx, UCI_CONFIG_FILE, &pkg))
        goto cleanup; //如果打开UCI文件失败,则跳到末尾 清理 UCI 上下文.


    /*遍历UCI的每一个节*/
    uci_foreach_element(&pkg->sections, e)
    {
        struct uci_section *s = uci_to_section(e);
        // 将一个 element 转换为 section类型, 如果节点有名字,则 s->anonymous 为 false.
        // 此时通过 s->e->name 来获取.
        // 此时 您可以通过 uci_lookup_option()来获取 当前节下的一个值.
        if (NULL != (value = uci_lookup_option_string(ctx, s, "ipaddr")))
        {
            ip = strdup(value) //如果您想持有该变量值,一定要拷贝一份。当 pkg销毁后value的内存会被释放。
        }
        // 如果您不确定是 string类型 可以先使用 uci_lookup_option() 函数得到Option 然后再判断.
        // Option 的类型有 UCI_TYPE_STRING 和 UCI_TYPE_LIST 两种.


    }
    uci_unload(ctx, pkg); // 释放 pkg 
cleanup:
    uci_free_context(ctx);
    ctx = NULL;
}


遍历一个UCI_TYPE_LIST 类型.



加入现在有一个如下的配置文件:


    config  "server" "webserver"
        list    "index" "index.html"
        list    "index" "index.php"
        list    "index" "default.html"


代码片:


// s 为 section.
struct uci_option * o = uci_lookup_option(ctx, s, "index");
if ((NULL != o) && (UCI_TYPE_LIST == o->type)) //o存在 且 类型是 UCI_TYPE_LIST则可以继续.
{
    struct uci_element *e;
    uci_foreach_element(&o->v.list, e)
    {
        //这里会循环遍历 list
        // e->name 的值依次是 index.html, index.php, default.html
    }
}


写配置



UCI提供了一个简洁的办法来操作配置信息,例如有一个配置文件


#文件名: testconfig
config  'servver'
    option  'value' '123' # 我们想修改 'value' 的值为 '456'


代码如下:


struct uci_context * ctx = uci_alloc_context(); //申请上下文
struct uci_ptr ptr ={
    .package = "config",
    .section = "servver",
    .option = "value",
    .value = "256",
};
uci_set(_ctx,&ptr); //写入配置
uci_commit(_ctx, &ptr.p, false); //提交保存更改
uci_unload(_ctx,ptr.p); //卸载包


uci_free_context(ctx); //释放上下文


依照上面的例子,我们可以举一反三, uci_ptr 用来指定信息.而是用uci_set则是写入信息.同类的函数有如下几个: 针对list的操作:
    uci_add_list()  // 添加一个list 值
    uci_del_list()  // 删除一个list 值
    uci_delete()    // 删除一个option值




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenWRT UCI API的使用 的相关文章

随机推荐

  • 容器 - unordered_map

    unordered map是C Boost库中的内容 这里的unordered指的是散列式的存储方式 unordered库提供了两个散列映射表 unordered map和unordered multimap 利用散列表代替了二叉树的实现
  • 11. Leaf-segment 分布式ID

    Spring Cloud 微服务系列文章 点击上方合集 1 开头 当应用程序只使用单个数据库时 可以使用数据库自增的方式来生成id 这种方式既简单 查询又快 然而 当应用程序需要进行分库分表时 即将数据分散到多个数据库和数据表中 使用数据库
  • catia如何将曲面加厚变为实体_CATIA如何将片体转换为实体?

    下面介绍一种在CATIA中将片体转换为实体的方法 1 首先打开CATIA软件 再打开需要曲面操作的模型零件 2 然后进入创成式外形设计模块 在软件界面的开始菜单栏中点击开始 形状 创成式外形设计 3 接下来从实体中提取面 先使用 提取 命令
  • 设计规范-导航、弹窗、视图

    常见导航样式 根据产品的特性 导航可以混合使用 体现形式多样化 不能为了追求多样化 滥用导航类型 扁平式导航 在一级页面提供导航栏 一般处于顶部 底部 适合频繁切换的模块 方便用户在不同的模块间操作 例 微信的底部导航栏 小红书的顶部 底部
  • LADRC的学习——用simulink搭建仿真模型

    作者 墨心 时间 2019 7 25 用simulink搭建仿真模型 前面两篇博客主要讲了ADRC的相关概念和知识 并且尝试着搭建模型和仿真 之后学习了PID的相关知识 了解了Kp Ki Kd三个参数的意义 接下来 主要根据高志强教授的论文
  • java会话技术--02--服务器session共享

    java会话技术 02 服务器session共享 1 原理图 2 代码实现 2 1 接口代码 package cn zhou common web session import java io Serializable import jav
  • leetcode63. 不同路径 II

    题目 一个机器人位于一个 m x n 网格的左上角 起始点在下图中标记为 Start 机器人每次只能向下或者向右移动一步 机器人试图达到网格的右下角 在下图中标记为 Finish 现在考虑网格中有障碍物 那么从左上角到右下角将会有多少条不同
  • ssd_tensorflow训练自己的模型填坑记

    人工智能开发真的很难 虽然网上有相应的教程 但在关键的环节还是要自己摸索 否则搞的一头雾水 昨天开始研究SSD Tensorflow的训练 想实现训练自己的模型 但万事开头难啊 网上找资料照着做 然而可能机器配制环境什么不一样 总是会出问题
  • 测试用例使用传统excel还是思维导图(Xmind、MindManager等)?

    一 使用感言 实习时随便使用了word文档编写测试用例 也没有人带 后来第一份正式测试工作 也没有人带测试 那时跟着大众学用思维导图写测试用例 发现思维导图非常灵活 目前使用xmind 使用思维导图后 EXCEL仅作为测试数据准备和计算公式
  • servlet与jsp的使用

    文章目录 一 servlet无法使用的问题 二 右键找不到servlet的问题 三 找不到jsp的页面 四 src目录下的java文件无法直接被servlet导入 五 cataline日志乱码问题 六 如何直接对servlet进行传参 七
  • 调试osgEarth(33)分页瓦片卸载器子节点的作用-(3)渲染遍历的帧号和时间设置-TerrainCuller赋值给可渲染图层--TerrainRenderData-Layedrawable构造

    继续调试 总结下 LayerDrawable类是通过DrawTileCommand在各种Layer上绘制的drawable 有自己的渲染状态和渲染次序 可以在VisibleLayer ImageLayer PatchLayer上绘制
  • mac 上brew加速

    修改brew源即可 open e zshrc 写入 export HOMEBREW CORE GIT REMOTE https mirrors tuna tsinghua edu cn git homebrew homebrew core
  • Python+Selenium_UI自动化操作(10)——判断元素是否可见

    UI自动化 判断元素是否可见 练习 元素判断页面元素是否可见 语法 is displayed encoding utf 8 from selenium import webdriver import time unittest class
  • Unity UGUI按钮控制物体显示隐藏的小技巧

    首先我们说明一下常用的按钮控制显示隐藏的方法 Header 关闭按钮 public Button close btn Header 需要关闭的对象 public GameObject obj image void Start close b
  • Java中两种比较器的实现

    先举例说明 例一 如果要对一组数字进行排序 可以写一个排序算法实现 例如 1 4 6 5 3 8 排序后 1 3 4 5 6 8 例二 如果要对字母进行排序 则可以通过26个字母的自然顺序进行排序 例如 a f b e d c 排序后 a
  • 如何判断当前程序是否正以管理员或root权限运行

    在windows下 一般超级用户是管理员权限administrator 在linux下 一般超级用户是root windows下 使用IsUserAnAdmin 函数进行判断 linux下 使用geteuid 函数进行判断 编写一个UAC
  • 1、在不配置CATALINA_HOME环境变量的情况下启动tomcat

    场景 tomcat执行startup bat的时候 会寻找全局环境变量CATALINA HOME 如果CATALINA HOME对应的tomcat目录不是当前tomcat的目录 则就会启动报错 解决方法如下 1 打开bin目录下的start
  • 2020-04-27

    jsp中方法为找到异常 java lang NoSuchMethodException com bjsxt servlet UserServlet at java lang Class getConstructor0 Class java
  • MySQL高级篇-第02章_MySQL的数据目录

    1 MySQL的主要目录 root atguigu01 find name mysql 安装好MySQL 8之后 我们查看如下的目录结构 1 1 数据库文件的存放路径 MySQL数据库文件的存放路径 var lib mysql mysql
  • OpenWRT UCI API的使用

    OpenWRT UCI API的使用 UCI 是OpenWRT为实现配置集中化而引入的一个软件包 通过修改UCI 可以实现对OpenWRT的绝对部分配置的修改 LUCI OpenWRT 的WEB配置界面 也是通过读UCI配置文件的操作来实现