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