• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "file_utils.h"
16 
17 #include <cerrno>
18 #include <cinttypes>
19 
20 #include <sys/stat.h>
21 #include <unistd.h>
22 
23 #include "sensors_errors.h"
24 
25 namespace OHOS {
26 namespace Sensors {
27 namespace {
28 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MISC_LOG_DOMAIN, "MiscdeviceFileUtils" };
29 const std::string CONFIG_DIR = "/vendor/etc/vibrator/";
30 constexpr int32_t FILE_SIZE_MAX = 0x5000;
31 constexpr int64_t READ_DATA_BUFF_SIZE = 256;
32 constexpr int32_t INVALID_FILE_SIZE = -1;
33 constexpr int32_t FILE_PATH_MAX = 1024;
34 }  // namespace
35 
ReadJsonFile(const std::string & filePath)36 std::string ReadJsonFile(const std::string &filePath)
37 {
38     if (filePath.empty()) {
39         MISC_HILOGE("Path is empty");
40         return {};
41     }
42     char realPath[PATH_MAX] = {};
43     if (realpath(filePath.c_str(), realPath) == nullptr) {
44         MISC_HILOGE("Path is error, %{public}d", errno);
45         return {};
46     }
47     if (!CheckFileDir(realPath, CONFIG_DIR)) {
48         MISC_HILOGE("File dir is invalid");
49         return {};
50     }
51     if (!CheckFileExtendName(realPath, "json")) {
52         MISC_HILOGE("Unable to parse files other than json format");
53         return {};
54     }
55     if (!IsFileExists(realPath)) {
56         MISC_HILOGE("File not exist");
57         return {};
58     }
59     if (!CheckFileSize(realPath)) {
60         MISC_HILOGE("File size out of read range");
61         return {};
62     }
63     return ReadFile(realPath);
64 }
65 
GetFileSize(const std::string & filePath)66 int32_t GetFileSize(const std::string& filePath)
67 {
68     struct stat statbuf = { 0 };
69     if (stat(filePath.c_str(), &statbuf) != 0) {
70         MISC_HILOGE("Get file size error");
71         return INVALID_FILE_SIZE;
72     }
73     return statbuf.st_size;
74 }
75 
GetFileSize(int32_t fd)76 int64_t GetFileSize(int32_t fd)
77 {
78     if (fd < 0) {
79         MISC_HILOGE("fd is invalid, fd:%{public}d", fd);
80         return INVALID_FILE_SIZE;
81     }
82     struct stat64 statbuf = { 0 };
83     if (fstat64(fd, &statbuf) != 0) {
84         MISC_HILOGE("fstat error, errno:%{public}d", errno);
85         return INVALID_FILE_SIZE;
86     }
87     return statbuf.st_size;
88 }
89 
CheckFileDir(const std::string & filePath,const std::string & dir)90 bool CheckFileDir(const std::string& filePath, const std::string& dir)
91 {
92     if (filePath.compare(0, CONFIG_DIR.size(), CONFIG_DIR) != 0) {
93         MISC_HILOGE("filePath dir is invalid");
94         return false;
95     }
96     return true;
97 }
98 
CheckFileSize(const std::string & filePath)99 bool CheckFileSize(const std::string& filePath)
100 {
101     int32_t fileSize = GetFileSize(filePath);
102     if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) {
103         MISC_HILOGE("File size out of read range");
104         return false;
105     }
106     return true;
107 }
108 
CheckFileExtendName(const std::string & filePath,const std::string & checkExtension)109 bool CheckFileExtendName(const std::string& filePath, const std::string& checkExtension)
110 {
111     std::string::size_type pos = filePath.find_last_of('.');
112     if (pos == std::string::npos) {
113         MISC_HILOGE("File is not find extension");
114         return false;
115     }
116     return (filePath.substr(pos + 1, filePath.npos) == checkExtension);
117 }
118 
IsFileExists(const std::string & fileName)119 bool IsFileExists(const std::string& fileName)
120 {
121     return (access(fileName.c_str(), F_OK) == 0);
122 }
123 
ReadFile(const std::string & filePath)124 std::string ReadFile(const std::string &filePath)
125 {
126     FILE* fp = fopen(filePath.c_str(), "r");
127     CHKPS(fp);
128     std::string dataStr;
129     char buf[READ_DATA_BUFF_SIZE] = { '\0' };
130     while (fgets(buf, sizeof(buf), fp) != nullptr) {
131         dataStr += buf;
132     }
133     if (fclose(fp) != 0) {
134         MISC_HILOGW("Close file failed");
135     }
136     return dataStr;
137 }
138 
ReadFd(const RawFileDescriptor & rawFd)139 std::string ReadFd(const RawFileDescriptor &rawFd)
140 {
141     if (rawFd.fd < 0) {
142         MISC_HILOGE("fd is invalid, fd:%{public}d", rawFd.fd);
143         return {};
144     }
145     int64_t fdSize = GetFileSize(rawFd.fd);
146     if ((rawFd.offset < 0) || (rawFd.offset > fdSize)) {
147         MISC_HILOGE("offset is invalid, offset:%{public}" PRId64, rawFd.offset);
148         return {};
149     }
150     if ((rawFd.length <= 0) || (rawFd.length > fdSize - rawFd.offset)) {
151         MISC_HILOGE("length is invalid, length:%{public}" PRId64, rawFd.length);
152         return {};
153     }
154     FILE* fp = fdopen(rawFd.fd, "r");
155     CHKPS(fp);
156     if (fseek(fp, rawFd.offset, SEEK_SET) != 0) {
157         MISC_HILOGE("fseek failed, errno:%{public}d", errno);
158         if (fclose(fp) != 0) {
159             MISC_HILOGW("Close file failed, errno:%{public}d", errno);
160         }
161         return {};
162     }
163     std::string dataStr;
164     char buf[READ_DATA_BUFF_SIZE] = { '\0' };
165     int64_t alreadyRead = 0;
166     while (alreadyRead < rawFd.length) {
167         int64_t onceRead = std::min(rawFd.length - alreadyRead, READ_DATA_BUFF_SIZE - 1);
168         fgets(buf, onceRead + 1, fp);
169         dataStr += buf;
170         alreadyRead = ftell(fp) - rawFd.offset;
171     }
172     if (fclose(fp) != 0) {
173         MISC_HILOGW("Close file failed after read, errno:%{public}d", errno);
174     }
175     return dataStr;
176 }
177 
GetFileSuffix(int32_t fd)178 std::string GetFileSuffix(int32_t fd)
179 {
180     std::string fdPath = "/proc/self/fd/" + std::to_string(fd);
181     char filePath[FILE_PATH_MAX + 1] = { '\0' };
182     ssize_t ret = readlink(fdPath.c_str(), filePath, FILE_PATH_MAX);
183     if (ret < 0 || ret > FILE_PATH_MAX) {
184         MISC_HILOGE("Readlink failed, errno:%{public}d", errno);
185         return {};
186     }
187     std::string fileAbsolutePath(filePath);
188     size_t pos = fileAbsolutePath.find_last_of('.');
189     if (pos == std::string::npos) {
190         MISC_HILOGE("File suffix is invalid, fileAbsolutePath:%{public}s", fileAbsolutePath.c_str());
191         return {};
192     }
193     return fileAbsolutePath.substr(pos + 1);
194 }
195 }  // namespace Sensors
196 }  // namespace OHOS
197