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
33 namespace Updater {
34 namespace Utils {
35
MkdirRecursive(const std::string & pathName,mode_t mode)36 int 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
GetFilesFromDirectory(const std::string & path,std::vector<std::string> & files,bool isRecursive)70 int64_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
RemoveDir(const std::string & path)100 bool 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
IsFileExist(const std::string & path)134 bool 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
IsDirExist(const std::string & path)143 bool 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