代码片段_配置文件解析_1

配置文件的内容格式如下:

复制代码
# Copyright (c) 2013 Peng Donglin.
#
# Authors: Peng Donglin  <pengdonglin137@163.com>
#

# this is a config file
# 
# imagenum            : the number of images included in output file 
# output              : the file name of update package
#
# enable              :  
#                       0: the corresponding image will not be included in update package
#                       1: the corresponding image will be included int update package
# type                : 
#                       0: HEAD_INFO_TYPE_UPDATE_FILE
#                       1: HEAD_INFO_TYPE_TOOL
#                       2: HEAD_INFO_TYPE_IVA
# filename            : the image name which will be deal with
# flashoffset         : tht offset of corresponding image in /dev/mtdx
# flashtype           : Nand or Nor
# imageorder          : the order number of image  at the same partition
# erase_or_not        : 1 erase /dev/mtdx   0 not erase /dev/mtdx
#                       if imageorder is not 0, the erase_or_not must be 0
# reserve             : the size of area not to be erased at the end of /dev/mtdx
# imagetype           : yaffs/jffs2/data/oob_raw/ubi 
#                       data : the image which does not have oob area
#                       oob_raw : the image which has oob area, but not yaffs or jffs2, such as sony's spl and sony's uboot
#                       ubi: first of all, copy the image to the memory(/tmp/filename),then use function ubiformat to write the image into /dev/mtdx
# mtd                 : the dev node which the corresponding image will be write in 
# oob_usr_offset      : the offset of oob_usr  in  oob area
# oob_usr_length      : the length of oob_usr data

< MAIN >

output          = dvr_img.bin


< HEADER >
enable          = 1
type            = 0
filename        = u-boot_evb_nandspl_bs.bin.raw
flashoffset     = 0x0
flashtype       = Nand
imageorder      = 0
erase_or_not    = 1
reserve         = 0x0
imagetype       = oob_raw
mtd             = /dev/mtd0

blocksize       = 128KiB
pagesize        = 2KiB
oobsize         = 64

oob_usr_offset  = 0
oob_usr_length  = 32

< HEADER >
enable          = 1
type            = 0
filename        = u-boot_evb_bs.bin.raw
flashoffset     = 0x0
flashtype       = Nand
imageorder      = 0
erase_or_not    = 1
reserve         = 0x400000
imagetype       = oob_raw
mtd             = /dev/mtd1

blocksize       = 128KiB
pagesize        = 2KiB
oobsize         = 64

oob_usr_offset  = 0
oob_usr_length  = 32

< HEADER >
enable          = 1
type            = 0
filename        = ubenv0.bin
flashoffset     = 0xB00000
flashtype       = Nand
imageorder      = 1
erase_or_not    = 0
reserve         = 0x0
imagetype       = data
mtd             = /dev/mtd1

blocksize       = 128KiB
pagesize        = 2KiB
oobsize         = 64

oob_usr_offset  = 0
oob_usr_length  = 32

< HEADER >
enable          = 1
type            = 0
filename        = ubenv1.bin
flashoffset     = 0xB80000
flashtype       = Nand
imageorder      = 2
erase_or_not    = 0
reserve         = 0x0
imagetype       = data
mtd             = /dev/mtd1

blocksize       = 128KiB
pagesize        = 2KiB
oobsize         = 64

oob_usr_offset  = 0
oob_usr_length  = 32

< HEADER >
enable          = 1
type            = 0
filename        = ubifs_fw.ubi
flashoffset     = 0x0
flashtype       = Nand
imageorder      = 0
erase_or_not    = 1
reserve         = 0x0
imagetype       = ubi
mtd             = /dev/mtd2

blocksize       = 128KiB
pagesize        = 2KiB
oobsize         = 64

oob_usr_offset  = 0
oob_usr_length  = 32

