代码片段_配置文件解析_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; }
本文来自博客园,作者:dolinux,未经同意,禁止转载
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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的设计模式综述