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