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