1bae44755Sopenharmony_ci/* 2bae44755Sopenharmony_ci * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 3bae44755Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4bae44755Sopenharmony_ci * you may not use this file except in compliance with the License. 5bae44755Sopenharmony_ci * You may obtain a copy of the License at 6bae44755Sopenharmony_ci * 7bae44755Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8bae44755Sopenharmony_ci * 9bae44755Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10bae44755Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11bae44755Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12bae44755Sopenharmony_ci * See the License for the specific language governing permissions and 13bae44755Sopenharmony_ci * limitations under the License. 14bae44755Sopenharmony_ci */ 15bae44755Sopenharmony_ci 16bae44755Sopenharmony_ci#include "context_tool.h" 17bae44755Sopenharmony_ci 18bae44755Sopenharmony_ci#include <stdlib.h> 19bae44755Sopenharmony_ci#include <errno.h> 20bae44755Sopenharmony_ci#include <string.h> 21bae44755Sopenharmony_ci#include <limits.h> 22bae44755Sopenharmony_ci#include <sys/stat.h> 23bae44755Sopenharmony_ci#include "securec.h" 24bae44755Sopenharmony_ci 25bae44755Sopenharmony_ci#include "endian_internal.h" 26bae44755Sopenharmony_ci 27bae44755Sopenharmony_ci#ifdef SYSCAP_DEFINE_EXTERN_ENABLE 28bae44755Sopenharmony_ci#include "syscap_define_custom.h" 29bae44755Sopenharmony_ci#else 30bae44755Sopenharmony_ci#include "syscap_define.h" 31bae44755Sopenharmony_ci#endif 32bae44755Sopenharmony_ci 33bae44755Sopenharmony_civoid FreeContextBuffer(char *contextBuffer) 34bae44755Sopenharmony_ci{ 35bae44755Sopenharmony_ci if (contextBuffer != NULL) { 36bae44755Sopenharmony_ci (void)free(contextBuffer); 37bae44755Sopenharmony_ci } 38bae44755Sopenharmony_ci} 39bae44755Sopenharmony_ci 40bae44755Sopenharmony_ciint32_t GetFileContext(const char *inputFile, char **contextBufPtr, uint32_t *bufferLen) 41bae44755Sopenharmony_ci{ 42bae44755Sopenharmony_ci int32_t ret; 43bae44755Sopenharmony_ci FILE *fp = NULL; 44bae44755Sopenharmony_ci struct stat statBuf; 45bae44755Sopenharmony_ci char *contextBuffer = NULL; 46bae44755Sopenharmony_ci char path[PATH_MAX + 1] = {0x00}; 47bae44755Sopenharmony_ci 48bae44755Sopenharmony_ci#ifdef _POSIX_ 49bae44755Sopenharmony_ci if (strlen(inputFile) > PATH_MAX || strncpy_s(path, PATH_MAX, inputFile, strlen(inputFile)) != EOK) { 50bae44755Sopenharmony_ci PRINT_ERR("get path(%s) failed\n", inputFile); 51bae44755Sopenharmony_ci return -1; 52bae44755Sopenharmony_ci } 53bae44755Sopenharmony_ci#else 54bae44755Sopenharmony_ci if (strlen(inputFile) > PATH_MAX || realpath(inputFile, path) == NULL) { 55bae44755Sopenharmony_ci PRINT_ERR("get file(%s) real path failed\n", inputFile); 56bae44755Sopenharmony_ci return -1; 57bae44755Sopenharmony_ci } 58bae44755Sopenharmony_ci#endif 59bae44755Sopenharmony_ci 60bae44755Sopenharmony_ci ret = stat(path, &statBuf); 61bae44755Sopenharmony_ci if (ret != 0) { 62bae44755Sopenharmony_ci PRINT_ERR("get file(%s) st_mode failed, errno = %d\n", path, errno); 63bae44755Sopenharmony_ci return -1; 64bae44755Sopenharmony_ci } 65bae44755Sopenharmony_ci if (!(statBuf.st_mode & S_IRUSR)) { 66bae44755Sopenharmony_ci PRINT_ERR("don't have permission to read the file(%s)\n", path); 67bae44755Sopenharmony_ci return -1; 68bae44755Sopenharmony_ci } 69bae44755Sopenharmony_ci contextBuffer = (char *)malloc(statBuf.st_size + 1); 70bae44755Sopenharmony_ci if (contextBuffer == NULL) { 71bae44755Sopenharmony_ci PRINT_ERR("malloc buffer failed, size = %d, errno = %d\n", (int32_t)statBuf.st_size + 1, errno); 72bae44755Sopenharmony_ci return -1; 73bae44755Sopenharmony_ci } 74bae44755Sopenharmony_ci fp = fopen(path, "rb"); 75bae44755Sopenharmony_ci if (fp == NULL) { 76bae44755Sopenharmony_ci PRINT_ERR("open file(%s) failed, errno = %d\n", path, errno); 77bae44755Sopenharmony_ci FreeContextBuffer(contextBuffer); 78bae44755Sopenharmony_ci return -1; 79bae44755Sopenharmony_ci } 80bae44755Sopenharmony_ci size_t retFread = fread(contextBuffer, statBuf.st_size, 1, fp); 81bae44755Sopenharmony_ci if (retFread != 1) { 82bae44755Sopenharmony_ci PRINT_ERR("read file(%s) failed, errno = %d\n", path, errno); 83bae44755Sopenharmony_ci FreeContextBuffer(contextBuffer); 84bae44755Sopenharmony_ci (void)fclose(fp); 85bae44755Sopenharmony_ci return -1; 86bae44755Sopenharmony_ci } 87bae44755Sopenharmony_ci contextBuffer[statBuf.st_size] = '\0'; 88bae44755Sopenharmony_ci (void)fclose(fp); 89bae44755Sopenharmony_ci 90bae44755Sopenharmony_ci *contextBufPtr = contextBuffer; 91bae44755Sopenharmony_ci *bufferLen = statBuf.st_size + 1; 92bae44755Sopenharmony_ci return 0; 93bae44755Sopenharmony_ci} 94bae44755Sopenharmony_ci 95bae44755Sopenharmony_ciint32_t CheckFileAndGetFileContext(const char *inputFile, char **contextBufPtr, uint32_t *bufferLen) 96bae44755Sopenharmony_ci{ 97bae44755Sopenharmony_ci if (inputFile == NULL) { 98bae44755Sopenharmony_ci PRINT_ERR("input file is NULL.\n"); 99bae44755Sopenharmony_ci return -1; 100bae44755Sopenharmony_ci } 101bae44755Sopenharmony_ci int32_t ret = GetFileContext(inputFile, contextBufPtr, bufferLen); 102bae44755Sopenharmony_ci if (ret != 0) { 103bae44755Sopenharmony_ci PRINT_ERR("GetFileContext failed, input file : %s\n", inputFile); 104bae44755Sopenharmony_ci } 105bae44755Sopenharmony_ci return ret; 106bae44755Sopenharmony_ci} 107bae44755Sopenharmony_ci 108bae44755Sopenharmony_ciint32_t ConvertedContextSaveAsFile(char *outDirPath, const char *filename, char *convertedBuffer, size_t contextBufLen) 109bae44755Sopenharmony_ci{ 110bae44755Sopenharmony_ci int32_t ret; 111bae44755Sopenharmony_ci FILE *fp = NULL; 112bae44755Sopenharmony_ci char path[PATH_MAX + 1] = {0x00}; 113bae44755Sopenharmony_ci 114bae44755Sopenharmony_ci#ifdef _POSIX_ 115bae44755Sopenharmony_ci if (strlen(outDirPath) >= PATH_MAX || strncpy_s(path, PATH_MAX, outDirPath, strlen(outDirPath)) != EOK) { 116bae44755Sopenharmony_ci PRINT_ERR("get path(%s) failed\n", outDirPath); 117bae44755Sopenharmony_ci return -1; 118bae44755Sopenharmony_ci } 119bae44755Sopenharmony_ci#else 120bae44755Sopenharmony_ci if (strlen(outDirPath) >= PATH_MAX || realpath(outDirPath, path) == NULL) { 121bae44755Sopenharmony_ci PRINT_ERR("get file(%s) real path failed\n", outDirPath); 122bae44755Sopenharmony_ci return -1; 123bae44755Sopenharmony_ci } 124bae44755Sopenharmony_ci#endif 125bae44755Sopenharmony_ci int32_t pathLen = strlen(path); 126bae44755Sopenharmony_ci if (path[pathLen - 1] != '/' && path[pathLen - 1] != '\\') { 127bae44755Sopenharmony_ci path[pathLen] = '/'; 128bae44755Sopenharmony_ci } 129bae44755Sopenharmony_ci 130bae44755Sopenharmony_ci if (strlen(path) + strlen(filename) + 1 > PATH_MAX) { 131bae44755Sopenharmony_ci PRINT_ERR("length of path too long.\n"); 132bae44755Sopenharmony_ci return -1; 133bae44755Sopenharmony_ci } 134bae44755Sopenharmony_ci ret = strncat_s(path, PATH_MAX, filename, strlen(filename) + 1); 135bae44755Sopenharmony_ci if (ret != 0) { 136bae44755Sopenharmony_ci PRINT_ERR("strncat_s failed, (%s, %d, %s, %d), errno = %d\n", 137bae44755Sopenharmony_ci path, PATH_MAX, filename, (int32_t)strlen(filename) + 1, errno); 138bae44755Sopenharmony_ci return -1; 139bae44755Sopenharmony_ci } 140bae44755Sopenharmony_ci 141bae44755Sopenharmony_ci fp = fopen(path, "wb"); 142bae44755Sopenharmony_ci if (fp == NULL) { 143bae44755Sopenharmony_ci PRINT_ERR("can't create file(%s), errno = %d\n", path, errno); 144bae44755Sopenharmony_ci return -1; 145bae44755Sopenharmony_ci } 146bae44755Sopenharmony_ci 147bae44755Sopenharmony_ci if (fwrite(convertedBuffer, contextBufLen, 1, fp) != 1) { 148bae44755Sopenharmony_ci PRINT_ERR("can't write file(%s),errno = %d\n", path, errno); 149bae44755Sopenharmony_ci (void)fclose(fp); 150bae44755Sopenharmony_ci return -1; 151bae44755Sopenharmony_ci } 152bae44755Sopenharmony_ci 153bae44755Sopenharmony_ci (void)fclose(fp); 154bae44755Sopenharmony_ci 155bae44755Sopenharmony_ci return 0; 156bae44755Sopenharmony_ci} 157bae44755Sopenharmony_ci 158bae44755Sopenharmony_ciint32_t CheckRpcidFormat(const char *inputFile, char **buffer, uint32_t *len) 159bae44755Sopenharmony_ci{ 160bae44755Sopenharmony_ci uint32_t bufferLen; 161bae44755Sopenharmony_ci uint16_t sysCaptype, sysCapLength; 162bae44755Sopenharmony_ci char *contextBuffer = NULL; 163bae44755Sopenharmony_ci RPCIDHead *rpcidHeader = NULL; 164bae44755Sopenharmony_ci 165bae44755Sopenharmony_ci if (GetFileContext(inputFile, &contextBuffer, &bufferLen)) { 166bae44755Sopenharmony_ci PRINT_ERR("GetFileContext failed, input file : %s\n", inputFile); 167bae44755Sopenharmony_ci return -1; 168bae44755Sopenharmony_ci } 169bae44755Sopenharmony_ci if (bufferLen < (2 * sizeof(uint32_t))) { // 2, header of rpcid.sc 170bae44755Sopenharmony_ci PRINT_ERR("Parse file failed(format is invalid), input file : %s\n", inputFile); 171bae44755Sopenharmony_ci FreeContextBuffer(contextBuffer); 172bae44755Sopenharmony_ci return -1; 173bae44755Sopenharmony_ci } 174bae44755Sopenharmony_ci rpcidHeader = (RPCIDHead *)contextBuffer; 175bae44755Sopenharmony_ci if (rpcidHeader->apiVersionType != 1) { 176bae44755Sopenharmony_ci PRINT_ERR("Parse file failed(apiVersionType != 1), input file : %s\n", inputFile); 177bae44755Sopenharmony_ci FreeContextBuffer(contextBuffer); 178bae44755Sopenharmony_ci return -1; 179bae44755Sopenharmony_ci } 180bae44755Sopenharmony_ci sysCaptype = NtohsInter(*(uint16_t *)(rpcidHeader + 1)); 181bae44755Sopenharmony_ci if (sysCaptype != 2) { // 2, app syscap type 182bae44755Sopenharmony_ci PRINT_ERR("Parse file failed(sysCaptype != 2), input file : %s\n", inputFile); 183bae44755Sopenharmony_ci FreeContextBuffer(contextBuffer); 184bae44755Sopenharmony_ci return -1; 185bae44755Sopenharmony_ci } 186bae44755Sopenharmony_ci sysCapLength = NtohsInter(*(uint16_t *)((char *)(rpcidHeader + 1) + sizeof(uint16_t))); 187bae44755Sopenharmony_ci if (bufferLen < sizeof(RPCIDHead) + sizeof(uint32_t) + sysCapLength) { 188bae44755Sopenharmony_ci PRINT_ERR("Parse file failed(SysCap length exceeded), input file : %s\n", inputFile); 189bae44755Sopenharmony_ci FreeContextBuffer(contextBuffer); 190bae44755Sopenharmony_ci return -1; 191bae44755Sopenharmony_ci } 192bae44755Sopenharmony_ci 193bae44755Sopenharmony_ci *buffer = contextBuffer; 194bae44755Sopenharmony_ci *len = bufferLen; 195bae44755Sopenharmony_ci return 0; 196bae44755Sopenharmony_ci} 197bae44755Sopenharmony_ci 198bae44755Sopenharmony_cicJSON *CreateWholeSyscapJsonObj(void) 199bae44755Sopenharmony_ci{ 200bae44755Sopenharmony_ci cJSON *syscapJsonObj = cJSON_CreateObject(); 201bae44755Sopenharmony_ci if (syscapJsonObj == NULL) { 202bae44755Sopenharmony_ci PRINT_ERR("interface-create jsonObj failed."); 203bae44755Sopenharmony_ci return NULL; 204bae44755Sopenharmony_ci } 205bae44755Sopenharmony_ci 206bae44755Sopenharmony_ci size_t syscapNums = sizeof(g_arraySyscap) / sizeof(SyscapWithNum); 207bae44755Sopenharmony_ci for (size_t i = 0; i < syscapNums; i++) { 208bae44755Sopenharmony_ci cJSON_AddItemToObject(syscapJsonObj, g_arraySyscap[i].str, cJSON_CreateNumber(g_arraySyscap[i].num)); 209bae44755Sopenharmony_ci } 210bae44755Sopenharmony_ci return syscapJsonObj; 211bae44755Sopenharmony_ci} 212