• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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