static int optimus_read_keyfile_2_mem(const char* filePath, u8* buf, unsigned* keyValLen) { int rc = 0; unsigned keySz = 0; if(DEV_FILE_FMT_VFAT == _optKeyInfo.fileFmt) { long hFile = -1; unsigned readSz = 0; #if 1//FIXME: remove this mmcinfo /*rc = run_command("mmcinfo 0", 0);*/ rc = optimus_sdc_burn_switch_to_extmmc(); if(rc){ DWN_ERR("Fail in mmcinfo\n"); return __LINE__; } #endif// keySz = (unsigned)do_fat_get_fileSz(filePath);//can support both sdc and udisk if(!keySz){ DWN_ERR("size is 0 of file [%s]\n", filePath); return __LINE__; } hFile = do_fat_fopen(filePath); if(hFile < 0){ DWN_ERR("Fail to open file[%s]\n", filePath); return __LINE__; } readSz = do_fat_fread(hFile, buf, keySz); if(readSz != keySz){ DWN_ERR("Want read %d bytes, but %d\n", keySz, readSz); return __LINE__; } do_fat_fclose(hFile); } *keyValLen = keySz; return rc; }
//1, Read the whole file content to buffer //2, parse file content to lines //3, parse each valid line static int parse_ini_file(const char* filePath, u8* iniBuf, const unsigned bufSz) { const int MaxLines = 1024;// const int MaxWordsALine = 32; char* lines[MaxLines]; char* wordsALine[MaxWordsALine]; int ret = 0; unsigned fileSz = 0; unsigned lineNum = 0; int nwords = 0; int currentSetIndex = -1; int hFile = -1; unsigned readLen = 0; unsigned i = 0; unsigned lineIndex = 0; fileSz = (unsigned)do_fat_get_fileSz(filePath); if(!fileSz){ err("File %s not exist in sdcard??\n", filePath); return __LINE__; } if(fileSz >= bufSz){ err("file size 0x%x illegal, buf size is 0x%x\n", fileSz, bufSz); return __LINE__; } DWN_MSG("ini sz 0x%xB\n", fileSz); hFile = do_fat_fopen(filePath); if(hFile < 0){ err("Fail to open file %s\n", filePath); return __LINE__; } readLen = do_fat_fread(hFile, iniBuf, fileSz); if(readLen != fileSz){ err("failed to load cfg file, want size 0x%x, but 0x%x\n", fileSz, readLen); do_fat_fclose(hFile); return __LINE__; } iniBuf[fileSz] = 0; do_fat_fclose(hFile); dbg("\\r is 0x%x\t, \\n is 0x%x\n", '\r', '\n'); char* curLine = (char*)iniBuf; char* pTemp = curLine; //step1:first loop to seprate buffer to lines for (i = 0; i < fileSz ; i++, ++pTemp) { char c = *pTemp; int isFileEnd = i + 1 >= fileSz; if(MaxLines <= lineNum){ err("total line number %d too many, at most %d lines!\n", lineNum, MaxLines); break; } if(isFileEnd) { lines[lineNum++] = curLine; break;//End to read file if file ended } if('\r' != c && '\n' != c) { continue; } *pTemp = 0;/// dbg("%3d: %s\n", lineNum, curLine); if('\r' == c)//for DOS \r\n mode { if('\n' == pTemp[1]) { lines[lineNum++] = curLine; ++pTemp; curLine = pTemp + 1; ++i;//skip '\n' which follows '\r' } else { err("Syntax error at line %d, DOS end \\r\\n, but \\r%x\n", lineNum + 1, pTemp[1]); return __LINE__; } } else if('\n' == c)//for UNIX '\n' mode { lines[lineNum++] = curLine; curLine = pTemp + 1; } } //step 2: abandon comment or space lines for (lineIndex = 0; lineIndex < lineNum ; lineIndex++) { int isSpaceLine = 1; char c = 0; curLine = lines[lineIndex]; while(c = *curLine++, c) { //escape space and tab if (is_space_char(c)) { continue; } isSpaceLine = 0;//no space line //test if frist char is comment delimeter if(';' == c) { lines[lineIndex] = NULL;//invalid comment lines } } //if all character is space or tab, also invlalid it if (isSpaceLine) { lines[lineIndex] = NULL; } } dbg("\nvalid lines:\n"); for (lineIndex = 0; lineIndex < lineNum ; lineIndex++) { int lineType = INI_LINE_TYPE_ERR; const char* iniKey = NULL; const char* iniVal = NULL; const char* iniSet = NULL; curLine = lines[lineIndex]; if(!curLine)continue; if(!line_is_valid(curLine)) //only comment lines can contain non-ASCII letters { err("line %d contain invalid chars\n", lineIndex + 1); ret = __LINE__; break; } dbg("%3d: %s\n",lineIndex, curLine); nwords = line_2_words(curLine, wordsALine, MaxWordsALine); if(nwords <= 0){ ret = __LINE__; break; } if(nwords > 3){ err("line %d error: ini support at most 3 words, but %d\n", lineIndex + 1, nwords); ret = __LINE__; break; } switch (nwords) { case 3: { if (!strcmp("=", wordsALine[1]))//k/v pair { lineType = INI_LINE_TYPE_KE_VALUE; iniKey = wordsALine[0]; iniVal = wordsALine[2]; break; } else if(!strcmp("[" , wordsALine[0]) && !strcmp("]" , wordsALine[2]))//set line { lineType = INI_LINE_TYPE_SET; iniSet = wordsALine[1]; break; } else { lineType = INI_LINE_TYPE_ERR; err("Ini syntax error when parse line %d\n", lineIndex + 1); ret = __LINE__; break; } } break; case 2: { if('[' == wordsALine[0][0])//set like "[set ]" or "[ set]" { if(!strcmp("]", wordsALine[1])) { lineType = INI_LINE_TYPE_SET; iniSet = wordsALine[0] + 1; break; } else if (']' == wordsALine[1][strlen(wordsALine[1]) - 1] && !strcmp("[", wordsALine[0])) { lineType = INI_LINE_TYPE_SET; iniSet = wordsALine[1]; wordsALine[1][strlen(wordsALine[1]) - 1] = 0; break; } } else if(!strcmp("=", wordsALine[1]))//k/v pair like "key = " { lineType = INI_LINE_TYPE_KE_VALUE; iniKey = wordsALine[0]; break; } else if('=' == wordsALine[1][0])//k/v pair like "key =v" or "key= v" { lineType = INI_LINE_TYPE_KE_VALUE; iniKey = wordsALine[0]; iniVal = wordsALine[1] + 1; break; } else if ('=' == wordsALine[0][strlen(wordsALine[0]) - 1])//k/v pair like "key= v" { wordsALine[0][strlen(wordsALine[0]) - 1] = 0; lineType = INI_LINE_TYPE_KE_VALUE; iniKey = wordsALine[0]; iniVal = wordsALine[1]; } } break; case 1: { char* word = wordsALine[0]; char firstChar = word[0]; char lastChar = word[strlen(word) - 1]; if('[' == firstChar && ']' == lastChar) { lineType = INI_LINE_TYPE_SET; iniSet = word + 1; word[strlen(word) - 1] = 0; break; } else { char c = 0; iniKey = word; while(c = *word++, c) { if ('=' == c)//TODO: not assert only delimeter in a line yet { lineType = INI_LINE_TYPE_KE_VALUE; *--word = 0; iniVal = ++word; iniVal = *iniVal ? iniVal : NULL; break; } } } } break; default: break; } if (INI_LINE_TYPE_SET == lineType) { const char* setname = NULL; dbg("set line, set is %s\n", iniSet); currentSetIndex = -1;//set index to invalid for (i = 0; i < TOTAL_SET_NUM; i++) { setname = _iniSets[i]; if (!strcmp(setname, iniSet))break;//set is useful for sdc burn } //set is useful if(i < TOTAL_SET_NUM) { if(!strcmp(setname, SET_BURN_PARTS)) { if(g_sdcBurnPara.setsBitMap.burnParts){ ret = __LINE__; goto _set_duplicated; } g_sdcBurnPara.setsBitMap.burnParts = 1; } if(!strcmp(setname, SET_BURN_PARA_EX)) { if(g_sdcBurnPara.setsBitMap.burnEx){ ret = __LINE__; goto _set_duplicated; } g_sdcBurnPara.setsBitMap.burnEx = 1; } if(!strcmp(setname, SET_CUSTOM_PARA)) { if(g_sdcBurnPara.setsBitMap.custom){ ret = __LINE__; goto _set_duplicated; } g_sdcBurnPara.setsBitMap.custom = 1; } currentSetIndex = i;//set set index to valid } } if(INI_LINE_TYPE_KE_VALUE == lineType) { dbg("k/v line, key (%s), val (%s)\n", iniKey, iniVal); if (currentSetIndex >= 0 && currentSetIndex < TOTAL_SET_NUM)//set is valid { const char* setName = _iniSets[currentSetIndex]; if (!strcmp(setName, SET_BURN_PARTS)) { ret = parse_burn_parts(iniKey, iniVal); if(ret){ ret = __LINE__; goto _line_err; } } if (!strcmp(setName, SET_BURN_PARA_EX)) { ret = parse_set_burnEx(iniKey, iniVal); if(ret){ ret = __LINE__; goto _line_err; } } if (!strcmp(setName, SET_CUSTOM_PARA)) { ret = parse_set_custom_para(iniKey, iniVal); if(ret){ ret = __LINE__; goto _line_err; } } } } } return ret; _line_err: err("Fail to parse line %d\n", lineIndex + 1); return ret; _set_duplicated: err("line %d err:set is duplicated!!\n", lineIndex + 1); return ret; }