• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <grp.h>
16 #include <pwd.h>
17 #include <sys/ioctl.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <sys/wait.h>
21 #include <termios.h>
22 #include <unistd.h>
23 #include <signal.h>
24 #undef _GNU_SOURCE
25 #define _GNU_SOURCE
26 #include <sched.h>
27 
28 #include "begetctl.h"
29 #include "param_manager.h"
30 #include "param_security.h"
31 #include "init_param.h"
32 #include "shell_utils.h"
33 #include "param_init.h"
34 #include "beget_ext.h"
35 #ifdef PARAM_SUPPORT_SELINUX
36 #include <policycoreutils.h>
37 #include <selinux/selinux.h>
38 #include "selinux_parameter.h"
39 #endif // PARAM_SUPPORT_SELINUX
40 
41 typedef struct {
42     uid_t uid;
43     gid_t gid;
44     int cloneFlg;
45     char *parameter;
46 } ParamShellExecArgs;
47 
48 #define STACK_SIZE (1024 * 1024 * 8)
49 #define MASK_LENGTH_MAX 4
50 pid_t g_shellPid = 0;
51 #ifndef STARTUP_INIT_TEST
52 static struct termios g_terminalState;
53 #endif
54 char g_isSetTerminal = 0;
55 
demoExit(void)56 void demoExit(void)
57 {
58     if (g_shellPid != 0) {
59 #ifndef STARTUP_INIT_TEST
60         kill(g_shellPid, SIGKILL);
61 #endif
62     }
63 }
64 
65 #define CMD_PATH "/system/bin/paramshell"
66 #define SHELL_NAME "paramshell"
67 #ifndef TIOCSCTTY
68 #define TIOCSCTTY 0x540E
69 #endif
GetLocalBuffer(uint32_t * buffSize)70 static char *GetLocalBuffer(uint32_t *buffSize)
71 {
72     static char buffer[PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX] = {0};
73     BEGET_CHECK(buffSize == NULL, *buffSize = sizeof(buffer));
74     return buffer;
75 }
76 
GetRealParameter(BShellHandle shell,const char * name,char * buffer,uint32_t buffSize)77 static char *GetRealParameter(BShellHandle shell, const char *name, char *buffer, uint32_t buffSize)
78 {
79     BSH_CHECK(buffer != NULL && name != NULL, return NULL, "Invalid parameter");
80     const BShellParam *param = BShellEnvGetParam(shell, PARAM_REVERESD_NAME_CURR_PARAMETER);
81     const char *current = (param == NULL) ? "" : param->value.string;
82     int32_t realLen = 0;
83     int ret = 0;
84     if (name[0] == '.') { // relatively
85         if (strcmp(name, "..") == 0) {
86             char *tmp = strrchr(current, '.');
87             if (tmp != NULL) {
88                 realLen = tmp - current;
89                 ret = memcpy_s(buffer, buffSize, current, realLen);
90             } else {
91                 ret = memcpy_s(buffer, buffSize, "#", 1);
92                 realLen = 1;
93             }
94             BSH_CHECK(ret == 0, return NULL, "Failed to memcpy");
95         } else if (strcmp(name, ".") == 0) {
96             realLen = sprintf_s(buffer, buffSize, "%s", current);
97         } else {
98             realLen = sprintf_s(buffer, buffSize, "%s%s", current, name);
99         }
100     } else if (strlen(name) == 0) {
101         realLen = sprintf_s(buffer, buffSize, "%s", current);
102     } else {
103         realLen = sprintf_s(buffer, buffSize, "%s", name);
104     }
105     BSH_CHECK(realLen >= 0, return NULL, "Failed to format buffer");
106     buffer[realLen] = '\0';
107     BSH_LOGV("GetRealParameter current %s input %s real %s", current, name, buffer);
108     return buffer;
109 }
110 
SetParamShellPrompt(BShellHandle shell,const char * param)111 int SetParamShellPrompt(BShellHandle shell, const char *param)
112 {
113     uint32_t buffSize = 0;
114     char *buffer = GetLocalBuffer(&buffSize);
115     char *realParameter = GetRealParameter(shell, param, buffer, buffSize);
116     BSH_CHECK(realParameter != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
117     if (strlen(realParameter) == 0) {
118         BShellEnvOutputPrompt(shell, PARAM_SHELL_DEFAULT_PROMPT);
119         return -1;
120     }
121     // check parameter
122     int ret = SystemCheckParamExist(realParameter);
123     if (ret == PARAM_CODE_NOT_FOUND) {
124         BShellEnvOutput(shell, "Error: parameter \'%s\' not found\r\n", realParameter);
125         return -1;
126     } else if (ret != 0 && ret != PARAM_CODE_NODE_EXIST) {
127         BShellEnvOutput(shell, "Error: Forbid to enter parameters \'%s\'\r\n", realParameter);
128         return -1;
129     }
130     if (strcmp(realParameter, "#") == 0) {
131         ret = BShellEnvSetParam(shell, PARAM_REVERESD_NAME_CURR_PARAMETER,
132             "", PARAM_STRING, (void *)"");
133         BSH_CHECK(ret == 0, return BSH_SYSTEM_ERR, "Failed to set param value");
134         BShellEnvOutputPrompt(shell, PARAM_SHELL_DEFAULT_PROMPT);
135         return 0;
136     }
137     ret = BShellEnvSetParam(shell, PARAM_REVERESD_NAME_CURR_PARAMETER,
138         "", PARAM_STRING, (void *)realParameter);
139     BSH_CHECK(ret == 0, return BSH_SYSTEM_ERR, "Failed to set param value");
140     if (strcat_s(realParameter, buffSize, "#") != 0) {
141         BSH_CHECK(ret != 0, return BSH_SYSTEM_ERR, "Failed to cat prompt %s", realParameter);
142     }
143     BShellEnvOutputPrompt(shell, realParameter);
144     return 0;
145 }
146 
GetPermissionString(uint32_t mode,int shift,char * str,int size)147 static char *GetPermissionString(uint32_t mode, int shift, char *str, int size)
148 {
149     BEGET_CHECK(!(size < MASK_LENGTH_MAX), return str);
150     str[0] = '-';
151     str[1] = '-';
152     str[2] = '-'; // 2 watcher
153     str[3] = '\0'; // 3 end
154     if (mode & (DAC_READ >> shift)) {
155         str[0] = 'r';
156     }
157     if (mode & (DAC_WRITE >> shift)) {
158         str[1] = 'w';
159     }
160     if (mode & (DAC_WATCH >> shift)) {
161         str[2] = 'w'; // 2 watcher
162     }
163     return str;
164 }
165 
ShowParam(BShellHandle shell,const char * name,const char * value)166 static void ShowParam(BShellHandle shell, const char *name, const char *value)
167 {
168     ParamAuditData auditData = {};
169     int ret = GetParamSecurityAuditData(name, 0, &auditData);
170     BSH_CHECK(ret == 0, return, "Failed to get param security for %s", name);
171     BShellEnvOutput(shell, "Parameter information:\r\n");
172 #ifdef PARAM_SUPPORT_SELINUX
173     BShellEnvOutput(shell, "selinux  : %s \r\n", auditData.label);
174 #endif
175     char permissionStr[3][MASK_LENGTH_MAX] = {}; // 3 permission
176     struct passwd *user = getpwuid(auditData.dacData.uid);
177     struct group *group = getgrgid(auditData.dacData.gid);
178     if (user != NULL && group != NULL) {
179         BShellEnvOutput(shell, "    dac  : %s(%s) %s(%s) (%s) \r\n",
180             user->pw_name,
181             GetPermissionString(auditData.dacData.mode, 0, permissionStr[0], MASK_LENGTH_MAX),
182             group->gr_name,
183             GetPermissionString(auditData.dacData.mode, DAC_GROUP_START, permissionStr[1], MASK_LENGTH_MAX),
184              // 2 other
185             GetPermissionString(auditData.dacData.mode, DAC_OTHER_START, permissionStr[2], MASK_LENGTH_MAX));
186     }
187     if (strcmp("#", name) != 0) {
188         BShellEnvOutput(shell, "    name : %s\r\n", name);
189     }
190     if (value != NULL) {
191         BShellEnvOutput(shell, "    value: %s\r\n", value);
192     }
193 }
194 
ShowParamForCmdLs(ParamHandle handle,void * cookie)195 static void ShowParamForCmdLs(ParamHandle handle, void *cookie)
196 {
197     uint32_t buffSize = 0;
198     char *buffer = GetLocalBuffer(&buffSize);
199     if (buffSize < (PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX)) {
200         return;
201     }
202     char *value = buffer + PARAM_NAME_LEN_MAX;
203     (void)SystemGetParameterName(handle, buffer, PARAM_NAME_LEN_MAX);
204     uint32_t valueLen = buffSize - PARAM_NAME_LEN_MAX;
205     (void)SystemGetParameterValue(handle, value, &valueLen);
206     ShowParam((BShellHandle)cookie, buffer, value);
207 }
208 
BShellParamCmdLs(BShellHandle shell,int32_t argc,char * argv[])209 static int32_t BShellParamCmdLs(BShellHandle shell, int32_t argc, char *argv[])
210 {
211     BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
212     int all = 0;
213     char *input = NULL;
214     for (int32_t i = 1; i < argc; i++) {
215         if (strcmp(argv[i], "-r") == 0) {
216             all = 1;
217         } else if (input == NULL) {
218             input = argv[i];
219         }
220     }
221     uint32_t buffSize = 0;
222     char *buffer = GetLocalBuffer(&buffSize);
223     char *realParameter = GetRealParameter(shell, (input == NULL) ? "" : input, buffer, buffSize);
224     BSH_CHECK(realParameter != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
225     char *prefix = strdup((strlen(realParameter) == 0) ? "#" : realParameter);
226     BSH_CHECK(prefix != NULL, return BSH_SYSTEM_ERR, "failed dup perfix");
227     BSH_LOGV("BShellParamCmdLs prefix %s", prefix);
228     int ret = 0;
229     if (all != 0) {
230         ret = SystemTraversalParameter(prefix, ShowParamForCmdLs, (void *)shell);
231         if (ret != 0) {
232             BShellEnvOutput(shell, "Error: Forbid to list parameters\r\n");
233         }
234     } else {
235         ret = SystemCheckParamExist(prefix);
236         if (ret == 0) {
237             ParamHandle handle;
238             ret = SystemFindParameter(prefix, &handle);
239             if (ret != 0) {
240                 BShellEnvOutput(shell, "Error: Forbid to list parameters\r\n");
241             } else {
242                 ShowParamForCmdLs(handle, (void *)shell);
243             }
244         } else if (ret == PARAM_CODE_NODE_EXIST) {
245             ShowParam(shell, prefix, NULL);
246         } else if (ret != PARAM_CODE_NOT_FOUND) {
247             BShellEnvOutput(shell, "Error: Forbid to list parameters\r\n");
248         } else {
249             BShellEnvOutput(shell, "Parameter %s not found\r\n", prefix);
250         }
251     }
252     free(prefix);
253     return 0;
254 }
255 
BShellParamCmdCat(BShellHandle shell,int32_t argc,char * argv[])256 static int32_t BShellParamCmdCat(BShellHandle shell, int32_t argc, char *argv[])
257 {
258     BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
259     BSH_CHECK(argc >= 1, return BSH_CMD_PARAM_INVALID, "Invalid shell env");
260     uint32_t buffSize = 0;
261     char *buffer = GetLocalBuffer(&buffSize);
262     char *realParameter = GetRealParameter(shell, argv[1], buffer, buffSize);
263     BSH_CHECK(realParameter != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
264     int ret = SystemGetParameter(realParameter, buffer, &buffSize);
265     BSH_CHECK(ret != 0, BShellEnvOutput(shell, "    %s\r\n", buffer));
266     return 0;
267 }
268 
BShellParamCmdCd(BShellHandle shell,int32_t argc,char * argv[])269 static int32_t BShellParamCmdCd(BShellHandle shell, int32_t argc, char *argv[])
270 {
271     BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
272     BSH_CHECK(argc >= 1, return BSH_CMD_PARAM_INVALID, "Invalid shell env");
273     SetParamShellPrompt(shell, argv[1]);
274     return 0;
275 }
276 
ShowParamForCmdGet(ParamHandle handle,void * cookie)277 static void ShowParamForCmdGet(ParamHandle handle, void *cookie)
278 {
279     uint32_t buffSize = 0;
280     char *buffer = GetLocalBuffer(&buffSize);
281     BSH_CHECK(!(buffSize < (PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX)), return);
282     char *value = buffer + PARAM_NAME_LEN_MAX;
283     (void)SystemGetParameterName(handle, buffer, PARAM_NAME_LEN_MAX);
284     uint32_t valueLen = buffSize - PARAM_NAME_LEN_MAX;
285     (void)SystemGetParameterValue(handle, value, &valueLen);
286     BShellEnvOutput((BShellHandle)cookie, "    %s = %s\r\n", buffer, value);
287 }
288 
BShellParamCmdGet(BShellHandle shell,int32_t argc,char * argv[])289 static int32_t BShellParamCmdGet(BShellHandle shell, int32_t argc, char *argv[])
290 {
291     BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
292     BSH_CHECK(argc >= 1, return BSH_CMD_PARAM_INVALID, "Invalid shell env");
293     int ret = 0;
294     uint32_t buffSize = 0;
295     char *buffer = GetLocalBuffer(&buffSize);
296     char *realParameter = GetRealParameter(shell, (argc == 1) ? "" : argv[1], buffer, buffSize);
297     if ((argc == 1) || (realParameter == NULL) ||
298         (strlen(realParameter) == 0) || (strcmp(realParameter, "#") == 0)) {
299         ret = SystemTraversalParameter(realParameter, ShowParamForCmdGet, (void *)shell);
300         if (ret != 0) {
301             BShellEnvOutput(shell, "Error: Forbid to get all parameters\r\n");
302         }
303         return 0;
304     }
305     char *key = strdup(realParameter);
306     BSH_CHECK(key != NULL, return BSH_SYSTEM_ERR, "failed to fup key");
307     ret = SystemGetParameter(key, buffer, &buffSize);
308     if (ret == 0) {
309         BShellEnvOutput(shell, "%s \n", buffer);
310     } else {
311         BShellEnvOutput(shell, "Get parameter \"%s\" fail! errNum is:%d!\n", key, ret);
312     }
313     free(key);
314     return 0;
315 }
316 
BShellParamCmdSet(BShellHandle shell,int32_t argc,char * argv[])317 static int32_t BShellParamCmdSet(BShellHandle shell, int32_t argc, char *argv[])
318 {
319     BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
320     if (argc < 3) { // 3 min param
321         char *helpArgs[] = {"param", NULL};
322         BShellCmdHelp(shell, 1, helpArgs);
323         return 0;
324     }
325     uint32_t buffSize = 0;
326     char *buffer = GetLocalBuffer(&buffSize);
327     char *realParameter = GetRealParameter(shell, argv[1], buffer, buffSize);
328     if ((realParameter == NULL) || (strlen(realParameter) == 0) || (strcmp(realParameter, "#") == 0)) {
329         BShellEnvOutput(shell, "Set parameter %s %s fail\n", argv[1], argv[2]); // 2 value param
330         return 0;
331     }
332     int ret = SystemSetParameter(realParameter, argv[2]); // 2 value param
333     if (ret == 0) {
334         BShellEnvOutput(shell, "Set parameter %s %s success\n", realParameter, argv[2]); // 2 value param
335     } else {
336         BShellEnvOutput(shell, "Set parameter %s %s fail! errNum is:%d!\n", realParameter, argv[2], ret); // 2 param
337     }
338     return 0;
339 }
340 
BShellParamCmdSave(BShellHandle shell,int32_t argc,char * argv[])341 static int32_t BShellParamCmdSave(BShellHandle shell, int32_t argc, char *argv[])
342 {
343     BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
344     BSH_CHECK(argc == 1, return BSH_CMD_PARAM_INVALID, "Invalid shell env");
345 
346     int ret = SystemSaveParameters();
347     if (ret == 0) {
348         BShellEnvOutput(shell, "Save persist parameters success\n");
349     } else {
350         BShellEnvOutput(shell, "Save persist parameters fail! errNum is:%d!\n", ret);
351     }
352     return 0;
353 }
354 
BShellParamCmdWait(BShellHandle shell,int32_t argc,char * argv[])355 static int32_t BShellParamCmdWait(BShellHandle shell, int32_t argc, char *argv[])
356 {
357     BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
358     if (argc < 2) { // 2 min param
359         char *helpArgs[] = {"param", NULL};
360         BShellCmdHelp(shell, 1, helpArgs);
361         return 0;
362     }
363     int32_t timeout = 30; // 30s
364     char *value = "*";
365     if (argc > 2) { // 2 value param
366         value = argv[2]; // 2 value param
367     }
368     if (argc > 3) { // 3 timeout param
369         timeout = atoi(argv[3]); // 3 timeout param
370     }
371     uint32_t buffSize = 0;
372     char *buffer = GetLocalBuffer(&buffSize);
373     char *realParameter = GetRealParameter(shell, argv[1], buffer, buffSize);
374     if ((realParameter == NULL) || (strlen(realParameter) == 0) || (strcmp(realParameter, "#") == 0)) {
375         BShellEnvOutput(shell, "Wait parameter %s fail\n", argv[1]);
376         return 0;
377     }
378 
379     int ret = SystemWaitParameter(realParameter, value, timeout);
380     if (ret == 0) {
381         BShellEnvOutput(shell, "Wait parameter %s success\n", argv[1]);
382     } else {
383         BShellEnvOutput(shell, "Wait parameter %s fail! errNum is:%d!\n", argv[1], ret);
384     }
385     return 0;
386 }
387 
BShellParamCmdDump(BShellHandle shell,int32_t argc,char * argv[])388 static int32_t BShellParamCmdDump(BShellHandle shell, int32_t argc, char *argv[])
389 {
390     BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
391     if (argc >= 2) { // 2 min parameter
392         if (strcmp(argv[1], "verbose") == 0) {
393             SystemDumpParameters(1, -1, printf);
394             return 0;
395         }
396         int index = StringToInt(argv[1], 0);
397         SystemDumpParameters(1, index, printf);
398         return 0;
399     }
400     SystemDumpParameters(0, -1, printf);
401     return 0;
402 }
403 
BShellParamCmdPwd(BShellHandle shell,int32_t argc,char * argv[])404 static int32_t BShellParamCmdPwd(BShellHandle shell, int32_t argc, char *argv[])
405 {
406     uint32_t buffSize = 0;
407     char *buffer = GetLocalBuffer(&buffSize);
408     char *realParameter = GetRealParameter(shell, "", buffer, buffSize);
409     BShellEnvOutput(shell, "%s\r\n", realParameter);
410     return 0;
411 }
412 
413 #ifndef STARTUP_INIT_TEST
GetUserInfo(ParamShellExecArgs * execArg,int32_t argc,char * argv[])414 static void GetUserInfo(ParamShellExecArgs *execArg, int32_t argc, char *argv[])
415 {
416     int32_t i = 0;
417     execArg->parameter = NULL;
418     while (i < argc) {
419         if (strcmp(argv[i], "-p") == 0 && ((i + 1) < argc)) {
420             execArg->parameter = argv[i + 1];
421             ++i;
422         } else if (strcmp(argv[i], "-u") == 0 && ((i + 1) < argc)) {
423             execArg->uid = DecodeUid(argv[i + 1]);
424             execArg->uid = (execArg->uid == -1) ? 0 : execArg->uid;
425             ++i;
426         } else if (strcmp(argv[i], "-g") == 0 && ((i + 1) < argc)) {
427             execArg->gid = DecodeGid(argv[i + 1]);
428             execArg->gid = (execArg->gid == -1) ? 0 : execArg->gid;
429             ++i;
430         } else if (strcmp(argv[i], "-c") == 0) {
431             execArg->cloneFlg = 1;
432         }
433         ++i;
434     }
435 }
436 
ExecFunc(void * arg)437 static int ExecFunc(void *arg)
438 {
439     ParamShellExecArgs *execArg = (ParamShellExecArgs *)arg;
440     int ret = 0;
441     setuid(execArg->uid);
442     setgid(execArg->gid);
443     BSH_LOGI("Exec shell %s \n", SHELL_NAME);
444     if (execArg->parameter != NULL) { // 2 min argc
445         char *args[] = {SHELL_NAME, execArg->parameter, NULL};
446         ret = execv(CMD_PATH, args);
447     } else {
448         char *args[] = {SHELL_NAME, NULL};
449         ret = execv(CMD_PATH, args);
450     }
451     if (ret != 0) {
452         printf("error on exec %d \n", errno);
453         exit(0);
454     }
455     return ret;
456 }
457 
ForkChild(int (* childFunc)(void * arg),void * args)458 static pid_t ForkChild(int (*childFunc)(void *arg), void *args)
459 {
460     pid_t pid = fork();
461     if (pid == 0) {
462         childFunc(args);
463         exit(0);
464     }
465     return pid;
466 }
467 #endif
468 
BShellParamCmdShell(BShellHandle shell,int32_t argc,char * argv[])469 static int32_t BShellParamCmdShell(BShellHandle shell, int32_t argc, char *argv[])
470 {
471 #ifndef STARTUP_INIT_TEST
472     BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
473     int ret = 0;
474     if (tcgetattr(0, &g_terminalState)) {
475         return BSH_SYSTEM_ERR;
476     }
477     g_isSetTerminal = 1;
478     ParamShellExecArgs args = {0, 0, 0, NULL};
479     GetUserInfo(&args, argc, argv);
480     BSH_LOGV("BShellParamCmdShell %s %d %d argc %d", args.parameter, args.uid, args.gid, argc);
481     if (args.parameter != NULL) {
482         ret = SystemCheckParamExist(args.parameter);
483         if (ret != 0) {
484             BShellEnvOutput(shell, "Error: parameter \'%s\' not found\r\n", args.parameter);
485             return -1;
486         }
487     }
488     SetInitLogLevel(INIT_INFO);
489     pid_t pid = 0;
490     if (args.cloneFlg) {
491         char *childStack = (char *)calloc(1, STACK_SIZE);
492         BSH_CHECK(childStack != NULL, return -1, "calloc failed");
493         pid = clone(ExecFunc, childStack + STACK_SIZE, CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, (void *)&args);
494         free(childStack);
495     } else {
496         pid = ForkChild(ExecFunc, (void *)&args);
497     }
498     if (pid > 0) {
499         g_shellPid = pid;
500         int status = 0;
501         wait(&status);
502         tcsetattr(0, TCSAFLUSH, &g_terminalState);
503         g_isSetTerminal = 0;
504     }
505 #endif
506     return 0;
507 }
508 
BShellParamCmdRegForShell(BShellHandle shell)509 static int32_t BShellParamCmdRegForShell(BShellHandle shell)
510 {
511     const CmdInfo infos[] = {
512         {"ls", BShellParamCmdLs, "display system parameter", "ls [-r] [name]", NULL},
513         {"get", BShellParamCmdGet, "get system parameter", "get [name]", NULL},
514         {"set", BShellParamCmdSet, "set system parameter", "set name value", NULL},
515         {"wait", BShellParamCmdWait, "wait system parameter", "wait name [value] [timeout]", NULL},
516         {"dump", BShellParamCmdDump, "dump system parameter", "dump [verbose]", ""},
517         {"cd", BShellParamCmdCd, "change path of parameter", "cd name", NULL},
518         {"cat", BShellParamCmdCat, "display value of parameter", "cat name", NULL},
519         {"pwd", BShellParamCmdPwd, "display current parameter", "pwd", NULL},
520         {"save", BShellParamCmdSave, "save all persist parameters in workspace", "save", NULL},
521     };
522     for (size_t i = sizeof(infos) / sizeof(infos[0]); i > 0; i--) {
523         BShellEnvRegisterCmd(shell, &infos[i - 1]);
524     }
525     return 0;
526 }
527 
IsUserMode()528 static bool IsUserMode()
529 {
530     bool isUser = true;
531     char value[2] = {0};
532     uint32_t length = sizeof(value);
533     int ret = SystemGetParameter("const.debuggable", value, &length);
534     if (ret != 0) {
535         BSH_LOGI("Failed to get param");
536         return isUser;
537     }
538     if (strcmp(value, "1") == 0) {
539         isUser = false;
540     }
541     return isUser;
542 }
543 
IsDebugCmd(const CmdInfo * cmdInfo)544 static bool IsDebugCmd(const CmdInfo *cmdInfo)
545 {
546     if (strcmp(cmdInfo->multikey, "param dump") == 0 || strcmp(cmdInfo->multikey, "param shell") == 0) {
547         return true;
548     }
549     return false;
550 }
551 
BShellParamCmdRegForIndepent(BShellHandle shell)552 static int32_t BShellParamCmdRegForIndepent(BShellHandle shell)
553 {
554     const CmdInfo infos[] = {
555         {"param", BShellParamCmdLs, "display system parameter", "param ls [-r] [name]", "param ls"},
556         {"param", BShellParamCmdGet, "get system parameter", "param get [name]", "param get"},
557         {"param", BShellParamCmdSet, "set system parameter", "param set name value", "param set"},
558         {"param", BShellParamCmdWait, "wait system parameter", "param wait name [value] [timeout]", "param wait"},
559         {"param", BShellParamCmdDump, "dump system parameter", "param dump [verbose]", "param dump"},
560         {"param", BShellParamCmdShell, "shell system parameter",
561             "param shell [-p] [name] [-u] [username] [-g] [groupname]", "param shell"},
562         {"param", BShellParamCmdSave, "save all persist parameters in workspace", "param save", "param save"},
563     };
564     for (size_t i = sizeof(infos) / sizeof(infos[0]); i > 0; i--) {
565         if (IsUserMode() && IsDebugCmd(&infos[i - 1])) {
566             continue;
567         }
568         BShellEnvRegisterCmd(shell, &infos[i - 1]);
569     }
570     return 0;
571 }
572 
UpdateInitLogLevel(void)573 static void UpdateInitLogLevel(void)
574 {
575     char level[2] = {0}; // 2 max length
576     uint32_t length = sizeof(level);
577     int ret = SystemGetParameter(INIT_DEBUG_LEVEL, level, &length);
578     if (ret == 0) {
579         errno = 0;
580         InitLogLevel value = (InitLogLevel)strtoul(level, NULL, DECIMAL_BASE);
581         SetInitLogLevel((errno != 0) ? INIT_WARN : value);
582     }
583 }
584 
BShellParamCmdRegister(BShellHandle shell,int execMode)585 int32_t BShellParamCmdRegister(BShellHandle shell, int execMode)
586 {
587     UpdateInitLogLevel();
588     if (execMode) {
589         BShellParamCmdRegForShell(shell);
590     } else {
591         BShellParamCmdRegForIndepent(shell);
592     }
593     return 0;
594 }
595