• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2024 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 "hks_iterative_reader.h"
17 
18 #include <dirent.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <securec.h>
22 #include <sys/types.h>
23 #include <stdio.h>
24 #include <sys/stat.h>
25 
26 #include "hks_file_operator.h"
27 #include "hks_log.h"
28 #include "hks_mem.h"
29 #include "hks_template.h"
30 #include "hks_type_inner.h"
31 
32 #define DEFAULT_PATH_LEN 256
33 
34 #define DEFAULT_FILE_INFO_NUM 64
35 
36 #define DIR_TYPE 4
37 
HksFreeFileInfo(struct HksReadFileInfo * info)38 static void HksFreeFileInfo(struct HksReadFileInfo *info)
39 {
40     HKS_FREE(info->path);
41     HKS_FREE(info->fileName);
42 }
43 
HksFreeFileInfoList(struct HksReadFileInfoList ** infos)44 static void HksFreeFileInfoList(struct HksReadFileInfoList **infos)
45 {
46     if (*infos == NULL) {
47         return;
48     }
49     if ((*infos)->infos != NULL && (*infos)->occu > 0) {
50         for (uint32_t i = 0; i < (*infos)->occu; ++i) {
51             HksFreeFileInfo(&(*infos)->infos[i]);
52         }
53     }
54     HKS_FREE((*infos)->infos);
55     HKS_FREE(*infos);
56 }
57 
HksInitFileInfoList(void)58 static struct HksReadFileInfoList *HksInitFileInfoList(void)
59 {
60     struct HksReadFileInfoList *infos;
61     do {
62         infos = (struct HksReadFileInfoList *)HksMalloc(sizeof(struct HksReadFileInfoList));
63         if (infos == NULL) {
64             HKS_LOG_E("malloc HksReadFileInfoList failed.");
65             break;
66         }
67         infos->infos = (struct HksReadFileInfo *)HksMalloc(sizeof(struct HksReadFileInfo) * DEFAULT_FILE_INFO_NUM);
68         if (infos->infos == NULL) {
69             break;
70         }
71         infos->occu = 0;
72         infos->cap = DEFAULT_FILE_INFO_NUM;
73         return infos;
74     } while (false);
75     HksFreeFileInfoList(&infos);
76     return NULL;
77 }
78 
79 // each time for re-alloc, the capacity of OldFileInfoList will be added with DEFAULT_FILE_INFO_NUM.
HksReAllocFileInfoList(struct HksReadFileInfoList * infos)80 static int32_t HksReAllocFileInfoList(struct HksReadFileInfoList *infos)
81 {
82     struct HksReadFileInfo *newInfo =
83         (struct HksReadFileInfo *)HksMalloc(sizeof(struct HksReadFileInfo) * (infos->cap + DEFAULT_FILE_INFO_NUM));
84     if (newInfo == NULL) {
85         return HKS_ERROR_MALLOC_FAIL;
86     }
87     (void)memcpy_s(newInfo, (infos->cap + DEFAULT_FILE_INFO_NUM) * sizeof(struct HksReadFileInfo),
88         infos->infos, infos->occu * sizeof(struct HksReadFileInfo));
89     HKS_FREE(infos->infos);
90     infos->infos = newInfo;
91     infos->cap += DEFAULT_FILE_INFO_NUM;
92     return HKS_SUCCESS;
93 }
94 
AppendFilePath(const char * path,const char * fileName,struct HksReadFileInfoList * infos)95 static int32_t AppendFilePath(const char *path, const char *fileName, struct HksReadFileInfoList *infos)
96 {
97     int32_t ret;
98     if (infos->occu == infos->cap) {
99         ret = HksReAllocFileInfoList(infos);
100         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "re-alloc old file info list failed.")
101     }
102     struct HksReadFileInfo *info = &infos->infos[infos->occu]; // the (infos->occu + 1)th info
103     do {
104         info->path = (char *)HksMalloc(strlen(path) + 1);
105         HKS_IF_NULL_BREAK(info->path)
106         info->fileName = (char *)HksMalloc(strlen(fileName) + 1);
107         HKS_IF_NULL_BREAK(info->fileName)
108         (void)memcpy_s(info->path, strlen(path), path, strlen(path));
109         (void)memcpy_s(info->fileName, strlen(fileName), fileName, strlen(fileName));
110         infos->occu += 1;
111 
112         return HKS_SUCCESS;
113     } while (false);
114     HksFreeFileInfo(info);
115     return ret;
116 }
117 
ConstructSubPath(const struct dirent * ptr,const char * curPath,char * subPath)118 static int ConstructSubPath(const struct dirent *ptr, const char *curPath, char *subPath)
119 {
120     int ret = strcpy_s(subPath, DEFAULT_PATH_LEN, curPath);
121     if (ret != EOK) {
122         return ret;
123     }
124     ret = strcat_s(subPath, DEFAULT_PATH_LEN, "/");
125     if (ret != EOK) {
126         return ret;
127     }
128 
129     ret = strcat_s(subPath, DEFAULT_PATH_LEN, ptr->d_name);
130     if (ret != EOK) {
131         return ret;
132     }
133 
134     return EOK;
135 }
136 
HksGetOldStoreFileInfo(const char * path,struct HksReadFileInfoList * infos)137 static int32_t HksGetOldStoreFileInfo(const char *path, struct HksReadFileInfoList *infos)
138 {
139     DIR *dir = opendir(path);
140     if (dir == NULL) {
141         HKS_LOG_E("open dir failed");
142         return HKS_ERROR_MAKE_DIR_FAIL;
143     }
144     struct dirent *ptr;
145     int ret = EOK;
146     while ((ptr = readdir(dir)) != NULL) {
147         if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
148             continue;
149         }
150         if (ptr->d_type == DIR_TYPE) {
151             char subPath[DEFAULT_PATH_LEN] = { 0 };
152 
153             ret = ConstructSubPath(ptr, path, subPath);
154             if (ret != EOK) {
155                 HKS_LOG_E("construct src and target path failed!");
156                 break;
157             }
158             HKS_IF_NOT_SUCC_LOGE_BREAK(HksGetOldStoreFileInfo(subPath, infos), "HksGetOldStoreFileInfo failed")
159         } else {
160             AppendFilePath(path, ptr->d_name, infos);
161         }
162     }
163     closedir(dir);
164     return HKS_SUCCESS;
165 }
166 
HksInitFileIterativeReader(struct HksIterativeReader * reader,char * path)167 int32_t HksInitFileIterativeReader(struct HksIterativeReader *reader, char *path)
168 {
169     reader->fileLists = HksInitFileInfoList();
170     if (reader->fileLists == NULL) {
171         return HKS_ERROR_MALLOC_FAIL;
172     }
173     reader->curIndex = 0;
174     int32_t ret = HksGetOldStoreFileInfo(path, reader->fileLists);
175     if (ret != HKS_SUCCESS) {
176         HksFreeFileInfoList(&reader->fileLists);
177     }
178     return ret;
179 }
180 
HksDestroyFileIterativeReader(struct HksIterativeReader * reader)181 void HksDestroyFileIterativeReader(struct HksIterativeReader *reader)
182 {
183     HksFreeFileInfoList(&reader->fileLists);
184 }
185 
HksReadFileWithIterativeReader(struct HksIterativeReader * reader,struct HksBlob * fileContent,struct HksBlob * alias,struct HksBlob * path)186 int32_t HksReadFileWithIterativeReader(struct HksIterativeReader *reader, struct HksBlob *fileContent,
187     struct HksBlob *alias, struct HksBlob *path)
188 {
189     if (reader->curIndex == reader->fileLists->occu) {
190         return HKS_ERROR_BUFFER_TOO_SMALL;
191     }
192 
193     int32_t ret = HKS_SUCCESS;
194     do {
195         uint32_t size = HksFileSize(reader->fileLists->infos[reader->curIndex].path,
196             reader->fileLists->infos[reader->curIndex].fileName);
197         if (size == 0) {
198             ret = HKS_ERROR_FILE_SIZE_FAIL;
199             break;
200         }
201         fileContent->data = (uint8_t *)HksMalloc(size);
202         if (fileContent->data == NULL) {
203             HKS_LOG_E("malloc fileContent->data failed.");
204             ret = HKS_ERROR_MALLOC_FAIL;
205             break;
206         }
207         fileContent->size = size;
208         alias->data = (uint8_t *)HksMalloc(strlen(reader->fileLists->infos[reader->curIndex].fileName) + 1);
209         if (alias->data == NULL) {
210             HKS_LOG_E("malloc alias->data failed.");
211             ret = HKS_ERROR_MALLOC_FAIL;
212             break;
213         }
214         alias->size = strlen(reader->fileLists->infos[reader->curIndex].fileName) + 1;
215         (void)memcpy_s(alias->data, strlen(reader->fileLists->infos[reader->curIndex].fileName),
216             reader->fileLists->infos[reader->curIndex].fileName,
217             strlen(reader->fileLists->infos[reader->curIndex].fileName));
218         path->data = (uint8_t *)HksMalloc(strlen(reader->fileLists->infos[reader->curIndex].path) + 1);
219         if (path->data == NULL) {
220             HKS_LOG_E("malloc path->data failed.");
221             ret = HKS_ERROR_MALLOC_FAIL;
222             break;
223         }
224         path->size = strlen(reader->fileLists->infos[reader->curIndex].path) + 1;
225         (void)memcpy_s(path->data, strlen(reader->fileLists->infos[reader->curIndex].path),
226             reader->fileLists->infos[reader->curIndex].path, strlen(reader->fileLists->infos[reader->curIndex].path));
227         ret = HksFileRead(reader->fileLists->infos[reader->curIndex].path,
228             reader->fileLists->infos[reader->curIndex].fileName, 0, fileContent, &fileContent->size);
229         reader->curIndex++;
230         return ret;
231     } while (false);
232     HKS_FREE_BLOB(*fileContent);
233     HKS_FREE_BLOB(*alias);
234     HKS_FREE_BLOB(*path);
235     return ret;
236 }