当前位置: 首页 > news >正文

openwrt中自定义配置文件解析

在Linux/openwrt等嵌入式系统中,使用到了大量配置文件,比如硬件配置,系统配置,应用程序

配置。这些配置信息通常都是以文本文件为载体,以键值对的形式存储于本地或远程文件系统中。

可以参考openwrt的uci命令系统,简易的自定义自己程序的配置文件解析,方便于在命令行或

应用程序内部即时读写配置参数。

config_file_rw.c

/** create by iversondeng168 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <ctype.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <time.h> #define DEBUG #define CONFIG_FILE "./etc/config_file_rw.conf" //键值对结构体 typedef struct item_t { char *key; char *value; }ITEM; //去除一行字符串右边的空格 char *str_trim_right(char *pstr) { int i; i = strlen(pstr) - 1; while (isspace(pstr[i]) && i >= 0) pstr[i--] = 0; return pstr; } //去除一行字符串左边的空格 char *str_trim_left(char *pstr) { int i = 0,j = 0; j = strlen(pstr) - 1; while (isspace(pstr[i]) && (i <= j)) i++; if (0 < i) strcpy(pstr, &pstr[i]); return pstr; } //同时去除字符串左右两边的空格 char *str_trim(char *pstr) { char *p; p = str_trim_right(pstr); return str_trim_left(p); } //从一行字符串中解析出键值对 int get_item_from_line(char *line, ITEM *item) { char *pline = str_trim(line); int len = strlen(pline); if(len <= 0) { return -1; } else if(pline[0]=='#' || pline[0]=='/') { return -2; } else { char *p = strchr(pline, '='); *p++ = 0; item->key = (char *)malloc(strlen(pline) + 1); item->value = (char *)malloc(strlen(p) + 1); pline = str_trim(pline); p = str_trim(p); strcpy(item->key,pline); strcpy(item->value,p); } return 0; } //将整个配置文件解析出键值对数组保存在内存中 int file_to_items(const char *filename, ITEM *items, int *num) { char line[1024]; FILE *fp; fp = fopen(filename,"r"); if(fp == NULL) return 1; int i = 0; int len = 0; char*p1 = NULL; char*p2 = NULL; while(fgets(line, 1024 - 1, fp)) { p1 = str_trim(line); len = strlen(p1); if(len <= 0) { continue; } else if(p1[0]=='#') { continue; } else { p2 = strchr(p1, '='); if(p2 == NULL) continue; *p2++ = 0; items[i].key = (char *)malloc(strlen(p1) + 1); items[i].value = (char *)malloc(strlen(p2) + 1); p1 = str_trim(p1); p2 = str_trim(p2); strcpy(items[i].key,p1); strcpy(items[i].value,p2); i++; } } *num = i; fclose(fp); return 0; } //从配置文件中读取指定键的值 int read_conf_value(const char *filename,char *key,char *value) { char line[1024]; FILE *fp; ITEM item; fp = fopen(filename,"r"); if(fp == NULL) return -1; while (fgets(line, 1024-1, fp)) { if(get_item_from_line(line,&item)) { continue; } if(!strcmp(item.key,key)) { strcpy(value,item.value); free(item.key); free(item.value); fclose(fp); return 0; } } fclose(fp); return -2; } //向配置文件中写入指定键的值 int write_conf_value(const char *filename,char *key,char *value) { ITEM items[1024]; int num; //将文件的键值对加载到内存 file_to_items(filename, items, &num); int i=0; //修改指定键值 for(i=0;i<num;i++) { if(!strcmp(items[i].key, key)) { items[i].value = value; break; } } if(i >= num) { return -1; } //同步到文件 FILE *fp; fp = fopen(filename, "w"); if(fp == NULL) { return -2; } for(i=0;i<num;i++) { fprintf(fp,"%s=%s\n",items[i].key, items[i].value); } fclose(fp); return 0; } /**eg. config_file_rw -r A1 config_file_rw -r B2 config_file_rw -w C3 test */ int main(int argc,char*argv[]) { char tmpdata[128] = {0}; int retval; if(3 != argc && 4 != argc) { #ifdef DEBUG printf("not support!\n"); #endif return -1; } if(3 == argc) { if(strcmp(argv[1],"-r")) { #ifdef DEBUG printf("argv[1] must -r!\n"); #endif return -2; } retval = read_conf_value((const char*)CONFIG_FILE,argv[2],tmpdata); if(retval) { switch(retval) { case 0: break; case -1: #ifdef DEBUG printf("read error!\n"); #endif break; case -2: #ifdef DEBUG printf("not found!\n"); #endif break; } return -3; } printf("%s",tmpdata); } else { if(strcmp(argv[1],"-w")) { #ifdef DEBUG printf("argv[1] must -w!\n"); #endif return -4; } strcpy(tmpdata,argv[3]); retval = write_conf_value((const char*)CONFIG_FILE,argv[2],tmpdata); if(retval) { switch(retval) { case 0: break; case -1: #ifdef DEBUG printf("not found!\n"); #endif break; case -2: #ifdef DEBUG printf("write error!\n"); #endif break; } return -5; } } return 0; }

测试配置文件./etc/config_file_rw.conf

A1=one
B2=two
C3=three

执行交叉编译

/home/source/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-musl/toolchain/bin/arm-openwrt-linux-gcc config_file_rw.c -o config_file_rw -O2 -w

http://www.jsqmd.com/news/615281/

相关文章:

  • 某手热门短剧逆向AI直接秒
  • 问题拆解:绩效管理系统的ROI到底怎么算?
  • 从BIO,NIO到多路复用IO——认识Netty框架
  • 【国家级数字农场认证标准】:PHP可视化配置合规性检查清单(含GDPR+农业农村部2024新规适配)
  • OctoPi性能优化:7个技巧提升打印质量和速度
  • Browser.html开发环境配置:Node.js、Servo和Electron客户端详解
  • 从零开始手搓一个STM32与机智云的小项目——GPIO的输入输出
  • DeepTutor学习社区:与其他学习者交流经验的终极指南
  • Blazor WebAssembly性能突破:实测冷启动<80ms、首屏加载<300ms的7项高级优化技法(含源码级Hook方案)
  • ESPS USB MSC 调试全过程记录栽
  • RangeSeekBar测试策略:单元测试和UI自动化测试完整方案
  • rapidocr v3.8.0发布了
  • 终极指南:如何用虎符台Legion Seal轻松管理你的全面战争MOD
  • 体系结构论文(九十八):NPUEval: Optimizing NPU Kernels with LLMs and Open Source Compilers
  • openwrt在allwinner r328平台开启5G WIFI AP
  • 0.DJI-PSDK开发准备及资料说明(基于DJI经纬M300RTK和M350RTK无人机上使用)
  • 联发科MTK专用刷机提取工具|免引导文件直提原厂固件包|支持安卓4-11全平台救砖与系统刷写
  • PHP + CodeLlama + 自研规则引擎:构建企业级AI代码审查流水线(附GitHub开源配置模板)
  • Calico IPIP 使用指南章
  • NFC Tool 免vip,使用联动密钥破解加密门禁卡教程
  • ThreadlessInject终极指南:掌握无线程进程注入的完整教程
  • Lua语法详解:从变量声明到循环遍历的避坑指南
  • 如何完整破解Cursor Pro功能限制:一键激活与无限使用的终极指南
  • 终极指南:5分钟快速配置OpenTabletDriver开源数位板驱动
  • 为什么选择Mobile Native Foundation:大规模移动应用开发的完整解决方案终极指南
  • LANs.py代码实现原理:深入理解nfqueue与Scapy的协同工作机制
  • 将盾CDN:安全运营中心建设的实战经验
  • Goreman性能优化:提升多进程管理效率的10个最佳实践
  • 突破音乐加密壁垒:Unlock Music的技术创新与实践指南
  • 一个0基础的人怎么开始学AI?(不说废话)