< HEADER >
enable          = 1
type            = 0
filename        = ubifs_rootfs.ubi
flashoffset     = 0x0
flashtype       = Nand
imageorder      = 0
erase_or_not    = 1
reserve         = 0x0
imagetype       = data
mtd             = /dev/mtd3

blocksize       = 128KiB
pagesize        = 2KiB
oobsize         = 64

oob_usr_offset  = 0
oob_usr_length  = 32

< HEADER >
enable          = 1
type            = 0
filename        = ubifs_local.ubi
flashoffset     = 0x0
flashtype       = Nand
imageorder      = 0
erase_or_not    = 1
reserve         = 0x0
imagetype       = data
mtd             = /dev/mtd5

blocksize       = 128KiB
pagesize        = 2KiB
oobsize         = 64

oob_usr_offset  = 0
oob_usr_length  = 32

#note: the header that describes uptool should be placed at the end.
< HEADER >
enable          = 1
type            = 1
filename        = uptool

< END >
复制代码

 

解析:

 

复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <strings.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>

#include "mk_dvr_img.h"

#define err_msg(fmt, ...) ({                                \
    fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__); \
    -1;                                                 \
})

struct head_info heads[10] ;
int heads_count = 0;
char update_filename[256] = {0};

static char *appcmd_strim(char *s, const char *skip_str)
{
    char *e = s+strlen(s)-1;
    while(*s && strchr(skip_str,*s)) {*s++=0;};
    while(*e && e>s && strchr(skip_str,*e)) {*e=0;e--;};
    return s;
}

static int get_multiplier(const char *str)
{
    if (!str)
        return 1;

    /* Remove spaces before the specifier */
    while (*str == ' ' || *str == '\t')
        str += 1;

    if (!strcmp(str, "KiB"))
        return 1024;
    if (!strcmp(str, "MiB"))
        return 1024 * 1024;
    if (!strcmp(str, "GiB"))
        return 1024 * 1024 * 1024;

    return -1;
}


static unsigned int get_bytes(const char *str)
{
    char *endp;
    unsigned int bytes = (unsigned int)strtoul(str, &endp, 0);

    if (endp == str || bytes < 0)
        return err_msg("incorrect amount of bytes: \"%s\"", str);

    if (*endp != '\0') {
        int mult = get_multiplier(endp);

        if (mult == -1)
            return err_msg("bad size specifier: \"%s\" - "
                       "should be 'KiB', 'MiB' or 'GiB'", endp);
        bytes *= mult;
    }

    return bytes;
}


