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