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