static int parse_cfg(const char *filename)
{
    FILE * fp = NULL;
    size_t len = 0;
    ssize_t read;
    char * line = NULL;
    int type = -1;
    int index = -1;
    int enable_flag = 0;

    fp = fopen(filename, "r");
    if(fp == NULL)
    {
        perror("fail to open config file");
        return -1;
    }

    printf("\e[1;32mBegin to analyse %s\n\e[0m", filename);

    while ((read = getline(&line, &len, fp)) != -1)
    {
        char *sval, *str = appcmd_strim(line, "\t ;\r\n");
        int slen = str?strlen(str):0;
        if(slen<2)
            continue;

        /* comment */
        if (!str || *str==0 || *str=='#' || *str==';')
            continue;

        if(*str == '<' && str[slen-1] == '>')
        {
            str = appcmd_strim(str,"<> ");
            if(str &&strlen(str)>0)
            {
                if(strcmp(str, "MAIN") == 0)
                {
                    type = 0;
                    enable_flag = 0;
                    printf("\n\n");
                }
                else if(strcmp(str, "HEADER") == 0)
                {
                    type = 1;
                    enable_flag = 0;
                }
                else if(strcmp(str, "END") == 0)
                {
                    heads_count = index+1;
                    fprintf(stderr, "\e[1;32mparse end\n\e[0m");
                    return 0;
                }
                else
                {
                    type = 2;
                }
            }

            continue;
        }

        if(enable_flag)
        {
            continue;
        }
        sval = strchr(str, '=');
        if (!sval)    continue;
        *sval++=0;
        str = appcmd_strim(str,"\t ;\r\n");
        sval = appcmd_strim(sval,"\t ;\r\n");

        if(str && *str&& sval&&*sval)
        {
            if(type == 0)
            {
                if(strcmp(str, "output") == 0)
                {
                    strcpy(update_filename, sval);
                    printf("output file name = %s\n", update_filename);
                }
            }
            else if(type == 1)
            {
                if(strcmp(str, "enable") == 0)
                {
                    if(0 == get_bytes((const char *)sval))
                    {
                        enable_flag = 1;
                        continue;
                    }
                    else
                    {
                        index++;
                        enable_flag = 0;
                        printf("\n");
                    }
                }
                else if(strcmp(str, "type") == 0)
                {
                    heads[index].type = get_bytes((const char *)sval);
                    printf("type = %d\n", heads[index].type);
                }
                else if(strcmp(str, "filename") == 0)
                {
                    strcpy(heads[index].name, sval);
                    printf("filename = %s\n", heads[index].name);
                }
                else if(strcmp(str, "flashoffset")== 0)
                {
                    heads[index].flash_offset = get_bytes((const char *)sval);
                    printf("flashoffset = %#x\n", heads[index].flash_offset);
                }
                else if(strcmp(str, "flashtype") == 0)
                {
                    heads[index].flashType = strcmp(sval, "Nand")?NorFlash:NandFlash;
                    printf("flashtype = %s\n", sval);
                }
                else if(strcmp(str, "imageorder") == 0)
                {
                    heads[index].flash_num = get_bytes((const char *)sval);
                    printf("imageorder = %d\n", heads[index].flash_num);
                }
                else if(strcmp(str, "erase_or_not") == 0)
                {
                    heads[index].erase_or_not = get_bytes((const char *)sval);
                    printf("erase_or_not = %d\n", heads[index].erase_or_not);
                }
                else if(strcmp(str, "reserve") == 0)
                {
                    heads[index].reserve = get_bytes((const char *)sval);
                    printf("reserve = %#x\n", heads[index].reserve);
                }
                else if(strcmp(str, "imagetype") == 0)
                {
                    if(strcmp(sval, "yaffs") == 0)
                    {
                        heads[index].imageType = YAFFS;
                    }
                    else if(strcmp(sval, "jffs2") == 0)
                    {
                        heads[index].imageType = JFFS2;
                    }
                    else if(strcmp(sval, "data") == 0)
                    {
                        heads[index].imageType = DATA;
                    }
                    else if(strcmp(sval, "oob_raw") == 0)
                    {
                        heads[index].imageType = OOB_RAW;
                    }
                    else if(strcmp(sval, "ubi") == 0)
                    {
                        heads[index].imageType = UBI;
                    }
                    printf("imagetype = %d\n", heads[index].imageType);
                }
                else if(strcmp(str, "mtd") == 0)
                {
                    strcpy(heads[index].flash_addr, sval);
                    printf("mtd = %s\n", heads[index].flash_addr);
                }
                else if(strcmp(str, "blocksize") == 0)
                {
                    heads[index].blockSize = get_bytes((const char *)sval);
                    printf("blocksize = %#x\n", heads[index].blockSize);
                }
                else if(strcmp(str, "pagesize") == 0)
                {
                    heads[index].pageSize = get_bytes((const char *)sval);
                    printf("pagesize = %#x\n", heads[index].pageSize);
                }
                else if(strcmp(str, "oobsize") == 0)
                {
                    heads[index].oobSize = get_bytes((const char *)sval);
                    printf("oobsize = %d\n", heads[index].oobSize);
                }
                else if(strcmp(str, "oob_usr_offset") == 0)
                {
                    heads[index].oob_usr_offset = get_bytes((const char *)sval);
                    printf("oob_usr_offset = %#x\n", heads[index].oob_usr_offset);
                }
                else if(strcmp(str, "oob_usr_length") == 0)
                {
                    heads[index].oob_usr_length = get_bytes((const char *)sval);
                    printf("oob_usr_length = %d\n", heads[index].oob_usr_length);
                }

            }
            else if(type == 2)
            {
                continue;
            }
        }

    }

    return 0;
}


