1 /*
2 * Copyright (c) 2022-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 <arpa/inet.h>
17 #include <fcntl.h>
18 #include <stdbool.h>
19 #include <string.h>
20
21 #include "client_trans_proxy_file_common.h"
22
23 #include "securec.h"
24 #include "softbus_adapter_file.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_adapter_timer.h"
27 #include "softbus_def.h"
28 #include "softbus_errcode.h"
29 #include "trans_log.h"
30
31 #pragma pack(push, 1)
32 struct FileListItem {
33 uint32_t index;
34 uint32_t fileNameLength;
35 char fileName[0];
36 };
37 #pragma pack(pop)
38
IsPathValid(char * filePath)39 bool IsPathValid(char *filePath)
40 {
41 if (filePath == NULL) {
42 TRANS_LOGE(TRANS_FILE, "filePath is null");
43 return false;
44 }
45 if ((strlen(filePath) == 0) || (strlen(filePath) > (MAX_FILE_PATH_NAME_LEN - 1))) {
46 TRANS_LOGE(TRANS_FILE, "filePathSize is wrong. filePathSize=%{public}d", (int32_t)strlen(filePath));
47 return false;
48 }
49
50 if (filePath[strlen(filePath) - 1] == PATH_SEPARATOR) {
51 TRANS_LOGE(TRANS_FILE, "filePath is end with '/' ");
52 return false;
53 }
54 return true;
55 }
56
GetAndCheckRealPath(const char * filePath,char * absPath)57 int32_t GetAndCheckRealPath(const char *filePath, char *absPath)
58 {
59 if ((filePath == NULL) || (absPath == NULL)) {
60 TRANS_LOGE(TRANS_FILE, "invalid param");
61 return SOFTBUS_INVALID_PARAM;
62 }
63
64 if (SoftBusRealPath(filePath, absPath) == NULL) {
65 TRANS_LOGE(TRANS_FILE, "softbus realpath failed");
66 return SOFTBUS_FILE_ERR;
67 }
68
69 int32_t pathLength = (int32_t)(strlen(absPath));
70 if (pathLength > (MAX_FILE_PATH_NAME_LEN - 1)) {
71 TRANS_LOGE(TRANS_FILE, "pathLength is too large. pathLength=%{public}d", pathLength);
72 return SOFTBUS_INVALID_PARAM;
73 }
74 return SOFTBUS_OK;
75 }
76
CheckDestFilePathValid(const char * destFile)77 bool CheckDestFilePathValid(const char *destFile)
78 {
79 if (destFile == NULL) {
80 TRANS_LOGE(TRANS_FILE, "destFile is null");
81 return false;
82 }
83 int32_t len = (int32_t)(strlen(destFile));
84 if ((len == 0) || (len > MAX_FILE_PATH_NAME_LEN)) {
85 TRANS_LOGE(TRANS_FILE, "destFile path len is invalid");
86 return false;
87 }
88
89 if (strstr(destFile, "..") != NULL) {
90 TRANS_LOGE(TRANS_FILE, "dest path is not canonical form");
91 return false;
92 }
93 return true;
94 }
95
FrameIndexToType(uint64_t index,uint64_t frameNumber)96 int32_t FrameIndexToType(uint64_t index, uint64_t frameNumber)
97 {
98 if (index == FRAME_NUM_0 || frameNumber == FRAME_NUM_0) {
99 return TRANS_SESSION_FILE_FIRST_FRAME;
100 }
101 if ((index == FRAME_NUM_1) && (frameNumber == FRAME_NUM_2)) {
102 return TRANS_SESSION_FILE_ONLYONE_FRAME;
103 }
104 if (index == (frameNumber - 1)) {
105 return TRANS_SESSION_FILE_LAST_FRAME;
106 }
107 return TRANS_SESSION_FILE_ONGOINE_FRAME;
108 }
109
110 // crc校验表
111 static const unsigned char g_auchCRCHi[] = {
112 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
113 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
114 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
115 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80,
116 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
117 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
118 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
119 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
120 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
121 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01,
122 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
123 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80,
124 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
125 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01,
126 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
127 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80,
128 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
129 0x81, 0x40};
130
131 static const unsigned char g_auchCRCLo[] = {
132 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5,
133 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B,
134 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE,
135 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6,
136 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2,
137 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F,
138 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB,
139 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25,
140 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
141 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C,
142 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8,
143 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D,
144 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73,
145 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57,
146 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A,
147 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E,
148 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86,
149 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40};
150
151 // 校验函数
RTU_CRC(const unsigned char * puchMsg,uint16_t usDataLen)152 uint16_t RTU_CRC(const unsigned char *puchMsg, uint16_t usDataLen)
153 {
154 unsigned char uchCRCHi = 0xFF;
155 unsigned char uchCRCLo = 0xFF;
156 uint16_t dataLen = usDataLen;
157 const uint8_t *data = puchMsg;
158 while (dataLen--) {
159 unsigned char uIndex = uchCRCLo ^ (*data++);
160 uchCRCLo = uchCRCHi ^ g_auchCRCHi[uIndex];
161 uchCRCHi = g_auchCRCLo[uIndex];
162 }
163 return ((uchCRCHi << BIT_BYTE_NUM) | uchCRCLo);
164 }
165
TransGetFileName(const char * path)166 const char *TransGetFileName(const char *path)
167 {
168 if (path == NULL) {
169 TRANS_LOGE(TRANS_FILE, "input is NULL!");
170 return NULL;
171 }
172 size_t pathLength = strlen(path);
173 if (pathLength == 0) {
174 TRANS_LOGE(TRANS_FILE, "input length is 0!");
175 return NULL;
176 }
177 if (path[pathLength - 1] == SOFTBUS_PATH_SEPRATOR) {
178 TRANS_LOGE(TRANS_FILE, "input is dir path!");
179 return NULL;
180 }
181
182 int i;
183 for (i = (int)(pathLength - 1); i >= 0; i--) {
184 if (path[i] == SOFTBUS_PATH_SEPRATOR) {
185 i++;
186 break;
187 }
188 if (i == 0) {
189 break;
190 }
191 }
192 return path + i;
193 }
194
FileListToBuffer(const char ** destFile,uint32_t fileCnt,FileListBuffer * outbufferInfo)195 int32_t FileListToBuffer(const char **destFile, uint32_t fileCnt, FileListBuffer *outbufferInfo)
196 {
197 if (destFile == NULL || outbufferInfo == NULL || fileCnt == 0) {
198 TRANS_LOGE(TRANS_FILE, "invalid param");
199 return SOFTBUS_INVALID_PARAM;
200 }
201 int32_t errCode = SOFTBUS_OK;
202 uint32_t totalLength = 0;
203 uint32_t offset = 0;
204 for (uint32_t i = 0; i < fileCnt; i++) {
205 size_t fileNameLength = strlen(destFile[i]);
206 if (fileNameLength == 0 || fileNameLength > MAX_FILE_PATH_NAME_LEN) {
207 TRANS_LOGE(TRANS_FILE, "bad file name at index=%{public}" PRIu32, i);
208 return SOFTBUS_INVALID_PARAM;
209 } else {
210 totalLength += fileNameLength;
211 }
212 }
213
214 size_t bufferSize = totalLength + (sizeof(struct FileListItem) * fileCnt);
215 uint8_t *buffer = (uint8_t *)SoftBusCalloc(bufferSize);
216 if (buffer == NULL) {
217 TRANS_LOGE(TRANS_FILE, "calloc filelist failed");
218 return SOFTBUS_MALLOC_ERR;
219 }
220
221 for (uint32_t index = 0; index < fileCnt; index++) {
222 uint32_t fileNameSize = strlen(destFile[index]);
223 struct FileListItem *fileItem = (struct FileListItem *)(buffer + offset);
224 fileItem->index = htonl(index);
225 fileItem->fileNameLength = htonl(fileNameSize);
226 offset += sizeof(struct FileListItem);
227
228 // note: no \0 here
229 if (memcpy_s(fileItem->fileName, bufferSize - offset, destFile[index], fileNameSize) != EOK) {
230 TRANS_LOGE(TRANS_FILE, "copy file name failed!");
231 errCode = SOFTBUS_MEM_ERR;
232 break;
233 }
234
235 offset += fileNameSize;
236 }
237
238 if (errCode != SOFTBUS_OK) {
239 SoftBusFree(buffer);
240 return errCode;
241 }
242
243 outbufferInfo->buffer = buffer;
244 outbufferInfo->bufferSize = offset;
245 return SOFTBUS_OK;
246 }
247
BufferToFileList(uint8_t * buffer,uint32_t bufferSize,int32_t * fileCount)248 char *BufferToFileList(uint8_t *buffer, uint32_t bufferSize, int32_t *fileCount)
249 {
250 if ((buffer == NULL) || (fileCount == NULL) || bufferSize < sizeof(struct FileListItem)) {
251 TRANS_LOGE(TRANS_FILE, "input invalid");
252 return NULL;
253 }
254 char *firstFile = (char *)SoftBusCalloc(MAX_FILE_PATH_NAME_LEN + 1);
255 if (firstFile == NULL) {
256 TRANS_LOGE(TRANS_FILE, "calloc fail");
257 return NULL;
258 }
259 uint32_t offset = 0;
260 int32_t count = 0;
261 while (offset < bufferSize - sizeof(struct FileListItem)) {
262 const struct FileListItem *fileListItem = (const struct FileListItem *)(buffer + offset);
263 offset += sizeof(struct FileListItem);
264
265 uint32_t fileNameLength = ntohl(fileListItem->fileNameLength);
266 if (fileNameLength > bufferSize - offset || fileNameLength > MAX_FILE_PATH_NAME_LEN) {
267 TRANS_LOGE(TRANS_FILE, "invalid fileLength");
268 SoftBusFree(firstFile);
269 return NULL;
270 }
271 /* only output first file path */
272 if (count == 0) {
273 // note: no \0 in buffer
274 if (memcpy_s(firstFile, MAX_FILE_PATH_NAME_LEN, fileListItem->fileName, fileNameLength) != EOK) {
275 SoftBusFree(firstFile);
276 return NULL;
277 }
278 }
279 offset += fileNameLength;
280 count++;
281 }
282
283 *fileCount = count;
284 return firstFile;
285 }
286
FileLock(int32_t fd,int32_t type,bool isBlock)287 int32_t FileLock(int32_t fd, int32_t type, bool isBlock)
288 {
289 if (fd < 0) {
290 TRANS_LOGE(TRANS_FILE, "[FileLock] invalid file handle");
291 return SOFTBUS_INVALID_PARAM;
292 }
293 struct flock fl = {0};
294 fl.l_type = (short)(type == SOFTBUS_F_RDLCK ? F_RDLCK : F_WRLCK);
295 fl.l_whence = SEEK_SET;
296 fl.l_start = 0;
297 fl.l_len = 0;
298 int32_t ret = fcntl(fd, isBlock ? F_SETLKW : F_SETLK, &fl);
299 if (ret != 0 && !isBlock) {
300 TRANS_LOGE(TRANS_FILE, "lock file is blocked, file busy errno=%{public}d", errno);
301 return SOFTBUS_FILE_BUSY;
302 }
303 TRANS_LOGE(TRANS_FILE, "file locked! ret=%{public}d, errno=%{public}d", ret, errno);
304 return SOFTBUS_OK;
305 }
306
TryFileLock(int32_t fd,int32_t type,int32_t retryTimes)307 int32_t TryFileLock(int32_t fd, int32_t type, int32_t retryTimes)
308 {
309 #define TRY_LOCK_WAIT_TIME 100
310 int32_t errCode;
311 while (retryTimes > 0) {
312 errCode = FileLock(fd, type, false);
313 if (errCode == SOFTBUS_OK) {
314 return SOFTBUS_OK;
315 } else if (errCode == SOFTBUS_FILE_BUSY) {
316 --retryTimes;
317 SoftBusSleepMs(TRY_LOCK_WAIT_TIME);
318 continue;
319 } else {
320 return SOFTBUS_FILE_ERR;
321 }
322 }
323 return SOFTBUS_FILE_BUSY;
324 }
325
FileUnLock(int32_t fd)326 int32_t FileUnLock(int32_t fd)
327 {
328 if (fd < 0) {
329 TRANS_LOGE(TRANS_FILE, "[FileUnLock] invalid file handle");
330 return SOFTBUS_OK;
331 }
332 struct flock fl = {0};
333 fl.l_type = F_UNLCK;
334 fl.l_whence = SEEK_SET;
335 fl.l_start = 0;
336 fl.l_len = 0;
337 if (fcntl(fd, F_SETLK, &fl) < 0) {
338 TRANS_LOGE(TRANS_FILE, "unLock file failed, errno=%{public}d", errno);
339 return SOFTBUS_FILE_ERR;
340 }
341 TRANS_LOGE(TRANS_FILE, "unLock file success");
342 return SOFTBUS_OK;
343 }