• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "directory_ex.h"
17 #include <dirent.h>
18 #include <errno.h>
19 #include "securec.h"
20 #include "unistd.h"
21 #include "utils_log.h"
22 using namespace std;
23 
24 namespace OHOS {
25 
GetCurrentProcFullFileName()26 string GetCurrentProcFullFileName()
27 {
28     char procFile[PATH_MAX + 1] = {0};
29     int ret = readlink("/proc/self/exe", procFile, PATH_MAX);
30     if (ret < 0 || ret > PATH_MAX) {
31         UTILS_LOGE("Get proc name failed, ret is: %{public}d!", ret);
32         return string();
33     }
34     procFile[ret] = '\0';
35     return string(procFile);
36 }
37 
GetCurrentProcPath()38 string GetCurrentProcPath()
39 {
40     return ExtractFilePath(GetCurrentProcFullFileName());
41 }
42 
ExtractFilePath(const string & fileFullName)43 string ExtractFilePath(const string& fileFullName)
44 {
45     return string(fileFullName).substr(0, fileFullName.rfind("/") + 1);
46 }
47 
ExtractFileName(const std::string & fileFullName)48 std::string ExtractFileName(const std::string& fileFullName)
49 {
50     return string(fileFullName).substr(fileFullName.rfind("/") + 1, fileFullName.size());
51 }
52 
ExtractFileExt(const string & fileName)53 string ExtractFileExt(const string& fileName)
54 {
55     string::size_type pos = fileName.rfind(".");
56     if (pos == string::npos) {
57         return "";
58     }
59 
60     return string(fileName).substr(pos + 1, fileName.size());
61 }
62 
ExcludeTrailingPathDelimiter(const std::string & path)63 string ExcludeTrailingPathDelimiter(const std::string& path)
64 {
65     if (path.rfind("/") != path.size() - 1) {
66         return path;
67     }
68 
69     if (!path.empty()) {
70         return path.substr(0, (int)path.size() - 1);
71     }
72 
73     return path;
74 }
75 
IncludeTrailingPathDelimiter(const std::string & path)76 string IncludeTrailingPathDelimiter(const std::string& path)
77 {
78     if (path.rfind("/") != path.size() - 1) {
79         return path + "/";
80     }
81 
82     return path;
83 }
84 
GetDirFiles(const string & path,vector<string> & files)85 void GetDirFiles(const string& path, vector<string>& files)
86 {
87     string pathStringWithDelimiter;
88     DIR *dir = opendir(path.c_str());
89     if (dir == nullptr) {
90         return;
91     }
92 
93     while (true) {
94         struct dirent *ptr = readdir(dir);
95         if (ptr == nullptr) {
96             break;
97         }
98 
99         // current dir OR parent dir
100         if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
101             continue;
102         } else if (ptr->d_type == DT_DIR) {
103             pathStringWithDelimiter = IncludeTrailingPathDelimiter(path) + string(ptr->d_name);
104             GetDirFiles(pathStringWithDelimiter, files);
105         } else {
106             files.push_back(IncludeTrailingPathDelimiter(path) + string(ptr->d_name));
107         }
108     }
109     closedir(dir);
110 }
111 
ForceCreateDirectory(const string & path)112 bool ForceCreateDirectory(const string& path)
113 {
114     string::size_type index = 0;
115     do {
116         string subPath;
117         index = path.find('/', index + 1);
118         if (index == string::npos) {
119             subPath = path;
120         } else {
121             subPath = path.substr(0, index);
122         }
123 
124         if (access(subPath.c_str(), F_OK) != 0) {
125             if (mkdir(subPath.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0 && errno != EEXIST) {
126                 return false;
127             }
128         }
129     } while (index != string::npos);
130 
131     return access(path.c_str(), F_OK) == 0;
132 }
133 
ForceRemoveDirectory(const string & path)134 bool ForceRemoveDirectory(const string& path)
135 {
136     string subPath;
137     bool ret = true;
138     DIR *dir = opendir(path.c_str());
139     if (dir == nullptr) {
140         return false;
141     }
142 
143     while (true) {
144         struct dirent *ptr = readdir(dir);
145         if (ptr == nullptr) {
146             break;
147         }
148 
149         // current dir OR parent dir
150         if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
151             continue;
152         }
153         subPath = IncludeTrailingPathDelimiter(path) + string(ptr->d_name);
154         if (ptr->d_type == DT_DIR) {
155             ret = ForceRemoveDirectory(subPath);
156         } else {
157             if (access(subPath.c_str(), F_OK) == 0) {
158                 if (remove(subPath.c_str()) != 0) {
159                     closedir(dir);
160                     return false;
161                 }
162             }
163         }
164     }
165     closedir(dir);
166 
167     string currentPath = ExcludeTrailingPathDelimiter(path);
168     if (access(currentPath.c_str(), F_OK) == 0) {
169         if (remove(currentPath.c_str()) != 0) {
170             return false;
171         }
172     }
173 
174     return ret && (access(path.c_str(), F_OK) != 0);
175 }
176 
RemoveFile(const string & fileName)177 bool RemoveFile(const string& fileName)
178 {
179     if (access(fileName.c_str(), F_OK) == 0) {
180         return remove(fileName.c_str()) == 0;
181     }
182 
183     return true;
184 }
185 
IsEmptyFolder(const string & path)186 bool IsEmptyFolder(const string& path)
187 {
188     vector<string> files;
189     GetDirFiles(path, files);
190     return files.empty();
191 }
192 
GetFolderSize(const string & path)193 uint64_t GetFolderSize(const string& path)
194 {
195     vector<string> files;
196     struct stat statbuf = {0};
197     GetDirFiles(path, files);
198     uint64_t totalSize = 0;
199     for (auto& file : files) {
200         if (stat(file.c_str(), &statbuf) == 0) {
201             totalSize += statbuf.st_size;
202         }
203     }
204 
205     return totalSize;
206 }
207 
208 // inner function, and param is legitimate
ChangeMode(const string & fileName,const mode_t & mode)209 bool ChangeMode(const string& fileName, const mode_t& mode)
210 {
211     return (chmod(fileName.c_str(), mode) == 0);
212 }
213 
ChangeModeFile(const string & fileName,const mode_t & mode)214 bool ChangeModeFile(const string& fileName, const mode_t& mode)
215 {
216     if (access(fileName.c_str(), F_OK) != 0) {
217         return false;
218     }
219 
220     return ChangeMode(fileName, mode);
221 }
222 
ChangeModeDirectory(const string & path,const mode_t & mode)223 bool ChangeModeDirectory(const string& path, const mode_t& mode)
224 {
225     string subPath;
226     bool ret = true;
227     DIR *dir = opendir(path.c_str());
228     if (dir == nullptr) {
229         return false;
230     }
231 
232     while (true) {
233         struct dirent *ptr = readdir(dir);
234         if (ptr == nullptr) {
235             break;
236         }
237 
238         // current dir OR parent dir
239         if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
240             continue;
241         }
242         subPath = IncludeTrailingPathDelimiter(path) + string(ptr->d_name);
243         if (ptr->d_type == DT_DIR) {
244             ret = ChangeModeDirectory(subPath, mode);
245         } else {
246             if (access(subPath.c_str(), F_OK) == 0) {
247                 if (!ChangeMode(subPath, mode)) {
248                     UTILS_LOGE("Failed to exec ChangeMode");
249                     closedir(dir);
250                     return false;
251                 }
252             }
253         }
254     }
255     closedir(dir);
256     string currentPath = ExcludeTrailingPathDelimiter(path);
257     if (access(currentPath.c_str(), F_OK) == 0) {
258         if (!ChangeMode(currentPath, mode)) {
259             UTILS_LOGE("Failed to exec ChangeMode");
260             return false;
261         }
262     }
263     return ret;
264 }
265 
PathToRealPath(const string & path,string & realPath)266 bool PathToRealPath(const string& path, string& realPath)
267 {
268     if (path.empty()) {
269         UTILS_LOGE("path is empty!");
270         return false;
271     }
272 
273     if ((path.length() >= PATH_MAX)) {
274         UTILS_LOGE("path len is error, the len is: [%{public}zu]", path.length());
275         return false;
276     }
277 
278     char tmpPath[PATH_MAX] = {0};
279     if (realpath(path.c_str(), tmpPath) == nullptr) {
280         UTILS_LOGE("path to realpath error");
281         return false;
282     }
283 
284     realPath = tmpPath;
285     if (access(realPath.c_str(), F_OK) != 0) {
286         UTILS_LOGE("check realpath (%{private}s) error", realPath.c_str());
287         return false;
288     }
289     return true;
290 }
291 
292 } // OHOS
293