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