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*)calloc((size_t)(fileStat.st_size + 1), sizeof(char));
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 >= endData) {
261             return -1;
262         }
263         if (*tmp == '=') {
264             break;
265         }
266         tmp = strstr(tmp + 1, name);
267     } while (tmp < endData);
268     tmp++;
269     size_t i = 0;
270     size_t endIndex = 0;
271     while (tmp < endData && *tmp == ' ') {
272         tmp++;
273     }
274     for (; i < (size_t)length; tmp++) {
275         if (tmp >= endData || *tmp == ' ' || *tmp == '\n' || *tmp == '\r' || *tmp == '\t') {
276             endIndex = i;
277             break;
278         }
279         if (*tmp == '=') {
280             if (endIndex != 0) { // for root=uuid=xxxx
281                 break;
282             }
283             i = 0;
284             endIndex = 0;
285             continue;
286         }
287         value[i++] = *tmp;
288     }
289     if (i >= (size_t)length) {
290         return -1;
291     }
292     value[endIndex] = '\0';
293     return 0;
294 }
295 
SplitString(char * srcPtr,const char * del,char ** dstPtr,int maxNum)296 int SplitString(char *srcPtr, const char *del, char **dstPtr, int maxNum)
297 {
298     INIT_CHECK_RETURN_VALUE(srcPtr != NULL && dstPtr != NULL && del != NULL, -1);
299     char *buf = NULL;
300     dstPtr[0] = strtok_r(srcPtr, del, &buf);
301     int counter = 0;
302     while ((counter < maxNum) && (dstPtr[counter] != NULL)) {
303         counter++;
304         if (counter >= maxNum) {
305             break;
306         }
307         dstPtr[counter] = strtok_r(NULL, del, &buf);
308     }
309     return counter;
310 }
311 
FreeStringVector(char ** vector,int count)312 void FreeStringVector(char **vector, int count)
313 {
314     if (vector != NULL) {
315         for (int i = 0; i < count; i++) {
316             if (vector[i] != NULL) {
317                 free(vector[i]);
318             }
319         }
320         free(vector);
321     }
322 }
323 
SplitStringExt(char * buffer,const char * del,int * returnCount,int maxItemCount)324 char **SplitStringExt(char *buffer, const char *del, int *returnCount, int maxItemCount)
325 {
326     INIT_CHECK_RETURN_VALUE((maxItemCount >= 0) && (buffer != NULL) && (del != NULL) && (returnCount != NULL), NULL);
327     // Why is this number?
328     // Now we use this function to split a string with a given delimiter
329     // We do not know how many sub-strings out there after splitting.
330     // 50 is just a guess value.
331     const int defaultItemCounts = 50;
332     int itemCounts = maxItemCount;
333 
334     if (maxItemCount > defaultItemCounts) {
335         itemCounts = defaultItemCounts;
336     }
337     char **items = (char **)malloc(sizeof(char*) * itemCounts);
338     INIT_ERROR_CHECK(items != NULL, return NULL, "No enough memory to store items");
339     char *rest = NULL;
340     char *p = strtok_r(buffer, del, &rest);
341     int count = 0;
342     while (p != NULL) {
343         if (count > itemCounts - 1) {
344             itemCounts += (itemCounts / 2) + 1; // 2 Request to increase the original memory by half.
345             INIT_LOGV("Too many items,expand size");
346             char **expand = (char **)(realloc(items, sizeof(char *) * itemCounts));
347             INIT_ERROR_CHECK(expand != NULL, FreeStringVector(items, count);
348                 return NULL, "Failed to expand memory");
349             items = expand;
350         }
351         size_t len = strlen(p);
352         items[count] = (char *)calloc(len + 1, sizeof(char));
353         INIT_CHECK(items[count] != NULL, FreeStringVector(items, count);
354             return NULL);
355         if (strncpy_s(items[count], len + 1, p, len) != EOK) {
356             INIT_LOGE("Copy string failed");
357             FreeStringVector(items, count);
358             return NULL;
359         }
360         count++;
361         p = strtok_r(NULL, del, &rest);
362     }
363     *returnCount = count;
364     return items;
365 }
366 
InitDiffTime(INIT_TIMING_STAT * stat)367 long long InitDiffTime(INIT_TIMING_STAT *stat)
368 {
369     long long diff = (long long)(stat->endTime.tv_sec - stat->startTime.tv_sec) * 1000000; // 1000000 1000ms
370     if (stat->endTime.tv_nsec > stat->startTime.tv_nsec) {
371         diff += (stat->endTime.tv_nsec - stat->startTime.tv_nsec) / BASE_MS_UNIT;
372     } else {
373         diff -= (stat->startTime.tv_nsec - stat->endTime.tv_nsec) / BASE_MS_UNIT;
374     }
375     return diff;
376 }
377 
WaitForFile(const char * source,unsigned int maxSecond)378 void WaitForFile(const char *source, unsigned int maxSecond)
379 {
380     INIT_ERROR_CHECK(maxSecond <= WAIT_MAX_SECOND, maxSecond = WAIT_MAX_SECOND,
381         "WaitForFile max time is %us", WAIT_MAX_SECOND);
382     struct stat sourceInfo = {0};
383     unsigned int waitTime = 10 * BASE_MS_UNIT; // 10ms
384     long long maxDuration = maxSecond * BASE_MS_UNIT * BASE_MS_UNIT; // 5s
385 #ifdef STARTUP_INIT_TEST
386     maxDuration = 0;
387 #endif
388     long long duration = 0;
389     INIT_TIMING_STAT cmdTimer;
390     (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.startTime);
391     while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (duration < maxDuration)) {
392         usleep(waitTime);
393         (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime);
394         duration = InitDiffTime(&cmdTimer);
395     }
396     INIT_CHECK_ONLY_ELOG(duration < maxDuration, "wait for file:%s failed after %d second.", source, maxSecond);
397     return;
398 }
399 
WriteAll(int fd,const char * buffer,size_t size)400 size_t WriteAll(int fd, const char *buffer, size_t size)
401 {
402     INIT_CHECK_RETURN_VALUE(buffer != NULL && fd >= 0 && *buffer != '\0', 0);
403     const char *p = buffer;
404     size_t left = size;
405     ssize_t written;
406     while (left > 0) {
407         do {
408             written = write(fd, p, left);
409         } while (written < 0 && errno == EINTR);
410         if (written < 0) {
411             INIT_LOGE("Failed to write %lu bytes, err = %d", left, errno);
412             break;
413         }
414         p += written;
415         left -= written;
416     }
417     return size - left;
418 }
419 
GetRealPath(const char * source)420 char *GetRealPath(const char *source)
421 {
422     INIT_CHECK_RETURN_VALUE(source != NULL, NULL);
423     char *path = realpath(source, NULL);
424     if (path == NULL) {
425         INIT_ERROR_CHECK(errno == ENOENT, return NULL, "Failed to resolve %s real path err=%d", source, errno);
426     }
427     return path;
428 }
429 
MakeDir(const char * dir,mode_t mode)430 int MakeDir(const char *dir, mode_t mode)
431 {
432     int rc = -1;
433     if (dir == NULL || *dir == '\0') {
434         errno = EINVAL;
435         return rc;
436     }
437     rc = mkdir(dir, mode);
438     INIT_ERROR_CHECK(!(rc < 0 && errno != EEXIST), return rc,
439         "Create directory \" %s \" failed, err = %d", dir, errno);
440     // create dir success or it already exist.
441     return 0;
442 }
443 
MakeDirRecursive(const char * dir,mode_t mode)444 int MakeDirRecursive(const char *dir, mode_t mode)
445 {
446     int rc = -1;
447     char buffer[PATH_MAX] = {0};
448     const char *p = NULL;
449     if (dir == NULL || *dir == '\0') {
450         errno = EINVAL;
451         return rc;
452     }
453     p = dir;
454     char *slash = strchr(dir, '/');
455     while (slash != NULL) {
456         int gap = slash - p;
457         p = slash + 1;
458         if (gap == 0) {
459             slash = strchr(p, '/');
460             continue;
461         }
462         if (gap < 0) { // end with '/'
463             break;
464         }
465         INIT_CHECK_RETURN_VALUE(memcpy_s(buffer, PATH_MAX, dir, p - dir - 1) == 0, -1);
466         rc = MakeDir(buffer, mode);
467         INIT_CHECK_RETURN_VALUE(rc >= 0, rc);
468         slash = strchr(p, '/');
469     }
470     return MakeDir(dir, mode);
471 }
472 
CheckAndCreateDir(const char * fileName)473 void CheckAndCreateDir(const char *fileName)
474 {
475 #ifndef __LITEOS_M__
476     if (fileName == NULL || *fileName == '\0') {
477         return;
478     }
479     char *path = strndup(fileName, strrchr(fileName, '/') - fileName);
480     if (path == NULL) {
481         return;
482     }
483     if (access(path, F_OK) == 0) {
484         free(path);
485         return;
486     }
487     MakeDirRecursive(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
488     free(path);
489 #else
490     (void)fileName;
491 #endif
492 }
493 
CheckAndCreatFile(const char * file,mode_t mode)494 int CheckAndCreatFile(const char *file, mode_t mode)
495 {
496     if (access(file, F_OK) == 0) {
497         BEGET_LOGW("File \' %s \' already exist", file);
498         return 0;
499     } else {
500         if (errno == ENOENT) {
501             CheckAndCreateDir(file);
502             int fd = open(file, O_CREAT, mode);
503             if (fd < 0) {
504                 BEGET_LOGE("Failed create %s, err=%d", file, errno);
505                 return -1;
506             } else {
507                 close(fd);
508             }
509         } else {
510             BEGET_LOGW("Failed to access \' %s \', err = %d", file, errno);
511             return -1;
512         }
513     }
514     return 0;
515 }
516 
StringToInt(const char * str,int defaultValue)517 int StringToInt(const char *str, int defaultValue)
518 {
519     if (str == NULL || *str == '\0') {
520         return defaultValue;
521     }
522     errno = 0;
523     int value = (int)strtoul(str, NULL, DECIMAL_BASE);
524     return (errno != 0) ? defaultValue : value;
525 }
526 
ReadFileInDir(const char * dirPath,const char * includeExt,int (* processFile)(const char * fileName,void * context),void * context)527 int ReadFileInDir(const char *dirPath, const char *includeExt,
528     int (*processFile)(const char *fileName, void *context), void *context)
529 {
530     INIT_CHECK_RETURN_VALUE(dirPath != NULL && processFile != NULL, -1);
531     DIR *pDir = opendir(dirPath);
532     INIT_ERROR_CHECK(pDir != NULL, return -1, "Read dir :%s failed.%d", dirPath, errno);
533     char *fileName = calloc(1, MAX_BUF_SIZE);
534     INIT_ERROR_CHECK(fileName != NULL, closedir(pDir);
535         return -1, "Failed to malloc for %s", dirPath);
536 
537     struct dirent *dp;
538     uint32_t count = 0;
539     while ((dp = readdir(pDir)) != NULL) {
540         if (dp->d_type == DT_DIR) {
541             continue;
542         }
543         if (includeExt != NULL) {
544             char *tmp = strstr(dp->d_name, includeExt);
545             if (tmp == NULL) {
546                 continue;
547             }
548             if (strcmp(tmp, includeExt) != 0) {
549                 continue;
550             }
551         }
552         int ret = snprintf_s(fileName, MAX_BUF_SIZE, MAX_BUF_SIZE - 1, "%s/%s", dirPath, dp->d_name);
553         if (ret <= 0) {
554             INIT_LOGE("Failed to get file name for %s", dp->d_name);
555             continue;
556         }
557         struct stat st;
558         if (stat(fileName, &st) == 0) {
559             count++;
560             processFile(fileName, context);
561         }
562     }
563     INIT_LOGV("ReadFileInDir dirPath %s %d", dirPath, count);
564     free(fileName);
565     closedir(pDir);
566     return 0;
567 }
568 
569 // Check if in updater mode.
InUpdaterMode(void)570 int InUpdaterMode(void)
571 {
572 #ifdef OHOS_LITE
573     return 0;
574 #else
575     const char * const updaterExecutableFile = "/bin/updater";
576     if (access(updaterExecutableFile, X_OK) == 0) {
577         return 1;
578     } else {
579         return 0;
580     }
581 #endif
582 }
583 
584 // Check if in rescue mode.
InRescueMode(void)585 int InRescueMode(void)
586 {
587 #ifdef OHOS_LITE
588     return 1;
589 #else
590     char value[MAX_BUFFER_LEN] = {0};
591     int ret = GetParameterFromCmdLine("rescue_mode", value, MAX_BUFFER_LEN);
592     if (ret == 0 && strcmp(value, "true") == 0) {
593         return 0;
594     }
595     return 1;
596 #endif
597 }
598 
StringReplaceChr(char * strl,char oldChr,char newChr)599 int StringReplaceChr(char *strl, char oldChr, char newChr)
600 {
601     INIT_ERROR_CHECK(strl != NULL, return -1, "Invalid parament");
602     char *p = strl;
603     while (*p != '\0') {
604         if (*p == oldChr) {
605             *p = newChr;
606         }
607         p++;
608     }
609     INIT_LOGV("strl is %s", strl);
610     return 0;
611 }
612 
613 #ifndef __LITEOS_M__
RedirectStdio(int fd)614 static void RedirectStdio(int fd)
615 {
616     const int stdError = 2;
617     dup2(fd, 0);
618     dup2(fd, 1);
619     dup2(fd, stdError); // Redirect fd to 0, 1, 2
620 }
621 #endif
622 
623 #ifndef __LITEOS_M__
OpenStdioDevice(const char * dev,int flag)624 static int OpenStdioDevice(const char *dev, int flag)
625 {
626     setsid();
627     WaitForFile(dev, WAIT_MAX_SECOND);
628     int fd = open(dev, O_RDWR);
629     if (fd >= 0) {
630         ioctl(fd, TIOCSCTTY, flag);
631         RedirectStdio(fd);
632         if (fd > 2) {
633             close(fd);
634         }
635     } else {
636         return errno;
637     }
638     return 0;
639 }
640 #endif
641 
OpenConsole(void)642 int OpenConsole(void)
643 {
644 #ifndef __LITEOS_M__
645     return OpenStdioDevice("/dev/console", 1);
646 #else
647     return 0;
648 #endif
649 }
650 
OpenKmsg(void)651 int OpenKmsg(void)
652 {
653 #ifndef __LITEOS_M__
654     return OpenStdioDevice("/dev/kmsg", 0);
655 #else
656     return 0;
657 #endif
658 }
659 
StringToLL(const char * str,long long int * out)660 INIT_LOCAL_API int StringToLL(const char *str, long long int *out)
661 {
662     INIT_ERROR_CHECK(str != NULL && out != NULL, return -1, "Invalid parament");
663     const char *s = str;
664     while (isspace(*s)) {
665         s++;
666     }
667 
668     size_t len = strlen(s);
669     int positiveHex = (len > 1 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
670     int negativeHex = (len > 2 && s[0] == '-' && s[1] == '0' && (s[2] == 'x' || s[2] == 'X')); // 2: shorttest
671     int base = (positiveHex || negativeHex) ? HEX_BASE : DECIMAL_BASE;
672     char *end = NULL;
673     errno = 0;
674     *out = strtoll(s, &end, base);
675     if (errno != 0) {
676         INIT_LOGE("StringToLL %s err = %d", str, errno);
677         return -1;
678     }
679     BEGET_CHECK(!(s == end || *end != '\0'), return -1);
680     return 0;
681 }
682 
StringToULL(const char * str,unsigned long long int * out)683 INIT_LOCAL_API int StringToULL(const char *str, unsigned long long int *out)
684 {
685     INIT_ERROR_CHECK(str != NULL && out != NULL, return -1, "Invalid parament");
686     const char *s = str;
687     while (isspace(*s)) {
688         s++;
689     }
690     BEGET_CHECK(s[0] != '-', return -1);
691     int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? HEX_BASE : DECIMAL_BASE;
692     char *end = NULL;
693     errno = 0;
694     *out = strtoull(s, &end, base);
695     if (errno != 0) {
696         INIT_LOGE("StringToULL %s err = %d", str, errno);
697         return -1;
698     }
699     BEGET_CHECK(end != s, return -1);
700     BEGET_CHECK(*end == '\0', return -1);
701     return 0;
702 }
703 
TrimTail(char * str,char c)704 void TrimTail(char *str, char c)
705 {
706     char *end = str + strlen(str) - 1;
707     while (end >= str && *end == c) {
708         *end = '\0';
709         end--;
710     }
711 }
712 
TrimHead(char * str,char c)713 char *TrimHead(char *str, char c)
714 {
715     char *head = str;
716     const char *end = str + strlen(str);
717     while (head < end && *head == c) {
718         *head = '\0';
719         head++;
720     }
721     return head;
722 }
723 
GetParameterFromCmdLine(const char * paramName,char * value,size_t valueLen)724 int GetParameterFromCmdLine(const char *paramName, char *value, size_t valueLen)
725 {
726     char *buffer = ReadFileData(BOOT_CMD_LINE);
727     BEGET_ERROR_CHECK(buffer != NULL, return -1, "Failed to read /proc/cmdline");
728     int ret = GetProcCmdlineValue(paramName, buffer, value, valueLen);
729     free(buffer);
730     return ret;
731 }
732 
IntervalTime(struct timespec * startTime,struct timespec * endTime)733 uint32_t IntervalTime(struct timespec *startTime, struct timespec *endTime)
734 {
735     uint32_t diff = 0;
736     if (endTime->tv_sec > startTime->tv_sec) {
737         diff = (uint32_t)(endTime->tv_sec - startTime->tv_sec);
738     } else {
739         diff = (uint32_t)(startTime->tv_sec - endTime->tv_sec);
740     }
741     return diff;
742 }
743 
744 typedef int (*str_compare)(const char *s1, const char *s2);
OH_ExtendableStrArrayGetIndex(const char * strArray[],const char * target,int ignoreCase,const char * extend[])745 int OH_ExtendableStrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase, const char *extend[])
746 {
747     int i;
748     int idx;
749     str_compare cmp = strcmp;
750 
751     if ((strArray == NULL) || (target == NULL) || (target[0] == '\0')) {
752         return -1;
753     }
754 
755     if (ignoreCase) {
756         cmp = strcasecmp;
757     }
758 
759     for (i = 0; strArray[i] != NULL; i++) {
760         if (cmp(strArray[i], target) == 0) {
761             return i;
762         }
763     }
764     if (extend == NULL) {
765         return -1;
766     }
767     idx = 0;
768     while (extend[idx] != NULL) {
769         if (cmp(extend[idx], target) == 0) {
770             return i + idx;
771         }
772         idx++;
773     }
774     return -1;
775 }
776 
OH_StrArrayGetIndex(const char * strArray[],const char * target,int ignoreCase)777 int OH_StrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase)
778 {
779     return OH_ExtendableStrArrayGetIndex(strArray, target, ignoreCase, NULL);
780 }
781 
OH_ExtendableStrDictGet(void ** strDict,int dictSize,const char * target,int ignoreCase,void ** extendStrDict)782 void *OH_ExtendableStrDictGet(void **strDict, int dictSize, const char *target, int ignoreCase, void **extendStrDict)
783 {
784     int i;
785     const char *pos;
786     str_compare cmp = strcmp;
787 
788     if ((strDict == NULL) || (dictSize < 0) || ((size_t)dictSize < sizeof(const char *)) ||
789         (target == NULL) || (target[0] == '\0')) {
790         return NULL;
791     }
792 
793     if (ignoreCase) {
794         cmp = strcasecmp;
795     }
796 
797     i = 0;
798     pos = (const char *)strDict;
799     while (*(const char **)pos != NULL) {
800         if (cmp(*(const char **)pos, target) == 0) {
801             return (void *)pos;
802         }
803         i++;
804         pos = pos + dictSize;
805     }
806     if (extendStrDict == NULL) {
807         return NULL;
808     }
809     pos = (const char *)extendStrDict;
810     while (*(const char **)pos != NULL) {
811         if (cmp(*(const char **)pos, target) == 0) {
812             return (void *)pos;
813         }
814         i++;
815         pos = pos + dictSize;
816     }
817     return NULL;
818 }
819 
OH_StrDictGet(void ** strDict,int dictSize,const char * target,int ignoreCase)820 void *OH_StrDictGet(void **strDict, int dictSize, const char *target, int ignoreCase)
821 {
822     return OH_ExtendableStrDictGet(strDict, dictSize, target, ignoreCase, NULL);
823 }
824 
GetUptimeInMicroSeconds(const struct timespec * uptime)825 long long GetUptimeInMicroSeconds(const struct timespec *uptime)
826 {
827     struct timespec now;
828 
829     if (uptime == NULL) {
830         clock_gettime(CLOCK_MONOTONIC, &now);
831         uptime = &now;
832     }
833 
834     #define SECOND_TO_MICRO_SECOND (1000000)
835     #define MICRO_SECOND_TO_NANOSECOND (1000)
836 
837     return ((long long)uptime->tv_sec * SECOND_TO_MICRO_SECOND) +
838             (uptime->tv_nsec / MICRO_SECOND_TO_NANOSECOND);
839 }
840