1 /*
2 * Copyright (c) 2020-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.h"
16 #include "init_jobs_internal.h"
17 #include "init_log.h"
18 #include "init_service_manager.h"
19 #include "init_utils.h"
20 #include "init_param.h"
21
22 static void ParseAllImports(const cJSON *root);
23
GetConfigContextType(const char * cfgName)24 InitContextType GetConfigContextType(const char *cfgName)
25 {
26 static const char *vendorDir[] = {
27 "/vendor/etc/init/", "/chipset/etc/init/", "/chip_prod/etc/init/"
28 };
29
30 for (size_t j = 0; j < ARRAY_LENGTH(vendorDir); j++) {
31 if (strncmp(vendorDir[j], cfgName, strlen(vendorDir[j])) == 0) {
32 return INIT_CONTEXT_CHIPSET;
33 }
34 }
35 return INIT_CONTEXT_MAIN;
36 }
37
ParseInitCfgContents(const char * cfgName,const cJSON * root)38 static void ParseInitCfgContents(const char *cfgName, const cJSON *root)
39 {
40 INIT_ERROR_CHECK(root != NULL, return, "Root is null");
41 ConfigContext context = { INIT_CONTEXT_MAIN };
42 context.type = GetConfigContextType(cfgName);
43 INIT_LOGV("Parse %s configs in context %d", cfgName, context.type);
44 ParseAllServices(root, &context);
45 // parse jobs
46 ParseAllJobs(root, &context);
47 // parse imports
48 ParseAllImports(root);
49 }
50
ParseInitCfg(const char * configFile,void * context)51 int ParseInitCfg(const char *configFile, void *context)
52 {
53 UNUSED(context);
54 INIT_LOGV("Parse init configs from %s", configFile);
55 char *fileBuf = ReadFileToBuf(configFile);
56 INIT_ERROR_CHECK(fileBuf != NULL, return -1, "Failed to read file content %s", configFile);
57
58 cJSON *fileRoot = cJSON_Parse(fileBuf);
59 INIT_ERROR_CHECK(fileRoot != NULL, free(fileBuf);
60 return -1, "Failed to parse json file %s", configFile);
61
62 ParseInitCfgContents(configFile, fileRoot);
63 cJSON_Delete(fileRoot);
64 free(fileBuf);
65 return 0;
66 }
67
ParseAllImports(const cJSON * root)68 static void ParseAllImports(const cJSON *root)
69 {
70 char *tmpParamValue = calloc(PARAM_VALUE_LEN_MAX + 1, sizeof(char));
71 INIT_ERROR_CHECK(tmpParamValue != NULL, return, "Failed to alloc memory for param");
72
73 cJSON *importAttr = cJSON_GetObjectItemCaseSensitive(root, "import");
74 if (!cJSON_IsArray(importAttr)) {
75 free(tmpParamValue);
76 return;
77 }
78 int importAttrSize = cJSON_GetArraySize(importAttr);
79 for (int i = 0; i < importAttrSize; i++) {
80 cJSON *importItem = cJSON_GetArrayItem(importAttr, i);
81 if (!cJSON_IsString(importItem)) {
82 INIT_LOGE("Invalid type of import item. should be string");
83 break;
84 }
85 char *importContent = cJSON_GetStringValue(importItem);
86 if (importContent == NULL) {
87 INIT_LOGE("cannot get import config file");
88 break;
89 }
90 int ret = GetParamValue(importContent, strlen(importContent), tmpParamValue, PARAM_VALUE_LEN_MAX);
91 if (ret != 0) {
92 INIT_LOGE("cannot get value for %s", importContent);
93 continue;
94 }
95 INIT_LOGI("Import %s ...", tmpParamValue);
96 ParseInitCfg(tmpParamValue, NULL);
97 }
98 free(tmpParamValue);
99 return;
100 }
101
ReadConfig(void)102 void ReadConfig(void)
103 {
104 // parse cfg
105 char buffer[32] = {0}; // 32 reason max leb
106 uint32_t len = sizeof(buffer);
107 SystemReadParam("ohos.boot.mode", buffer, &len);
108 INIT_LOGI("ohos.boot.mode %s", buffer);
109 if (strcmp(buffer, "charger") == 0) {
110 ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
111 ReadFileInDir(OTHER_CHARGE_PATH, ".cfg", ParseInitCfg, NULL);
112 } else if (InUpdaterMode() == 0) {
113 ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
114 ParseInitCfgByPriority();
115 } else {
116 ReadFileInDir("/etc", ".cfg", ParseInitCfg, NULL);
117 }
118 }
119