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 }