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