1 /*
2 * Copyright (C) 2021 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 "nstackx_file_list.h"
17 #include "nstackx_error.h"
18 #include "nstackx_util.h"
19 #include "nstackx_dfile_log.h"
20 #include "nstackx_dfile_frame.h"
21 #include "securec.h"
22
23 #define TAG "nStackXDFile"
24
FileListAllFileNameAcked(const FileList * fileList)25 uint8_t FileListAllFileNameAcked(const FileList *fileList)
26 {
27 uint32_t i;
28 if ((fileList->userDataFlag & NSTACKX_DFILE_HEADER_FRAME_USER_DATA_FLAG) &&
29 !(fileList->userDataFlag & NSTACKX_FLAGS_USER_DATA_ACK)) {
30 DFILE_LOGI(TAG, "user data not acked");
31 return NSTACKX_FALSE;
32 }
33
34 if (fileList->tarFlag == NSTACKX_TRUE) {
35 if (!(fileList->list[0].flags & NSTACKX_FLAGS_FILE_NAME_ACK)) {
36 DFILE_LOGI(TAG, "file name 1 is not ACKED yet");
37 return NSTACKX_FALSE;
38 } else {
39 return NSTACKX_TRUE;
40 }
41 }
42
43 for (i = 0; i < fileList->num; i++) {
44 if (!(fileList->list[i].flags & NSTACKX_FLAGS_FILE_NAME_ACK)) {
45 DFILE_LOGI(TAG, "file name id %u is not ACKED yet", i + 1);
46 return NSTACKX_FALSE;
47 }
48 }
49
50 return NSTACKX_TRUE;
51 }
52
FileListAllFileNameReceived(const FileList * fileList)53 uint8_t FileListAllFileNameReceived(const FileList *fileList)
54 {
55 uint32_t i;
56
57 if (!fileList->num) {
58 return NSTACKX_FALSE;
59 }
60
61 if ((fileList->userDataFlag & NSTACKX_DFILE_HEADER_FRAME_USER_DATA_FLAG) &&
62 !(fileList->userDataFlag & NSTACKX_FLAGS_FILE_NAME_RECEIVED)) {
63 return NSTACKX_FALSE;
64 }
65
66 if (fileList->tarFlag == NSTACKX_TRUE) {
67 if (!(fileList->list[0].flags & NSTACKX_FLAGS_FILE_NAME_RECEIVED)) {
68 DFILE_LOGI(TAG, "file name id 1 is not RECEIVED yet");
69 return NSTACKX_FALSE;
70 } else {
71 return NSTACKX_TRUE;
72 }
73 }
74
75 for (i = 0; i < fileList->num; i++) {
76 if (!(fileList->list[i].flags & NSTACKX_FLAGS_FILE_NAME_RECEIVED)) {
77 DFILE_LOGI(TAG, "file name id %u is not RECEIVED yet", i + 1);
78 return NSTACKX_FALSE;
79 }
80 }
81
82 return NSTACKX_TRUE;
83 }
84
FileListAllFileReceived(const FileList * fileList)85 uint8_t FileListAllFileReceived(const FileList *fileList)
86 {
87 uint32_t i;
88
89 if (fileList->tarFlag == NSTACKX_TRUE) {
90 if (!(fileList->list[0].flags & NSTACKX_FLAGS_FILE_RECEIVE_SUCCESS)) {
91 return NSTACKX_FALSE;
92 } else {
93 return NSTACKX_TRUE;
94 }
95 }
96
97 for (i = 0; i < fileList->num; i++) {
98 if (!(fileList->list[i].flags & NSTACKX_FLAGS_FILE_RECEIVE_SUCCESS)) {
99 return NSTACKX_FALSE;
100 }
101 }
102
103 return NSTACKX_TRUE;
104 }
105
FileListSetSendFileList(FileList * fileList,FileListInfo * fileListInfo)106 int32_t FileListSetSendFileList(FileList *fileList, FileListInfo *fileListInfo)
107 {
108 uint16_t i;
109 FileListEntry *fileListEntry = NULL;
110 FileListEntry *entryList = NULL;
111 int32_t ret;
112
113 if (fileListInfo->files == NULL || fileListInfo->fileNum == 0 ||
114 fileListInfo->fileNum > NSTACKX_DFILE_MAX_FILE_NUM) {
115 DFILE_LOGE(TAG, "invalid input");
116 return NSTACKX_EINVAL;
117 }
118
119 if (fileList->list != NULL) {
120 DFILE_LOGE(TAG, "invalid fileList->list");
121 return NSTACKX_EFAILED;
122 }
123
124 entryList = calloc(fileListInfo->fileNum, sizeof(FileListEntry));
125 if (entryList == NULL) {
126 DFILE_LOGE(TAG, "entryList calloc NULL");
127 return NSTACKX_ENOMEM;
128 }
129
130 for (i = 0; i < fileListInfo->fileNum; i++) {
131 fileListEntry = &entryList[i];
132 /* Reuse the input memory. */
133 fileListEntry->fullFileName = fileListInfo->files[i];
134 if (fileListInfo->remotePath != NULL) {
135 fileListEntry->remotePath = fileListInfo->remotePath[i];
136 }
137 ret = GetFileName(fileListEntry->fullFileName, fileListEntry->fileName, sizeof(fileListEntry->fileName));
138 if (ret != NSTACKX_EOK) {
139 DFILE_LOGE(TAG, "GetFileName error: %d", ret);
140 goto L_FIN;
141 }
142 ret = GetTargetFileSize(fileListEntry->fullFileName, &fileListEntry->fileSize);
143 if ((ret != NSTACKX_EOK) || (fileListEntry->fileSize > NSTACKX_MAX_FILE_SIZE)) {
144 DFILE_LOGE(TAG, "GetTargetFileSize error: %d", ret);
145 goto L_FIN;
146 }
147 if (fileListInfo->vtransFlag) {
148 fileListEntry->startOffset = fileListInfo->startOffset[i];
149 fileListEntry->fileSize = fileListInfo->fileSize[i];
150 }
151 fileListEntry->fileId = i + 1;
152 }
153
154 fileList->list = entryList;
155 fileList->num = fileListInfo->fileNum;
156 return NSTACKX_EOK;
157
158 L_FIN:
159 /* Something wrong, clear file list */
160 free(entryList);
161 entryList = NULL;
162 return ret;
163 }
164
FileListSetNum(FileList * fileList,uint32_t fileNum)165 int32_t FileListSetNum(FileList *fileList, uint32_t fileNum)
166 {
167 if (fileNum == 0 || fileNum > NSTACKX_DFILE_MAX_FILE_NUM) {
168 return NSTACKX_EINVAL;
169 }
170
171 if (fileList->list != NULL) {
172 return NSTACKX_EOK;
173 }
174
175 fileList->list = calloc(fileNum, sizeof(FileListEntry));
176 if (fileList->list == NULL) {
177 return NSTACKX_ENOMEM;
178 }
179 fileList->num = fileNum;
180 return NSTACKX_EOK;
181 }
182
FileListAddFile(FileList * fileList,uint16_t fileId,const uint8_t * fileName,size_t fileNameLength,uint64_t fileSize)183 int32_t FileListAddFile(FileList *fileList, uint16_t fileId, const uint8_t *fileName, size_t fileNameLength,
184 uint64_t fileSize)
185 {
186 FileListEntry *fileListEntry = NULL;
187
188 if (fileList->list == NULL || fileList->num == 0) {
189 return NSTACKX_EINVAL;
190 }
191
192 if (fileId == 0 || fileId > fileList->num) {
193 return NSTACKX_EINVAL;
194 }
195
196 if (fileNameLength + 1 > NSTACKX_MAX_REMOTE_PATH_LEN) {
197 return NSTACKX_EINVAL;
198 }
199
200 if (fileSize > NSTACKX_MAX_FILE_SIZE) {
201 return NSTACKX_EINVAL;
202 }
203
204 fileListEntry = &fileList->list[fileId - 1];
205
206 if (fileListEntry->flags & NSTACKX_FLAGS_FILE_NAME_RECEIVED) {
207 /* duplicate frame */
208 return NSTACKX_EOK;
209 }
210
211 if (memcpy_s(fileListEntry->fileName, sizeof(fileListEntry->fileName) - 1, fileName, fileNameLength) != EOK) {
212 return NSTACKX_EFAILED;
213 }
214 fileListEntry->fileId = fileId;
215 fileListEntry->fileSize = fileSize;
216 fileListEntry->flags |= NSTACKX_FLAGS_FILE_NAME_RECEIVED;
217 if (fileSize == 0) {
218 fileListEntry->flags |= NSTACKX_FLAGS_LAST_BLOCK_RECEIVED;
219 }
220
221 return NSTACKX_EOK;
222 }
223
ParsePackedDFileUserData(const uint8_t * buf,size_t userDataLength,uint16_t * pathType,char ** userData,uint8_t flag)224 static int32_t ParsePackedDFileUserData(const uint8_t *buf, size_t userDataLength, uint16_t *pathType, char **userData,
225 uint8_t flag)
226 {
227 char *validUserData = NULL;
228 uint16_t userDataStrLen;
229 const UserDataUnit *userDataUnit = NULL;
230 if (userDataLength < sizeof(UserDataUnit)) {
231 DFILE_LOGE(TAG, "userDataLength is too small");
232 return NSTACKX_EFAILED;
233 }
234 userDataUnit = (UserDataUnit *)buf;
235 *pathType = userDataUnit->pathType;
236 if (*pathType == 0) {
237 DFILE_LOGE(TAG, "path type is 0");
238 return NSTACKX_EFAILED;
239 }
240 if (!(flag & NSTACKX_DFILE_HEADER_FRAME_USER_DATA_FLAG)) {
241 return NSTACKX_EOK;
242 }
243 userDataStrLen = (uint16_t)(userDataLength - sizeof(UserDataUnit));
244 validUserData = (char *)calloc(userDataStrLen + 1, 1);
245 if (validUserData == NULL) {
246 return NSTACKX_EFAILED;
247 }
248 if (userDataStrLen > 0 &&
249 memcpy_s(validUserData, userDataStrLen + 1, userDataUnit->userData, userDataStrLen) != EOK) {
250 free(validUserData);
251 return NSTACKX_EFAILED;
252 }
253 *userData = validUserData;
254 return NSTACKX_EOK;
255 }
256
FileListAddUserData(FileList * fileList,const uint8_t * userData,size_t userDataLength,uint8_t flag)257 int32_t FileListAddUserData(FileList *fileList, const uint8_t *userData, size_t userDataLength, uint8_t flag)
258 {
259 if (fileList->userDataFlag & NSTACKX_FLAGS_FILE_NAME_RECEIVED) {
260 /* duplicate frame */
261 return NSTACKX_EOK;
262 }
263 if (flag & NSTACKX_DFILE_HEADER_FRAME_PATH_TYPE_FLAG) {
264 if (ParsePackedDFileUserData(userData, userDataLength, &fileList->pathType, &fileList->userData, flag) !=
265 NSTACKX_EOK) {
266 DFILE_LOGE(TAG, "ParsePackedDFileUserData failed");
267 }
268 } else if (flag & NSTACKX_DFILE_HEADER_FRAME_USER_DATA_FLAG) {
269 fileList->userData = calloc(1, userDataLength + 1);
270 if (fileList->userData == NULL) {
271 return NSTACKX_ENOMEM;
272 }
273 if (userDataLength) {
274 if (memcpy_s(fileList->userData, userDataLength + 1, userData, userDataLength) != EOK) {
275 free(fileList->userData);
276 fileList->userData = NULL;
277 return NSTACKX_EFAILED;
278 }
279 }
280 } else {
281 DFILE_LOGE(TAG, "invalid flag %2X", flag);
282 return NSTACKX_EFAILED;
283 }
284 fileList->userDataFlag |= NSTACKX_FLAGS_FILE_NAME_RECEIVED;
285 return NSTACKX_EOK;
286 }
287
FileListGetNames(FileList * fileList,char * files[],uint32_t * fileNum,uint8_t fileNameType)288 void FileListGetNames(FileList *fileList, char *files[], uint32_t *fileNum, uint8_t fileNameType)
289 {
290 uint32_t i;
291
292 for (i = 0; i < fileList->num && i < *fileNum; i++) {
293 /* Soft copy */
294 if (fileList->tarFlag == NSTACKX_TRUE) {
295 files[i] = fileList->tarFile;
296 *fileNum = 1;
297 return;
298 }
299 if (fileNameType == NOTICE_FULL_FILE_NAME_TYPE) {
300 files[i] = fileList->list[i].fullFileName;
301 } else if (fileNameType == NOTICE_FILE_NAME_TYPE) {
302 files[i] = fileList->list[i].fileName;
303 } else {
304 DFILE_LOGE(TAG, "invalid fileName type %u", fileNameType);
305 break;
306 }
307 }
308 *fileNum = i;
309 }
310
FileListGetReceivedFileIdList(FileList * fileList,uint16_t fileIdList[],uint32_t * fileNum)311 void FileListGetReceivedFileIdList(FileList *fileList, uint16_t fileIdList[], uint32_t *fileNum)
312 {
313 uint32_t i;
314 uint32_t count = 0;
315
316 for (i = 0; i < fileList->num && i < *fileNum; i++) {
317 if (fileList->list[i].flags & NSTACKX_FLAGS_FILE_RECEIVE_SUCCESS) {
318 fileIdList[count] = fileList->list[i].fileId;
319 count++;
320 }
321 }
322 *fileNum = count;
323 }
324
FileListGetFilesByFlag(FileList * fileList,uint8_t flags,char * files[],uint32_t * fileNum,uint8_t fileNameType)325 static void FileListGetFilesByFlag(FileList *fileList, uint8_t flags, char *files[], uint32_t *fileNum,
326 uint8_t fileNameType)
327 {
328 uint32_t i;
329 uint32_t count = 0;
330
331 for (i = 0; i < fileList->num && i < *fileNum; i++) {
332 if (fileList->list[i].flags & flags) {
333 if (fileList->tarFlag == NSTACKX_TRUE) {
334 files[count] = fileList->tarFile;
335 count++;
336 break;
337 }
338 if (fileNameType == NOTICE_FULL_FILE_NAME_TYPE) {
339 files[count] = fileList->list[i].fullFileName;
340 count++;
341 } else if (fileNameType == NOTICE_FILE_NAME_TYPE) {
342 files[count] = fileList->list[i].fileName;
343 count++;
344 } else {
345 DFILE_LOGE(TAG, "invalid fileName type %u", fileNameType);
346 break;
347 }
348 } else {
349 DFILE_LOGE(TAG, "the %uth file is not with target flag %2X", i, flags);
350 }
351 }
352 *fileNum = count;
353 }
354
FileListGetReceivedFiles(FileList * fileList,char * files[],uint32_t * fileNum)355 void FileListGetReceivedFiles(FileList *fileList, char *files[], uint32_t *fileNum)
356 {
357 FileListGetFilesByFlag(fileList, NSTACKX_FLAGS_FILE_RECEIVE_SUCCESS, files, fileNum, NOTICE_FILE_NAME_TYPE);
358 }
359
FileListGetSentFiles(FileList * fileList,char * files[],uint32_t * fileNum)360 void FileListGetSentFiles(FileList *fileList, char *files[], uint32_t *fileNum)
361 {
362 FileListGetFilesByFlag(fileList, NSTACKX_FLAGS_FILE_SEND_SUCCESS, files, fileNum, fileList->noticeFileNameType);
363 }
364
FileListSetFileNameAcked(FileList * fileList,uint16_t fileId)365 void FileListSetFileNameAcked(FileList *fileList, uint16_t fileId)
366 {
367 if (fileId == 1 || fileId == fileList->num) {
368 DFILE_LOGI(TAG, "set file id: %u acked", fileId);
369 }
370 if (fileId == 0) {
371 fileList->userDataFlag |= NSTACKX_FLAGS_USER_DATA_ACK;
372 } else {
373 (fileList)->list[(fileId) - 1].flags |= NSTACKX_FLAGS_FILE_NAME_ACK;
374 }
375 }
376
FileListGetFileNameAcked(FileList * fileList,uint16_t fileId)377 uint8_t FileListGetFileNameAcked(FileList *fileList, uint16_t fileId)
378 {
379 if (fileId == 0) {
380 return (fileList->userDataFlag & NSTACKX_FLAGS_USER_DATA_ACK);
381 } else {
382 return ((fileList)->list[(fileId) - 1].flags & NSTACKX_FLAGS_FILE_NAME_ACK);
383 }
384 }
385
FileListCreate(void)386 FileList *FileListCreate(void)
387 {
388 FileList *fileList = NULL;
389
390 fileList = malloc(sizeof(FileList));
391 if (fileList == NULL) {
392 return NULL;
393 }
394 (void)memset_s(fileList, sizeof(FileList), 0, sizeof(FileList));
395
396 return fileList;
397 }
398
FileListDestroy(FileList * fileList)399 void FileListDestroy(FileList *fileList)
400 {
401 uint32_t i;
402 FileListEntry *fileListEntry = NULL;
403 if (fileList->userData != NULL) {
404 free(fileList->userData);
405 fileList->userData = NULL;
406 }
407
408 if (fileList->packedUserData != NULL) {
409 free(fileList->packedUserData);
410 fileList->packedUserData = NULL;
411 }
412
413 if (fileList->tarFile != NULL) {
414 free(fileList->tarFile);
415 fileList->tarFile = NULL;
416 }
417
418 for (i = 0; i < fileList->num; i++) {
419 fileListEntry = &fileList->list[i];
420 free(fileListEntry->fullFileName);
421 fileListEntry->fullFileName = NULL;
422 if (fileListEntry->remotePath != NULL) {
423 free(fileListEntry->remotePath);
424 fileListEntry->remotePath = NULL;
425 }
426 }
427 free(fileList->list);
428 free(fileList);
429 fileList = NULL;
430 }
431
GetFilesTotalBytes(FileList * fileList)432 uint64_t GetFilesTotalBytes(FileList *fileList)
433 {
434 uint64_t ret = 0;
435 uint32_t i;
436 if (fileList == NULL) {
437 return ret;
438 }
439 for (i = 0; i < fileList->num; i++) {
440 ret += fileList->list[i].fileSize;
441 }
442 return ret;
443 }
444
PreparePackedDFileUserData(uint16_t pathType,const char * userData,uint16_t * packedLen)445 static uint8_t *PreparePackedDFileUserData(uint16_t pathType, const char *userData, uint16_t *packedLen)
446 {
447 UserDataUnit *userDataUnit = NULL;
448 uint32_t userDataLen = 0;
449 uint16_t packeUserDataLen;
450
451 if (userData != NULL) {
452 userDataLen = (uint32_t)strlen(userData);
453 }
454
455 packeUserDataLen = (uint16_t)(sizeof(pathType) + userDataLen);
456
457 userDataUnit = (UserDataUnit *)calloc(packeUserDataLen, 1);
458 if (userDataUnit == NULL) {
459 DFILE_LOGE(TAG, "userDataUnit calloc error");
460 return NULL;
461 }
462 userDataUnit->pathType = pathType;
463 if (userDataLen > 0 && memcpy_s(userDataUnit->userData, userDataLen, userData, userDataLen) != EOK) {
464 DFILE_LOGE(TAG, "userData memcpy error");
465 free(userDataUnit);
466 return NULL;
467 }
468 *packedLen = packeUserDataLen;
469 return (uint8_t *)userDataUnit;
470 }
471
FileListAddExtraInfo(FileList * fileList,uint16_t pathType,uint8_t noticeFileNameType,char * userData)472 int32_t FileListAddExtraInfo(FileList *fileList, uint16_t pathType, uint8_t noticeFileNameType, char *userData)
473 {
474 if (noticeFileNameType != NOTICE_FILE_NAME_TYPE && noticeFileNameType != NOTICE_FULL_FILE_NAME_TYPE) {
475 DFILE_LOGE(TAG, "invalid noticeFileNameType");
476 return NSTACKX_EFAILED;
477 }
478 fileList->noticeFileNameType = noticeFileNameType;
479
480 if (pathType == 0 && userData == NULL) {
481 return NSTACKX_EOK;
482 }
483 /*
484 * the first bit of userDataFlag means whether fileId 0 is vailid, and both pathType and userdata are
485 * transferred as part of the fileName of fileId 0.
486 */
487 fileList->userDataFlag = NSTACKX_DFILE_HEADER_FRAME_USER_DATA_FLAG;
488
489 fileList->userData = userData;
490 fileList->pathType = pathType;
491
492 if (pathType > 0) {
493 fileList->packedUserData = PreparePackedDFileUserData(pathType, userData, &fileList->packedUserDataLen);
494 if (fileList->packedUserData == NULL) {
495 DFILE_LOGE(TAG, "PreparePackedDFileUserData fail");
496 return NSTACKX_EFAILED;
497 }
498 }
499 return NSTACKX_EOK;
500 }
501
FileListRenameFile(FileList * fileList,uint16_t fileId,const char * newFileName)502 int32_t FileListRenameFile(FileList *fileList, uint16_t fileId, const char *newFileName)
503 {
504 if (fileList == NULL || fileId == 0 || fileId > fileList->num || newFileName == NULL ||
505 strlen(newFileName) == 0 || strlen(newFileName) >= NSTACKX_MAX_REMOTE_PATH_LEN) {
506 return NSTACKX_EINVAL;
507 }
508 if (strcpy_s(fileList->list[fileId - 1].fileName, NSTACKX_MAX_REMOTE_PATH_LEN, newFileName) != EOK) {
509 DFILE_LOGE(TAG, "strcpy_s error");
510 return NSTACKX_EFAILED;
511 }
512 return NSTACKX_EOK;
513 }
514
FreeFileListInfo(FileListInfo * fileListInfo,uint32_t end)515 static void FreeFileListInfo(FileListInfo *fileListInfo, uint32_t end)
516 {
517 while (end != 0) {
518 free(fileListInfo->files[end - 1]);
519 end--;
520 }
521 free(fileListInfo->files);
522 fileListInfo->files = NULL;
523 }
524
CopyFilesListInfo(FileListInfo * fileListInfo,FileListPara * fileListPara)525 static int32_t CopyFilesListInfo(FileListInfo *fileListInfo, FileListPara *fileListPara)
526 {
527 uint32_t i;
528 uint32_t end = 0;
529 char tmpFileName[PATH_MAX];
530
531 for (i = 0; i < fileListPara->fileNum; i++) {
532 /* When second parameter is NULL, realpath() uses malloc() to allocate a buffer of up to PATH_MAX bytes. */
533 if (realpath(fileListPara->files[i], tmpFileName) == NULL) {
534 DFILE_LOGE(TAG, "CreateFileListInfo realpath %s failed errno %d", fileListPara->files[i], errno);
535 end = i;
536 goto L_ERR_FILE;
537 }
538 fileListInfo->files[i] = calloc(1, strlen(fileListPara->files[i]) + 1);
539 if (fileListInfo->files[i] == NULL) {
540 DFILE_LOGE(TAG, "CreateFileListInfo calloc failed");
541 end = i;
542 goto L_ERR_FILE;
543 }
544 if (memcpy_s(fileListInfo->files[i], strlen(fileListPara->files[i]) + 1, fileListPara->files[i],
545 strlen(fileListPara->files[i])) != NSTACKX_EOK) {
546 DFILE_LOGE(TAG, "memcpy_s failed");
547 end = i + 1;
548 goto L_ERR_FILE;
549 }
550 uint32_t len = GetFileNameLen(fileListInfo->files[i]);
551 if (len > NSTACKX_MAX_FILE_NAME_LEN || len == 0 || !IsAccessiblePath(fileListInfo->files[i], R_OK, S_IFREG)) {
552 DFILE_LOGE(TAG, "file name %s is too long or the file is not a readable file", fileListPara->files[i]);
553 end = i + 1;
554 goto L_ERR_FILE;
555 }
556
557 if (fileListPara->startOffset) {
558 fileListInfo->startOffset[i] = fileListPara->startOffset[i];
559 }
560 if (fileListPara->fileSize) {
561 fileListInfo->fileSize[i] = fileListPara->fileSize[i];
562 }
563 }
564 return NSTACKX_EOK;
565
566 L_ERR_FILE:
567 FreeFileListInfo(fileListInfo, end);
568 return NSTACKX_EFAILED;
569 }
570
FileListInfoAddRemotePath(FileListInfo * fileListInfo,const char * remotePath[],uint32_t fileNum)571 static int32_t FileListInfoAddRemotePath(FileListInfo *fileListInfo, const char *remotePath[], uint32_t fileNum)
572 {
573 uint32_t i;
574 uint32_t end = 0;
575 if (fileListInfo == NULL || remotePath == NULL || fileNum == 0) {
576 DFILE_LOGE(TAG, "invalid input");
577 return NSTACKX_EINVAL;
578 }
579 fileListInfo->remotePath = calloc(fileNum, sizeof(char *));
580 if (fileListInfo->remotePath == NULL) {
581 return NSTACKX_EFAILED;
582 }
583
584 for (i = 0; i < fileNum; i++) {
585 if (fileListInfo->tarFlag != NSTACKX_TRUE) {
586 fileListInfo->remotePath[i] = strdup(remotePath[i]);
587 } else {
588 fileListInfo->remotePath[i] = strdup(remotePath[0]);
589 }
590 if (fileListInfo->remotePath[i] == NULL) {
591 DFILE_LOGE(TAG, "failed for copy %uth remotePath, errno(%d)", i, errno);
592 end = i;
593 goto L_ERR_FILE;
594 }
595 if (strlen(fileListInfo->remotePath[i]) + 1 > NSTACKX_MAX_REMOTE_PATH_LEN) {
596 DFILE_LOGE(TAG, "remotePath is too long");
597 end = i + 1;
598 goto L_ERR_FILE;
599 }
600 }
601
602 return NSTACKX_EOK;
603
604 L_ERR_FILE:
605 while (end > 0) {
606 free(fileListInfo->remotePath[end - 1]);
607 end--;
608 }
609 free(fileListInfo->remotePath);
610 fileListInfo->remotePath = NULL;
611 return NSTACKX_EFAILED;
612 }
613
CreateFileListInfo(FileListPara * fileListPara)614 FileListInfo *CreateFileListInfo(FileListPara *fileListPara)
615 {
616 if (fileListPara->fileNum == 0) {
617 return NULL;
618 }
619 FileListInfo *fileListInfo = calloc(1, sizeof(FileListInfo));
620 if (fileListInfo == NULL) {
621 return NULL;
622 }
623 fileListInfo->fileNum = fileListPara->fileNum;
624 fileListInfo->files = calloc(fileListPara->fileNum, sizeof(char *));
625 if (fileListInfo->files == NULL) {
626 goto L_ERR_LIST;
627 }
628 fileListInfo->tarFlag = fileListPara->tarFlag;
629 fileListInfo->noSyncFlag = NSTACKX_FALSE;
630
631 if (CopyFilesListInfo(fileListInfo, fileListPara) != NSTACKX_EOK) {
632 goto L_ERR_LIST;
633 }
634
635 if (fileListPara->userData != NULL) {
636 fileListInfo->userData = strdup(fileListPara->userData);
637 if (fileListInfo->userData == NULL) {
638 goto L_ERR_FILE;
639 }
640 }
641
642 if (fileListPara->remotePath != NULL &&
643 FileListInfoAddRemotePath(fileListInfo, fileListPara->remotePath, fileListPara->fileNum) != NSTACKX_EOK) {
644 if (fileListPara->userData != NULL) {
645 free(fileListInfo->userData);
646 fileListInfo->userData = NULL;
647 }
648 DFILE_LOGE(TAG, "CreateFileListInfo FileListInfoAddRemotePath failed");
649 goto L_ERR_FILE;
650 }
651
652 return fileListInfo;
653
654 L_ERR_FILE:
655 FreeFileListInfo(fileListInfo, fileListPara->fileNum);
656 L_ERR_LIST:
657 free(fileListInfo);
658 return NULL;
659 }
660
DestroyFileListInfo(FileListInfo * fileListInfo)661 void DestroyFileListInfo(FileListInfo *fileListInfo)
662 {
663 uint32_t i;
664
665 if (fileListInfo == NULL) {
666 return;
667 }
668
669 for (i = 0; i < fileListInfo->fileNum; i++) {
670 free(fileListInfo->files[i]);
671 }
672 free(fileListInfo->files);
673 fileListInfo->files = NULL;
674
675 if (fileListInfo->remotePath != NULL) {
676 for (i = 0; i < fileListInfo->fileNum; i++) {
677 free(fileListInfo->remotePath[i]);
678 }
679 free(fileListInfo->remotePath);
680 fileListInfo->remotePath = NULL;
681 }
682
683 if (fileListInfo->userData != NULL) {
684 free(fileListInfo->userData);
685 fileListInfo->userData = NULL;
686 }
687 if (fileListInfo->tarFile != NULL) {
688 free(fileListInfo->tarFile);
689 fileListInfo->tarFile = NULL;
690 }
691 free(fileListInfo);
692 }
693