1 /*
2 * Copyright (c) 2021 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 #include "init_utils.h"
16
17 #include <ctype.h>
18 #include <errno.h>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <grp.h>
22 #include <limits.h>
23 #include <pwd.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/ioctl.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <time.h>
30
31 #include "init_log.h"
32 #include "securec.h"
33 #include "service_control.h"
34
35 #define MAX_BUF_SIZE 1024
36 #define MAX_SMALL_BUFFER 4096
37
38 #define MAX_JSON_FILE_LEN 102400 // max init.cfg size 100KB
39 #define CONVERT_MICROSEC_TO_SEC(x) ((x) / 1000 / 1000.0)
40 #ifndef DT_DIR
41 #define DT_DIR 4
42 #endif
43
44 #define THOUSAND_UNIT_INT 1000
45 #define THOUSAND_UNIT_FLOAT 1000.0
46
ConvertMicrosecondToSecond(int x)47 float ConvertMicrosecondToSecond(int x)
48 {
49 return ((x / THOUSAND_UNIT_INT) / THOUSAND_UNIT_FLOAT);
50 }
51
52 #ifndef __LITEOS_M__
CheckDigit(const char * name)53 static bool CheckDigit(const char *name)
54 {
55 size_t nameLen = strlen(name);
56 for (size_t i = 0; i < nameLen; ++i) {
57 if (!isdigit(name[i])) {
58 return false;
59 }
60 }
61 return true;
62 }
63 #endif
64
StringToUint(const char * name,unsigned int * value)65 int StringToUint(const char *name, unsigned int *value)
66 {
67 errno = 0;
68 *value = (unsigned int)strtoul(name, 0, DECIMAL_BASE);
69 INIT_CHECK_RETURN_VALUE(errno == 0, -1);
70 return 0;
71 }
72
DecodeUid(const char * name)73 uid_t DecodeUid(const char *name)
74 {
75 #ifndef __LITEOS_M__
76 INIT_CHECK_RETURN_VALUE(name != NULL, -1);
77 uid_t uid = -1;
78 if (CheckDigit(name)) {
79 if (!StringToUint(name, &uid)) {
80 return uid;
81 } else {
82 return -1;
83 }
84 }
85 struct passwd *p = getpwnam(name);
86 if (p == NULL) {
87 return -1;
88 }
89 return p->pw_uid;
90 #else
91 (void)name;
92 return -1;
93 #endif
94 }
95
DecodeGid(const char * name)96 gid_t DecodeGid(const char *name)
97 {
98 #ifndef __LITEOS_M__
99 INIT_CHECK_RETURN_VALUE(name != NULL, -1);
100 gid_t gid = -1;
101 if (CheckDigit(name)) {
102 if (!StringToUint(name, &gid)) {
103 return gid;
104 } else {
105 return -1;
106 }
107 }
108 struct group *data = getgrnam(name);
109 if (data != NULL) {
110 return data->gr_gid;
111 }
112 while ((data = getgrent()) != NULL) {
113 if ((data->gr_name != NULL) && (strcmp(data->gr_name, name) == 0)) {
114 gid = data->gr_gid;
115 break;
116 }
117 }
118 endgrent();
119 return gid;
120 #else
121 (void)name;
122 return -1;
123 #endif
124 }
125
ReadFileToBuf(const char * configFile)126 char *ReadFileToBuf(const char *configFile)
127 {
128 char *buffer = NULL;
129 FILE *fd = NULL;
130 struct stat fileStat = {0};
131 INIT_CHECK_RETURN_VALUE(configFile != NULL && *configFile != '\0', NULL);
132 do {
133 if (stat(configFile, &fileStat) != 0 ||
134 fileStat.st_size <= 0 || fileStat.st_size > MAX_JSON_FILE_LEN) {
135 break;
136 }
137 fd = fopen(configFile, "r");
138 if (fd == NULL) {
139 INIT_LOGE("Open %s failed. err = %d", configFile, errno);
140 break;
141 }
142 buffer = (char*)malloc((size_t)(fileStat.st_size + 1));
143 if (buffer == NULL) {
144 INIT_LOGE("Failed to allocate memory for config file, err = %d", errno);
145 break;
146 }
147
148 if (fread(buffer, fileStat.st_size, 1, fd) != 1) {
149 free(buffer);
150 buffer = NULL;
151 break;
152 }
153 buffer[fileStat.st_size] = '\0';
154 } while (0);
155
156 if (fd != NULL) {
157 (void)fclose(fd);
158 fd = NULL;
159 }
160 return buffer;
161 }
162
CloseStdio(void)163 void CloseStdio(void)
164 {
165 #ifndef STARTUP_INIT_TEST
166 #ifndef __LITEOS_M__
167 int fd = open("/dev/null", O_RDWR);
168 if (fd < 0) {
169 return;
170 }
171 dup2(fd, 0);
172 dup2(fd, 1);
173 dup2(fd, STDERR_HANDLE);
174 if (fd > STDERR_HANDLE) {
175 close(fd);
176 }
177 #endif
178 #endif
179 }
180
ReadFileData(const char * fileName)181 char *ReadFileData(const char *fileName)
182 {
183 if (fileName == NULL) {
184 return NULL;
185 }
186 char *buffer = NULL;
187 int fd = -1;
188 fd = open(fileName, O_RDONLY);
189 INIT_ERROR_CHECK(fd >= 0, return NULL, "Failed to read file %s errno:%d", fileName, errno);
190 buffer = (char *)calloc(1, MAX_SMALL_BUFFER); // fsmanager not create, can not get fileStat st_size
191 INIT_ERROR_CHECK(buffer != NULL, close(fd);
192 return NULL, "Failed to allocate memory for %s", fileName);
193 ssize_t readLen = read(fd, buffer, MAX_SMALL_BUFFER - 1);
194 INIT_ERROR_CHECK((readLen > 0) && (readLen < (MAX_SMALL_BUFFER - 1)), close(fd);
195 free(buffer);
196 return NULL, "Failed to read data for %s", fileName);
197 buffer[readLen] = '\0';
198 if (fd != -1) {
199 close(fd);
200 }
201 return buffer;
202 }
203
IterateNameValuePairs(const char * src,void (* iterator)(const NAME_VALUE_PAIR * nv,void * context),void * context)204 int IterateNameValuePairs(const char *src, void (*iterator)(const NAME_VALUE_PAIR *nv, void *context), void *context)
205 {
206 int cnt = 0;
207 const char *seperator;
208 const char *tmp = src;
209 NAME_VALUE_PAIR nv;
210 if ((src == NULL) || (iterator == NULL)) {
211 return -1;
212 }
213
214 do {
215 // Find space seperator
216 nv.name = tmp;
217 seperator = strchr(tmp, ' ');
218 if (seperator == NULL) {
219 // Last nv
220 nv.valueEnd = tmp + strlen(tmp);
221 tmp = NULL;
222 } else {
223 nv.valueEnd = seperator;
224 tmp = seperator + 1;
225 }
226
227 // Find equal seperator
228 seperator = strchr(nv.name, '=');
229 if (seperator == NULL) {
230 // Invalid name value pair
231 continue;
232 }
233 if (seperator > nv.valueEnd) {
234 // name without value, just ignore
235 continue;
236 }
237 nv.nameEnd = seperator;
238 nv.value = seperator + 1;
239
240 iterator(&nv, context);
241 cnt += 1;
242 } while (tmp != NULL);
243
244 return cnt;
245 }
246
GetProcCmdlineValue(const char * name,const char * buffer,char * value,int length)247 int GetProcCmdlineValue(const char *name, const char *buffer, char *value, int length)
248 {
249 INIT_ERROR_CHECK(name != NULL && buffer != NULL && value != NULL, return -1, "Failed get parameters");
250 char *endData = (char *)buffer + strlen(buffer);
251 char *tmp = strstr(buffer, name);
252 do {
253 if (tmp == NULL) {
254 return -1;
255 }
256 tmp = tmp + strlen(name);
257 while (tmp < endData && *tmp == ' ') {
258 tmp++;
259 }
260 if (*tmp == '=') {
261 break;
262 }
263 tmp = strstr(tmp + 1, name);
264 } while (tmp < endData);
265 tmp++;
266 size_t i = 0;
267 size_t endIndex = 0;
268 while (tmp < endData && *tmp == ' ') {
269 tmp++;
270 }
271 for (; i < (size_t)length; tmp++) {
272 if (tmp >= endData) {
273 endIndex = i;
274 break;
275 }
276 if (*tmp == ' ' || *tmp == '\n' || *tmp == '\r' || *tmp == '\t') {
277 endIndex = i;
278 break;
279 }
280 if (*tmp == '=') {
281 if (endIndex != 0) { // for root=uuid=xxxx
282 break;
283 }
284 i = 0;
285 endIndex = 0;
286 continue;
287 }
288 value[i++] = *tmp;
289 }
290 if (i >= (size_t)length) {
291 return -1;
292 }
293 value[endIndex] = '\0';
294 return 0;
295 }
296
SplitString(char * srcPtr,const char * del,char ** dstPtr,int maxNum)297 int SplitString(char *srcPtr, const char *del, char **dstPtr, int maxNum)
298 {
299 INIT_CHECK_RETURN_VALUE(srcPtr != NULL && dstPtr != NULL && del != NULL, -1);
300 char *buf = NULL;
301 dstPtr[0] = strtok_r(srcPtr, del, &buf);
302 int counter = 0;
303 while ((counter < maxNum) && (dstPtr[counter] != NULL)) {
304 counter++;
305 if (counter >= maxNum) {
306 break;
307 }
308 dstPtr[counter] = strtok_r(NULL, del, &buf);
309 }
310 return counter;
311 }
312
FreeStringVector(char ** vector,int count)313 void FreeStringVector(char **vector, int count)
314 {
315 if (vector != NULL) {
316 for (int i = 0; i < count; i++) {
317 if (vector[i] != NULL) {
318 free(vector[i]);
319 }
320 }
321 free(vector);
322 }
323 }
324
SplitStringExt(char * buffer,const char * del,int * returnCount,int maxItemCount)325 char **SplitStringExt(char *buffer, const char *del, int *returnCount, int maxItemCount)
326 {
327 INIT_CHECK_RETURN_VALUE((maxItemCount >= 0) && (buffer != NULL) && (del != NULL) && (returnCount != NULL), NULL);
328 // Why is this number?
329 // Now we use this function to split a string with a given delimiter
330 // We do not know how many sub-strings out there after splitting.
331 // 50 is just a guess value.
332 const int defaultItemCounts = 50;
333 int itemCounts = maxItemCount;
334
335 if (maxItemCount > defaultItemCounts) {
336 itemCounts = defaultItemCounts;
337 }
338 char **items = (char **)malloc(sizeof(char*) * itemCounts);
339 INIT_ERROR_CHECK(items != NULL, return NULL, "No enough memory to store items");
340 char *rest = NULL;
341 char *p = strtok_r(buffer, del, &rest);
342 int count = 0;
343 while (p != NULL) {
344 if (count > itemCounts - 1) {
345 itemCounts += (itemCounts / 2) + 1; // 2 Request to increase the original memory by half.
346 INIT_LOGV("Too many items,expand size");
347 char **expand = (char **)(realloc(items, sizeof(char *) * itemCounts));
348 INIT_ERROR_CHECK(expand != NULL, FreeStringVector(items, count);
349 return NULL, "Failed to expand memory");
350 items = expand;
351 }
352 size_t len = strlen(p);
353 items[count] = (char *)malloc(len + 1);
354 INIT_CHECK(items[count] != NULL, FreeStringVector(items, count);
355 return NULL);
356 if (strncpy_s(items[count], len + 1, p, len) != EOK) {
357 INIT_LOGE("Copy string failed");
358 FreeStringVector(items, count);
359 return NULL;
360 }
361 items[count][len] = '\0';
362 count++;
363 p = strtok_r(NULL, del, &rest);
364 }
365 *returnCount = count;
366 return items;
367 }
368
InitDiffTime(INIT_TIMING_STAT * stat)369 long long InitDiffTime(INIT_TIMING_STAT *stat)
370 {
371 long long diff = (long long)((stat->endTime.tv_sec - stat->startTime.tv_sec) * 1000000); // 1000000 1000ms
372 if (stat->endTime.tv_nsec > stat->startTime.tv_nsec) {
373 diff += (stat->endTime.tv_nsec - stat->startTime.tv_nsec) / BASE_MS_UNIT;
374 } else {
375 diff -= (stat->startTime.tv_nsec - stat->endTime.tv_nsec) / BASE_MS_UNIT;
376 }
377 return diff;
378 }
379
WaitForFile(const char * source,unsigned int maxSecond)380 void WaitForFile(const char *source, unsigned int maxSecond)
381 {
382 INIT_ERROR_CHECK(maxSecond <= WAIT_MAX_SECOND, maxSecond = WAIT_MAX_SECOND,
383 "WaitForFile max time is %us", WAIT_MAX_SECOND);
384 struct stat sourceInfo = {0};
385 unsigned int waitTime = 10 * BASE_MS_UNIT; // 10ms
386 long long maxDuration = maxSecond * BASE_MS_UNIT * BASE_MS_UNIT; // 5s
387 #ifdef STARTUP_INIT_TEST
388 maxDuration = 0;
389 #endif
390 long long duration = 0;
391 INIT_TIMING_STAT cmdTimer;
392 (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.startTime);
393 while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (duration < maxDuration)) {
394 usleep(waitTime);
395 (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime);
396 duration = InitDiffTime(&cmdTimer);
397 }
398 INIT_CHECK_ONLY_ELOG(duration < maxDuration, "wait for file:%s failed after %d second.", source, maxSecond);
399 return;
400 }
401
WriteAll(int fd,const char * buffer,size_t size)402 size_t WriteAll(int fd, const char *buffer, size_t size)
403 {
404 INIT_CHECK_RETURN_VALUE(buffer != NULL && fd >= 0 && *buffer != '\0', 0);
405 const char *p = buffer;
406 size_t left = size;
407 ssize_t written;
408 while (left > 0) {
409 do {
410 written = write(fd, p, left);
411 } while (written < 0 && errno == EINTR);
412 if (written < 0) {
413 INIT_LOGE("Failed to write %lu bytes, err = %d", left, errno);
414 break;
415 }
416 p += written;
417 left -= written;
418 }
419 return size - left;
420 }
421
GetRealPath(const char * source)422 char *GetRealPath(const char *source)
423 {
424 INIT_CHECK_RETURN_VALUE(source != NULL, NULL);
425 char *path = realpath(source, NULL);
426 if (path == NULL) {
427 INIT_ERROR_CHECK(errno == ENOENT, return NULL, "Failed to resolve %s real path err=%d", source, errno);
428 }
429 return path;
430 }
431
MakeDir(const char * dir,mode_t mode)432 int MakeDir(const char *dir, mode_t mode)
433 {
434 int rc = -1;
435 if (dir == NULL || *dir == '\0') {
436 errno = EINVAL;
437 return rc;
438 }
439 rc = mkdir(dir, mode);
440 INIT_ERROR_CHECK(!(rc < 0 && errno != EEXIST), return rc,
441 "Create directory \" %s \" failed, err = %d", dir, errno);
442 // create dir success or it already exist.
443 return 0;
444 }
445
MakeDirRecursive(const char * dir,mode_t mode)446 int MakeDirRecursive(const char *dir, mode_t mode)
447 {
448 int rc = -1;
449 char buffer[PATH_MAX] = {0};
450 const char *p = NULL;
451 if (dir == NULL || *dir == '\0') {
452 errno = EINVAL;
453 return rc;
454 }
455 p = dir;
456 char *slash = strchr(dir, '/');
457 while (slash != NULL) {
458 int gap = slash - p;
459 p = slash + 1;
460 if (gap == 0) {
461 slash = strchr(p, '/');
462 continue;
463 }
464 if (gap < 0) { // end with '/'
465 break;
466 }
467 INIT_CHECK_RETURN_VALUE(memcpy_s(buffer, PATH_MAX, dir, p - dir - 1) == 0, -1);
468 rc = MakeDir(buffer, mode);
469 INIT_CHECK_RETURN_VALUE(rc >= 0, rc);
470 slash = strchr(p, '/');
471 }
472 return MakeDir(dir, mode);
473 }
474
CheckAndCreateDir(const char * fileName)475 void CheckAndCreateDir(const char *fileName)
476 {
477 #ifndef __LITEOS_M__
478 if (fileName == NULL || *fileName == '\0') {
479 return;
480 }
481 char *path = strndup(fileName, strrchr(fileName, '/') - fileName);
482 if (path == NULL) {
483 return;
484 }
485 if (access(path, F_OK) == 0) {
486 free(path);
487 return;
488 }
489 MakeDirRecursive(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
490 free(path);
491 #else
492 (void)fileName;
493 #endif
494 }
495
CheckAndCreatFile(const char * file,mode_t mode)496 int CheckAndCreatFile(const char *file, mode_t mode)
497 {
498 if (access(file, F_OK) == 0) {
499 BEGET_LOGW("File \' %s \' already exist", file);
500 return 0;
501 } else {
502 if (errno == ENOENT) {
503 CheckAndCreateDir(file);
504 int fd = open(file, O_CREAT, mode);
505 if (fd < 0) {
506 BEGET_LOGE("Failed create %s, err=%d", file, errno);
507 return -1;
508 } else {
509 close(fd);
510 }
511 } else {
512 BEGET_LOGW("Failed to access \' %s \', err = %d", file, errno);
513 return -1;
514 }
515 }
516 return 0;
517 }
518
StringToInt(const char * str,int defaultValue)519 int StringToInt(const char *str, int defaultValue)
520 {
521 if (str == NULL || *str == '\0') {
522 return defaultValue;
523 }
524 errno = 0;
525 int value = (int)strtoul(str, NULL, DECIMAL_BASE);
526 return (errno != 0) ? defaultValue : value;
527 }
528
ReadFileInDir(const char * dirPath,const char * includeExt,int (* processFile)(const char * fileName,void * context),void * context)529 int ReadFileInDir(const char *dirPath, const char *includeExt,
530 int (*processFile)(const char *fileName, void *context), void *context)
531 {
532 INIT_CHECK_RETURN_VALUE(dirPath != NULL && processFile != NULL, -1);
533 DIR *pDir = opendir(dirPath);
534 INIT_ERROR_CHECK(pDir != NULL, return -1, "Read dir :%s failed.%d", dirPath, errno);
535 char *fileName = calloc(1, MAX_BUF_SIZE);
536 INIT_ERROR_CHECK(fileName != NULL, closedir(pDir);
537 return -1, "Failed to malloc for %s", dirPath);
538
539 struct dirent *dp;
540 uint32_t count = 0;
541 while ((dp = readdir(pDir)) != NULL) {
542 if (dp->d_type == DT_DIR) {
543 continue;
544 }
545 if (includeExt != NULL) {
546 char *tmp = strstr(dp->d_name, includeExt);
547 if (tmp == NULL) {
548 continue;
549 }
550 if (strcmp(tmp, includeExt) != 0) {
551 continue;
552 }
553 }
554 int ret = snprintf_s(fileName, MAX_BUF_SIZE, MAX_BUF_SIZE - 1, "%s/%s", dirPath, dp->d_name);
555 if (ret <= 0) {
556 INIT_LOGE("Failed to get file name for %s", dp->d_name);
557 continue;
558 }
559 struct stat st;
560 if (stat(fileName, &st) == 0) {
561 count++;
562 processFile(fileName, context);
563 }
564 }
565 INIT_LOGV("ReadFileInDir dirPath %s %d", dirPath, count);
566 free(fileName);
567 closedir(pDir);
568 return 0;
569 }
570
571 // Check if in updater mode.
InUpdaterMode(void)572 int InUpdaterMode(void)
573 {
574 #ifdef OHOS_LITE
575 return 0;
576 #else
577 const char * const updaterExecutableFile = "/bin/updater";
578 if (access(updaterExecutableFile, X_OK) == 0) {
579 return 1;
580 } else {
581 return 0;
582 }
583 #endif
584 }
585
StringReplaceChr(char * strl,char oldChr,char newChr)586 int StringReplaceChr(char *strl, char oldChr, char newChr)
587 {
588 INIT_ERROR_CHECK(strl != NULL, return -1, "Invalid parament");
589 char *p = strl;
590 while (*p != '\0') {
591 if (*p == oldChr) {
592 *p = newChr;
593 }
594 p++;
595 }
596 INIT_LOGV("strl is %s", strl);
597 return 0;
598 }
599
600 #ifndef __LITEOS_M__
RedirectStdio(int fd)601 static void RedirectStdio(int fd)
602 {
603 const int stdError = 2;
604 dup2(fd, 0);
605 dup2(fd, 1);
606 dup2(fd, stdError); // Redirect fd to 0, 1, 2
607 }
608 #endif
609
610 #ifndef __LITEOS_M__
OpenStdioDevice(const char * dev)611 static int OpenStdioDevice(const char *dev)
612 {
613 setsid();
614 WaitForFile(dev, WAIT_MAX_SECOND);
615 int fd = open(dev, O_RDWR);
616 if (fd >= 0) {
617 ioctl(fd, TIOCSCTTY, 0);
618 RedirectStdio(fd);
619 if (fd > 2) {
620 close(fd);
621 }
622 } else {
623 return errno;
624 }
625 return 0;
626 }
627 #endif
628
OpenConsole(void)629 int OpenConsole(void)
630 {
631 #ifndef __LITEOS_M__
632 return OpenStdioDevice("/dev/console");
633 #endif
634 }
635
OpenKmsg(void)636 int OpenKmsg(void)
637 {
638 #ifndef __LITEOS_M__
639 return OpenStdioDevice("/dev/kmsg");
640 #endif
641 }
642
StringToLL(const char * str,long long int * out)643 INIT_LOCAL_API int StringToLL(const char *str, long long int *out)
644 {
645 INIT_ERROR_CHECK(str != NULL && out != NULL, return -1, "Invalid parament");
646 const char *s = str;
647 while (isspace(*s)) {
648 s++;
649 }
650
651 size_t len = strlen(str);
652 int positiveHex = (len > 1 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
653 int negativeHex = (len > 2 && s[0] == '-' && s[1] == '0' && (s[2] == 'x' || s[2] == 'X')); // 2: shorttest
654 int base = (positiveHex || negativeHex) ? HEX_BASE : DECIMAL_BASE;
655 char *end = NULL;
656 errno = 0;
657 *out = strtoll(s, &end, base);
658 if (errno != 0) {
659 INIT_LOGE("StringToLL %s err = %d", str, errno);
660 return -1;
661 }
662 BEGET_CHECK(!(s == end || *end != '\0'), return -1);
663 return 0;
664 }
665
StringToULL(const char * str,unsigned long long int * out)666 INIT_LOCAL_API int StringToULL(const char *str, unsigned long long int *out)
667 {
668 INIT_ERROR_CHECK(str != NULL && out != NULL, return -1, "Invalid parament");
669 const char *s = str;
670 while (isspace(*s)) {
671 s++;
672 }
673 BEGET_CHECK(s[0] != '-', return -1);
674 int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? HEX_BASE : DECIMAL_BASE;
675 char *end = NULL;
676 errno = 0;
677 *out = strtoull(s, &end, base);
678 if (errno != 0) {
679 INIT_LOGE("StringToULL %s err = %d", str, errno);
680 return -1;
681 }
682 BEGET_CHECK(end != s, return -1);
683 BEGET_CHECK(*end == '\0', return -1);
684 return 0;
685 }
686
TrimTail(char * str,char c)687 void TrimTail(char *str, char c)
688 {
689 char *end = str + strlen(str) - 1;
690 while (end >= str && *end == c) {
691 *end = '\0';
692 end--;
693 }
694 }
695
TrimHead(char * str,char c)696 char *TrimHead(char *str, char c)
697 {
698 char *head = str;
699 const char *end = str + strlen(str);
700 while (head < end && *head == c) {
701 *head = '\0';
702 head++;
703 }
704 return head;
705 }
706
GetParameterFromCmdLine(const char * paramName,char * value,size_t valueLen)707 int GetParameterFromCmdLine(const char *paramName, char *value, size_t valueLen)
708 {
709 char *buffer = ReadFileData(BOOT_CMD_LINE);
710 BEGET_ERROR_CHECK(buffer != NULL, return -1, "Failed to read /proc/cmdline");
711 int ret = GetProcCmdlineValue(paramName, buffer, value, valueLen);
712 free(buffer);
713 return ret;
714 }
715
IntervalTime(struct timespec * startTime,struct timespec * endTime)716 uint32_t IntervalTime(struct timespec *startTime, struct timespec *endTime)
717 {
718 uint32_t diff = 0;
719 if (endTime->tv_sec > startTime->tv_sec) {
720 diff = (uint32_t)(endTime->tv_sec - startTime->tv_sec);
721 } else {
722 diff = (uint32_t)(startTime->tv_sec - endTime->tv_sec);
723 }
724 return diff;
725 }
726
727 typedef int (*str_compare)(const char *s1, const char *s2);
OH_ExtendableStrArrayGetIndex(const char * strArray[],const char * target,int ignoreCase,const char * extend[])728 int OH_ExtendableStrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase, const char *extend[])
729 {
730 int i;
731 int idx;
732 str_compare cmp = strcmp;
733
734 if ((strArray == NULL) || (target == NULL) || (target[0] == '\0')) {
735 return -1;
736 }
737
738 if (ignoreCase) {
739 cmp = strcasecmp;
740 }
741
742 for (i = 0; strArray[i] != NULL; i++) {
743 if (cmp(strArray[i], target) == 0) {
744 return i;
745 }
746 }
747 if (extend == NULL) {
748 return -1;
749 }
750 idx = 0;
751 while (extend[idx] != NULL) {
752 if (cmp(extend[idx], target) == 0) {
753 return i + idx;
754 }
755 idx++;
756 }
757 return -1;
758 }
759
OH_StrArrayGetIndex(const char * strArray[],const char * target,int ignoreCase)760 int OH_StrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase)
761 {
762 return OH_ExtendableStrArrayGetIndex(strArray, target, ignoreCase, NULL);
763 }
764
OH_ExtendableStrDictGet(void ** strDict,int dictSize,const char * target,int ignoreCase,void ** extendStrDict)765 void *OH_ExtendableStrDictGet(void **strDict, int dictSize, const char *target, int ignoreCase, void **extendStrDict)
766 {
767 int i;
768 const char *pos;
769 str_compare cmp = strcmp;
770
771 if ((strDict == NULL) || (dictSize < sizeof(const char *)) || (target == NULL) || (target[0] == '\0')) {
772 return NULL;
773 }
774
775 if (ignoreCase) {
776 cmp = strcasecmp;
777 }
778
779 i = 0;
780 pos = (const char *)strDict;
781 while (*pos != '\0') {
782 if (cmp(*(const char **)pos, target) == 0) {
783 return (void *)pos;
784 }
785 i++;
786 pos = pos + dictSize;
787 }
788 if (extendStrDict == NULL) {
789 return NULL;
790 }
791 pos = (const char *)extendStrDict;
792 while (*pos != '\0') {
793 if (cmp(*(const char **)pos, target) == 0) {
794 return (void *)pos;
795 }
796 i++;
797 pos = pos + dictSize;
798 }
799 return NULL;
800 }
801
OH_StrDictGet(void ** strDict,int dictSize,const char * target,int ignoreCase)802 void *OH_StrDictGet(void **strDict, int dictSize, const char *target, int ignoreCase)
803 {
804 return OH_ExtendableStrDictGet(strDict, dictSize, target, ignoreCase, NULL);
805 }
806
GetUptimeInMicroSeconds(const struct timespec * uptime)807 long long GetUptimeInMicroSeconds(const struct timespec *uptime)
808 {
809 struct timespec now;
810
811 if (uptime == NULL) {
812 clock_gettime(CLOCK_MONOTONIC, &now);
813 uptime = &now;
814 }
815
816 #define SECOND_TO_MICRO_SECOND (1000000)
817 #define MICRO_SECOND_TO_NANOSECOND (1000)
818
819 return (long long)((uptime->tv_sec * SECOND_TO_MICRO_SECOND) +
820 (uptime->tv_nsec / MICRO_SECOND_TO_NANOSECOND));
821 }
822