1 /*
2 * Copyright (c) 2022-2025 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 "help_utils.h"
17
18 #include <cerrno>
19 #include <cstdio>
20 #include <dirent.h>
21 #include <fcntl.h>
22 #include <mntent.h>
23 #include <sys/mount.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26
27 #include "istorage_daemon.h"
28 #include "user/user_manager.h"
29 #include "utils/file_utils.h"
30 #include "storage_service_constant.h"
31 namespace OHOS {
32 namespace StorageDaemon {
33 namespace StorageTest {
34 const std::string hmdfsTarget = "/storage/media/%d/local";
35 static constexpr int MODE_0711 = 0711;
36 const std::vector<Dir> StorageTestUtils::gRootDirs = {
37 {"/data/app/%s/%d", MODE_0711, OID_ROOT, OID_ROOT},
38 {"/data/service/%s/%d", MODE_0711, OID_ROOT, OID_ROOT},
39 {"/data/chipset/%s/%d", MODE_0711, OID_ROOT, OID_ROOT}
40 };
41
42 const std::vector<Dir> StorageTestUtils::gSubDirs = {
43 {"/data/app/%s/%d/base", MODE_0711, OID_ROOT, OID_ROOT},
44 {"/data/app/%s/%d/database", MODE_0711, OID_ROOT, OID_ROOT}
45 };
46
47 const std::vector<Dir> StorageTestUtils::gHmdfsDirs = {
48 {"/data/service/el2/%d/hmdfs", MODE_0711, OID_SYSTEM, OID_SYSTEM},
49 {"/data/service/el2/%d/hmdfs/files", MODE_0711, OID_SYSTEM, OID_SYSTEM},
50 {"/data/service/el2/%d/hmdfs/data", MODE_0711, OID_SYSTEM, OID_SYSTEM},
51 {"/storage/media/%d", MODE_0711, OID_ROOT, OID_ROOT},
52 {"/storage/media/%d/local", MODE_0711, OID_ROOT, OID_ROOT}
53 };
54
CheckMount(const std::string & dstPath)55 bool StorageTestUtils::CheckMount(const std::string& dstPath)
56 {
57 const std::string fileName = "/proc/mounts";
58 FILE *mntFile;
59 struct mntent *mntent = nullptr;
60
61 mntFile = setmntent(fileName.c_str(), "r");
62 if (!mntFile) {
63 return false;
64 }
65
66 while ((mntent = getmntent(mntFile)) != nullptr) {
67 if (dstPath.compare(mntent->mnt_dir) == 0) {
68 endmntent(mntFile);
69 return true;
70 }
71 }
72 endmntent(mntFile);
73 return false;
74 }
75
CheckDir(const std::string & path)76 bool StorageTestUtils::CheckDir(const std::string &path)
77 {
78 struct stat st;
79 if (lstat(path.c_str(), &st) != 0) {
80 return false;
81 }
82 return S_ISDIR(st.st_mode) == 1;
83 }
84
CheckUserDir(int32_t userId,uint32_t flags)85 bool StorageTestUtils::CheckUserDir(int32_t userId, uint32_t flags)
86 {
87 for (const Dir &dir : gRootDirs) {
88 std::string path(dir.path);
89 path.replace(path.find("%d"), strlen("%d"), std::to_string(userId));
90
91 if (flags & IStorageDaemonEnum::CRYPTO_FLAG_EL1) {
92 std::string realPath(path);
93 realPath.replace(realPath.find("%s"), strlen("%s"), "el1");
94 if (CheckDir(realPath) == false) {
95 return false;
96 }
97 }
98 if (flags & IStorageDaemonEnum::CRYPTO_FLAG_EL2) {
99 std::string realPath(path);
100 realPath.replace(realPath.find("%s"), strlen("%s"), "el2");
101 if (CheckDir(realPath) == false) {
102 return false;
103 }
104 }
105 }
106
107 for (const Dir &dir : gSubDirs) {
108 if (flags & IStorageDaemonEnum::CRYPTO_FLAG_EL1) {
109 std::string path(dir.path);
110 path.replace(path.find("%d"), strlen("%d"), std::to_string(userId));
111 path.replace(path.find("%s"), strlen("%s"), "el1");
112 if (CheckDir(path) == false) {
113 return false;
114 }
115 }
116
117 if (flags & IStorageDaemonEnum::CRYPTO_FLAG_EL2) {
118 std::string path(dir.path);
119 path.replace(path.find("%d"), strlen("%d"), std::to_string(userId));
120 path.replace(path.find("%s"), strlen("%s"), "el2");
121 if (CheckDir(path) == false) {
122 return false;
123 }
124 }
125 }
126
127 for (const Dir &dir : gHmdfsDirs) {
128 std::string path(dir.path);
129 path.replace(path.find("%d"), strlen("%d"), std::to_string(userId));
130 if (CheckDir(path) == false) {
131 return false;
132 }
133 }
134 return true;
135 }
136
CreateFile(const std::string & path)137 bool StorageTestUtils::CreateFile(const std::string &path)
138 {
139 (void)RmDirRecurse(path);
140 FILE *f = fopen(path.c_str(), "w+");
141 if (f == nullptr) {
142 return false;
143 }
144 ChMod(path.c_str(), MODE);
145 int fd = fileno(f);
146 if (fd == -1) {
147 return false;
148 }
149 (void)fclose(f);
150 return true;
151 }
152
MkDir(const std::string & path,mode_t mode)153 bool StorageTestUtils::MkDir(const std::string &path, mode_t mode)
154 {
155 if (access(path.c_str(), 0) == 0) {
156 if (rmdir(path.c_str()) != 0) {
157 return false;
158 }
159 }
160 if (mkdir(path.c_str(), mode) != 0) {
161 return false;
162 }
163 if (access(path.c_str(), 0) != 0) {
164 return false;
165 }
166 return true;
167 }
168
RmDirRecurse(const std::string & path)169 bool StorageTestUtils::RmDirRecurse(const std::string &path)
170 {
171 struct stat st;
172 if (lstat(path.c_str(), &st) != 0) {
173 return false;
174 }
175 if (S_ISDIR(st.st_mode) != 1) {
176 return (unlink(path.c_str()) == 0);
177 }
178
179 DIR *dir = opendir(path.c_str());
180 if (!dir) {
181 if (errno == ENOENT) {
182 return true;
183 }
184 return false;
185 }
186
187 for (struct dirent *ent = readdir(dir); ent != nullptr; ent = readdir(dir)) {
188 if (ent->d_type == DT_DIR) {
189 if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
190 continue;
191 }
192
193 if (!RmDirRecurse(path + "/" + ent->d_name)) {
194 (void)closedir(dir);
195 return false;
196 }
197 } else {
198 if (unlink((path + "/" + ent->d_name).c_str())) {
199 (void)closedir(dir);
200 return false;
201 }
202 }
203 }
204
205 (void)closedir(dir);
206 if (rmdir(path.c_str())) {
207 return false;
208 }
209
210 return true;
211 }
212
RmDir(const int32_t userId)213 void StorageTestUtils::RmDir(const int32_t userId)
214 {
215 std::vector<std::string> paths = {
216 "/data/app/el1/",
217 "/data/app/el2/",
218 "/data/service/el1/",
219 "/data/service/el2/",
220 "/data/chipset/el1/",
221 "/data/chipset/el2/",
222 "/storage/media/"
223 };
224
225 for (auto path : paths) {
226 path.append(std::to_string(userId));
227 RmDirRecurse(path);
228 }
229 }
230
ClearTestResource()231 void StorageTestUtils::ClearTestResource()
232 {
233 const int32_t userIds[] = {
234 USER_ID1,
235 USER_ID2,
236 USER_ID3,
237 USER_ID4,
238 USER_ID5
239 };
240 for (const auto id : userIds) {
241 std::string dstPath(hmdfsTarget);
242 dstPath.replace(dstPath.find("%d"), strlen("%d"), std::to_string(id));
243 UMount(dstPath);
244 RmDir(id);
245 }
246 }
247 } // StorageTest
248 } // STORAGE_DAEMON
249 } // OHOS
250