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