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
16 #include "init_cmds.h"
17
18 #include <stdbool.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "init_log.h"
23 #include "init_utils.h"
24 #include "securec.h"
25
GetParamValue(const char * symValue,unsigned int symLen,char * paramValue,unsigned int paramLen)26 int GetParamValue(const char *symValue, unsigned int symLen, char *paramValue, unsigned int paramLen)
27 {
28 return (strncpy_s(paramValue, paramLen, symValue, symLen) == EOK) ? 0 : -1;
29 }
30
DoExec(const struct CmdArgs * ctx)31 static void DoExec(const struct CmdArgs *ctx)
32 {
33 // format: exec /xxx/xxx/xxx xxx
34 if (ctx == NULL || ctx->argv[0] == NULL) {
35 INIT_LOGE("DoExec: invalid arguments");
36 return;
37 }
38 pid_t pid = fork();
39 if (pid < 0) {
40 INIT_LOGE("DoExec: failed to fork child process to exec \"%s\"", ctx->argv[0]);
41 return;
42 }
43 if (pid == 0) {
44 int ret = execve(ctx->argv[0], ctx->argv, NULL);
45 if (ret == -1) {
46 INIT_LOGE("DoExec: execute \"%s\" failed: %d.", ctx->argv[0], errno);
47 }
48 _exit(0x7f);
49 }
50 return;
51 }
52
CheckValidCfg(const char * path)53 static bool CheckValidCfg(const char *path)
54 {
55 static const char *supportCfg[] = {
56 "/etc/patch.cfg",
57 "/patch/fstab.cfg",
58 };
59 INIT_ERROR_CHECK(path != NULL, return false, "Invalid path for cfg");
60 struct stat fileStat = { 0 };
61 if (stat(path, &fileStat) != 0 || fileStat.st_size <= 0 || fileStat.st_size > LOADCFG_MAX_FILE_LEN) {
62 return false;
63 }
64 size_t cfgCnt = ARRAY_LENGTH(supportCfg);
65 for (size_t i = 0; i < cfgCnt; ++i) {
66 if (strcmp(path, supportCfg[i]) == 0) {
67 return true;
68 }
69 }
70 return false;
71 }
72
DoLoadCfg(const struct CmdArgs * ctx)73 static void DoLoadCfg(const struct CmdArgs *ctx)
74 {
75 char buf[LOADCFG_BUF_SIZE] = { 0 };
76 size_t maxLoop = 0;
77 if (!CheckValidCfg(ctx->argv[0])) {
78 INIT_LOGE("CheckCfg file %s Failed", ctx->argv[0]);
79 return;
80 }
81 char *realPath = GetRealPath(ctx->argv[0]);
82 INIT_ERROR_CHECK(realPath != NULL, return, "Failed to get realpath %s", ctx->argv[0]);
83 FILE *fp = fopen(realPath, "r");
84 if (fp == NULL) {
85 INIT_LOGE("Failed to open cfg %s error:%d", ctx->argv[0], errno);
86 free(realPath);
87 return;
88 }
89
90 while (fgets(buf, LOADCFG_BUF_SIZE - 1, fp) != NULL && maxLoop < LOADCFG_MAX_LOOP) {
91 maxLoop++;
92 int len = strlen(buf);
93 if (len < 1) {
94 continue;
95 }
96 if (buf[len - 1] == '\n') {
97 buf[len - 1] = '\0'; // we replace '\n' with '\0'
98 }
99 const struct CmdTable *cmd = GetCmdByName(buf);
100 if (cmd == NULL) {
101 INIT_LOGE("Cannot support command: %s", buf);
102 continue;
103 }
104 ExecCmd(cmd, &buf[strlen(cmd->name) + 1]);
105 }
106 free(realPath);
107 (void)fclose(fp);
108 }
109
110 static const struct CmdTable g_cmdTable[] = {
111 { "exec ", 1, 10, 0, DoExec },
112 { "loadcfg ", 1, 1, 0, DoLoadCfg },
113 };
114
GetCmdTable(int * number)115 const struct CmdTable *GetCmdTable(int *number)
116 {
117 *number = (int)ARRAY_LENGTH(g_cmdTable);
118 return g_cmdTable;
119 }
120
PluginExecCmdByName(const char * name,const char * cmdContent)121 void PluginExecCmdByName(const char *name, const char *cmdContent)
122 {
123 }
124
PluginExecCmdByCmdIndex(int index,const char * cmdContent,const ConfigContext * context)125 void PluginExecCmdByCmdIndex(int index, const char *cmdContent, const ConfigContext *context)
126 {
127 }
128
PluginGetCmdIndex(const char * cmdStr,int * index)129 const char *PluginGetCmdIndex(const char *cmdStr, int *index)
130 {
131 return NULL;
132 }
133
GetPluginCmdNameByIndex(int index)134 const char *GetPluginCmdNameByIndex(int index)
135 {
136 return NULL;
137 }
138
SetFileCryptPolicy(const char * dir)139 int SetFileCryptPolicy(const char *dir)
140 {
141 return 0;
142 }
143
SetSubInitContext(const ConfigContext * context,const char * service)144 int SetSubInitContext(const ConfigContext *context, const char *service)
145 {
146 return 0;
147 }
148
ExecuteCmdInSubInit(const ConfigContext * context,const char * name,const char * cmdContent)149 int ExecuteCmdInSubInit(const ConfigContext *context, const char *name, const char *cmdContent)
150 {
151 return 0;
152 }
153
CheckExecuteInSubInit(const ConfigContext * context)154 int CheckExecuteInSubInit(const ConfigContext *context)
155 {
156 return 0;
157 }
158