158ec469eSopenharmony_ci/* 258ec469eSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 358ec469eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 458ec469eSopenharmony_ci * you may not use this file except in compliance with the License. 558ec469eSopenharmony_ci * You may obtain a copy of the License at 658ec469eSopenharmony_ci * 758ec469eSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 858ec469eSopenharmony_ci * 958ec469eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1058ec469eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1158ec469eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1258ec469eSopenharmony_ci * See the License for the specific language governing permissions and 1358ec469eSopenharmony_ci * limitations under the License. 1458ec469eSopenharmony_ci */ 1558ec469eSopenharmony_ci#include "file_utils.h" 1658ec469eSopenharmony_ci 1758ec469eSopenharmony_ci#include <cerrno> 1858ec469eSopenharmony_ci#include <cinttypes> 1958ec469eSopenharmony_ci#include <sys/stat.h> 2058ec469eSopenharmony_ci#include <unistd.h> 2158ec469eSopenharmony_ci 2258ec469eSopenharmony_ci#include "securec.h" 2358ec469eSopenharmony_ci#include "sensors_errors.h" 2458ec469eSopenharmony_ci 2558ec469eSopenharmony_ci#undef LOG_TAG 2658ec469eSopenharmony_ci#define LOG_TAG "MiscdeviceFileUtils" 2758ec469eSopenharmony_ci 2858ec469eSopenharmony_cinamespace OHOS { 2958ec469eSopenharmony_cinamespace Sensors { 3058ec469eSopenharmony_cinamespace { 3158ec469eSopenharmony_ciconst std::string CONFIG_DIR = "/vendor/etc/vibrator/"; 3258ec469eSopenharmony_ciconstexpr int32_t FILE_SIZE_MAX = 0x5000; 3358ec469eSopenharmony_ciconstexpr int64_t READ_DATA_BUFF_SIZE = 256; 3458ec469eSopenharmony_ciconstexpr int32_t INVALID_FILE_SIZE = -1; 3558ec469eSopenharmony_ciconstexpr int32_t FILE_PATH_MAX = 1024; 3658ec469eSopenharmony_ci} // namespace 3758ec469eSopenharmony_ci 3858ec469eSopenharmony_cistd::string ReadJsonFile(const std::string &filePath) 3958ec469eSopenharmony_ci{ 4058ec469eSopenharmony_ci if (filePath.empty()) { 4158ec469eSopenharmony_ci MISC_HILOGE("Path is empty"); 4258ec469eSopenharmony_ci return {}; 4358ec469eSopenharmony_ci } 4458ec469eSopenharmony_ci char realPath[PATH_MAX] = {}; 4558ec469eSopenharmony_ci if (realpath(filePath.c_str(), realPath) == nullptr) { 4658ec469eSopenharmony_ci MISC_HILOGE("Path is error, %{public}d", errno); 4758ec469eSopenharmony_ci return {}; 4858ec469eSopenharmony_ci } 4958ec469eSopenharmony_ci if (!CheckFileDir(realPath, CONFIG_DIR)) { 5058ec469eSopenharmony_ci MISC_HILOGE("File dir is invalid"); 5158ec469eSopenharmony_ci return {}; 5258ec469eSopenharmony_ci } 5358ec469eSopenharmony_ci if (!CheckFileExtendName(realPath, "json")) { 5458ec469eSopenharmony_ci MISC_HILOGE("Unable to parse files other than json format"); 5558ec469eSopenharmony_ci return {}; 5658ec469eSopenharmony_ci } 5758ec469eSopenharmony_ci if (!IsFileExists(realPath)) { 5858ec469eSopenharmony_ci MISC_HILOGE("File not exist"); 5958ec469eSopenharmony_ci return {}; 6058ec469eSopenharmony_ci } 6158ec469eSopenharmony_ci if (!CheckFileSize(realPath)) { 6258ec469eSopenharmony_ci MISC_HILOGE("File size out of read range"); 6358ec469eSopenharmony_ci return {}; 6458ec469eSopenharmony_ci } 6558ec469eSopenharmony_ci FILE *fp = fopen(realPath, "r"); 6658ec469eSopenharmony_ci CHKPS(fp); 6758ec469eSopenharmony_ci std::string dataStr; 6858ec469eSopenharmony_ci char buf[READ_DATA_BUFF_SIZE] = { '\0' }; 6958ec469eSopenharmony_ci while (fgets(buf, sizeof(buf), fp) != nullptr) { 7058ec469eSopenharmony_ci dataStr += buf; 7158ec469eSopenharmony_ci } 7258ec469eSopenharmony_ci if (fclose(fp) != 0) { 7358ec469eSopenharmony_ci MISC_HILOGW("Close file failed, errno:%{public}d", errno); 7458ec469eSopenharmony_ci } 7558ec469eSopenharmony_ci return dataStr; 7658ec469eSopenharmony_ci} 7758ec469eSopenharmony_ci 7858ec469eSopenharmony_ciint32_t GetFileSize(const std::string &filePath) 7958ec469eSopenharmony_ci{ 8058ec469eSopenharmony_ci struct stat statbuf = { 0 }; 8158ec469eSopenharmony_ci if (stat(filePath.c_str(), &statbuf) != 0) { 8258ec469eSopenharmony_ci MISC_HILOGE("Get file size error"); 8358ec469eSopenharmony_ci return INVALID_FILE_SIZE; 8458ec469eSopenharmony_ci } 8558ec469eSopenharmony_ci return statbuf.st_size; 8658ec469eSopenharmony_ci} 8758ec469eSopenharmony_ci 8858ec469eSopenharmony_ciint64_t GetFileSize(int32_t fd) 8958ec469eSopenharmony_ci{ 9058ec469eSopenharmony_ci if (fd < 0) { 9158ec469eSopenharmony_ci MISC_HILOGE("fd is invalid, fd:%{public}d", fd); 9258ec469eSopenharmony_ci return INVALID_FILE_SIZE; 9358ec469eSopenharmony_ci } 9458ec469eSopenharmony_ci struct stat64 statbuf = { 0 }; 9558ec469eSopenharmony_ci if (fstat64(fd, &statbuf) != 0) { 9658ec469eSopenharmony_ci MISC_HILOGE("fstat error, errno:%{public}d", errno); 9758ec469eSopenharmony_ci return INVALID_FILE_SIZE; 9858ec469eSopenharmony_ci } 9958ec469eSopenharmony_ci return statbuf.st_size; 10058ec469eSopenharmony_ci} 10158ec469eSopenharmony_ci 10258ec469eSopenharmony_ciint32_t GetFileName(const int32_t &fd, std::string &fileName) 10358ec469eSopenharmony_ci{ 10458ec469eSopenharmony_ci if (fd < 0) { 10558ec469eSopenharmony_ci MISC_HILOGE("fd is invalid, fd:%{public}d", fd); 10658ec469eSopenharmony_ci return ERROR; 10758ec469eSopenharmony_ci } 10858ec469eSopenharmony_ci char buf[FILE_PATH_MAX] = {'\0'}; 10958ec469eSopenharmony_ci char filePath[FILE_PATH_MAX] = {'\0'}; 11058ec469eSopenharmony_ci 11158ec469eSopenharmony_ci int ret = snprintf_s(buf, sizeof(buf), (sizeof(buf) - 1), "/proc/self/fd/%d", fd); 11258ec469eSopenharmony_ci if (ret < 0) { 11358ec469eSopenharmony_ci MISC_HILOGE("snprintf failed with %{public}d", errno); 11458ec469eSopenharmony_ci return ERROR; 11558ec469eSopenharmony_ci } 11658ec469eSopenharmony_ci 11758ec469eSopenharmony_ci ret = readlink(buf, filePath, FILE_PATH_MAX); 11858ec469eSopenharmony_ci if (ret < 0 || ret >= FILE_PATH_MAX) { 11958ec469eSopenharmony_ci MISC_HILOGE("readlink failed with %{public}d", errno); 12058ec469eSopenharmony_ci return ERROR; 12158ec469eSopenharmony_ci } 12258ec469eSopenharmony_ci 12358ec469eSopenharmony_ci fileName = filePath; 12458ec469eSopenharmony_ci std::size_t firstSlash = fileName.rfind("/"); 12558ec469eSopenharmony_ci if (firstSlash == fileName.npos) { 12658ec469eSopenharmony_ci MISC_HILOGE("Get error path"); 12758ec469eSopenharmony_ci return ERROR; 12858ec469eSopenharmony_ci } 12958ec469eSopenharmony_ci fileName = fileName.substr(firstSlash + 1, fileName.size() - firstSlash); 13058ec469eSopenharmony_ci return SUCCESS; 13158ec469eSopenharmony_ci} 13258ec469eSopenharmony_ci 13358ec469eSopenharmony_ciint32_t GetFileExtName(const int32_t &fd, std::string &extName) 13458ec469eSopenharmony_ci{ 13558ec469eSopenharmony_ci if (fd < 0) { 13658ec469eSopenharmony_ci MISC_HILOGE("fd is invalid, fd:%{public}d", fd); 13758ec469eSopenharmony_ci return ERROR; 13858ec469eSopenharmony_ci } 13958ec469eSopenharmony_ci std::string fileName = ""; 14058ec469eSopenharmony_ci if (GetFileName(fd, fileName) == ERROR) { 14158ec469eSopenharmony_ci MISC_HILOGE("GetFileName failed"); 14258ec469eSopenharmony_ci return ERROR; 14358ec469eSopenharmony_ci } 14458ec469eSopenharmony_ci extName = fileName.substr(fileName.find_last_of(".") + 1); 14558ec469eSopenharmony_ci return SUCCESS; 14658ec469eSopenharmony_ci} 14758ec469eSopenharmony_ci 14858ec469eSopenharmony_cibool CheckFileDir(const std::string &filePath, const std::string &dir) 14958ec469eSopenharmony_ci{ 15058ec469eSopenharmony_ci if (filePath.compare(0, CONFIG_DIR.size(), CONFIG_DIR) != 0) { 15158ec469eSopenharmony_ci MISC_HILOGE("filePath dir is invalid"); 15258ec469eSopenharmony_ci return false; 15358ec469eSopenharmony_ci } 15458ec469eSopenharmony_ci return true; 15558ec469eSopenharmony_ci} 15658ec469eSopenharmony_ci 15758ec469eSopenharmony_cibool CheckFileSize(const std::string &filePath) 15858ec469eSopenharmony_ci{ 15958ec469eSopenharmony_ci int32_t fileSize = GetFileSize(filePath); 16058ec469eSopenharmony_ci if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) { 16158ec469eSopenharmony_ci MISC_HILOGE("File size out of read range"); 16258ec469eSopenharmony_ci return false; 16358ec469eSopenharmony_ci } 16458ec469eSopenharmony_ci return true; 16558ec469eSopenharmony_ci} 16658ec469eSopenharmony_ci 16758ec469eSopenharmony_cibool CheckFileExtendName(const std::string &filePath, const std::string &checkExtension) 16858ec469eSopenharmony_ci{ 16958ec469eSopenharmony_ci std::string::size_type pos = filePath.find_last_of('.'); 17058ec469eSopenharmony_ci if (pos == std::string::npos) { 17158ec469eSopenharmony_ci MISC_HILOGE("File is not find extension"); 17258ec469eSopenharmony_ci return false; 17358ec469eSopenharmony_ci } 17458ec469eSopenharmony_ci return (filePath.substr(pos + 1, filePath.npos) == checkExtension); 17558ec469eSopenharmony_ci} 17658ec469eSopenharmony_ci 17758ec469eSopenharmony_cibool IsFileExists(const std::string &fileName) 17858ec469eSopenharmony_ci{ 17958ec469eSopenharmony_ci return (access(fileName.c_str(), F_OK) == 0); 18058ec469eSopenharmony_ci} 18158ec469eSopenharmony_ci 18258ec469eSopenharmony_cistd::string ReadFd(const RawFileDescriptor &rawFd) 18358ec469eSopenharmony_ci{ 18458ec469eSopenharmony_ci if (rawFd.fd < 0) { 18558ec469eSopenharmony_ci MISC_HILOGE("fd is invalid, fd:%{public}d", rawFd.fd); 18658ec469eSopenharmony_ci return {}; 18758ec469eSopenharmony_ci } 18858ec469eSopenharmony_ci int64_t fdSize = GetFileSize(rawFd.fd); 18958ec469eSopenharmony_ci if ((rawFd.offset < 0) || (rawFd.offset > fdSize)) { 19058ec469eSopenharmony_ci MISC_HILOGE("offset is invalid, offset:%{public}" PRId64, rawFd.offset); 19158ec469eSopenharmony_ci return {}; 19258ec469eSopenharmony_ci } 19358ec469eSopenharmony_ci if ((rawFd.length <= 0) || (rawFd.length > fdSize - rawFd.offset)) { 19458ec469eSopenharmony_ci MISC_HILOGE("length is invalid, length:%{public}" PRId64, rawFd.length); 19558ec469eSopenharmony_ci return {}; 19658ec469eSopenharmony_ci } 19758ec469eSopenharmony_ci FILE *fp = fdopen(rawFd.fd, "r"); 19858ec469eSopenharmony_ci CHKPS(fp); 19958ec469eSopenharmony_ci if (fseek(fp, rawFd.offset, SEEK_SET) != 0) { 20058ec469eSopenharmony_ci MISC_HILOGE("fseek failed, errno:%{public}d", errno); 20158ec469eSopenharmony_ci if (fclose(fp) != 0) { 20258ec469eSopenharmony_ci MISC_HILOGW("Close file failed, errno:%{public}d", errno); 20358ec469eSopenharmony_ci } 20458ec469eSopenharmony_ci return {}; 20558ec469eSopenharmony_ci } 20658ec469eSopenharmony_ci std::string dataStr; 20758ec469eSopenharmony_ci char buf[READ_DATA_BUFF_SIZE] = { '\0' }; 20858ec469eSopenharmony_ci int64_t alreadyRead = 0; 20958ec469eSopenharmony_ci while (alreadyRead < rawFd.length) { 21058ec469eSopenharmony_ci int64_t onceRead = std::min(rawFd.length - alreadyRead, READ_DATA_BUFF_SIZE - 1); 21158ec469eSopenharmony_ci fgets(buf, onceRead + 1, fp); 21258ec469eSopenharmony_ci dataStr += buf; 21358ec469eSopenharmony_ci alreadyRead = ftell(fp) - rawFd.offset; 21458ec469eSopenharmony_ci } 21558ec469eSopenharmony_ci if (fclose(fp) != 0) { 21658ec469eSopenharmony_ci MISC_HILOGW("Close file failed, errno:%{public}d", errno); 21758ec469eSopenharmony_ci } 21858ec469eSopenharmony_ci return dataStr; 21958ec469eSopenharmony_ci} 22058ec469eSopenharmony_ci 22158ec469eSopenharmony_cistd::string GetFileSuffix(int32_t fd) 22258ec469eSopenharmony_ci{ 22358ec469eSopenharmony_ci std::string fdPath = "/proc/self/fd/" + std::to_string(fd); 22458ec469eSopenharmony_ci char filePath[FILE_PATH_MAX + 1] = { '\0' }; 22558ec469eSopenharmony_ci ssize_t ret = readlink(fdPath.c_str(), filePath, FILE_PATH_MAX); 22658ec469eSopenharmony_ci if (ret < 0 || ret > FILE_PATH_MAX) { 22758ec469eSopenharmony_ci MISC_HILOGE("Readlink failed, errno:%{public}d", errno); 22858ec469eSopenharmony_ci return {}; 22958ec469eSopenharmony_ci } 23058ec469eSopenharmony_ci std::string fileAbsolutePath(filePath); 23158ec469eSopenharmony_ci size_t pos = fileAbsolutePath.find_last_of('.'); 23258ec469eSopenharmony_ci if (pos == std::string::npos) { 23358ec469eSopenharmony_ci MISC_HILOGE("File suffix is invalid, fileAbsolutePath:%{public}s", fileAbsolutePath.c_str()); 23458ec469eSopenharmony_ci return {}; 23558ec469eSopenharmony_ci } 23658ec469eSopenharmony_ci return fileAbsolutePath.substr(pos + 1); 23758ec469eSopenharmony_ci} 23858ec469eSopenharmony_ci} // namespace Sensors 23958ec469eSopenharmony_ci} // namespace OHOS 240