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