13f4cbf05Sopenharmony_ci/* 23f4cbf05Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License. 53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at 63f4cbf05Sopenharmony_ci * 73f4cbf05Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83f4cbf05Sopenharmony_ci * 93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and 133f4cbf05Sopenharmony_ci * limitations under the License. 143f4cbf05Sopenharmony_ci */ 153f4cbf05Sopenharmony_ci 163f4cbf05Sopenharmony_ci#include "directory_ex.h" 173f4cbf05Sopenharmony_ci#include <dirent.h> 183f4cbf05Sopenharmony_ci#include <cerrno> 193f4cbf05Sopenharmony_ci#include <fcntl.h> 203f4cbf05Sopenharmony_ci#include <stack> 213f4cbf05Sopenharmony_ci#include "securec.h" 223f4cbf05Sopenharmony_ci#include "unistd.h" 233f4cbf05Sopenharmony_ci#include "utils_log.h" 243f4cbf05Sopenharmony_ciusing namespace std; 253f4cbf05Sopenharmony_ci 263f4cbf05Sopenharmony_cinamespace OHOS { 273f4cbf05Sopenharmony_ci 283f4cbf05Sopenharmony_ci#ifdef UTILS_CXX_RUST 293f4cbf05Sopenharmony_cirust::String RustGetCurrentProcFullFileName() 303f4cbf05Sopenharmony_ci{ 313f4cbf05Sopenharmony_ci return rust::String(GetCurrentProcFullFileName()); 323f4cbf05Sopenharmony_ci} 333f4cbf05Sopenharmony_ci 343f4cbf05Sopenharmony_cirust::String RustGetCurrentProcPath() 353f4cbf05Sopenharmony_ci{ 363f4cbf05Sopenharmony_ci return rust::String(GetCurrentProcPath()); 373f4cbf05Sopenharmony_ci} 383f4cbf05Sopenharmony_ci 393f4cbf05Sopenharmony_cirust::String RustExtractFilePath(const rust::String& fileFullName) 403f4cbf05Sopenharmony_ci{ 413f4cbf05Sopenharmony_ci std::string tmpName = std::string(fileFullName); 423f4cbf05Sopenharmony_ci return rust::String(ExtractFilePath(tmpName)); 433f4cbf05Sopenharmony_ci} 443f4cbf05Sopenharmony_ci 453f4cbf05Sopenharmony_cirust::String RustExtractFileName(const rust::String& fileFullName) 463f4cbf05Sopenharmony_ci{ 473f4cbf05Sopenharmony_ci std::string tmpName = std::string(fileFullName); 483f4cbf05Sopenharmony_ci return rust::String(ExtractFileName(tmpName)); 493f4cbf05Sopenharmony_ci} 503f4cbf05Sopenharmony_ci 513f4cbf05Sopenharmony_cirust::String RustExtractFileExt(const rust::String& fileName) 523f4cbf05Sopenharmony_ci{ 533f4cbf05Sopenharmony_ci std::string tmpName = std::string(fileName); 543f4cbf05Sopenharmony_ci return rust::String(ExtractFileExt(tmpName)); 553f4cbf05Sopenharmony_ci} 563f4cbf05Sopenharmony_ci 573f4cbf05Sopenharmony_cirust::String RustExcludeTrailingPathDelimiter(const rust::String& path) 583f4cbf05Sopenharmony_ci{ 593f4cbf05Sopenharmony_ci std::string tmpPath = std::string(path); 603f4cbf05Sopenharmony_ci return rust::String(ExcludeTrailingPathDelimiter(tmpPath)); 613f4cbf05Sopenharmony_ci} 623f4cbf05Sopenharmony_ci 633f4cbf05Sopenharmony_cirust::String RustIncludeTrailingPathDelimiter(const rust::String& path) 643f4cbf05Sopenharmony_ci{ 653f4cbf05Sopenharmony_ci std::string tmpPath = std::string(path); 663f4cbf05Sopenharmony_ci return rust::String(IncludeTrailingPathDelimiter(tmpPath)); 673f4cbf05Sopenharmony_ci} 683f4cbf05Sopenharmony_ci 693f4cbf05Sopenharmony_cibool RustPathToRealPath(const rust::String& path, rust::String& realPath) 703f4cbf05Sopenharmony_ci{ 713f4cbf05Sopenharmony_ci std::string tmpPath = std::string(path); 723f4cbf05Sopenharmony_ci std::string tmpResolved; 733f4cbf05Sopenharmony_ci 743f4cbf05Sopenharmony_ci if (PathToRealPath(tmpPath, tmpResolved)) { 753f4cbf05Sopenharmony_ci realPath = tmpResolved; 763f4cbf05Sopenharmony_ci return true; 773f4cbf05Sopenharmony_ci } 783f4cbf05Sopenharmony_ci 793f4cbf05Sopenharmony_ci return false; 803f4cbf05Sopenharmony_ci} 813f4cbf05Sopenharmony_ci 823f4cbf05Sopenharmony_civoid RustGetDirFiles(const rust::String& path, rust::vec<rust::String>& files) 833f4cbf05Sopenharmony_ci{ 843f4cbf05Sopenharmony_ci std::string tmpPath(path); 853f4cbf05Sopenharmony_ci std::vector<std::string> tmpFiles(files.begin(), files.end()); 863f4cbf05Sopenharmony_ci GetDirFiles(tmpPath, tmpFiles); 873f4cbf05Sopenharmony_ci std::copy(tmpFiles.begin(), tmpFiles.end(), std::back_inserter(files)); 883f4cbf05Sopenharmony_ci} 893f4cbf05Sopenharmony_ci#endif 903f4cbf05Sopenharmony_ci 913f4cbf05Sopenharmony_cistring GetCurrentProcFullFileName() 923f4cbf05Sopenharmony_ci{ 933f4cbf05Sopenharmony_ci char procFile[PATH_MAX + 1] = {0}; 943f4cbf05Sopenharmony_ci int ret = readlink("/proc/self/exe", procFile, PATH_MAX); 953f4cbf05Sopenharmony_ci if (ret < 0 || ret > PATH_MAX) { 963f4cbf05Sopenharmony_ci UTILS_LOGD("Get proc name failed, ret is: %{public}d!", ret); 973f4cbf05Sopenharmony_ci return string(); 983f4cbf05Sopenharmony_ci } 993f4cbf05Sopenharmony_ci procFile[ret] = '\0'; 1003f4cbf05Sopenharmony_ci return string(procFile); 1013f4cbf05Sopenharmony_ci} 1023f4cbf05Sopenharmony_ci 1033f4cbf05Sopenharmony_cistring GetCurrentProcPath() 1043f4cbf05Sopenharmony_ci{ 1053f4cbf05Sopenharmony_ci return ExtractFilePath(GetCurrentProcFullFileName()); 1063f4cbf05Sopenharmony_ci} 1073f4cbf05Sopenharmony_ci 1083f4cbf05Sopenharmony_cistring ExtractFilePath(const string& fileFullName) 1093f4cbf05Sopenharmony_ci{ 1103f4cbf05Sopenharmony_ci return string(fileFullName).substr(0, fileFullName.rfind("/") + 1); 1113f4cbf05Sopenharmony_ci} 1123f4cbf05Sopenharmony_ci 1133f4cbf05Sopenharmony_cistd::string ExtractFileName(const std::string& fileFullName) 1143f4cbf05Sopenharmony_ci{ 1153f4cbf05Sopenharmony_ci return string(fileFullName).substr(fileFullName.rfind("/") + 1, fileFullName.size()); 1163f4cbf05Sopenharmony_ci} 1173f4cbf05Sopenharmony_ci 1183f4cbf05Sopenharmony_cistring ExtractFileExt(const string& fileName) 1193f4cbf05Sopenharmony_ci{ 1203f4cbf05Sopenharmony_ci string::size_type pos = fileName.rfind("."); 1213f4cbf05Sopenharmony_ci if (pos == string::npos) { 1223f4cbf05Sopenharmony_ci return ""; 1233f4cbf05Sopenharmony_ci } 1243f4cbf05Sopenharmony_ci 1253f4cbf05Sopenharmony_ci return string(fileName).substr(pos + 1, fileName.size()); 1263f4cbf05Sopenharmony_ci} 1273f4cbf05Sopenharmony_ci 1283f4cbf05Sopenharmony_cistring ExcludeTrailingPathDelimiter(const std::string& path) 1293f4cbf05Sopenharmony_ci{ 1303f4cbf05Sopenharmony_ci if (path.rfind("/") != path.size() - 1) { 1313f4cbf05Sopenharmony_ci return path; 1323f4cbf05Sopenharmony_ci } 1333f4cbf05Sopenharmony_ci 1343f4cbf05Sopenharmony_ci if (!path.empty()) { 1353f4cbf05Sopenharmony_ci return path.substr(0, (int)path.size() - 1); 1363f4cbf05Sopenharmony_ci } 1373f4cbf05Sopenharmony_ci 1383f4cbf05Sopenharmony_ci return path; 1393f4cbf05Sopenharmony_ci} 1403f4cbf05Sopenharmony_ci 1413f4cbf05Sopenharmony_cistring IncludeTrailingPathDelimiter(const std::string& path) 1423f4cbf05Sopenharmony_ci{ 1433f4cbf05Sopenharmony_ci if (path.empty()) { 1443f4cbf05Sopenharmony_ci return "/"; 1453f4cbf05Sopenharmony_ci } 1463f4cbf05Sopenharmony_ci if (path.rfind("/") != path.size() - 1) { 1473f4cbf05Sopenharmony_ci return path + "/"; 1483f4cbf05Sopenharmony_ci } 1493f4cbf05Sopenharmony_ci 1503f4cbf05Sopenharmony_ci return path; 1513f4cbf05Sopenharmony_ci} 1523f4cbf05Sopenharmony_ci 1533f4cbf05Sopenharmony_civoid GetDirFiles(const string& path, vector<string>& files) 1543f4cbf05Sopenharmony_ci{ 1553f4cbf05Sopenharmony_ci DIR *dir = opendir(path.c_str()); 1563f4cbf05Sopenharmony_ci if (dir == nullptr) { 1573f4cbf05Sopenharmony_ci UTILS_LOGD("Failed to open root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); 1583f4cbf05Sopenharmony_ci return; 1593f4cbf05Sopenharmony_ci } 1603f4cbf05Sopenharmony_ci 1613f4cbf05Sopenharmony_ci string currentPath = ExcludeTrailingPathDelimiter(path); 1623f4cbf05Sopenharmony_ci stack<DIR *> traverseStack; 1633f4cbf05Sopenharmony_ci traverseStack.push(dir); 1643f4cbf05Sopenharmony_ci while (!traverseStack.empty()) { 1653f4cbf05Sopenharmony_ci DIR *topNode = traverseStack.top(); 1663f4cbf05Sopenharmony_ci dirent *ptr = readdir(topNode); 1673f4cbf05Sopenharmony_ci if (ptr == nullptr) { 1683f4cbf05Sopenharmony_ci closedir(topNode); 1693f4cbf05Sopenharmony_ci traverseStack.pop(); 1703f4cbf05Sopenharmony_ci auto pos = currentPath.find_last_of("/"); 1713f4cbf05Sopenharmony_ci if (pos != string::npos) { 1723f4cbf05Sopenharmony_ci currentPath.erase(pos); 1733f4cbf05Sopenharmony_ci } 1743f4cbf05Sopenharmony_ci continue; 1753f4cbf05Sopenharmony_ci } 1763f4cbf05Sopenharmony_ci 1773f4cbf05Sopenharmony_ci string name = ptr->d_name; 1783f4cbf05Sopenharmony_ci if (name == "." || name == "..") { 1793f4cbf05Sopenharmony_ci continue; 1803f4cbf05Sopenharmony_ci } 1813f4cbf05Sopenharmony_ci if (ptr->d_type == DT_DIR) { 1823f4cbf05Sopenharmony_ci int currentFd = dirfd(topNode); 1833f4cbf05Sopenharmony_ci if (currentFd < 0) { 1843f4cbf05Sopenharmony_ci UTILS_LOGD("Failed to get dirfd, fd: %{public}d: %{public}s ", currentFd, strerror(errno)); 1853f4cbf05Sopenharmony_ci continue; 1863f4cbf05Sopenharmony_ci } 1873f4cbf05Sopenharmony_ci int subFd = openat(currentFd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); 1883f4cbf05Sopenharmony_ci if (subFd < 0) { 1893f4cbf05Sopenharmony_ci UTILS_LOGD("Failed in subFd openat: %{public}s ", name.c_str()); 1903f4cbf05Sopenharmony_ci continue; 1913f4cbf05Sopenharmony_ci } 1923f4cbf05Sopenharmony_ci DIR *subDir = fdopendir(subFd); 1933f4cbf05Sopenharmony_ci if (subDir == nullptr) { 1943f4cbf05Sopenharmony_ci close(subFd); 1953f4cbf05Sopenharmony_ci UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); 1963f4cbf05Sopenharmony_ci continue; 1973f4cbf05Sopenharmony_ci } 1983f4cbf05Sopenharmony_ci traverseStack.push(subDir); 1993f4cbf05Sopenharmony_ci currentPath = IncludeTrailingPathDelimiter(currentPath) + name; 2003f4cbf05Sopenharmony_ci } else { 2013f4cbf05Sopenharmony_ci files.push_back(IncludeTrailingPathDelimiter(currentPath) + name); 2023f4cbf05Sopenharmony_ci } 2033f4cbf05Sopenharmony_ci } 2043f4cbf05Sopenharmony_ci} 2053f4cbf05Sopenharmony_ci 2063f4cbf05Sopenharmony_cibool ForceCreateDirectory(const string& path) 2073f4cbf05Sopenharmony_ci{ 2083f4cbf05Sopenharmony_ci string::size_type index = 0; 2093f4cbf05Sopenharmony_ci do { 2103f4cbf05Sopenharmony_ci string subPath; 2113f4cbf05Sopenharmony_ci index = path.find('/', index + 1); 2123f4cbf05Sopenharmony_ci if (index == string::npos) { 2133f4cbf05Sopenharmony_ci subPath = path; 2143f4cbf05Sopenharmony_ci } else { 2153f4cbf05Sopenharmony_ci subPath = path.substr(0, index); 2163f4cbf05Sopenharmony_ci } 2173f4cbf05Sopenharmony_ci 2183f4cbf05Sopenharmony_ci if (access(subPath.c_str(), F_OK) != 0) { 2193f4cbf05Sopenharmony_ci if (mkdir(subPath.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0 && errno != EEXIST) { 2203f4cbf05Sopenharmony_ci return false; 2213f4cbf05Sopenharmony_ci } 2223f4cbf05Sopenharmony_ci } 2233f4cbf05Sopenharmony_ci } while (index != string::npos); 2243f4cbf05Sopenharmony_ci 2253f4cbf05Sopenharmony_ci return access(path.c_str(), F_OK) == 0; 2263f4cbf05Sopenharmony_ci} 2273f4cbf05Sopenharmony_ci 2283f4cbf05Sopenharmony_cistruct DirectoryNode { 2293f4cbf05Sopenharmony_ci DIR *dir; 2303f4cbf05Sopenharmony_ci int currentFd; 2313f4cbf05Sopenharmony_ci char name[256]; // the same max char length with d_name in struct dirent 2323f4cbf05Sopenharmony_ci}; 2333f4cbf05Sopenharmony_ci 2343f4cbf05Sopenharmony_cibool ForceRemoveDirectory(const string& path) 2353f4cbf05Sopenharmony_ci{ 2363f4cbf05Sopenharmony_ci bool ret = true; 2373f4cbf05Sopenharmony_ci int strRet; 2383f4cbf05Sopenharmony_ci DIR *dir = opendir(path.c_str()); 2393f4cbf05Sopenharmony_ci if (dir == nullptr) { 2403f4cbf05Sopenharmony_ci UTILS_LOGE("Failed to open root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); 2413f4cbf05Sopenharmony_ci return false; 2423f4cbf05Sopenharmony_ci } 2433f4cbf05Sopenharmony_ci stack<DIR *> traversStack; 2443f4cbf05Sopenharmony_ci stack<DirectoryNode> removeStack; 2453f4cbf05Sopenharmony_ci traversStack.push(dir); 2463f4cbf05Sopenharmony_ci while (!traversStack.empty()) { 2473f4cbf05Sopenharmony_ci DIR *currentDir = traversStack.top(); 2483f4cbf05Sopenharmony_ci traversStack.pop(); 2493f4cbf05Sopenharmony_ci DirectoryNode node; 2503f4cbf05Sopenharmony_ci int currentFd = dirfd(currentDir); 2513f4cbf05Sopenharmony_ci if (currentFd < 0) { 2523f4cbf05Sopenharmony_ci UTILS_LOGE("Failed to get dirfd, fd: %{public}d: %{public}s ", currentFd, strerror(errno)); 2533f4cbf05Sopenharmony_ci ret = false; 2543f4cbf05Sopenharmony_ci continue; 2553f4cbf05Sopenharmony_ci } 2563f4cbf05Sopenharmony_ci 2573f4cbf05Sopenharmony_ci while (true) { 2583f4cbf05Sopenharmony_ci struct dirent *ptr = readdir(currentDir); 2593f4cbf05Sopenharmony_ci if (ptr == nullptr) { 2603f4cbf05Sopenharmony_ci break; 2613f4cbf05Sopenharmony_ci } 2623f4cbf05Sopenharmony_ci const char *name = ptr->d_name; 2633f4cbf05Sopenharmony_ci // current dir or parent dir 2643f4cbf05Sopenharmony_ci if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { 2653f4cbf05Sopenharmony_ci continue; 2663f4cbf05Sopenharmony_ci } 2673f4cbf05Sopenharmony_ci 2683f4cbf05Sopenharmony_ci if (ptr->d_type == DT_DIR) { 2693f4cbf05Sopenharmony_ci int subFd = openat(currentFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); 2703f4cbf05Sopenharmony_ci if (subFd < 0) { 2713f4cbf05Sopenharmony_ci UTILS_LOGE("Failed in subFd openat: %{public}s ", name); 2723f4cbf05Sopenharmony_ci ret = false; 2733f4cbf05Sopenharmony_ci continue; 2743f4cbf05Sopenharmony_ci } 2753f4cbf05Sopenharmony_ci DIR *subDir = fdopendir(subFd); 2763f4cbf05Sopenharmony_ci if (subDir == nullptr) { 2773f4cbf05Sopenharmony_ci close(subFd); 2783f4cbf05Sopenharmony_ci UTILS_LOGE("Failed in fdopendir: %{public}s", strerror(errno)); 2793f4cbf05Sopenharmony_ci ret = false; 2803f4cbf05Sopenharmony_ci continue; 2813f4cbf05Sopenharmony_ci } 2823f4cbf05Sopenharmony_ci node.dir = subDir; 2833f4cbf05Sopenharmony_ci node.currentFd = currentFd; 2843f4cbf05Sopenharmony_ci strRet = strcpy_s(node.name, sizeof(node.name), name); 2853f4cbf05Sopenharmony_ci if (strRet != EOK) { 2863f4cbf05Sopenharmony_ci UTILS_LOGE("Failed to exec strcpy_s, name= %{public}s, strRet= %{public}d", name, strRet); 2873f4cbf05Sopenharmony_ci } 2883f4cbf05Sopenharmony_ci removeStack.push(node); 2893f4cbf05Sopenharmony_ci traversStack.push(subDir); 2903f4cbf05Sopenharmony_ci } else { 2913f4cbf05Sopenharmony_ci if (faccessat(currentFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { 2923f4cbf05Sopenharmony_ci if (unlinkat(currentFd, name, 0) < 0) { 2933f4cbf05Sopenharmony_ci UTILS_LOGE("Couldn't unlinkat subFile %{public}s: %{public}s", name, strerror(errno)); 2943f4cbf05Sopenharmony_ci ret = false; 2953f4cbf05Sopenharmony_ci break; 2963f4cbf05Sopenharmony_ci } 2973f4cbf05Sopenharmony_ci } else { 2983f4cbf05Sopenharmony_ci UTILS_LOGE("Access to file: %{public}s is failed", name); 2993f4cbf05Sopenharmony_ci ret = false; 3003f4cbf05Sopenharmony_ci break; 3013f4cbf05Sopenharmony_ci } 3023f4cbf05Sopenharmony_ci } 3033f4cbf05Sopenharmony_ci } 3043f4cbf05Sopenharmony_ci } 3053f4cbf05Sopenharmony_ci if (!ret) { 3063f4cbf05Sopenharmony_ci UTILS_LOGD("Failed to remove some subfile under path: %{public}s", path.c_str()); 3073f4cbf05Sopenharmony_ci } 3083f4cbf05Sopenharmony_ci while (!removeStack.empty()) { 3093f4cbf05Sopenharmony_ci DirectoryNode node = removeStack.top(); 3103f4cbf05Sopenharmony_ci removeStack.pop(); 3113f4cbf05Sopenharmony_ci closedir(node.dir); 3123f4cbf05Sopenharmony_ci if (unlinkat(node.currentFd, node.name, AT_REMOVEDIR) < 0) { 3133f4cbf05Sopenharmony_ci UTILS_LOGE("Couldn't unlinkat subDir %{public}s: %{public}s", node.name, strerror(errno)); 3143f4cbf05Sopenharmony_ci continue; 3153f4cbf05Sopenharmony_ci } 3163f4cbf05Sopenharmony_ci } 3173f4cbf05Sopenharmony_ci closedir(dir); 3183f4cbf05Sopenharmony_ci if (faccessat(AT_FDCWD, path.c_str(), F_OK, AT_SYMLINK_NOFOLLOW) == 0) { 3193f4cbf05Sopenharmony_ci if (remove(path.c_str()) != 0) { 3203f4cbf05Sopenharmony_ci UTILS_LOGE("Failed to remove root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); 3213f4cbf05Sopenharmony_ci return false; 3223f4cbf05Sopenharmony_ci } 3233f4cbf05Sopenharmony_ci } 3243f4cbf05Sopenharmony_ci return faccessat(AT_FDCWD, path.c_str(), F_OK, AT_SYMLINK_NOFOLLOW) != 0; 3253f4cbf05Sopenharmony_ci} 3263f4cbf05Sopenharmony_ci 3273f4cbf05Sopenharmony_cibool RemoveFile(const string& fileName) 3283f4cbf05Sopenharmony_ci{ 3293f4cbf05Sopenharmony_ci if (access(fileName.c_str(), F_OK) == 0) { 3303f4cbf05Sopenharmony_ci return remove(fileName.c_str()) == 0; 3313f4cbf05Sopenharmony_ci } 3323f4cbf05Sopenharmony_ci 3333f4cbf05Sopenharmony_ci return true; 3343f4cbf05Sopenharmony_ci} 3353f4cbf05Sopenharmony_ci 3363f4cbf05Sopenharmony_cibool IsEmptyFolder(const string& path) 3373f4cbf05Sopenharmony_ci{ 3383f4cbf05Sopenharmony_ci vector<string> files; 3393f4cbf05Sopenharmony_ci GetDirFiles(path, files); 3403f4cbf05Sopenharmony_ci return files.empty(); 3413f4cbf05Sopenharmony_ci} 3423f4cbf05Sopenharmony_ci 3433f4cbf05Sopenharmony_ciuint64_t GetFolderSize(const string& path) 3443f4cbf05Sopenharmony_ci{ 3453f4cbf05Sopenharmony_ci vector<string> files; 3463f4cbf05Sopenharmony_ci struct stat statbuf = {0}; 3473f4cbf05Sopenharmony_ci GetDirFiles(path, files); 3483f4cbf05Sopenharmony_ci uint64_t totalSize = 0; 3493f4cbf05Sopenharmony_ci for (auto& file : files) { 3503f4cbf05Sopenharmony_ci if (stat(file.c_str(), &statbuf) == 0) { 3513f4cbf05Sopenharmony_ci totalSize += statbuf.st_size; 3523f4cbf05Sopenharmony_ci } 3533f4cbf05Sopenharmony_ci } 3543f4cbf05Sopenharmony_ci 3553f4cbf05Sopenharmony_ci return totalSize; 3563f4cbf05Sopenharmony_ci} 3573f4cbf05Sopenharmony_ci 3583f4cbf05Sopenharmony_ci// inner function, and param is legitimate 3593f4cbf05Sopenharmony_cibool ChangeMode(const string& fileName, const mode_t& mode) 3603f4cbf05Sopenharmony_ci{ 3613f4cbf05Sopenharmony_ci return (chmod(fileName.c_str(), mode) == 0); 3623f4cbf05Sopenharmony_ci} 3633f4cbf05Sopenharmony_ci 3643f4cbf05Sopenharmony_cibool ChangeModeFile(const string& fileName, const mode_t& mode) 3653f4cbf05Sopenharmony_ci{ 3663f4cbf05Sopenharmony_ci if (access(fileName.c_str(), F_OK) != 0) { 3673f4cbf05Sopenharmony_ci return false; 3683f4cbf05Sopenharmony_ci } 3693f4cbf05Sopenharmony_ci 3703f4cbf05Sopenharmony_ci return ChangeMode(fileName, mode); 3713f4cbf05Sopenharmony_ci} 3723f4cbf05Sopenharmony_ci 3733f4cbf05Sopenharmony_cibool ChangeModeDirectory(const string& path, const mode_t& mode) 3743f4cbf05Sopenharmony_ci{ 3753f4cbf05Sopenharmony_ci string subPath; 3763f4cbf05Sopenharmony_ci bool ret = true; 3773f4cbf05Sopenharmony_ci DIR *dir = opendir(path.c_str()); 3783f4cbf05Sopenharmony_ci if (dir == nullptr) { 3793f4cbf05Sopenharmony_ci return false; 3803f4cbf05Sopenharmony_ci } 3813f4cbf05Sopenharmony_ci 3823f4cbf05Sopenharmony_ci while (true) { 3833f4cbf05Sopenharmony_ci struct dirent *ptr = readdir(dir); 3843f4cbf05Sopenharmony_ci if (ptr == nullptr) { 3853f4cbf05Sopenharmony_ci break; 3863f4cbf05Sopenharmony_ci } 3873f4cbf05Sopenharmony_ci 3883f4cbf05Sopenharmony_ci // current dir or parent dir 3893f4cbf05Sopenharmony_ci if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { 3903f4cbf05Sopenharmony_ci continue; 3913f4cbf05Sopenharmony_ci } 3923f4cbf05Sopenharmony_ci subPath = IncludeTrailingPathDelimiter(path) + string(ptr->d_name); 3933f4cbf05Sopenharmony_ci if (ptr->d_type == DT_DIR) { 3943f4cbf05Sopenharmony_ci ret = ChangeModeDirectory(subPath, mode); 3953f4cbf05Sopenharmony_ci } else { 3963f4cbf05Sopenharmony_ci if (access(subPath.c_str(), F_OK) == 0) { 3973f4cbf05Sopenharmony_ci if (!ChangeMode(subPath, mode)) { 3983f4cbf05Sopenharmony_ci UTILS_LOGD("Failed to exec ChangeMode"); 3993f4cbf05Sopenharmony_ci closedir(dir); 4003f4cbf05Sopenharmony_ci return false; 4013f4cbf05Sopenharmony_ci } 4023f4cbf05Sopenharmony_ci } 4033f4cbf05Sopenharmony_ci } 4043f4cbf05Sopenharmony_ci } 4053f4cbf05Sopenharmony_ci closedir(dir); 4063f4cbf05Sopenharmony_ci string currentPath = ExcludeTrailingPathDelimiter(path); 4073f4cbf05Sopenharmony_ci if (access(currentPath.c_str(), F_OK) == 0) { 4083f4cbf05Sopenharmony_ci if (!ChangeMode(currentPath, mode)) { 4093f4cbf05Sopenharmony_ci UTILS_LOGD("Failed to exec ChangeMode"); 4103f4cbf05Sopenharmony_ci return false; 4113f4cbf05Sopenharmony_ci } 4123f4cbf05Sopenharmony_ci } 4133f4cbf05Sopenharmony_ci return ret; 4143f4cbf05Sopenharmony_ci} 4153f4cbf05Sopenharmony_ci 4163f4cbf05Sopenharmony_cibool PathToRealPath(const string& path, string& realPath) 4173f4cbf05Sopenharmony_ci{ 4183f4cbf05Sopenharmony_ci if (path.empty()) { 4193f4cbf05Sopenharmony_ci UTILS_LOGD("path is empty!"); 4203f4cbf05Sopenharmony_ci return false; 4213f4cbf05Sopenharmony_ci } 4223f4cbf05Sopenharmony_ci 4233f4cbf05Sopenharmony_ci if ((path.length() >= PATH_MAX)) { 4243f4cbf05Sopenharmony_ci UTILS_LOGD("path len is error, the len is: [%{public}zu]", path.length()); 4253f4cbf05Sopenharmony_ci return false; 4263f4cbf05Sopenharmony_ci } 4273f4cbf05Sopenharmony_ci 4283f4cbf05Sopenharmony_ci char tmpPath[PATH_MAX] = {0}; 4293f4cbf05Sopenharmony_ci if (realpath(path.c_str(), tmpPath) == nullptr) { 4303f4cbf05Sopenharmony_ci UTILS_LOGE("path (%{public}s) to realpath error: %{public}s", path.c_str(), strerror(errno)); 4313f4cbf05Sopenharmony_ci return false; 4323f4cbf05Sopenharmony_ci } 4333f4cbf05Sopenharmony_ci 4343f4cbf05Sopenharmony_ci realPath = tmpPath; 4353f4cbf05Sopenharmony_ci if (access(realPath.c_str(), F_OK) != 0) { 4363f4cbf05Sopenharmony_ci UTILS_LOGE("check realpath (%{private}s) error: %{public}s", realPath.c_str(), strerror(errno)); 4373f4cbf05Sopenharmony_ci return false; 4383f4cbf05Sopenharmony_ci } 4393f4cbf05Sopenharmony_ci return true; 4403f4cbf05Sopenharmony_ci} 4413f4cbf05Sopenharmony_ci 4423f4cbf05Sopenharmony_ci#if defined(IOS_PLATFORM) || defined(_WIN32) 4433f4cbf05Sopenharmony_cistring TransformFileName(const string& fileName) 4443f4cbf05Sopenharmony_ci{ 4453f4cbf05Sopenharmony_ci string::size_type pos = fileName.find("."); 4463f4cbf05Sopenharmony_ci string transformfileName = ""; 4473f4cbf05Sopenharmony_ci if (pos == string::npos) { 4483f4cbf05Sopenharmony_ci transformfileName = fileName; 4493f4cbf05Sopenharmony_ci 4503f4cbf05Sopenharmony_ci#ifdef _WIN32 4513f4cbf05Sopenharmony_ci transformfileName = transformfileName.append(".dll"); 4523f4cbf05Sopenharmony_ci#elif defined IOS_PLATFORM 4533f4cbf05Sopenharmony_ci transformfileName = transformfileName.append(".dylib"); 4543f4cbf05Sopenharmony_ci#endif 4553f4cbf05Sopenharmony_ci 4563f4cbf05Sopenharmony_ci return transformfileName; 4573f4cbf05Sopenharmony_ci } else { 4583f4cbf05Sopenharmony_ci transformfileName = string(fileName).substr(0, pos + 1); 4593f4cbf05Sopenharmony_ci 4603f4cbf05Sopenharmony_ci#ifdef _WIN32 4613f4cbf05Sopenharmony_ci transformfileName = transformfileName.append("dll"); 4623f4cbf05Sopenharmony_ci#elif defined IOS_PLATFORM 4633f4cbf05Sopenharmony_ci transformfileName = transformfileName.append("dylib"); 4643f4cbf05Sopenharmony_ci#endif 4653f4cbf05Sopenharmony_ci 4663f4cbf05Sopenharmony_ci return transformfileName; 4673f4cbf05Sopenharmony_ci } 4683f4cbf05Sopenharmony_ci} 4693f4cbf05Sopenharmony_ci#endif 4703f4cbf05Sopenharmony_ci 4713f4cbf05Sopenharmony_ci} // OHOS 472