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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenWRT 是一种开源的嵌入式操作系统,常用于路由器等网络设备。通过配置自定义的DDNS(动态域名解析服务),可以实现远程访问路由器的功能。 首先,我们需要在路由器上安装相应的软件包。在OpenWRT的系统管理界面,选择“软件包管理器”,并确保软件包列表已更新。然后搜索并安装“ddns-scripts”软件包。 安装完成后,我们需要在配置文件设置DDNS相关的参数。在路由器的系统管理界面,选择“文件浏览器”,找到“/etc/config/ddns”文件,并点击编辑。 在配置文件,我们需要设置以下参数: 1. `option enabled '1'`:启用DDNS功能。 2. `option lookup_host 'yourdomain.com'`:设置需要解析的域名。 3. `option domain 'yourdomain.com'`:设置域名所在的顶级域。例如,如果是yourdomain.com,则此参数为`yourdomain.com`。 4. `option username 'yourusername'`:设置DDNS服务的用户名。 5. `option password 'yourpassword'`:设置DDNS服务的密码。 6. `option interface 'wan'`:设置使用的网络接口。 7. `option use_syslog '1'`:启用系统日志功能。 配置完成后,保存文件并重启路由器。系统会根据你的设置定期更新DDNS记录。 为了验证DDNS是否正确配置,可以通过远程访问路由器的方式来确认。在浏览器输入你的域名,如果能够正确访问到路由器的管理界面,则说明DDNS已成功配置。 需要注意的是,自定义DDNS服务需要事先在域名注册商处设置正确的DNS记录,将域名解析服务器指向你的路由器的公共IP地址。 以上就是OpenWRT配置自定义DDNS的简要介绍。希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值