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