• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "file_utils.h"
17 
18 #include <fcntl.h>
19 #include <fstream>
20 #include <sys/time.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 
24 #include "font_hilog.h"
25 #include "securec.h"
26 
27 namespace OHOS {
28 namespace Global {
29 namespace FontManager {
30 static constexpr int32_t MAX_SIZE = 1024 * 20;
31 static constexpr uint32_t TIME_STRING_LENGTH = 20;
32 static constexpr uint32_t BEGIN_YEAR = 1900;
33 
CheckPathExist(const std::string & pathName)34 bool FileUtils::CheckPathExist(const std::string &pathName)
35 {
36     if (pathName.empty()) {
37         FONT_LOGE("CheckPathExsit pathName is empty.");
38         return false;
39     }
40     std::error_code errorCode;
41     bool ret = std::filesystem::exists(pathName, errorCode);
42     if (errorCode.operator bool()) {
43         FONT_LOGE("CheckPathExsit %{public}s exists error, error code = %{public}d",
44             pathName.c_str(), errorCode.value());
45         return false;
46     }
47     return ret;
48 }
49 
CreateFileWithPermission(const std::string & filePath,const std::string & defalutStr)50 bool FileUtils::CreateFileWithPermission(const std::string &filePath, const std::string &defalutStr)
51 {
52     if (filePath.empty() || strstr(filePath.c_str(), "/.") != NULL || strstr(filePath.c_str(), "./") != NULL) {
53         FONT_LOGE("filePath %{public}s is invalid", filePath.c_str());
54         return false;
55     }
56     std::error_code errorCode;
57     std::filesystem::path path(filePath);
58     std::fstream file(path, std::ios::out | std::ios::trunc);
59     if (!file) {
60         FONT_LOGE("Create File path %{public}s failed", filePath.c_str());
61         return false;
62     }
63     if (!defalutStr.empty()) {
64         file << defalutStr;
65     }
66     file.close();
67 
68     std::filesystem::permissions(
69         filePath, std::filesystem::perms::others_write, std::filesystem::perm_options::remove, errorCode);
70     if (errorCode.operator bool()) {
71         FONT_LOGE("Assign permissions failed, path = %{public}s,error message : %{public}s",
72             filePath.c_str(), errorCode.message().c_str());
73         return false;
74     }
75     return true;
76 }
77 
CreatDirWithPermission(const std::string & fileDir)78 bool FileUtils::CreatDirWithPermission(const std::string &fileDir)
79 {
80     if (fileDir.empty() || strstr(fileDir.c_str(), "/.") != NULL || strstr(fileDir.c_str(), "./") != NULL) {
81         FONT_LOGE("dirName %{public}s is invalid", fileDir.c_str());
82         return false;
83     }
84     std::error_code errorCode;
85     std::filesystem::create_directory(fileDir, errorCode);
86     if (errorCode.operator bool()) {
87         FONT_LOGE("Create directory dir %{public}s fail, error message : %{public}s", fileDir.c_str(),
88             errorCode.message().c_str());
89         return false;
90     }
91     std::filesystem::permissions(fileDir, std::filesystem::perms::others_write,
92         std::filesystem::perm_options::remove, errorCode);
93     if (errorCode.operator bool()) {
94         FONT_LOGE("Assign permissions failed, path = %{public}s,error message : %{public}s", fileDir.c_str(),
95             errorCode.message().c_str());
96         return false;
97     }
98     return true;
99 }
100 
GetFilePathByFd(const int32_t & fd)101 std::string FileUtils::GetFilePathByFd(const int32_t &fd)
102 {
103     auto filePath = std::make_unique<char[]>(PATH_MAX);
104     if (filePath == nullptr) {
105         FONT_LOGE("make_unique failed , filePath is null !");
106         return "";
107     }
108     std::string linkPath = std::string("/proc/") + std::to_string(getpid()) + "/fd/" + std::to_string(fd);
109     ssize_t pathLen = readlink(linkPath.c_str(), filePath.get(), PATH_MAX - 1);
110     if (pathLen < 0) {
111         FONT_LOGE("fd readlink: %{private}s failed, errno: %{public}d", linkPath.c_str(), errno);
112         return "";
113     }
114     filePath[pathLen] = '\0';
115     return std::string(filePath.get());
116 }
117 
GetFileName(const std::string & path)118 std::string FileUtils::GetFileName(const std::string &path)
119 {
120     std::string split = "/";
121     size_t pos = path.find_last_of(split);
122     if (pos == std::string::npos) {
123         return path;
124     }
125     return path.substr(pos + 1);
126 }
127 
CopyFile(int32_t sourceFd,const std::string & path)128 bool FileUtils::CopyFile(int32_t sourceFd, const std::string& path)
129 {
130     constexpr int32_t filePermission = 0644;
131     int32_t targetFd = open(path.c_str(), O_WRONLY | O_CREAT | O_SYNC, filePermission);
132     bool ret = CopyFileByFd(sourceFd, targetFd);
133     if (targetFd >= 0) {
134         close(targetFd);
135     }
136     return ret;
137 }
138 
CopyFileByFd(int32_t sourceFd,int32_t targetFd)139 bool FileUtils::CopyFileByFd(int32_t sourceFd, int32_t targetFd)
140 {
141     if (sourceFd < 0) {
142         FONT_LOGE("Failed to open source file");
143         return false;
144     }
145     struct stat sourceStat;
146     if (fstat(sourceFd, &sourceStat) < 0) {
147         FONT_LOGE("Failed to get source file stat");
148         return false;
149     }
150     if (targetFd < 0) {
151         FONT_LOGE("Failed to write to target file");
152         return false;
153     }
154     lseek(sourceFd, 0, SEEK_SET);
155     lseek(targetFd, 0, SEEK_SET);
156     constexpr int32_t bufferSize = MAX_SIZE;
157     char buffer[bufferSize];
158     int32_t bytesRead = 0;
159     int32_t bytesWritten = 0;
160     while ((bytesRead = read(sourceFd, buffer, sizeof(buffer))) > 0) {
161         bytesWritten = write(targetFd, buffer, bytesRead);
162         if (bytesWritten != bytesRead) {
163             FONT_LOGE("Failed to write to target file");
164             return false;
165         }
166     }
167     return true;
168 }
169 
GetFileTime()170 std::string FileUtils::GetFileTime()
171 {
172     struct timeval time;
173     gettimeofday(&time, nullptr);
174     struct tm timeInfo;
175     localtime_r(&time.tv_sec, &timeInfo);
176 
177     char timeBuf[TIME_STRING_LENGTH] = {0};
178     int result = sprintf_s(timeBuf, TIME_STRING_LENGTH, "%04u%02d%02d-%02d%02d%02d",
179         timeInfo.tm_year + BEGIN_YEAR,
180         timeInfo.tm_mon + 1,
181         timeInfo.tm_mday,
182         timeInfo.tm_hour,
183         timeInfo.tm_min,
184         timeInfo.tm_sec);
185     if (result < 0) {
186         FONT_LOGE("GetFileTimeStr sprintf_s error");
187         return "";
188     }
189     return timeBuf;
190 }
191 
RenameFile(const std::string & src,const std::string & dest)192 bool FileUtils::RenameFile(const std::string& src, const std::string& dest)
193 {
194     if (!CheckPathExist(src)) {
195         FONT_LOGI("file %{public}s is not exist", src.c_str());
196         return false;
197     }
198     std::error_code errorCode;
199     std::filesystem::rename(src, dest, errorCode);
200     if (errorCode.operator bool()) {
201         FONT_LOGE("filesystem::rename error, error code = %{public}d", errorCode.value());
202         return false;
203     }
204     return true;
205 }
206 
RemoveFile(const std::string & fileName)207 bool FileUtils::RemoveFile(const std::string &fileName)
208 {
209     if (!CheckPathExist(fileName)) {
210         FONT_LOGI("file %{public}s is not exist", fileName.c_str());
211         return true;
212     }
213     return RemoveAll(fileName);
214 }
215 
DeleteDir(const std::string & rootPath,bool isDeleteRootDir)216 void FileUtils::DeleteDir(const std::string &rootPath, bool isDeleteRootDir)
217 {
218     if (!CheckPathExist(rootPath)) {
219         FONT_LOGI("dir %{public}s is not exist", rootPath.c_str());
220         return;
221     }
222     auto myPath = std::filesystem::path(rootPath);
223     if (isDeleteRootDir) {
224         RemoveAll(myPath);
225         return;
226     }
227 
228     for (auto const &dirEntry : std::filesystem::directory_iterator{ myPath }) {
229         RemoveAll(dirEntry.path());
230     }
231 }
232 
RemoveAll(const std::filesystem::path & path)233 bool FileUtils::RemoveAll(const std::filesystem::path &path)
234 {
235     std::error_code errorCode;
236     std::filesystem::remove_all(path, errorCode);
237     if (errorCode.operator bool()) {
238         FONT_LOGI("remove dir %{public}s fail, error message : %{public}s", path.c_str(),
239             errorCode.message().c_str());
240         return false;
241     }
242     return true;
243 }
244 } // namespace FontManager
245 } // namespace Global
246 } // namespace OHOS
247 
248