1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "shmsg.h"
33 #include "securec.h"
34 #include "shcmd.h"
35 #include "show.h"
36 #if (LOSCFG_USE_SHELL == 1)
37 #include "uart.h"
38 #endif
39 #include "los_event.h"
40 #include "los_task.h"
41
42 EVENT_CB_S g_shellInputEvent;
43 #define SHELL_CMD_MAX_SIZE 64
44
45 #define VISIABLE_CHAR(ch) ((ch) > 0x1F && (ch) < 0x7F)
46
ShellMsgTypeGet(CmdParsed * cmdParsed,const CHAR * cmdType)47 UINT32 ShellMsgTypeGet(CmdParsed *cmdParsed, const CHAR *cmdType)
48 {
49 CmdItemNode *curCmdItem = (CmdItemNode *)NULL;
50 UINT32 len;
51 UINT32 minLen;
52 CmdModInfo *cmdInfo = OsCmdInfoGet();
53
54 if ((cmdParsed == NULL) || (cmdType == NULL)) {
55 return OS_INVALID;
56 }
57
58 len = strlen(cmdType);
59 LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(cmdInfo->cmdList.list), CmdItemNode, list) {
60 if ((len == strlen(curCmdItem->cmd->cmdKey)) &&
61 (strncmp((CHAR *)(curCmdItem->cmd->cmdKey), cmdType, len) == 0)) {
62 minLen = (len < CMD_KEY_LEN) ? len : CMD_KEY_LEN;
63 (VOID)memcpy_s((CHAR *)(cmdParsed->cmdKeyword), CMD_KEY_LEN, cmdType, minLen);
64 cmdParsed->cmdType = curCmdItem->cmd->cmdType;
65 return LOS_OK;
66 }
67 }
68
69 return OS_INVALID;
70 }
71
GetCmdName(const CHAR * cmdline,UINT32 len)72 CHAR *GetCmdName(const CHAR *cmdline, UINT32 len)
73 {
74 UINT32 loop;
75 const CHAR *tmpStr = NULL;
76 BOOL quotes = FALSE;
77 CHAR *cmdName = NULL;
78 if (cmdline == NULL) {
79 return NULL;
80 }
81
82 cmdName = (CHAR *)malloc(len + 1);
83 if (cmdName == NULL) {
84 PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__);
85 return NULL;
86 }
87
88 /* Scan the 'cmdline' string for command */
89 /* Notice: Command string must not have any special name */
90 for (tmpStr = cmdline, loop = 0; (*tmpStr != '\0') && (loop < len); ) {
91 /* If reach a double quotes, switch the quotes matching status */
92 if (*tmpStr == '\"') {
93 SWITCH_QUOTES_STATUS(quotes);
94 /* Ignore the double quote charactor itself */
95 tmpStr++;
96 continue;
97 }
98 /* If detected a space which the quotes matching status is false */
99 /* which said has detected the first space for separator, finish this scan operation */
100 if ((*tmpStr == ' ') && (QUOTES_STATUS_CLOSE(quotes))) {
101 break;
102 }
103 cmdName[loop] = *tmpStr++;
104 loop++;
105 }
106 cmdName[loop] = '\0';
107
108 return cmdName;
109 }
110
111
PreHandleCmdline(const CHAR * input,CHAR ** output,UINT32 * outputlen)112 UINT32 PreHandleCmdline(const CHAR *input, CHAR **output, UINT32 *outputlen)
113 {
114 UINT32 shiftLen;
115 UINT32 ret;
116 const CHAR *cmdBuf = input;
117 UINT32 cmdBufLen = strlen(cmdBuf);
118 CHAR *shiftStr = (CHAR *)malloc(cmdBufLen + 1);
119
120 if (shiftStr == NULL) {
121 PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__);
122 return SH_NOK;
123 }
124 (VOID)memset_s(shiftStr, cmdBufLen + 1, 0, cmdBufLen + 1);
125
126 /* Call function 'OsCmdKeyShift' to squeeze and clear useless or overmuch space if string buffer */
127 ret = OsCmdKeyShift(cmdBuf, shiftStr, cmdBufLen + 1);
128 shiftLen = strlen(shiftStr);
129 if ((ret != SH_OK) || (shiftLen == 0)) {
130 ret = SH_NOK;
131 goto END_FREE_SHIFTSTR;
132 }
133 *output = shiftStr;
134 *outputlen = shiftLen;
135
136 ret = SH_OK;
137 goto END;
138
139 END_FREE_SHIFTSTR:
140 free(shiftStr);
141 END:
142 return ret;
143 }
144
ParseAndExecCmdline(CmdParsed * cmdParsed,const CHAR * cmdline,UINT32 len)145 STATIC VOID ParseAndExecCmdline(CmdParsed *cmdParsed, const CHAR *cmdline, UINT32 len)
146 {
147 INT32 i;
148 UINT32 ret;
149 CHAR *cmdName = NULL;
150
151 cmdName = GetCmdName(cmdline, len);
152 if (cmdName == NULL) {
153 PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__);
154 return;
155 }
156
157 ret = ShellMsgTypeGet(cmdParsed, cmdName);
158 if (ret != LOS_OK) {
159 PRINTK("%s:command not found\n", cmdName);
160 free(cmdName);
161 return;
162 }
163
164 ret = OsCmdParse((CHAR *)cmdline, cmdParsed);
165 if (ret != SH_OK) {
166 PRINTK("cmd parse failure in %s[%d]\n", __FUNCTION__, __LINE__);
167 goto OUT;
168 }
169
170 (VOID)OsCmdExec(cmdParsed);
171
172 OUT:
173 for (i = 0; i < cmdParsed->paramCnt; i++) {
174 if (cmdParsed->paramArray[i] != NULL) {
175 free(cmdParsed->paramArray[i]);
176 cmdParsed->paramArray[i] = NULL;
177 }
178 }
179 free(cmdName);
180 }
181
ExecCmdline(const CHAR * cmdline)182 LITE_OS_SEC_TEXT_MINOR VOID ExecCmdline(const CHAR *cmdline)
183 {
184 UINT32 ret;
185 CHAR *output = NULL;
186 UINT32 outputlen;
187 CmdParsed cmdParsed;
188
189 if (cmdline == NULL) {
190 return;
191 }
192
193 (VOID)OsShellInit();
194
195 /* strip out unnecessary characters */
196 ret = PreHandleCmdline(cmdline, &output, &outputlen);
197 if (ret == SH_NOK) {
198 return;
199 }
200
201 (VOID)memset_s(&cmdParsed, sizeof(CmdParsed), 0, sizeof(CmdParsed));
202 ParseAndExecCmdline(&cmdParsed, output, outputlen);
203 free(output);
204 }
205
206 #if (LOSCFG_USE_SHELL == 1)
ShellTaskEntry(VOID)207 VOID ShellTaskEntry(VOID)
208 {
209 CHAR buf[SHELL_CMD_MAX_SIZE] = {0};
210 CHAR *ptr = buf;
211 PRINTK("OHOS # ");
212 while (1) {
213 (VOID)LOS_EventRead(&g_shellInputEvent, 0x1, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
214 while ((*ptr = (UINT8)UartGetc()) != 0 && *ptr != 13) {
215 if (*ptr == '\x03') { /* ctrl + c */
216 PRINTK("^C\n\rOHOS # ");
217 ptr = buf;
218 break;
219 }
220 if (*ptr == '\b' && ptr != buf) { /* support backspace */
221 PRINTK("\b \b");
222 ptr--;
223 break;
224 }
225 if (!VISIABLE_CHAR(*ptr)) {
226 break;
227 }
228 PRINTK("%c", *ptr);
229 if ((ptr - buf) == (sizeof(buf) - 1)) {
230 break;
231 }
232 ptr++;
233 }
234 if (ptr != buf) {
235 if (*ptr == 13 || ((ptr - buf) == (sizeof(buf) - 1))) {
236 *ptr = '\0';
237 ptr = buf;
238 PRINTK("\n\r");
239 ExecCmdline(buf);
240 PRINTK("OHOS # ");
241 }
242 } else if (*ptr == 13) {
243 PRINTK("\n\rOHOS # ");
244 }
245 }
246 }
247
LosShellInit(VOID)248 LITE_OS_SEC_TEXT_MINOR UINT32 LosShellInit(VOID)
249 {
250 UINT32 ret;
251 UINT32 taskID1;
252 TSK_INIT_PARAM_S task1 = { 0 };
253
254 ret = LOS_EventInit(&g_shellInputEvent);
255 if (ret != LOS_OK) {
256 PRINTK("Init shellInputEvent failed! ERROR: 0x%x\n", ret);
257 return ret;
258 }
259
260 task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellTaskEntry;
261 task1.uwStackSize = LOSCFG_SHELL_STACK_SIZE;
262 task1.pcName = "ShellTaskEntry";
263 task1.usTaskPrio = LOSCFG_SHELL_PRIO;
264 ret = LOS_TaskCreate(&taskID1, &task1);
265 if (ret != LOS_OK) {
266 PRINTK("Create Shell Task failed! ERROR: 0x%x\n", ret);
267 return ret;
268 }
269
270 return ret;
271 }
272 #endif
273