1fb299fa2Sopenharmony_ci/* 2fb299fa2Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at 6fb299fa2Sopenharmony_ci * 7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb299fa2Sopenharmony_ci * 9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and 13fb299fa2Sopenharmony_ci * limitations under the License. 14fb299fa2Sopenharmony_ci */ 15fb299fa2Sopenharmony_ci 16fb299fa2Sopenharmony_ci#include "utils_fs.h" 17fb299fa2Sopenharmony_ci#include <algorithm> 18fb299fa2Sopenharmony_ci#include <cerrno> 19fb299fa2Sopenharmony_ci#include <cstdint> 20fb299fa2Sopenharmony_ci#include <cstdlib> 21fb299fa2Sopenharmony_ci#include <dirent.h> 22fb299fa2Sopenharmony_ci#include <fcntl.h> 23fb299fa2Sopenharmony_ci#include <limits> 24fb299fa2Sopenharmony_ci#include <linux/reboot.h> 25fb299fa2Sopenharmony_ci#include <string> 26fb299fa2Sopenharmony_ci#include <sys/reboot.h> 27fb299fa2Sopenharmony_ci#include <sys/stat.h> 28fb299fa2Sopenharmony_ci#include <sys/syscall.h> 29fb299fa2Sopenharmony_ci#include <unistd.h> 30fb299fa2Sopenharmony_ci#include <vector> 31fb299fa2Sopenharmony_ci#include "log/log.h" 32fb299fa2Sopenharmony_ci 33fb299fa2Sopenharmony_cinamespace Updater { 34fb299fa2Sopenharmony_cinamespace Utils { 35fb299fa2Sopenharmony_ci 36fb299fa2Sopenharmony_ciint MkdirRecursive(const std::string &pathName, mode_t mode) 37fb299fa2Sopenharmony_ci{ 38fb299fa2Sopenharmony_ci size_t slashPos = 0; 39fb299fa2Sopenharmony_ci struct stat info {}; 40fb299fa2Sopenharmony_ci while (true) { 41fb299fa2Sopenharmony_ci slashPos = pathName.find_first_of("/", slashPos); 42fb299fa2Sopenharmony_ci if (slashPos == std::string::npos) { 43fb299fa2Sopenharmony_ci break; 44fb299fa2Sopenharmony_ci } 45fb299fa2Sopenharmony_ci if (slashPos == 0) { 46fb299fa2Sopenharmony_ci slashPos++; 47fb299fa2Sopenharmony_ci continue; 48fb299fa2Sopenharmony_ci } 49fb299fa2Sopenharmony_ci if (slashPos > PATH_MAX) { 50fb299fa2Sopenharmony_ci LOG(ERROR) << "path too long for mkdir"; 51fb299fa2Sopenharmony_ci return -1; 52fb299fa2Sopenharmony_ci } 53fb299fa2Sopenharmony_ci auto subDir = pathName.substr(0, slashPos); 54fb299fa2Sopenharmony_ci LOG(INFO) << "subDir : " << subDir; 55fb299fa2Sopenharmony_ci if (stat(subDir.c_str(), &info) != 0) { 56fb299fa2Sopenharmony_ci int ret = mkdir(subDir.c_str(), mode); 57fb299fa2Sopenharmony_ci if (ret && errno != EEXIST) { 58fb299fa2Sopenharmony_ci return ret; 59fb299fa2Sopenharmony_ci } 60fb299fa2Sopenharmony_ci } 61fb299fa2Sopenharmony_ci slashPos++; 62fb299fa2Sopenharmony_ci } 63fb299fa2Sopenharmony_ci int ret = mkdir(pathName.c_str(), mode); 64fb299fa2Sopenharmony_ci if (ret && errno != EEXIST) { 65fb299fa2Sopenharmony_ci return ret; 66fb299fa2Sopenharmony_ci } 67fb299fa2Sopenharmony_ci return 0; 68fb299fa2Sopenharmony_ci} 69fb299fa2Sopenharmony_ci 70fb299fa2Sopenharmony_ciint64_t GetFilesFromDirectory(const std::string &path, std::vector<std::string> &files, 71fb299fa2Sopenharmony_ci bool isRecursive) 72fb299fa2Sopenharmony_ci{ 73fb299fa2Sopenharmony_ci struct stat sb {}; 74fb299fa2Sopenharmony_ci if (stat(path.c_str(), &sb) == -1) { 75fb299fa2Sopenharmony_ci LOG(ERROR) << "Failed to stat"; 76fb299fa2Sopenharmony_ci return -1; 77fb299fa2Sopenharmony_ci } 78fb299fa2Sopenharmony_ci DIR *dirp = opendir(path.c_str()); 79fb299fa2Sopenharmony_ci struct dirent *dp; 80fb299fa2Sopenharmony_ci int64_t totalSize = 0; 81fb299fa2Sopenharmony_ci while ((dp = readdir(dirp)) != nullptr) { 82fb299fa2Sopenharmony_ci std::string fileName = path + "/" + dp->d_name; 83fb299fa2Sopenharmony_ci struct stat st {}; 84fb299fa2Sopenharmony_ci if (stat(fileName.c_str(), &st) == 0) { 85fb299fa2Sopenharmony_ci std::string tmpName = dp->d_name; 86fb299fa2Sopenharmony_ci if (tmpName == "." || tmpName == "..") { 87fb299fa2Sopenharmony_ci continue; 88fb299fa2Sopenharmony_ci } 89fb299fa2Sopenharmony_ci if (isRecursive && S_ISDIR(st.st_mode)) { 90fb299fa2Sopenharmony_ci totalSize += GetFilesFromDirectory(fileName, files, isRecursive); 91fb299fa2Sopenharmony_ci } 92fb299fa2Sopenharmony_ci files.push_back(fileName); 93fb299fa2Sopenharmony_ci totalSize += st.st_size; 94fb299fa2Sopenharmony_ci } 95fb299fa2Sopenharmony_ci } 96fb299fa2Sopenharmony_ci closedir(dirp); 97fb299fa2Sopenharmony_ci return totalSize; 98fb299fa2Sopenharmony_ci} 99fb299fa2Sopenharmony_ci 100fb299fa2Sopenharmony_cibool RemoveDir(const std::string &path) 101fb299fa2Sopenharmony_ci{ 102fb299fa2Sopenharmony_ci if (path.empty()) { 103fb299fa2Sopenharmony_ci LOG(ERROR) << "input path is empty."; 104fb299fa2Sopenharmony_ci return false; 105fb299fa2Sopenharmony_ci } 106fb299fa2Sopenharmony_ci std::string strPath = path; 107fb299fa2Sopenharmony_ci if (strPath.at(strPath.length() - 1) != '/') { 108fb299fa2Sopenharmony_ci strPath.append("/"); 109fb299fa2Sopenharmony_ci } 110fb299fa2Sopenharmony_ci DIR *d = opendir(strPath.c_str()); 111fb299fa2Sopenharmony_ci if (d != nullptr) { 112fb299fa2Sopenharmony_ci struct dirent *dt = nullptr; 113fb299fa2Sopenharmony_ci dt = readdir(d); 114fb299fa2Sopenharmony_ci while (dt != nullptr) { 115fb299fa2Sopenharmony_ci if (strcmp(dt->d_name, "..") == 0 || strcmp(dt->d_name, ".") == 0) { 116fb299fa2Sopenharmony_ci dt = readdir(d); 117fb299fa2Sopenharmony_ci continue; 118fb299fa2Sopenharmony_ci } 119fb299fa2Sopenharmony_ci struct stat st {}; 120fb299fa2Sopenharmony_ci auto file_name = strPath + std::string(dt->d_name); 121fb299fa2Sopenharmony_ci stat(file_name.c_str(), &st); 122fb299fa2Sopenharmony_ci if (S_ISDIR(st.st_mode)) { 123fb299fa2Sopenharmony_ci RemoveDir(file_name); 124fb299fa2Sopenharmony_ci } else { 125fb299fa2Sopenharmony_ci remove(file_name.c_str()); 126fb299fa2Sopenharmony_ci } 127fb299fa2Sopenharmony_ci dt = readdir(d); 128fb299fa2Sopenharmony_ci } 129fb299fa2Sopenharmony_ci closedir(d); 130fb299fa2Sopenharmony_ci } 131fb299fa2Sopenharmony_ci return rmdir(strPath.c_str()) == 0 ? true : false; 132fb299fa2Sopenharmony_ci} 133fb299fa2Sopenharmony_ci 134fb299fa2Sopenharmony_cibool IsFileExist(const std::string &path) 135fb299fa2Sopenharmony_ci{ 136fb299fa2Sopenharmony_ci struct stat st {}; 137fb299fa2Sopenharmony_ci if (stat(path.c_str(), &st) == 0 && S_ISREG(st.st_mode)) { 138fb299fa2Sopenharmony_ci return true; 139fb299fa2Sopenharmony_ci } 140fb299fa2Sopenharmony_ci return false; 141fb299fa2Sopenharmony_ci} 142fb299fa2Sopenharmony_ci 143fb299fa2Sopenharmony_cibool IsDirExist(const std::string &path) 144fb299fa2Sopenharmony_ci{ 145fb299fa2Sopenharmony_ci struct stat st {}; 146fb299fa2Sopenharmony_ci if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { 147fb299fa2Sopenharmony_ci return true; 148fb299fa2Sopenharmony_ci } 149fb299fa2Sopenharmony_ci return false; 150fb299fa2Sopenharmony_ci} 151fb299fa2Sopenharmony_ci} // Utils 152fb299fa2Sopenharmony_ci} // updater 153