openwrt中自定义配置文件解析

张开发
2026/5/18 6:18:33 15 分钟阅读
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 i0; //修改指定键值 for(i0;inum;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(i0;inum;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.confA1oneB2twoC3three执行交叉编译/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

更多文章