1/* 2 * Copyright (c) 2024 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 "utils_fs.h" 17#include <algorithm> 18#include <cerrno> 19#include <cstdint> 20#include <cstdlib> 21#include <dirent.h> 22#include <fcntl.h> 23#include <limits> 24#include <linux/reboot.h> 25#include <string> 26#include <sys/reboot.h> 27#include <sys/stat.h> 28#include <sys/syscall.h> 29#include <unistd.h> 30#include <vector> 31#include "log/log.h" 32 33namespace Updater { 34namespace Utils { 35 36int MkdirRecursive(const std::string &pathName, mode_t mode) 37{ 38 size_t slashPos = 0; 39 struct stat info {}; 40 while (true) { 41 slashPos = pathName.find_first_of("/", slashPos); 42 if (slashPos == std::string::npos) { 43 break; 44 } 45 if (slashPos == 0) { 46 slashPos++; 47 continue; 48 } 49 if (slashPos > PATH_MAX) { 50 LOG(ERROR) << "path too long for mkdir"; 51 return -1; 52 } 53 auto subDir = pathName.substr(0, slashPos); 54 LOG(INFO) << "subDir : " << subDir; 55 if (stat(subDir.c_str(), &info) != 0) { 56 int ret = mkdir(subDir.c_str(), mode); 57 if (ret && errno != EEXIST) { 58 return ret; 59 } 60 } 61 slashPos++; 62 } 63 int ret = mkdir(pathName.c_str(), mode); 64 if (ret && errno != EEXIST) { 65 return ret; 66 } 67 return 0; 68} 69 70int64_t GetFilesFromDirectory(const std::string &path, std::vector<std::string> &files, 71 bool isRecursive) 72{ 73 struct stat sb {}; 74 if (stat(path.c_str(), &sb) == -1) { 75 LOG(ERROR) << "Failed to stat"; 76 return -1; 77 } 78 DIR *dirp = opendir(path.c_str()); 79 struct dirent *dp; 80 int64_t totalSize = 0; 81 while ((dp = readdir(dirp)) != nullptr) { 82 std::string fileName = path + "/" + dp->d_name; 83 struct stat st {}; 84 if (stat(fileName.c_str(), &st) == 0) { 85 std::string tmpName = dp->d_name; 86 if (tmpName == "." || tmpName == "..") { 87 continue; 88 } 89 if (isRecursive && S_ISDIR(st.st_mode)) { 90 totalSize += GetFilesFromDirectory(fileName, files, isRecursive); 91 } 92 files.push_back(fileName); 93 totalSize += st.st_size; 94 } 95 } 96 closedir(dirp); 97 return totalSize; 98} 99 100bool RemoveDir(const std::string &path) 101{ 102 if (path.empty()) { 103 LOG(ERROR) << "input path is empty."; 104 return false; 105 } 106 std::string strPath = path; 107 if (strPath.at(strPath.length() - 1) != '/') { 108 strPath.append("/"); 109 } 110 DIR *d = opendir(strPath.c_str()); 111 if (d != nullptr) { 112 struct dirent *dt = nullptr; 113 dt = readdir(d); 114 while (dt != nullptr) { 115 if (strcmp(dt->d_name, "..") == 0 || strcmp(dt->d_name, ".") == 0) { 116 dt = readdir(d); 117 continue; 118 } 119 struct stat st {}; 120 auto file_name = strPath + std::string(dt->d_name); 121 stat(file_name.c_str(), &st); 122 if (S_ISDIR(st.st_mode)) { 123 RemoveDir(file_name); 124 } else { 125 remove(file_name.c_str()); 126 } 127 dt = readdir(d); 128 } 129 closedir(d); 130 } 131 return rmdir(strPath.c_str()) == 0 ? true : false; 132} 133 134bool IsFileExist(const std::string &path) 135{ 136 struct stat st {}; 137 if (stat(path.c_str(), &st) == 0 && S_ISREG(st.st_mode)) { 138 return true; 139 } 140 return false; 141} 142 143bool IsDirExist(const std::string &path) 144{ 145 struct stat st {}; 146 if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { 147 return true; 148 } 149 return false; 150} 151} // Utils 152} // updater 153