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