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