• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #include <dirent.h>
16 #include <fcntl.h>
17 #include <sys/stat.h>
18 #include <unistd.h>
19 
20 #include <algorithm>
21 #include <cstdio>
22 #include <filesystem>
23 #include <sstream>
24 #include <string>
25 #include <vector>
26 
27 #include "file_deal.h"
28 #include "hilog_wrapper.h"
29 
30 namespace fs = std::filesystem;
31 namespace OHOS {
32 namespace WallpaperMgrService {
33 constexpr const mode_t MODE = 0740;
34 constexpr const int32_t SLICE_SIZE = 2;
35 constexpr const int32_t PATH_SIZE_MIX = 4;
36 constexpr const char *DEFAULT_ANONYMOUS = "***";
FileDeal(void)37 FileDeal::FileDeal(void)
38 {
39 }
~FileDeal()40 FileDeal::~FileDeal()
41 {
42 }
IsDirExist(std::string path)43 bool FileDeal::IsDirExist(std::string path)
44 {
45     DIR *dp;
46     if ((dp = opendir(path.c_str())) == NULL) {
47         HILOG_ERROR("FileDeal : openDir  is not exist, errInfo=%{public}s", strerror(errno));
48         return false;
49     }
50     closedir(dp);
51     return true;
52 }
53 
Mkdir(const std::string & path)54 bool FileDeal::Mkdir(const std::string &path)
55 {
56     if (!IsDirExist(path)) {
57         if (mkdir(path.c_str(), MODE) != 0) {
58             HILOG_ERROR("FileDeal : mkdir errInfo=%{public}s", strerror(errno));
59             return false;
60         }
61     }
62     return true;
63 }
64 
CopyFile(const std::string & sourceFile,const std::string & newFile)65 bool FileDeal::CopyFile(const std::string &sourceFile, const std::string &newFile)
66 {
67     std::filesystem::path dstPath(newFile);
68     std::filesystem::path srcPath(sourceFile);
69     std::error_code errCode;
70     if (!std::filesystem::copy_file(srcPath, dstPath, std::filesystem::copy_options::overwrite_existing, errCode)) {
71         HILOG_ERROR("Failed to copy file, error code: %{public}d", errCode.value());
72         return false;
73     }
74     if (!ForcedRefreshDisk(newFile)) {
75         HILOG_WARN("ForcedRefreshDisk failed!");
76     }
77     return true;
78 }
79 
DeleteFile(const std::string & sourceFile)80 bool FileDeal::DeleteFile(const std::string &sourceFile)
81 {
82     if (!IsFileExist(sourceFile)) {
83         return true;
84     }
85     if (remove(sourceFile.c_str()) < 0) {
86         HILOG_ERROR("Failed to remove source file, errInfo=%{public}s.", strerror(errno));
87         return false;
88     }
89     return true;
90 }
91 
DeleteDir(const std::string & path,bool deleteRootDir)92 bool FileDeal::DeleteDir(const std::string &path, bool deleteRootDir)
93 {
94     DIR *dir = opendir(path.c_str());
95     if (dir == nullptr) {
96         return false;
97     }
98     dirent *dirent;
99     while ((dirent = readdir(dir)) != nullptr) {
100         if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) {
101             continue;
102         }
103         std::string fullPath = path;
104         if (path[path.size() - 1] != '/') {
105             fullPath += '/';
106         }
107         fullPath += dirent->d_name;
108         if (dirent->d_type == DT_DIR) {
109             if (!DeleteDir(fullPath)) {
110                 closedir(dir);
111                 return false;
112             }
113         } else if (remove(fullPath.c_str()) < 0) {
114             HILOG_ERROR("remove failed, fullPath=%{public}s, errInfo=%{public}s", ToBeAnonymous(fullPath).c_str(),
115                 strerror(errno));
116             closedir(dir);
117             return false;
118         }
119     }
120     closedir(dir);
121     if (deleteRootDir && rmdir(path.c_str()) != 0) {
122         HILOG_ERROR("remove failed, path=%{public}s, errInfo=%{public}s", path.c_str(), strerror(errno));
123         return false;
124     }
125     return true;
126 }
127 
IsFileExist(const std::string & name)128 bool FileDeal::IsFileExist(const std::string &name)
129 {
130     if (access(name.c_str(), F_OK) != 0) {
131         HILOG_DEBUG("FileDeal : access errInfo=%{public}s", strerror(errno));
132         return false;
133     }
134     return true;
135 }
136 
GetExtension(const std::string & filePath)137 std::string FileDeal::GetExtension(const std::string &filePath)
138 {
139     std::string filename = filePath;
140     std::string extension = "";
141     std::string::size_type pos = filePath.find_last_of('/');
142     if (pos != std::string::npos) {
143         if (pos + 1 < filePath.length()) {
144             filename = filePath.substr(pos + 1);
145         }
146     }
147 
148     pos = filename.find_last_of('.');
149     if (pos != std::string::npos && pos + 1 < filename.length()) {
150         extension = filename.substr(pos);
151         std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
152     }
153     return extension;
154 }
GetRealPath(const std::string & inOriPath,std::string & outRealPath)155 bool FileDeal::GetRealPath(const std::string &inOriPath, std::string &outRealPath)
156 {
157     char realPath[PATH_MAX + 1] = { 0x00 };
158     if (inOriPath.size() > PATH_MAX || realpath(inOriPath.c_str(), realPath) == nullptr) {
159         HILOG_ERROR("get real path fail!");
160         return false;
161     }
162     outRealPath = std::string(realPath);
163     if (!IsFileExist(outRealPath)) {
164         HILOG_ERROR("real path file is not exist! %{public}s", outRealPath.c_str());
165         return false;
166     }
167     if (outRealPath != inOriPath) {
168         HILOG_ERROR("illegal file path input %{public}s", inOriPath.c_str());
169         return false;
170     }
171     return true;
172 }
IsZipFile(const std::string & filePath)173 bool FileDeal::IsZipFile(const std::string &filePath)
174 {
175     fs::path file(filePath);
176     if (fs::exists(file) && fs::is_regular_file(file)) {
177         std::string extension = file.extension().string();
178         if (extension == ".zip") {
179             return true;
180         }
181     }
182     HILOG_ERROR("this is not a zip.filePath:%{private}s", filePath.c_str());
183     return false;
184 }
ForcedRefreshDisk(const std::string & sourcePath)185 bool FileDeal::ForcedRefreshDisk(const std::string &sourcePath)
186 {
187     std::string fileRealPath;
188     if (!GetRealPath(sourcePath, fileRealPath)) {
189         HILOG_ERROR("get real path file failed!");
190         return false;
191     }
192     FILE *file = std::fopen(fileRealPath.c_str(), "rb");
193     if (file == nullptr) {
194         HILOG_ERROR("Fopen failed, %{public}s, %{public}s", fileRealPath.c_str(), strerror(errno));
195         return false;
196     }
197     if (fflush(file) != 0) {
198         HILOG_ERROR("fflush file failed, errno=%{public}d", errno);
199         fclose(file);
200         return false;
201     }
202     if (fsync(fileno(file)) != 0) {
203         HILOG_ERROR("fsync file failed, errno=%{public}d", errno);
204         fclose(file);
205         return false;
206     }
207     (void)fclose(file);
208     return true;
209 }
IsFileExistInDir(const std::string & path)210 bool FileDeal::IsFileExistInDir(const std::string &path)
211 {
212     DIR *dp = opendir(path.c_str());
213     if (dp == nullptr) {
214         HILOG_ERROR("FileDeal : openDir  is error, errInfo=%{public}s", strerror(errno));
215         return false;
216     }
217     dirent *dir = readdir(dp);
218     while (dir != nullptr) {
219         if (dir->d_type == DT_DIR) {
220             if (strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0) {
221                 closedir(dp);
222                 return true;
223             }
224         } else {
225             closedir(dp);
226             return true;
227         }
228         dir = readdir(dp);
229     }
230     closedir(dp);
231     HILOG_INFO("Dir is empty");
232     return false;
233 }
234 
ToBeAnonymous(const std::string & path)235 std::string FileDeal::ToBeAnonymous(const std::string &path)
236 {
237     std::vector<std::string> pathVector;
238     std::stringstream wallpaperPath(path);
239     std::string pathName;
240     char delimiter = '/';
241     while (std::getline(wallpaperPath, pathName, delimiter)) {
242         if (!pathName.empty()) {
243             pathVector.push_back(pathName);
244         }
245     }
246 
247     if (pathVector.size() <= PATH_SIZE_MIX) {
248         return DEFAULT_ANONYMOUS;
249     }
250     return pathVector[0] + "/" + pathVector[1] + "/" + DEFAULT_ANONYMOUS + "/"
251            + pathVector[pathVector.size() - SLICE_SIZE] + "/" + pathVector.back();
252 }
253 } // namespace WallpaperMgrService
254 } // namespace OHOS
255