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