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 pid_t pid = fork();
35 if (pid < 0) {
36 INIT_LOGE("DoExec: failed to fork child process to exec \"%s\"", ctx->argv[0]);
37 return;
38 }
39 if (pid == 0) {
40 if (ctx == NULL || ctx->argv[0] == NULL) {
41 INIT_LOGE("DoExec: invalid arguments");
42 _exit(0x7f);
43 }
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 int len;
78 if (!CheckValidCfg(ctx->argv[0])) {
79 INIT_LOGE("CheckCfg file %s Failed", ctx->argv[0]);
80 return;
81 }
82 char *realPath = GetRealPath(ctx->argv[0]);
83 INIT_ERROR_CHECK(realPath != NULL, return, "Failed to get realpath %s", ctx->argv[0]);
84 FILE *fp = fopen(realPath, "r");
85 if (fp == NULL) {
86 INIT_LOGE("Failed to open cfg %s error:%d", ctx->argv[0], errno);
87 free(realPath);
88 return;
89 }
90
91 while (fgets(buf, LOADCFG_BUF_SIZE - 1, fp) != NULL && maxLoop < LOADCFG_MAX_LOOP) {
92 maxLoop++;
93 len = strlen(buf);
94 if (len < 1) {
95 continue;
96 }
97 if (buf[len - 1] == '\n') {
98 buf[len - 1] = '\0'; // we replace '\n' with '\0'
99 }
100 const struct CmdTable *cmd = GetCmdByName(buf);
101 if (cmd == NULL) {
102 INIT_LOGE("Cannot support command: %s", buf);
103 continue;
104 }
105 ExecCmd(cmd, &buf[strlen(cmd->name) + 1]);
106 }
107 free(realPath);
108 (void)fclose(fp);
109 }
110
FileCryptEnable(char * fileCryptOption)111 int FileCryptEnable(char *fileCryptOption)
112 {
113 return 0;
114 }
115
116 static const struct CmdTable g_cmdTable[] = {
117 { "exec ", 1, 10, DoExec },
118 { "loadcfg ", 1, 1, DoLoadCfg },
119 };
120
GetCmdTable(int * number)121 const struct CmdTable *GetCmdTable(int *number)
122 {
123 *number = (int)ARRAY_LENGTH(g_cmdTable);
124 return g_cmdTable;
125 }
126
PluginExecCmdByName(const char * name,const char * cmdContent)127 void PluginExecCmdByName(const char *name, const char *cmdContent)
128 {
129 }
PluginExecCmdByCmdIndex(int index,const char * cmdContent)130 void PluginExecCmdByCmdIndex(int index, const char *cmdContent)
131 {
132 }
PluginGetCmdIndex(const char * cmdStr,int * index)133 const char *PluginGetCmdIndex(const char *cmdStr, int *index)
134 {
135 return NULL;
136 }