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