• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "syscap_tool.h"
17 
18 #include <arpa/inet.h>
19 #include <errno.h>
20 #include <libgen.h>
21 #include <securec.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 
30 #include "hilog/log.h"
31 
32 const int32_t OK = 0;
33 const int32_t ERROR = -1;
34 const int32_t API_VERSION_TYPE = 1;
35 const int32_t APP_SYSCAP_TYPE = 2;
36 const int32_t SYSCAP_PREFIX_NAME_LEN = 18;
37 const char SYSCAP_PREFIX_NAME[] = "SystemCapability.";
38 
39 typedef struct RequiredProductCompatibilityIDHead {
40     uint16_t apiVersion : 15;
41     uint16_t apiVersionType : 1;
42 } RPCIDHead;
43 
FreeContextBuffer(char * contextBuffer)44 static void FreeContextBuffer(char *contextBuffer)
45 {
46     (void)free(contextBuffer);
47 }
48 
GetFileContext(char * inputFile,char ** contextBufPtr,uint32_t * bufferLen)49 static int32_t GetFileContext(char *inputFile, char **contextBufPtr, uint32_t *bufferLen)
50 {
51     if (inputFile == NULL) {
52         return ERROR;
53     }
54     int32_t ret;
55     FILE *fp = NULL;
56     struct stat statBuf;
57     char *contextBuffer = NULL;
58     ret = stat(inputFile, &statBuf);
59     if (ret != OK) {
60         HILOG_ERROR(LOG_CORE, "get file(%s) st_mode failed, errno = %d\n", inputFile, errno);
61         return ret;
62     }
63 
64     if (!(statBuf.st_mode & S_IRUSR)) {
65         HILOG_ERROR(LOG_CORE, "don't have permission to read the file(%s)\n", inputFile);
66         return ERROR;
67     }
68 
69     contextBuffer = (char *)malloc(statBuf.st_size + 1);
70     if (contextBuffer == NULL) {
71         HILOG_ERROR(LOG_CORE, "malloc contextBuffer failed, size = %d, errno = %d\n",
72                     (int32_t)statBuf.st_size + 1, errno);
73         return ERROR;
74     }
75 
76     fp = fopen(inputFile, "r");
77     if (fp == NULL) {
78         HILOG_ERROR(LOG_CORE, "open file(%s) failed, errno = %d\n", inputFile, errno);
79         FreeContextBuffer(contextBuffer);
80         return ERROR;
81     }
82 
83     size_t res = fread(contextBuffer, statBuf.st_size, 1, fp);
84     if (res != 1) {
85         HILOG_ERROR(LOG_CORE, "read file(%s) failed, errno = %d\n", inputFile, errno);
86         FreeContextBuffer(contextBuffer);
87         (void)fclose(fp);
88         return ERROR;
89     }
90 
91     contextBuffer[statBuf.st_size] = '\0';
92     (void)fclose(fp);
93     *contextBufPtr = contextBuffer;
94     *bufferLen = statBuf.st_size + 1;
95     return OK;
96 }
97 
RPCIDStreamDecodeToBuffer(char * contextBuffer,uint32_t bufferLen,char ** syscapSetBuf,uint32_t * syscapSetLength)98 int32_t RPCIDStreamDecodeToBuffer(
99     char *contextBuffer, uint32_t bufferLen, char **syscapSetBuf, uint32_t *syscapSetLength)
100 {
101     errno_t ret;
102     char *contextBufferTail = NULL;
103     char *syscapBuf = NULL;
104     uint32_t syscapBufLen;
105     uint16_t sysCaptype, sysCapLength;
106     RPCIDHead *headPtr = NULL;
107     char *sysCapArrayPtr = NULL;
108     *syscapSetBuf = NULL;
109     *syscapSetLength = 0;
110     if (contextBuffer == NULL) {
111         HILOG_ERROR(LOG_CORE, "input buffer is NULL\n");
112         return ERROR;
113     }
114 
115     contextBufferTail = contextBuffer + bufferLen;
116     sysCapArrayPtr = contextBuffer + sizeof(RPCIDHead) + APP_SYSCAP_TYPE * sizeof(uint16_t);
117     if (contextBufferTail <= sysCapArrayPtr) {
118         HILOG_ERROR(LOG_CORE, "format error:sysCapArray head over to buffer\n");
119         return ERROR;
120     }
121 
122     headPtr = (RPCIDHead *)contextBuffer;
123     if (headPtr->apiVersionType != API_VERSION_TYPE) {
124         HILOG_ERROR(LOG_CORE, "format error:apiVersionType is invaild\n");
125         return ERROR;
126     }
127 
128     sysCaptype = ntohs(*(uint16_t *)(sysCapArrayPtr - APP_SYSCAP_TYPE * sizeof(uint16_t)));
129     if (sysCaptype != APP_SYSCAP_TYPE) {
130         HILOG_ERROR(LOG_CORE, "format error:sysCaptype is invaild\n");
131         return ERROR;
132     }
133 
134     sysCapLength = ntohs(*(uint16_t *)(sysCapArrayPtr - sizeof(uint16_t)));
135     if (contextBufferTail < sysCapArrayPtr + sysCapLength) {
136         HILOG_ERROR(LOG_CORE, "format error:sysCapArray tail over to buffer\n");
137         return ERROR;
138     }
139 
140     if ((sysCapLength % SINGLE_FEAT_LENGTH) != 0) {
141         HILOG_ERROR(LOG_CORE, "format error:sysCapLength is invalid\n");
142         return ERROR;
143     }
144 
145     syscapBufLen = sysCapLength / SINGLE_FEAT_LENGTH * SINGLE_SYSCAP_LENGTH;
146     syscapBuf = (char *)malloc(syscapBufLen);
147     if (syscapBuf == NULL) {
148         HILOG_ERROR(LOG_CORE, "malloc syscapBuf failed, size = %u, errno = %d\n", syscapBufLen, errno);
149         return ERROR;
150     }
151 
152     (void)memset_s(syscapBuf, syscapBufLen, 0, syscapBufLen);
153     char *bufferPtr = syscapBuf;
154     for (int32_t i = 0; i < ((int32_t)sysCapLength / SINGLE_FEAT_LENGTH); i++) {
155         if (*(sysCapArrayPtr + (i + 1) * SINGLE_FEAT_LENGTH - 1) != '\0') {
156             HILOG_ERROR(LOG_CORE, "prase failed, format is invaild, in line %d\n", __LINE__);
157             (void)free(syscapBuf);
158             return ERROR;
159         }
160 
161         ret = memcpy_s(bufferPtr, SINGLE_SYSCAP_LENGTH, SYSCAP_PREFIX_NAME, SYSCAP_PREFIX_NAME_LEN);
162         if (ret != EOK) {
163             HILOG_ERROR(LOG_CORE, "context of \"os\" array is invaild\n");
164             (void)free(syscapBuf);
165             return ERROR;
166         }
167 
168         ret = strncat_s(bufferPtr, SINGLE_SYSCAP_LENGTH, sysCapArrayPtr + i * SINGLE_FEAT_LENGTH, SINGLE_FEAT_LENGTH);
169         if (ret != EOK) {
170             HILOG_ERROR(LOG_CORE, "strncat_s failed, (%s, %d, %s, %d)\n", bufferPtr, SINGLE_SYSCAP_LENGTH,
171                         sysCapArrayPtr + i * SINGLE_FEAT_LENGTH, SINGLE_FEAT_LENGTH);
172             (void)free(syscapBuf);
173             return ERROR;
174         }
175 
176         bufferPtr += SINGLE_SYSCAP_LENGTH;
177     }
178 
179     *syscapSetBuf = syscapBuf;
180     *syscapSetLength = syscapBufLen;
181     return OK;
182 }
183 
RPCIDFileDecodeToBuffer(char * inputFile,char ** syscapSetBuf,uint32_t * syscapSetLength)184 int32_t RPCIDFileDecodeToBuffer(char *inputFile, char **syscapSetBuf, uint32_t *syscapSetLength)
185 {
186     int32_t ret;
187     char *contextBuffer = NULL;
188     uint32_t bufferLen;
189     ret = GetFileContext(inputFile, &contextBuffer, &bufferLen);
190     if (ret != 0) {
191         HILOG_ERROR(LOG_CORE, "GetFileContext failed, input file : %s\n", inputFile);
192         return ret;
193     }
194 
195     ret = RPCIDStreamDecodeToBuffer(contextBuffer, bufferLen, syscapSetBuf, syscapSetLength);
196     FreeContextBuffer(contextBuffer);
197     return ret;
198 }
199 
FreeDecodeBuffer(char * syscapSetBuf)200 void FreeDecodeBuffer(char *syscapSetBuf)
201 {
202     (void)free(syscapSetBuf);
203 }
204