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
24 #include "file_deal.h"
25 #include "hilog_wrapper.h"
26
27 namespace fs = std::filesystem;
28 namespace OHOS {
29 namespace WallpaperMgrService {
30 constexpr mode_t MODE = 0740;
FileDeal(void)31 FileDeal::FileDeal(void)
32 {
33 }
~FileDeal()34 FileDeal::~FileDeal()
35 {
36 }
IsDirExist(std::string path)37 bool FileDeal::IsDirExist(std::string path)
38 {
39 DIR *dp;
40 if ((dp = opendir(path.c_str())) == NULL) {
41 HILOG_ERROR("FileDeal : openDir is not exist, errInfo=%{public}s", strerror(errno));
42 return false;
43 }
44 closedir(dp);
45 return true;
46 }
47
Mkdir(const std::string & path)48 bool FileDeal::Mkdir(const std::string &path)
49 {
50 if (!IsDirExist(path)) {
51 if (mkdir(path.c_str(), MODE) != 0) {
52 HILOG_ERROR("FileDeal : mkdir errInfo=%{public}s", strerror(errno));
53 return false;
54 }
55 }
56 return true;
57 }
58
CopyFile(const std::string & sourceFile,const std::string & newFile)59 bool FileDeal::CopyFile(const std::string &sourceFile, const std::string &newFile)
60 {
61 std::filesystem::path dstPath(newFile);
62 std::filesystem::path srcPath(sourceFile);
63 std::error_code errCode;
64 if (!std::filesystem::copy_file(srcPath, dstPath, std::filesystem::copy_options::overwrite_existing, errCode)) {
65 HILOG_ERROR("Failed to copy file, error code: %{public}d", errCode.value());
66 return false;
67 }
68 if (!ForcedRefreshDisk(newFile)) {
69 HILOG_WARN("ForcedRefreshDisk failed!");
70 }
71 return true;
72 }
73
DeleteFile(const std::string & sourceFile)74 bool FileDeal::DeleteFile(const std::string &sourceFile)
75 {
76 if (!IsFileExist(sourceFile)) {
77 return true;
78 }
79 if (remove(sourceFile.c_str()) < 0) {
80 HILOG_ERROR("Failed to remove source file, errInfo=%{public}s.", strerror(errno));
81 return false;
82 }
83 return true;
84 }
85
IsFileExist(const std::string & name)86 bool FileDeal::IsFileExist(const std::string &name)
87 {
88 if (access(name.c_str(), F_OK) != 0) {
89 HILOG_DEBUG("FileDeal : access errInfo=%{public}s", strerror(errno));
90 return false;
91 }
92 return true;
93 }
94
GetExtension(const std::string & filePath)95 std::string FileDeal::GetExtension(const std::string &filePath)
96 {
97 std::string filename = filePath;
98 std::string extension = "";
99 std::string::size_type pos = filePath.find_last_of('/');
100 if (pos != std::string::npos) {
101 if (pos + 1 < filePath.length()) {
102 filename = filePath.substr(pos + 1);
103 }
104 }
105
106 pos = filename.find_last_of('.');
107 if (pos != std::string::npos && pos + 1 < filename.length()) {
108 extension = filename.substr(pos);
109 std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
110 }
111 return extension;
112 }
GetRealPath(const std::string & inOriPath,std::string & outRealPath)113 bool FileDeal::GetRealPath(const std::string &inOriPath, std::string &outRealPath)
114 {
115 char realPath[PATH_MAX + 1] = { 0x00 };
116 if (inOriPath.size() > PATH_MAX || realpath(inOriPath.c_str(), realPath) == nullptr) {
117 HILOG_ERROR("get real path fail!");
118 return false;
119 }
120 outRealPath = std::string(realPath);
121 if (!IsFileExist(outRealPath)) {
122 HILOG_ERROR("real path file is not exist! %{public}s", outRealPath.c_str());
123 return false;
124 }
125 if (outRealPath != inOriPath) {
126 HILOG_ERROR("illegal file path input %{public}s", inOriPath.c_str());
127 return false;
128 }
129 return true;
130 }
IsZipFile(const std::string & filePath)131 bool FileDeal::IsZipFile(const std::string &filePath)
132 {
133 fs::path file(filePath);
134 if (fs::exists(file) && fs::is_regular_file(file)) {
135 std::string extension = file.extension().string();
136 if (extension == ".zip") {
137 return true;
138 }
139 }
140 HILOG_ERROR("this is not a zip.filePath:%{private}s", filePath.c_str());
141 return false;
142 }
ForcedRefreshDisk(const std::string & sourcePath)143 bool FileDeal::ForcedRefreshDisk(const std::string &sourcePath)
144 {
145 std::string fileRealPath;
146 if (!GetRealPath(sourcePath, fileRealPath)) {
147 HILOG_ERROR("get real path file failed!");
148 return false;
149 }
150 FILE *file = std::fopen(fileRealPath.c_str(), "rb");
151 if (file == nullptr) {
152 HILOG_ERROR("Fopen failed, %{public}s, %{public}s", fileRealPath.c_str(), strerror(errno));
153 return false;
154 }
155 if (fflush(file) != 0) {
156 HILOG_ERROR("fflush file failed, errno=%{public}d", errno);
157 fclose(file);
158 return false;
159 }
160 if (fsync(fileno(file)) != 0) {
161 HILOG_ERROR("fsync file failed, errno=%{public}d", errno);
162 fclose(file);
163 return false;
164 }
165 (void)fclose(file);
166 return true;
167 }
168 } // namespace WallpaperMgrService
169 } // namespace OHOS
170