1f857971dSopenharmony_ci/* 2f857971dSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3f857971dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4f857971dSopenharmony_ci * you may not use this file except in compliance with the License. 5f857971dSopenharmony_ci * You may obtain a copy of the License at 6f857971dSopenharmony_ci * 7f857971dSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8f857971dSopenharmony_ci * 9f857971dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10f857971dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11f857971dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f857971dSopenharmony_ci * See the License for the specific language governing permissions and 13f857971dSopenharmony_ci * limitations under the License. 14f857971dSopenharmony_ci */ 15f857971dSopenharmony_ci 16f857971dSopenharmony_ci#include "utility.h" 17f857971dSopenharmony_ci 18f857971dSopenharmony_ci#include <grp.h> 19f857971dSopenharmony_ci#include <pwd.h> 20f857971dSopenharmony_ci#include <unistd.h> 21f857971dSopenharmony_ci 22f857971dSopenharmony_ci#include <cerrno> 23f857971dSopenharmony_ci#include <chrono> 24f857971dSopenharmony_ci#include <limits> 25f857971dSopenharmony_ci#include <map> 26f857971dSopenharmony_ci#include <regex> 27f857971dSopenharmony_ci#include <sstream> 28f857971dSopenharmony_ci 29f857971dSopenharmony_ci#include <sys/stat.h> 30f857971dSopenharmony_ci#include <sys/types.h> 31f857971dSopenharmony_ci 32f857971dSopenharmony_ci#include "parcel.h" 33f857971dSopenharmony_ci#include "securec.h" 34f857971dSopenharmony_ci 35f857971dSopenharmony_ci#include "devicestatus_common.h" 36f857971dSopenharmony_ci#include "devicestatus_define.h" 37f857971dSopenharmony_ci 38f857971dSopenharmony_ci#undef LOG_TAG 39f857971dSopenharmony_ci#define LOG_TAG "Utility" 40f857971dSopenharmony_ci 41f857971dSopenharmony_cinamespace OHOS { 42f857971dSopenharmony_cinamespace Msdp { 43f857971dSopenharmony_cinamespace DeviceStatus { 44f857971dSopenharmony_cinamespace { 45f857971dSopenharmony_ciconstexpr size_t SUBSTR_ID_LENGTH { 5 }; 46f857971dSopenharmony_ciconstexpr int32_t MULTIPLES { 2 }; 47f857971dSopenharmony_ci} // namespace 48f857971dSopenharmony_ci 49f857971dSopenharmony_cisize_t Utility::CopyNulstr(char *dest, size_t size, const char *src) 50f857971dSopenharmony_ci{ 51f857971dSopenharmony_ci CHKPR(dest, 0); 52f857971dSopenharmony_ci CHKPR(src, 0); 53f857971dSopenharmony_ci 54f857971dSopenharmony_ci size_t len = strlen(src); 55f857971dSopenharmony_ci if (len >= size) { 56f857971dSopenharmony_ci if (size > 1) { 57f857971dSopenharmony_ci len = size - 1; 58f857971dSopenharmony_ci } else { 59f857971dSopenharmony_ci len = 0; 60f857971dSopenharmony_ci } 61f857971dSopenharmony_ci } 62f857971dSopenharmony_ci if (len > 0) { 63f857971dSopenharmony_ci errno_t ret = memcpy_s(dest, size, src, len); 64f857971dSopenharmony_ci if (ret != EOK) { 65f857971dSopenharmony_ci FI_HILOGW("memcpy_s:bounds checking failed"); 66f857971dSopenharmony_ci } 67f857971dSopenharmony_ci } 68f857971dSopenharmony_ci if (size > 0) { 69f857971dSopenharmony_ci dest[len] = '\0'; 70f857971dSopenharmony_ci } 71f857971dSopenharmony_ci return len; 72f857971dSopenharmony_ci} 73f857971dSopenharmony_ci 74f857971dSopenharmony_cibool Utility::StartWith(const char *str, const char *prefix) 75f857971dSopenharmony_ci{ 76f857971dSopenharmony_ci size_t prefixlen = strlen(prefix); 77f857971dSopenharmony_ci return (prefixlen > 0 ? (strncmp(str, prefix, strlen(prefix)) == 0) : false); 78f857971dSopenharmony_ci} 79f857971dSopenharmony_ci 80f857971dSopenharmony_cibool Utility::StartWith(const std::string &str, const std::string &prefix) 81f857971dSopenharmony_ci{ 82f857971dSopenharmony_ci if (str.size() < prefix.size()) { 83f857971dSopenharmony_ci return false; 84f857971dSopenharmony_ci } 85f857971dSopenharmony_ci return (str.compare(0, prefix.size(), prefix) == 0); 86f857971dSopenharmony_ci} 87f857971dSopenharmony_ci 88f857971dSopenharmony_civoid Utility::RemoveTrailingChars(char c, char *path) 89f857971dSopenharmony_ci{ 90f857971dSopenharmony_ci CHKPV(path); 91f857971dSopenharmony_ci size_t len = strlen(path); 92f857971dSopenharmony_ci while (len > 0 && path[len-1] == c) { 93f857971dSopenharmony_ci path[--len] = '\0'; 94f857971dSopenharmony_ci } 95f857971dSopenharmony_ci} 96f857971dSopenharmony_ci 97f857971dSopenharmony_civoid Utility::RemoveTrailingChars(const std::string &toRemoved, std::string &path) 98f857971dSopenharmony_ci{ 99f857971dSopenharmony_ci while (!path.empty() && (toRemoved.find(path.back()) != std::string::npos)) { 100f857971dSopenharmony_ci path.pop_back(); 101f857971dSopenharmony_ci } 102f857971dSopenharmony_ci} 103f857971dSopenharmony_ci 104f857971dSopenharmony_civoid Utility::RemoveSpace(std::string &str) 105f857971dSopenharmony_ci{ 106f857971dSopenharmony_ci str.erase(remove_if(str.begin(), str.end(), [](unsigned char c) { return std::isspace(c);}), str.end()); 107f857971dSopenharmony_ci} 108f857971dSopenharmony_ci 109f857971dSopenharmony_cibool Utility::IsInteger(const std::string &target) 110f857971dSopenharmony_ci{ 111f857971dSopenharmony_ci std::regex pattern("^\\s*-?(0|([1-9]\\d*))\\s*$"); 112f857971dSopenharmony_ci return std::regex_match(target, pattern); 113f857971dSopenharmony_ci} 114f857971dSopenharmony_ci 115f857971dSopenharmony_cistd::string Utility::Anonymize(const char* id) 116f857971dSopenharmony_ci{ 117f857971dSopenharmony_ci if (id == nullptr) { 118f857971dSopenharmony_ci return std::string(MULTIPLES * SUBSTR_ID_LENGTH, '*'); 119f857971dSopenharmony_ci } 120f857971dSopenharmony_ci std::string idStr(id); 121f857971dSopenharmony_ci if (idStr.empty() || idStr.length() < SUBSTR_ID_LENGTH) { 122f857971dSopenharmony_ci return std::string(MULTIPLES * SUBSTR_ID_LENGTH, '*'); 123f857971dSopenharmony_ci } 124f857971dSopenharmony_ci return idStr.substr(0, SUBSTR_ID_LENGTH) + std::string(SUBSTR_ID_LENGTH, '*') + 125f857971dSopenharmony_ci idStr.substr(idStr.length() - SUBSTR_ID_LENGTH); 126f857971dSopenharmony_ci} 127f857971dSopenharmony_ci 128f857971dSopenharmony_cibool Utility::DoesFileExist(const char *path) 129f857971dSopenharmony_ci{ 130f857971dSopenharmony_ci return (access(path, F_OK) == 0); 131f857971dSopenharmony_ci} 132f857971dSopenharmony_ci 133f857971dSopenharmony_cissize_t Utility::GetFileSize(const std::string &filePath) 134f857971dSopenharmony_ci{ 135f857971dSopenharmony_ci return GetFileSize(filePath.c_str()); 136f857971dSopenharmony_ci} 137f857971dSopenharmony_ci 138f857971dSopenharmony_cissize_t Utility::GetFileSize(const char *path) 139f857971dSopenharmony_ci{ 140f857971dSopenharmony_ci struct stat buf {}; 141f857971dSopenharmony_ci ssize_t sz { 0 }; 142f857971dSopenharmony_ci 143f857971dSopenharmony_ci if (stat(path, &buf) == 0) { 144f857971dSopenharmony_ci if (S_ISREG(buf.st_mode)) { 145f857971dSopenharmony_ci sz = buf.st_size; 146f857971dSopenharmony_ci } else { 147f857971dSopenharmony_ci FI_HILOGE("Not regular file:\'%{public}s\'", path); 148f857971dSopenharmony_ci } 149f857971dSopenharmony_ci } else { 150f857971dSopenharmony_ci FI_HILOGE("stat(\'%{public}s\') failed:%{public}s", path, strerror(errno)); 151f857971dSopenharmony_ci } 152f857971dSopenharmony_ci return sz; 153f857971dSopenharmony_ci} 154f857971dSopenharmony_ci 155f857971dSopenharmony_civoid Utility::ShowFileAttributes(const char *path) 156f857971dSopenharmony_ci{ 157f857971dSopenharmony_ci CALL_DEBUG_ENTER; 158f857971dSopenharmony_ci FI_HILOGD("======================= File Attributes ========================"); 159f857971dSopenharmony_ci FI_HILOGD("%{public}20s:%{public}s", "FILE NAME", path); 160f857971dSopenharmony_ci 161f857971dSopenharmony_ci struct stat buf {}; 162f857971dSopenharmony_ci if (stat(path, &buf) != 0) { 163f857971dSopenharmony_ci FI_HILOGE("stat(\'%{public}s\') failed:%{public}s", path, strerror(errno)); 164f857971dSopenharmony_ci return; 165f857971dSopenharmony_ci } 166f857971dSopenharmony_ci if (S_ISDIR(buf.st_mode)) { 167f857971dSopenharmony_ci FI_HILOGD("%{public}20s: directory", "TYPE"); 168f857971dSopenharmony_ci } else if (S_ISCHR(buf.st_mode)) { 169f857971dSopenharmony_ci FI_HILOGD("%{public}20s: character special file", "TYPE"); 170f857971dSopenharmony_ci } else if (S_ISREG(buf.st_mode)) { 171f857971dSopenharmony_ci FI_HILOGD("%{public}20s: regular file", "TYPE"); 172f857971dSopenharmony_ci } 173f857971dSopenharmony_ci 174f857971dSopenharmony_ci std::ostringstream ss; 175f857971dSopenharmony_ci std::map<mode_t, std::string> modes {{S_IRUSR, "U+R "}, {S_IWUSR, "U+W "}, {S_IXUSR, "U+X "}, {S_IRGRP, "G+R "}, 176f857971dSopenharmony_ci {S_IWGRP, "G+W "}, {S_IXGRP, "G+X "}, {S_IROTH, "O+R "}, {S_IWOTH, "O+W "}, {S_IXOTH, "O+X "}}; 177f857971dSopenharmony_ci for (const auto &element : modes) { 178f857971dSopenharmony_ci if (buf.st_mode & element.first) { 179f857971dSopenharmony_ci ss << element.second; 180f857971dSopenharmony_ci break; 181f857971dSopenharmony_ci } 182f857971dSopenharmony_ci } 183f857971dSopenharmony_ci 184f857971dSopenharmony_ci FI_HILOGD("%{public}20s:%{public}s", "PERMISSIONS", ss.str().c_str()); 185f857971dSopenharmony_ci} 186f857971dSopenharmony_ci 187f857971dSopenharmony_civoid Utility::ShowUserAndGroup() 188f857971dSopenharmony_ci{ 189f857971dSopenharmony_ci CALL_DEBUG_ENTER; 190f857971dSopenharmony_ci static constexpr size_t BUFSIZE { 1024 }; 191f857971dSopenharmony_ci char buffer[BUFSIZE]; 192f857971dSopenharmony_ci struct passwd buf; 193f857971dSopenharmony_ci struct passwd *pbuf = nullptr; 194f857971dSopenharmony_ci struct group grp; 195f857971dSopenharmony_ci struct group *pgrp = nullptr; 196f857971dSopenharmony_ci 197f857971dSopenharmony_ci FI_HILOGD("======================= Users and Groups ======================="); 198f857971dSopenharmony_ci uid_t uid = getuid(); 199f857971dSopenharmony_ci if (getpwuid_r(uid, &buf, buffer, sizeof(buffer), &pbuf) != 0) { 200f857971dSopenharmony_ci FI_HILOGE("getpwuid_r failed:%{public}s", strerror(errno)); 201f857971dSopenharmony_ci } else { 202f857971dSopenharmony_ci FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "USER", uid, buf.pw_name); 203f857971dSopenharmony_ci } 204f857971dSopenharmony_ci 205f857971dSopenharmony_ci gid_t gid = getgid(); 206f857971dSopenharmony_ci if (getgrgid_r(gid, &grp, buffer, sizeof(buffer), &pgrp) != 0) { 207f857971dSopenharmony_ci FI_HILOGE("getgrgid_r failed:%{public}s", strerror(errno)); 208f857971dSopenharmony_ci } else { 209f857971dSopenharmony_ci FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "GROUP", gid, grp.gr_name); 210f857971dSopenharmony_ci } 211f857971dSopenharmony_ci 212f857971dSopenharmony_ci uid = geteuid(); 213f857971dSopenharmony_ci if (getpwuid_r(uid, &buf, buffer, sizeof(buffer), &pbuf) != 0) { 214f857971dSopenharmony_ci FI_HILOGE("getpwuid_r failed:%{public}s", strerror(errno)); 215f857971dSopenharmony_ci } else { 216f857971dSopenharmony_ci FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "EFFECTIVE USER", uid, buf.pw_name); 217f857971dSopenharmony_ci } 218f857971dSopenharmony_ci 219f857971dSopenharmony_ci gid = getegid(); 220f857971dSopenharmony_ci if (getgrgid_r(gid, &grp, buffer, sizeof(buffer), &pgrp) != 0) { 221f857971dSopenharmony_ci FI_HILOGE("getgrgid_r failed:%{public}s", strerror(errno)); 222f857971dSopenharmony_ci } else { 223f857971dSopenharmony_ci FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "EFFECTIVE GROUP", gid, grp.gr_name); 224f857971dSopenharmony_ci } 225f857971dSopenharmony_ci 226f857971dSopenharmony_ci gid_t groups[NGROUPS_MAX + 1]; 227f857971dSopenharmony_ci int32_t ngrps = getgroups(sizeof(groups), groups); 228f857971dSopenharmony_ci for (int32_t i = 0; i < ngrps; ++i) { 229f857971dSopenharmony_ci if (getgrgid_r(groups[i], &grp, buffer, sizeof(buffer), &pgrp) != 0) { 230f857971dSopenharmony_ci FI_HILOGE("getgrgid_r failed:%{public}s", strerror(errno)); 231f857971dSopenharmony_ci } else { 232f857971dSopenharmony_ci FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "SUPPLEMENTARY GROUP", groups[i], grp.gr_name); 233f857971dSopenharmony_ci } 234f857971dSopenharmony_ci } 235f857971dSopenharmony_ci} 236f857971dSopenharmony_ci 237f857971dSopenharmony_ciint64_t Utility::GetSysClockTime() 238f857971dSopenharmony_ci{ 239f857971dSopenharmony_ci return std::chrono::time_point_cast<std::chrono::microseconds>( 240f857971dSopenharmony_ci std::chrono::steady_clock::now()).time_since_epoch().count(); 241f857971dSopenharmony_ci} 242f857971dSopenharmony_ci} // namespace DeviceStatus 243f857971dSopenharmony_ci} // namespace Msdp 244f857971dSopenharmony_ci} // namespace OHOS 245