• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 
41 namespace OHOS {
42 namespace Msdp {
43 namespace DeviceStatus {
44 namespace {
45 constexpr size_t SUBSTR_ID_LENGTH { 5 };
46 constexpr int32_t MULTIPLES { 2 };
47 constexpr size_t DFX_RADAR_MASK_SIZE { 2 };
48 constexpr int64_t TIME_CONVERSION_UNIT { 1000 };
49 constexpr int64_t TIME_ROUND_UP { 999 };
50 } // namespace
51 
CopyNulstr(char * dest,size_t size,const char * src)52 size_t Utility::CopyNulstr(char *dest, size_t size, const char *src)
53 {
54     CHKPR(dest, 0);
55     CHKPR(src, 0);
56 
57     size_t len = strlen(src);
58     if (len >= size) {
59         if (size > 1) {
60             len = size - 1;
61         } else {
62             len = 0;
63         }
64     }
65     if (len > 0) {
66         errno_t ret = memcpy_s(dest, size, src, len);
67         if (ret != EOK) {
68             FI_HILOGW("memcpy_s:bounds checking failed");
69         }
70     }
71     if (size > 0) {
72         dest[len] = '\0';
73     }
74     return len;
75 }
76 
StartWith(const char * str,const char * prefix)77 bool Utility::StartWith(const char *str, const char *prefix)
78 {
79     size_t prefixlen = strlen(prefix);
80     return (prefixlen > 0 ? (strncmp(str, prefix, strlen(prefix)) == 0) : false);
81 }
82 
StartWith(const std::string & str,const std::string & prefix)83 bool Utility::StartWith(const std::string &str, const std::string &prefix)
84 {
85     if (str.size() < prefix.size()) {
86         return false;
87     }
88     return (str.compare(0, prefix.size(), prefix) == 0);
89 }
90 
RemoveTrailingChars(char c,char * path)91 void Utility::RemoveTrailingChars(char c, char *path)
92 {
93     CHKPV(path);
94     size_t len = strlen(path);
95     while (len > 0 && path[len-1] == c) {
96         path[--len] = '\0';
97     }
98 }
99 
RemoveTrailingChars(const std::string & toRemoved,std::string & path)100 void Utility::RemoveTrailingChars(const std::string &toRemoved, std::string &path)
101 {
102     while (!path.empty() && (toRemoved.find(path.back()) != std::string::npos)) {
103         path.pop_back();
104     }
105 }
106 
RemoveSpace(std::string & str)107 void Utility::RemoveSpace(std::string &str)
108 {
109     str.erase(remove_if(str.begin(), str.end(), [](unsigned char c) { return std::isspace(c);}), str.end());
110 }
111 
IsInteger(const std::string & target)112 bool Utility::IsInteger(const std::string &target)
113 {
114     std::regex pattern("^\\s*-?(0|([1-9]\\d*))\\s*$");
115     return std::regex_match(target, pattern);
116 }
117 
Anonymize(const char * id)118 std::string Utility::Anonymize(const char* id)
119 {
120     if (id == nullptr) {
121         return std::string(MULTIPLES * SUBSTR_ID_LENGTH, '*');
122     }
123     std::string idStr(id);
124     if (idStr.empty() || idStr.length() < SUBSTR_ID_LENGTH) {
125         return std::string(MULTIPLES * SUBSTR_ID_LENGTH, '*');
126     }
127     return idStr.substr(0, SUBSTR_ID_LENGTH) + std::string(SUBSTR_ID_LENGTH, '*') +
128         idStr.substr(idStr.length() - SUBSTR_ID_LENGTH);
129 }
130 
DFXRadarAnonymize(const char * id)131 std::string Utility::DFXRadarAnonymize(const char* id)
132 {
133     if (id == nullptr) {
134         return std::string(MULTIPLES * SUBSTR_ID_LENGTH, '*');
135     }
136     std::string idStr(id);
137     if (idStr.empty() || idStr.length() < SUBSTR_ID_LENGTH) {
138         return std::string(MULTIPLES * SUBSTR_ID_LENGTH, '*');
139     }
140     return idStr.substr(0, SUBSTR_ID_LENGTH) + std::string(DFX_RADAR_MASK_SIZE, '*') +
141         idStr.substr(idStr.length() - SUBSTR_ID_LENGTH);
142 }
143 
DoesFileExist(const char * path)144 bool Utility::DoesFileExist(const char *path)
145 {
146     return (access(path, F_OK) == 0);
147 }
148 
GetFileSize(const std::string & filePath)149 ssize_t Utility::GetFileSize(const std::string &filePath)
150 {
151     return GetFileSize(filePath.c_str());
152 }
153 
GetFileSize(const char * path)154 ssize_t Utility::GetFileSize(const char *path)
155 {
156     struct stat buf {};
157     ssize_t sz { 0 };
158 
159     if (stat(path, &buf) == 0) {
160         if (S_ISREG(buf.st_mode)) {
161             sz = buf.st_size;
162         } else {
163             FI_HILOGE("Not regular file:\'%{private}s\'", path);
164         }
165     } else {
166         FI_HILOGE("stat(\'%{private}s\') failed:%{public}s", path, strerror(errno));
167     }
168     return sz;
169 }
170 
ShowFileAttributes(const char * path)171 void Utility::ShowFileAttributes(const char *path)
172 {
173     CALL_DEBUG_ENTER;
174     FI_HILOGD("======================= File Attributes ========================");
175     FI_HILOGD("%{public}20s:%{private}s", "FILE NAME", path);
176 
177     struct stat buf {};
178     if (stat(path, &buf) != 0) {
179         FI_HILOGE("stat(\'%{private}s\') failed:%{public}s", path, strerror(errno));
180         return;
181     }
182     if (S_ISDIR(buf.st_mode)) {
183         FI_HILOGD("%{public}20s: directory", "TYPE");
184     } else if (S_ISCHR(buf.st_mode)) {
185         FI_HILOGD("%{public}20s: character special file", "TYPE");
186     } else if (S_ISREG(buf.st_mode)) {
187         FI_HILOGD("%{public}20s: regular file", "TYPE");
188     }
189 
190     std::ostringstream ss;
191     std::map<mode_t, std::string> modes {{S_IRUSR, "U+R "}, {S_IWUSR, "U+W "}, {S_IXUSR, "U+X "}, {S_IRGRP, "G+R "},
192         {S_IWGRP, "G+W "}, {S_IXGRP, "G+X "}, {S_IROTH, "O+R "}, {S_IWOTH, "O+W "}, {S_IXOTH, "O+X "}};
193     for (const auto &element : modes) {
194         if (buf.st_mode & element.first) {
195             ss << element.second;
196             break;
197         }
198     }
199 
200     FI_HILOGD("%{public}20s:%{public}s", "PERMISSIONS", ss.str().c_str());
201 }
202 
ShowUserAndGroup()203 void Utility::ShowUserAndGroup()
204 {
205     CALL_DEBUG_ENTER;
206     static constexpr size_t BUFSIZE { 1024 };
207     char buffer[BUFSIZE];
208     struct passwd buf;
209     struct passwd *pbuf = nullptr;
210     struct group grp;
211     struct group *pgrp = nullptr;
212 
213     FI_HILOGD("======================= Users and Groups =======================");
214     uid_t uid = getuid();
215     if (getpwuid_r(uid, &buf, buffer, sizeof(buffer), &pbuf) != 0) {
216         FI_HILOGE("getpwuid_r failed:%{public}s", strerror(errno));
217     } else {
218         FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "USER", uid, buf.pw_name);
219     }
220 
221     gid_t gid = getgid();
222     if (getgrgid_r(gid, &grp, buffer, sizeof(buffer), &pgrp) != 0) {
223         FI_HILOGE("getgrgid_r failed:%{public}s", strerror(errno));
224     } else {
225         FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "GROUP", gid, grp.gr_name);
226     }
227 
228     uid = geteuid();
229     if (getpwuid_r(uid, &buf, buffer, sizeof(buffer), &pbuf) != 0) {
230         FI_HILOGE("getpwuid_r failed:%{public}s", strerror(errno));
231     } else {
232         FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "EFFECTIVE USER", uid, buf.pw_name);
233     }
234 
235     gid = getegid();
236     if (getgrgid_r(gid, &grp, buffer, sizeof(buffer), &pgrp) != 0) {
237         FI_HILOGE("getgrgid_r failed:%{public}s", strerror(errno));
238     } else {
239         FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "EFFECTIVE GROUP", gid, grp.gr_name);
240     }
241 
242     gid_t groups[NGROUPS_MAX + 1];
243     int32_t ngrps = getgroups(sizeof(groups), groups);
244     for (int32_t i = 0; i < ngrps; ++i) {
245         if (getgrgid_r(groups[i], &grp, buffer, sizeof(buffer), &pgrp) != 0) {
246             FI_HILOGE("getgrgid_r failed:%{public}s", strerror(errno));
247         } else {
248             FI_HILOGD("%{public}20s:%{public}10u%{public}20s", "SUPPLEMENTARY GROUP", groups[i], grp.gr_name);
249         }
250     }
251 }
252 
GetSysClockTime()253 int64_t Utility::GetSysClockTime()
254 {
255     struct timespec ts = { 0, 0 };
256     if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
257         FI_HILOGD("clock_gettime failed:%{public}d", errno);
258         return 0;
259     }
260 
261     if (static_cast<uint64_t>(ts.tv_sec) > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) / (
262         TIME_CONVERSION_UNIT * TIME_CONVERSION_UNIT)) {
263         FI_HILOGE("Integer overflow detected!");
264         return 0;
265     }
266 
267     uint64_t totalMicroSeconds = static_cast<uint64_t>(ts.tv_sec) * TIME_CONVERSION_UNIT *
268     TIME_CONVERSION_UNIT + static_cast<uint64_t>(ts.tv_nsec) / TIME_CONVERSION_UNIT;
269 
270     if (totalMicroSeconds > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
271         FI_HILOGE("Total time value integer overflow detected!");
272         return 0;
273     }
274     return static_cast<int64_t>(totalMicroSeconds);
275 }
276 
GetSysClockTimeMilli(int64_t timeDT)277 int64_t Utility::GetSysClockTimeMilli(int64_t timeDT)
278 {
279     return (timeDT + TIME_ROUND_UP) / TIME_CONVERSION_UNIT;
280 }
281 } // namespace DeviceStatus
282 } // namespace Msdp
283 } // namespace OHOS
284