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
413 usleep(waitTime);
414 (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime);
415 duration = InitDiffTime(&cmdTimer);
416
417 if (duration >= maxDuration) {
418 INIT_LOGE("wait for file:%s failed after %d second.", source, maxSecond);
419 break;
420 }
421 }
422 }
423
WriteAll(int fd,const char * buffer,size_t size)424 size_t WriteAll(int fd, const char *buffer, size_t size)
425 {
426 INIT_CHECK_RETURN_VALUE(buffer != NULL && fd >= 0 && *buffer != '\0', 0);
427 const char *p = buffer;
428 size_t left = size;
429 ssize_t written;
430 while (left > 0) {
431 do {
432 written = write(fd, p, left);
433 } while (written < 0 && errno == EINTR);
434 if (written < 0) {
435 INIT_LOGE("Failed to write %lu bytes, err = %d", left, errno);
436 break;
437 }
438 p += written;
439 left -= written;
440 }
441 return size - left;
442 }
443
GetRealPath(const char * source)444 char *GetRealPath(const char *source)
445 {
446 INIT_CHECK_RETURN_VALUE(source != NULL, NULL);
447 char *path = realpath(source, NULL);
448 if (path == NULL) {
449 INIT_ERROR_CHECK(errno == ENOENT, return NULL, "Failed to resolve %s real path err=%d", source, errno);
450 }
451 return path;
452 }
453
MakeDir(const char * dir,mode_t mode)454 int MakeDir(const char *dir, mode_t mode)
455 {
456 int rc = -1;
457 if (dir == NULL || *dir == '\0') {
458 errno = EINVAL;
459 return rc;
460 }
461 rc = mkdir(dir, mode);
462 INIT_ERROR_CHECK(!(rc < 0 && errno != EEXIST), return rc,
463 "Create directory \" %s \" failed, err = %d", dir, errno);
464 // create dir success or it already exist.
465 return 0;
466 }
467
MakeDirRecursive(const char * dir,mode_t mode)468 int MakeDirRecursive(const char *dir, mode_t mode)
469 {
470 int rc = -1;
471 char buffer[PATH_MAX] = {0};
472 const char *p = NULL;
473 if (dir == NULL || *dir == '\0') {
474 errno = EINVAL;
475 return rc;
476 }
477 p = dir;
478 char *slash = strchr(dir, '/');
479 while (slash != NULL) {
480 int gap = slash - p;
481 p = slash + 1;
482 if (gap == 0) {
483 slash = strchr(p, '/');
484 continue;
485 }
486 if (gap < 0) { // end with '/'
487 break;
488 }
489 INIT_CHECK_RETURN_VALUE(memcpy_s(buffer, PATH_MAX, dir, p - dir - 1) == 0, -1);
490 rc = MakeDir(buffer, mode);
491 INIT_CHECK_RETURN_VALUE(rc >= 0, rc);
492 slash = strchr(p, '/');
493 }
494 return MakeDir(dir, mode);
495 }
496
CheckAndCreateDir(const char * fileName)497 void CheckAndCreateDir(const char *fileName)
498 {
499 #ifndef __LITEOS_M__
500 if (fileName == NULL || *fileName == '\0') {
501 return;
502 }
503 char *path = strndup(fileName, strrchr(fileName, '/') - fileName);
504 if (path == NULL) {
505 return;
506 }
507 if (access(path, F_OK) == 0) {
508 free(path);
509 return;
510 }
511 MakeDirRecursive(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
512 free(path);
513 #else
514 (void)fileName;
515 #endif
516 }
517
CheckAndCreatFile(const char * file,mode_t mode)518 int CheckAndCreatFile(const char *file, mode_t mode)
519 {
520 if (access(file, F_OK) == 0) {
521 BEGET_LOGW("File \' %s \' already exist", file);
522 return 0;
523 } else {
524 if (errno == ENOENT) {
525 CheckAndCreateDir(file);
526 int fd = open(file, O_CREAT, mode);
527 if (fd < 0) {
528 BEGET_LOGE("Failed create %s, err=%d", file, errno);
529 return -1;
530 } else {
531 close(fd);
532 }
533 } else {
534 BEGET_LOGW("Failed to access \' %s \', err = %d", file, errno);
535 return -1;
536 }
537 }
538 return 0;
539 }
540
StringToInt(const char * str,int defaultValue)541 int StringToInt(const char *str, int defaultValue)
542 {
543 if (str == NULL || *str == '\0') {
544 return defaultValue;
545 }
546 errno = 0;
547 int value = (int)strtoul(str, NULL, DECIMAL_BASE);
548 return (errno != 0) ? defaultValue : value;
549 }
550
ReadFileInDir(const char * dirPath,const char * includeExt,int (* processFile)(const char * fileName,void * context),void * context)551 int ReadFileInDir(const char *dirPath, const char *includeExt,
552 int (*processFile)(const char *fileName, void *context), void *context)
553 {
554 INIT_CHECK_RETURN_VALUE(dirPath != NULL && processFile != NULL, -1);
555 DIR *pDir = opendir(dirPath);
556 INIT_ERROR_CHECK(pDir != NULL, return -1, "Read dir :%s failed.%d", dirPath, errno);
557 char *fileName = calloc(1, MAX_BUF_SIZE);
558 INIT_ERROR_CHECK(fileName != NULL, closedir(pDir);
559 return -1, "Failed to malloc for %s", dirPath);
560
561 struct dirent *dp;
562 uint32_t count = 0;
563 while ((dp = readdir(pDir)) != NULL) {
564 if (dp->d_type == DT_DIR) {
565 continue;
566 }
567 if (includeExt != NULL) {
568 char *tmp = strstr(dp->d_name, includeExt);
569 if (tmp == NULL) {
570 continue;
571 }
572 if (strcmp(tmp, includeExt) != 0) {
573 continue;
574 }
575 }
576 int ret = snprintf_s(fileName, MAX_BUF_SIZE, MAX_BUF_SIZE - 1, "%s/%s", dirPath, dp->d_name);
577 if (ret <= 0) {
578 INIT_LOGE("Failed to get file name for %s", dp->d_name);
579 continue;
580 }
581 struct stat st;
582 if (stat(fileName, &st) == 0) {
583 count++;
584 processFile(fileName, context);
585 }
586 }
587 INIT_LOGV("ReadFileInDir dirPath %s %d", dirPath, count);
588 free(fileName);
589 closedir(pDir);
590 return 0;
591 }
592
593 // Check if in updater mode.
InUpdaterMode(void)594 int InUpdaterMode(void)
595 {
596 #ifdef OHOS_LITE
597 return 0;
598 #else
599 const char * const updaterExecutableFile = "/bin/updater";
600 if (access(updaterExecutableFile, X_OK) == 0) {
601 return 1;
602 } else {
603 return 0;
604 }
605 #endif
606 }
607
608 // Check if in rescue mode.
InRescueMode(void)609 int InRescueMode(void)
610 {
611 #ifdef OHOS_LITE
612 return 1;
613 #else
614 char value[MAX_BUFFER_LEN] = {0};
615 int ret = GetParameterFromCmdLine("rescue_mode", value, MAX_BUFFER_LEN);
616 if (ret == 0 && strcmp(value, "true") == 0) {
617 return 0;
618 }
619 return 1;
620 #endif
621 }
622
StringReplaceChr(char * strl,char oldChr,char newChr)623 int StringReplaceChr(char *strl, char oldChr, char newChr)
624 {
625 INIT_ERROR_CHECK(strl != NULL, return -1, "Invalid parament");
626 char *p = strl;
627 while (*p != '\0') {
628 if (*p == oldChr) {
629 *p = newChr;
630 }
631 p++;
632 }
633 INIT_LOGV("strl is %s", strl);
634 return 0;
635 }
636
637 #ifndef __LITEOS_M__
RedirectStdio(int fd)638 static void RedirectStdio(int fd)
639 {
640 const int stdError = 2;
641 dup2(fd, 0);
642 dup2(fd, 1);
643 dup2(fd, stdError); // Redirect fd to 0, 1, 2
644 }
645 #endif
646
647 #ifndef __LITEOS_M__
OpenStdioDevice(const char * dev,int flag)648 static int OpenStdioDevice(const char *dev, int flag)
649 {
650 setsid();
651 WaitForFile(dev, WAIT_MAX_SECOND);
652 int fd = open(dev, O_RDWR | O_NOCTTY | O_CLOEXEC);
653 if (fd >= 0) {
654 ioctl(fd, TIOCSCTTY, flag);
655 RedirectStdio(fd);
656 if (fd > 2) {
657 close(fd);
658 }
659 } else {
660 return errno;
661 }
662 return 0;
663 }
664 #endif
665
OpenConsole(void)666 int OpenConsole(void)
667 {
668 #ifndef __LITEOS_M__
669 return OpenStdioDevice("/dev/console", 1);
670 #else
671 return 0;
672 #endif
673 }
674
OpenKmsg(void)675 int OpenKmsg(void)
676 {
677 #ifndef __LITEOS_M__
678 return OpenStdioDevice("/dev/kmsg", 0);
679 #else
680 return 0;
681 #endif
682 }
683
StringToLL(const char * str,long long int * out)684 INIT_LOCAL_API int StringToLL(const char *str, long long int *out)
685 {
686 INIT_ERROR_CHECK(str != NULL && out != NULL, return -1, "Invalid parament");
687 const char *s = str;
688 while (isspace(*s)) {
689 s++;
690 }
691
692 size_t len = strlen(s);
693 int positiveHex = (len > 1 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
694 int negativeHex = (len > 2 && s[0] == '-' && s[1] == '0' && (s[2] == 'x' || s[2] == 'X')); // 2: shorttest
695 int base = (positiveHex || negativeHex) ? HEX_BASE : DECIMAL_BASE;
696 char *end = NULL;
697 errno = 0;
698 *out = strtoll(s, &end, base);
699 if (errno != 0) {
700 INIT_LOGE("StringToLL %s err = %d", str, errno);
701 return -1;
702 }
703 BEGET_CHECK(!(s == end || *end != '\0'), return -1);
704 return 0;
705 }
706
StringToULL(const char * str,unsigned long long int * out)707 INIT_LOCAL_API int StringToULL(const char *str, unsigned long long int *out)
708 {
709 INIT_ERROR_CHECK(str != NULL && out != NULL, return -1, "Invalid parament");
710 const char *s = str;
711 while (isspace(*s)) {
712 s++;
713 }
714 BEGET_CHECK(s[0] != '-', return -1);
715 int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? HEX_BASE : DECIMAL_BASE;
716 char *end = NULL;
717 errno = 0;
718 *out = strtoull(s, &end, base);
719 if (errno != 0) {
720 INIT_LOGE("StringToULL %s err = %d", str, errno);
721 return -1;
722 }
723 BEGET_CHECK(end != s, return -1);
724 BEGET_CHECK(*end == '\0', return -1);
725 return 0;
726 }
727
TrimTail(char * str,char c)728 void TrimTail(char *str, char c)
729 {
730 char *end = str + strlen(str) - 1;
731 while (end >= str && *end == c) {
732 *end = '\0';
733 end--;
734 }
735 }
736
TrimHead(char * str,char c)737 char *TrimHead(char *str, char c)
738 {
739 char *head = str;
740 const char *end = str + strlen(str);
741 while (head < end && *head == c) {
742 *head = '\0';
743 head++;
744 }
745 return head;
746 }
747
GetCmdlineValueByName(const char * name,const char * buffer,const char * endData)748 static const char *GetCmdlineValueByName(const char *name, const char *buffer, const char *endData)
749 {
750 const char *tmp = buffer;
751 do {
752 tmp = strstr(tmp, name);
753 if (tmp == NULL) {
754 return NULL;
755 }
756 if (tmp > buffer && *(tmp - 1) != ' ') {
757 tmp++;
758 continue;
759 }
760 tmp = tmp + strlen(name);
761 if (tmp >= endData) {
762 return NULL;
763 }
764 if (*tmp == '=') {
765 tmp++;
766 return tmp;
767 }
768 } while (tmp < endData);
769 return NULL;
770 }
771
GetExactProcCmdlineValue(const char * name,const char * buffer,char * value,int length)772 static int GetExactProcCmdlineValue(const char *name, const char *buffer, char *value, int length)
773 {
774 INIT_ERROR_CHECK(name != NULL && buffer != NULL && value != NULL, return -1, "Failed get parameters");
775 const char *endData = buffer + strlen(buffer);
776 const char *tmp = GetCmdlineValueByName(name, buffer, endData);
777 if (tmp == NULL) {
778 return -1;
779 }
780
781 const char *temp = GetCmdlineValueByName(name, tmp, endData);
782 if (temp == NULL) { // 无冲突
783 int i = 0;
784 while (i < length && tmp < endData && *tmp != ' ') {
785 value[i++] = *tmp;
786 tmp++;
787 }
788 if (i >= length) {
789 BEGET_LOGE("value is too long");
790 for (int j = 0; j < length; ++j) {
791 value[j] = '\0';
792 }
793 return -1;
794 }
795 value[i] = '\0';
796 return 0;
797 }
798 // 有冲突直接返回1, 不取任何一个值
799 return 1;
800 }
801
GetExactParameterFromCmdLine(const char * paramName,char * value,size_t valueLen)802 int GetExactParameterFromCmdLine(const char *paramName, char *value, size_t valueLen)
803 {
804 char *buffer = ReadFileData(BOOT_CMD_LINE);
805 BEGET_ERROR_CHECK(buffer != NULL, return -1, "Failed to read /proc/cmdline");
806 int ret = GetExactProcCmdlineValue(paramName, buffer, value, valueLen);
807 BEGET_LOGI("GetExactParameterFromCmdLine: ret=%d,paramName=%s,value=%s", ret, paramName, value);
808 free(buffer);
809 return ret;
810 }
811
GetParameterFromCmdLine(const char * paramName,char * value,size_t valueLen)812 int GetParameterFromCmdLine(const char *paramName, char *value, size_t valueLen)
813 {
814 char *buffer = ReadFileData(BOOT_CMD_LINE);
815 BEGET_ERROR_CHECK(buffer != NULL, return -1, "Failed to read /proc/cmdline");
816 int ret = GetProcCmdlineValue(paramName, buffer, value, valueLen);
817 BEGET_LOGI("GetParameterFromCmdLine: ret=%d,paramName=%s,value=%s", ret, paramName, value);
818 free(buffer);
819 return ret;
820 }
821
IntervalTime(struct timespec * startTime,struct timespec * endTime)822 uint32_t IntervalTime(struct timespec *startTime, struct timespec *endTime)
823 {
824 uint32_t diff = 0;
825 if (endTime->tv_sec > startTime->tv_sec) {
826 diff = (uint32_t)(endTime->tv_sec - startTime->tv_sec);
827 } else {
828 diff = (uint32_t)(startTime->tv_sec - endTime->tv_sec);
829 }
830 return diff;
831 }
832
833 typedef int (*str_compare)(const char *s1, const char *s2);
OH_ExtendableStrArrayGetIndex(const char * strArray[],const char * target,int ignoreCase,const char * extend[])834 int OH_ExtendableStrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase, const char *extend[])
835 {
836 int i;
837 int idx;
838 str_compare cmp = strcmp;
839
840 if ((strArray == NULL) || (target == NULL) || (target[0] == '\0')) {
841 return -1;
842 }
843
844 if (ignoreCase) {
845 cmp = strcasecmp;
846 }
847
848 for (i = 0; strArray[i] != NULL; i++) {
849 if (cmp(strArray[i], target) == 0) {
850 return i;
851 }
852 }
853 if (extend == NULL) {
854 return -1;
855 }
856 idx = 0;
857 while (extend[idx] != NULL) {
858 if (cmp(extend[idx], target) == 0) {
859 return i + idx;
860 }
861 idx++;
862 }
863 return -1;
864 }
865
OH_StrArrayGetIndex(const char * strArray[],const char * target,int ignoreCase)866 int OH_StrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase)
867 {
868 return OH_ExtendableStrArrayGetIndex(strArray, target, ignoreCase, NULL);
869 }
870
OH_ExtendableStrDictGet(void ** strDict,int dictSize,const char * target,int ignoreCase,void ** extendStrDict)871 void *OH_ExtendableStrDictGet(void **strDict, int dictSize, const char *target, int ignoreCase, void **extendStrDict)
872 {
873 int i;
874 const char *pos;
875 str_compare cmp = strcmp;
876
877 if ((strDict == NULL) || dictSize < 0 || ((size_t)dictSize < sizeof(const char *)) ||
878 (target == NULL) || (target[0] == '\0')) {
879 return NULL;
880 }
881
882 if (ignoreCase) {
883 cmp = strcasecmp;
884 }
885
886 i = 0;
887 pos = (const char *)strDict;
888 while (*(const char **)pos != NULL) {
889 if (cmp(*(const char **)pos, target) == 0) {
890 return (void *)pos;
891 }
892 i++;
893 pos = pos + dictSize;
894 }
895 if (extendStrDict == NULL) {
896 return NULL;
897 }
898 pos = (const char *)extendStrDict;
899 while (*(const char **)pos != NULL) {
900 if (cmp(*(const char **)pos, target) == 0) {
901 return (void *)pos;
902 }
903 i++;
904 pos = pos + dictSize;
905 }
906 return NULL;
907 }
908
OH_StrDictGet(void ** strDict,int dictSize,const char * target,int ignoreCase)909 void *OH_StrDictGet(void **strDict, int dictSize, const char *target, int ignoreCase)
910 {
911 return OH_ExtendableStrDictGet(strDict, dictSize, target, ignoreCase, NULL);
912 }
913
GetUptimeInMicroSeconds(const struct timespec * uptime)914 long long GetUptimeInMicroSeconds(const struct timespec *uptime)
915 {
916 struct timespec now;
917
918 if (uptime == NULL) {
919 clock_gettime(CLOCK_MONOTONIC, &now);
920 uptime = &now;
921 }
922
923 #define SECOND_TO_MICRO_SECOND (1000000)
924 #define MICRO_SECOND_TO_NANOSECOND (1000)
925
926 return ((long long)uptime->tv_sec * SECOND_TO_MICRO_SECOND) +
927 (uptime->tv_nsec / MICRO_SECOND_TO_NANOSECOND);
928 }
929