int mk_dvr_img(int img_fd,struct head_info *info)
{
    char *src = NULL;
    int fd = -1 , ret = 0;
    char buffer[2048];
    memset(buffer,0,2048);
    fd = open(info->name,O_RDONLY);
    if(fd < 0) GOTOERR(ret,fd,EXIT);

    src = (char *)mmap(NULL,info->size,PROT_READ,MAP_SHARED,fd,0);
    if(src == MAP_FAILED) GOTOERR(ret,-1,EXIT);

    info->dvr_crc = crc32((unsigned char const *)src,info->size);

    ret = lseek(img_fd,info->file_offset,SEEK_SET);
    if (ret <0) GOTOERR(ret,-1,EXIT);

    ret = write(img_fd,src, info->size );
    if (ret <0) GOTOERR(ret,-1,EXIT);

    //printf("offset is %d\n",lseek(img_fd,0,SEEK_CUR));

    ret = 0;
EXIT:
    munmap(src,info->size );
    close(fd);
    return ret;
}


int main(int argc, const char *argv[])
{
    int ret_val = -1;
    int start_offset = 0, prev_offset = 0;
    struct stat file_stat;
    size_t uptool_offset = 0,uptool_size = 0;
    int i;
    int img_fd = -1;
    char *dst = NULL;
    struct update_file_head *update_head;

    if(argc != 2)
    {
        printf("Usage: ./parse_cfg  config.cfg\n");
        goto EXIT;
    }

    bzero(heads,sizeof(heads) );
    ret_val = parse_cfg(argv[1]);
    if(ret_val < 0)
    {
        fprintf(stderr, "fail to parse config\n");
        goto EXIT;
    }

    if(heads_count <= 0)
    {
        printf("\e[1;31mthe number of image can not be zero \n\e[0m");
        goto EXIT;
    }

    img_fd = open(update_filename,O_RDWR | O_CREAT | O_TRUNC,0600);
    if(img_fd < 0)
    {
        printf("is open %s faild?/\n",update_filename);
        goto EXIT;
    }

    start_offset = heads_count * sizeof(struct head_info) + HEAD_INFO_OFFSET;
    prev_offset = start_offset;

    for(i=0;i<heads_count;++i)
    {
        bzero(&file_stat,sizeof(file_stat) );
        ret_val = stat(heads[i].name,&file_stat);
        if((ret_val < 0) || (file_stat.st_size <= 0) )
        {
            if (errno == ENOENT) {printf("unable open file:%s\n",heads[i].name);goto EXIT;}
            else if(file_stat.st_size <= 0) {printf("%s has 0 length.\n",heads[i].name);GOTOERR(ret_val,-1,EXIT);}
            else GOTOERR(ret_val,ret_val,EXIT);
        }

        heads[i].size = file_stat.st_size;
        heads[i].dvr_crc = 0;
        heads[i].file_offset = prev_offset;

        if(strcmp("uptool",heads[i].name) == 0)
        {
            uptool_offset = heads[i].file_offset;
            uptool_size = heads[i].size;
        }

        prev_offset += heads[i].size;
        printf("head index = %d name = %s flash_addr = %s size = %x file_offset = %x \n",
            i, heads[i].name, heads[i].flash_addr, heads[i].size, heads[i].file_offset);
    }

    ret_val = lseek(img_fd,HEAD_INFO_OFFSET + heads_count*sizeof(struct  head_info),SEEK_SET);
    if(ret_val < 0) GOTOERR(ret_val,-1,EXIT);
    for(i=0;i<heads_count;++i){
        ret_val = mk_dvr_img(img_fd,&heads[i]);
        if(ret_val < 0) GOTOERR(ret_val,ret_val,EXIT);
    }

    ret_val = lseek(img_fd,HEAD_INFO_OFFSET,SEEK_SET);
    if(ret_val < 0) GOTOERR(ret_val,-1,EXIT);
    for(i=0;i<heads_count;++i){
        ret_val = write(img_fd,(char *)&heads[i],sizeof(heads[i]));
        if(ret_val < 0) GOTOERR(ret_val,-1,EXIT);
    }

    dst = (char *)mmap(NULL,prev_offset,PROT_READ|PROT_WRITE,MAP_SHARED,img_fd,0);
    if(dst == MAP_FAILED) GOTOERR(ret_val,-1,EXIT);

    update_head = (struct update_file_head *)dst;
    bzero(update_head,sizeof(struct update_file_head) );
    update_head->mark = BSTAR_UPDATE_FILE_MARK;
    update_head->ipc_mark = IPC_UPDATE_FILE_MARK;
    update_head->version = IPC_UPDATE_PROG_VER;
    update_head->datasize = prev_offset - HEAD_INFO_OFFSET;
    update_head->crc = crc32((unsigned char const *)dst + HEAD_INFO_OFFSET, update_head->datasize);
    update_head->data_start_offset = HEAD_INFO_OFFSET;
    update_head->head_info_num = heads_count;
    update_head->uptool_offset = uptool_offset;
    update_head->uptool_size = uptool_size;


    printf("update_head.crc                 = %x\n", update_head->crc);
    printf("update_head->mark               =%d\n", update_head->mark);
    printf("update_head->ipc_mark           = %d\n", update_head->ipc_mark);
    printf("update_head->version            = %d\n", update_head->version);
    printf("update_head->datasize           = %d\n", update_head->datasize);
    printf("update_head->data_start_offset  = %d\n", update_head->data_start_offset);
    printf("update_head->head_info_num      = %d\n", update_head->head_info_num);
    printf("update_head->uptool_offset      = %x\n", update_head->uptool_offset);
    printf("update_head->uptool_size        = %d\n", update_head->uptool_size);
    printf("update_head->modCUUID           = %s", update_head->modCUUID);

    printf("\n");

    for(i=0; i<heads_count; i++)
    {
        printf("name:                %s\n", heads[i].name);
        printf("version:             %s\n", heads[i].version);
        printf("flash_addr:          %s\n", heads[i].flash_addr);
        printf("dvr_crc:             %x\n", heads[i].dvr_crc);
        printf("size:                %x\n", heads[i].size);
        printf("file_offset:         %x\n", heads[i].file_offset);
        printf("type:                %d\n", heads[i].type);
        printf("flashType:           %d\n", heads[i].flashType);
        printf("flash_offset:        %x\n", heads[i].flash_offset);
        printf("erase_or_not:        %d\n", heads[i].erase_or_not);
        printf("flash_num:           %d\n", heads[i].flash_num);
        printf("reserve  :           %d\n", heads[i].reserve);
        printf("blockSize:           %d\n", heads[i].blockSize);
        printf("pageSize:            %d\n", heads[i].pageSize);
        printf("oobSize:             %d\n", heads[i].oobSize);
        printf("oob_usr_offset:      %d\n", heads[i].oob_usr_offset);
        printf("oob_usr_length:      %d\n", heads[i].oob_usr_length);
        printf("imageType:           %d\n", heads[i].imageType);
        printf("\n");
    }

    ret_val = 0;
    printf("\e[1;32mSucceed!!\e[0m\n");
EXIT:
    if(dst) munmap(dst,prev_offset);
    if(img_fd > 0)  close(img_fd);
    if(ret_val < 0)
    {
        printf("\e[1;31mFailed!!\e[0m\n");
    }
    return ret_val;
}
复制代码

 

 

posted @   dolinux  阅读(299)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示