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 "shcmd.h"
33 #include "shell_pri.h"
34 #include "show.h"
35 #include "stdlib.h"
36 #include "unistd.h"
37 #include "dirent.h"
38 #include "securec.h"
39 #include "los_mux.h"
40 #include "los_memory.h"
41 #include "los_typedef.h"
42
43
44 #define SHELL_INIT_MAGIC_FLAG 0xABABABAB
45 #define CTRL_C 0x03 /* 0x03: ctrl+c ASCII */
46
47 STATIC CmdModInfo g_cmdInfo;
48
49 LOS_HAL_TABLE_BEGIN(g_shellcmd, shellcmd);
50 LOS_HAL_TABLE_END(g_shellcmdEnd, shellcmd);
51
OsCmdInfoGet(VOID)52 CmdModInfo *OsCmdInfoGet(VOID)
53 {
54 return &g_cmdInfo;
55 }
56
OsFreeCmdPara(CmdParsed * cmdParsed)57 STATIC VOID OsFreeCmdPara(CmdParsed *cmdParsed)
58 {
59 UINT32 i;
60 for (i = 0; i < cmdParsed->paramCnt; i++) {
61 if ((cmdParsed->paramArray[i]) != NULL) {
62 (VOID)LOS_MemFree(m_aucSysMem0, (cmdParsed->paramArray[i]));
63 cmdParsed->paramArray[i] = NULL;
64 }
65 }
66 }
67
OsStrSeparateTabStrGet(CHAR ** tabStr,CmdParsed * parsed,UINT32 tabStrLen)68 STATIC INT32 OsStrSeparateTabStrGet(CHAR **tabStr, CmdParsed *parsed, UINT32 tabStrLen)
69 {
70 CHAR *shiftStr = NULL;
71 CHAR *tempStr = (CHAR *)LOS_MemAlloc(m_aucSysMem0, SHOW_MAX_LEN << 1);
72 if (tempStr == NULL) {
73 return (INT32)OS_ERROR;
74 }
75
76 (VOID)memset_s(tempStr, SHOW_MAX_LEN << 1, 0, SHOW_MAX_LEN << 1);
77 shiftStr = tempStr + SHOW_MAX_LEN;
78
79 if (strncpy_s(tempStr, SHOW_MAX_LEN - 1, *tabStr, tabStrLen)) {
80 (VOID)LOS_MemFree(m_aucSysMem0, tempStr);
81 return (INT32)OS_ERROR;
82 }
83
84 parsed->cmdType = CMD_TYPE_STD;
85
86 /* cut useless or repeat space */
87 if (OsCmdKeyShift(tempStr, shiftStr, SHOW_MAX_LEN - 1)) {
88 (VOID)LOS_MemFree(m_aucSysMem0, tempStr);
89 return (INT32)OS_ERROR;
90 }
91
92 /* get exact position of string to complete */
93 /* situation different if end space lost or still exist */
94 if ((strlen(shiftStr) == 0) || (tempStr[strlen(tempStr) - 1] != shiftStr[strlen(shiftStr) - 1])) {
95 *tabStr = "";
96 } else {
97 if (OsCmdTokenSplit(shiftStr, ' ', parsed)) {
98 (VOID)LOS_MemFree(m_aucSysMem0, tempStr);
99 return (INT32)OS_ERROR;
100 }
101 *tabStr = parsed->paramArray[parsed->paramCnt - 1];
102 }
103
104 (VOID)LOS_MemFree(m_aucSysMem0, tempStr);
105 return LOS_OK;
106 }
107
OsStrSeparate(CHAR * tabStr,CHAR * strPath,CHAR * nameLooking,UINT32 tabStrLen)108 STATIC INT32 OsStrSeparate(CHAR *tabStr, CHAR *strPath, CHAR *nameLooking, UINT32 tabStrLen)
109 {
110 CHAR *strEnd = NULL;
111 CHAR *cutPos = NULL;
112 CmdParsed parsed = {0};
113 CHAR *shellWorkingDirectory = OsShellGetWorkingDirectory();
114 INT32 ret;
115
116 ret = OsStrSeparateTabStrGet(&tabStr, &parsed, tabStrLen);
117 if (ret != LOS_OK) {
118 return ret;
119 }
120
121 /* get fullpath str */
122 if (*tabStr != '/') {
123 if (strncpy_s(strPath, CMD_MAX_PATH, shellWorkingDirectory, CMD_MAX_PATH - 1)) {
124 OsFreeCmdPara(&parsed);
125 return (INT32)OS_ERROR;
126 }
127 if (strcmp(shellWorkingDirectory, "/")) {
128 if (strncat_s(strPath, CMD_MAX_PATH, "/", CMD_MAX_PATH - strlen(strPath) - 1)) {
129 OsFreeCmdPara(&parsed);
130 return (INT32)OS_ERROR;
131 }
132 }
133 }
134
135 if (strncat_s(strPath, CMD_MAX_PATH, tabStr, CMD_MAX_PATH - strlen(strPath) - 1)) {
136 OsFreeCmdPara(&parsed);
137 return (INT32)OS_ERROR;
138 }
139
140 /* split str by last '/' */
141 strEnd = strrchr(strPath, '/');
142 cutPos = strEnd;
143 if (strEnd != NULL) {
144 if (strncpy_s(nameLooking, CMD_MAX_PATH, strEnd + 1, CMD_MAX_PATH - 1)) { /* get cmp str */
145 OsFreeCmdPara(&parsed);
146 return (INT32)OS_ERROR;
147 }
148 *(cutPos + 1) = '\0';
149 }
150
151 OsFreeCmdPara(&parsed);
152 return LOS_OK;
153 }
154
OsShowPageInputControl(VOID)155 STATIC INT32 OsShowPageInputControl(VOID)
156 {
157 CHAR readChar;
158
159 while (1) {
160 if (read(STDIN_FILENO, &readChar, 1) != 1) { /* get one CHAR from stdin */
161 PRINTK("\n");
162 return (INT32)OS_ERROR;
163 }
164 if ((readChar == 'q') || (readChar == 'Q') || (readChar == CTRL_C)) {
165 PRINTK("\n");
166 return 0;
167 } else if (readChar == '\r') {
168 PRINTK("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b");
169 return 1;
170 }
171 }
172 }
173
OsShowPageControl(UINT32 timesPrint,UINT32 lineCap,UINT32 count)174 STATIC INT32 OsShowPageControl(UINT32 timesPrint, UINT32 lineCap, UINT32 count)
175 {
176 if (NEED_NEW_LINE(timesPrint, lineCap)) {
177 PRINTK("\n");
178 if (SCREEN_IS_FULL(timesPrint, lineCap) && (timesPrint < count)) {
179 PRINTK("--More--");
180 return OsShowPageInputControl();
181 }
182 }
183 return 1;
184 }
185
OsSurePrintAll(UINT32 count)186 STATIC INT32 OsSurePrintAll(UINT32 count)
187 {
188 CHAR readChar = 0;
189 PRINTK("\nDisplay all %u possibilities?(y/n)", count);
190 while (1) {
191 if (read(0, &readChar, 1) != 1) {
192 return (INT32)OS_ERROR;
193 }
194 if ((readChar == 'n') || (readChar == 'N') || (readChar == CTRL_C)) {
195 PRINTK("\n");
196 return 0;
197 } else if ((readChar == 'y') || (readChar == 'Y') || (readChar == '\r')) {
198 return 1;
199 }
200 }
201 }
202
OsPrintMatchList(UINT32 count,const CHAR * strPath,const CHAR * nameLooking,UINT32 printLen)203 STATIC INT32 OsPrintMatchList(UINT32 count, const CHAR *strPath, const CHAR *nameLooking, UINT32 printLen)
204 {
205 UINT32 timesPrint = 0;
206 UINT32 lineCap;
207 INT32 ret;
208 DIR *openDir = NULL;
209 struct dirent *readDir = NULL;
210 CHAR formatChar[10] = {0}; /* 10:for formatChar length */
211
212 printLen = (printLen > (DEFAULT_SCREEN_WIDTH - 2)) ? (DEFAULT_SCREEN_WIDTH - 2) : printLen; /* 2:revered 2 bytes */
213 lineCap = DEFAULT_SCREEN_WIDTH / (printLen + 2); /* 2:DEFAULT_SCREEN_WIDTH revered 2 bytes */
214 if (snprintf_s(formatChar, sizeof(formatChar) - 1, 7, "%%-%us ", printLen) < 0) { /* 7:format-len */
215 return (INT32)OS_ERROR;
216 }
217
218 if (count > (lineCap * DEFAULT_SCREEN_HEIGHT)) {
219 ret = OsSurePrintAll(count);
220 if (ret != 1) {
221 return ret;
222 }
223 }
224 openDir = opendir(strPath);
225 if (openDir == NULL) {
226 return (INT32)OS_ERROR;
227 }
228
229 PRINTK("\n");
230 for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) {
231 if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) {
232 continue;
233 }
234 PRINTK(formatChar, readDir->d_name);
235 timesPrint++;
236 ret = OsShowPageControl(timesPrint, lineCap, count);
237 if (ret != 1) {
238 if (closedir(openDir) < 0) {
239 return (INT32)OS_ERROR;
240 }
241 return ret;
242 }
243 }
244
245 PRINTK("\n");
246 if (closedir(openDir) < 0) {
247 return (INT32)OS_ERROR;
248 }
249
250 return LOS_OK;
251 }
252
strncmp_cut(const CHAR * s1,CHAR * s2,size_t n)253 STATIC VOID strncmp_cut(const CHAR *s1, CHAR *s2, size_t n)
254 {
255 if ((n == 0) || (s1 == NULL) || (s2 == NULL)) {
256 return;
257 }
258 do {
259 if (*s1 && *s2 && (*s1 == *s2)) {
260 s1++;
261 s2++;
262 } else {
263 break;
264 }
265 } while (--n != 0);
266 if (n > 0) {
267 /* NULL pad the remaining n-1 bytes */
268 while (n-- != 0)
269 *s2++ = 0;
270 }
271 return;
272 }
OsExecNameMatch(const CHAR * strPath,const CHAR * nameLooking,CHAR * strObj,UINT32 * maxLen)273 STATIC INT32 OsExecNameMatch(const CHAR *strPath, const CHAR *nameLooking, CHAR *strObj, UINT32 *maxLen)
274 {
275 INT32 count = 0;
276 DIR *openDir = NULL;
277 struct dirent *readDir = NULL;
278
279 openDir = opendir(strPath);
280 if (openDir == NULL) {
281 return (INT32)OS_ERROR;
282 }
283
284 for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) {
285 if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) {
286 continue;
287 }
288 if (count == 0) {
289 if (strncpy_s(strObj, CMD_MAX_PATH, readDir->d_name, CMD_MAX_PATH - 1)) {
290 (VOID)closedir(openDir);
291 return (INT32)OS_ERROR;
292 }
293 *maxLen = strlen(readDir->d_name);
294 } else {
295 /* strncmp&cut the same strings of name matched */
296 strncmp_cut(readDir->d_name, strObj, strlen(strObj));
297 if (strlen(readDir->d_name) > *maxLen) {
298 *maxLen = strlen(readDir->d_name);
299 }
300 }
301 count++;
302 }
303
304 if (closedir(openDir) < 0) {
305 return (INT32)OS_ERROR;
306 }
307
308 return count;
309 }
310
OsCompleteStr(const CHAR * result,const CHAR * target,CHAR * cmdKey,UINT32 * len)311 STATIC VOID OsCompleteStr(const CHAR *result, const CHAR *target, CHAR *cmdKey, UINT32 *len)
312 {
313 UINT32 size = strlen(result) - strlen(target);
314 CHAR *des = cmdKey + *len;
315 CHAR *src = (CHAR *)result + strlen(target);
316
317 while (size-- > 0) {
318 PRINTK("%c", *src);
319 if (*len == (SHOW_MAX_LEN - 1)) {
320 *des = '\0';
321 break;
322 }
323 *des++ = *src++;
324 (*len)++;
325 }
326 }
327
OsTabMatchCmd(CHAR * cmdKey,UINT32 * len)328 STATIC INT32 OsTabMatchCmd(CHAR *cmdKey, UINT32 *len)
329 {
330 INT32 count = 0;
331 INT32 ret;
332 CmdItemNode *cmdItemGuard = NULL;
333 CmdItemNode *curCmdItem = NULL;
334 const CHAR *cmdMajor = (const CHAR *)cmdKey;
335
336 while (*cmdMajor == 0x20) { /* cut left space */
337 cmdMajor++;
338 }
339
340 if (LOS_ListEmpty(&(g_cmdInfo.cmdList.list))) {
341 return (INT32)OS_ERROR;
342 }
343
344 LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(g_cmdInfo.cmdList.list), CmdItemNode, list) {
345 if ((curCmdItem == NULL) || (curCmdItem->cmd == NULL)) {
346 return -1;
347 }
348
349 if (strncmp(cmdMajor, curCmdItem->cmd->cmdKey, strlen(cmdMajor)) > 0) {
350 continue;
351 }
352
353 if (strncmp(cmdMajor, curCmdItem->cmd->cmdKey, strlen(cmdMajor)) != 0) {
354 break;
355 }
356
357 if (count == 0) {
358 cmdItemGuard = curCmdItem;
359 }
360 ++count;
361 }
362
363 if (cmdItemGuard == NULL) {
364 return 0;
365 }
366
367 if (count == 1) {
368 OsCompleteStr(cmdItemGuard->cmd->cmdKey, cmdMajor, cmdKey, len);
369 }
370
371 ret = count;
372 if (count > 1) {
373 PRINTK("\n");
374 while (count--) {
375 PRINTK("%s ", cmdItemGuard->cmd->cmdKey);
376 cmdItemGuard = LOS_DL_LIST_ENTRY(cmdItemGuard->list.pstNext, CmdItemNode, list);
377 }
378 PRINTK("\n");
379 }
380
381 return ret;
382 }
383
OsTabMatchFile(CHAR * cmdKey,UINT32 * len)384 STATIC INT32 OsTabMatchFile(CHAR *cmdKey, UINT32 *len)
385 {
386 UINT32 maxLen = 0;
387 INT32 count;
388 CHAR *strOutput = NULL;
389 CHAR *strCmp = NULL;
390 CHAR *dirOpen = (CHAR *)LOS_MemAlloc(m_aucSysMem0, CMD_MAX_PATH * 3); /* 3:dirOpen\strOutput\strCmp */
391 if (dirOpen == NULL) {
392 return (INT32)OS_ERROR;
393 }
394
395 (VOID)memset_s(dirOpen, CMD_MAX_PATH * 3, 0, CMD_MAX_PATH * 3); /* 3:dirOpen\strOutput\strCmp */
396 strOutput = dirOpen + CMD_MAX_PATH;
397 strCmp = strOutput + CMD_MAX_PATH;
398
399 if (OsStrSeparate(cmdKey, dirOpen, strCmp, *len)) {
400 (VOID)LOS_MemFree(m_aucSysMem0, dirOpen);
401 return (INT32)OS_ERROR;
402 }
403
404 count = OsExecNameMatch(dirOpen, strCmp, strOutput, &maxLen);
405 /* one or more matched */
406 if (count >= 1) {
407 OsCompleteStr(strOutput, strCmp, cmdKey, len);
408
409 if (count == 1) {
410 (VOID)LOS_MemFree(m_aucSysMem0, dirOpen);
411 return 1;
412 }
413 if (OsPrintMatchList((UINT32)count, dirOpen, strCmp, maxLen) == -1) {
414 (VOID)LOS_MemFree(m_aucSysMem0, dirOpen);
415 return (INT32)OS_ERROR;
416 }
417 }
418
419 (VOID)LOS_MemFree(m_aucSysMem0, dirOpen);
420 return count;
421 }
422
423 /*
424 * Description: Pass in the string and clear useless space, which include:
425 * 1) The overmatch space which is not be marked by Quote's area
426 * Squeeze the overmatch space into one space
427 * 2) Clear all space before first valid character
428 * Input: cmdKey : Pass in the buff string, which is ready to be operated
429 * cmdOut : Pass out the buffer string ,which has already been operated
430 * size : cmdKey length
431 */
OsCmdKeyShift(const CHAR * cmdKey,CHAR * cmdOut,UINT32 size)432 LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdKeyShift(const CHAR *cmdKey, CHAR *cmdOut, UINT32 size)
433 {
434 CHAR *output = NULL;
435 CHAR *outputBak = NULL;
436 UINT32 len;
437 INT32 ret;
438 BOOL quotes = FALSE;
439
440 if ((cmdKey == NULL) || (cmdOut == NULL)) {
441 return (UINT32)OS_ERROR;
442 }
443
444 len = strlen(cmdKey);
445 if (len >= size) {
446 return (UINT32)OS_ERROR;
447 }
448 output = (CHAR*)LOS_MemAlloc(m_aucSysMem0, len + 1);
449 if (output == NULL) {
450 PRINTK("malloc failure in %s[%d]", __FUNCTION__, __LINE__);
451 return (UINT32)OS_ERROR;
452 }
453 /* Backup the 'output' start address */
454 outputBak = output;
455 /* Scan each character in 'cmdKey',and squeeze the overmuch space and ignore invalid character */
456 for (; *cmdKey != '\0'; cmdKey++) {
457 /* Detected a Double Quotes, switch the matching status */
458 if (*(cmdKey) == '\"') {
459 SWITCH_QUOTES_STATUS(quotes);
460 }
461 /* Ignore the current character in following situation */
462 /* 1) Quotes matching status is FALSE (which said that the space is not been marked by double quotes) */
463 /* 2) Current character is a space */
464 /* 3) Next character is a space too, or the string is been seeked to the end already(\0) */
465 /* 4) Invalid character, such as single quotes */
466 if ((*cmdKey == ' ') && ((*(cmdKey + 1) == ' ') || (*(cmdKey + 1) == '\0')) && QUOTES_STATUS_CLOSE(quotes)) {
467 continue;
468 }
469 if (*cmdKey == '\'') {
470 continue;
471 }
472 *output = *cmdKey;
473 output++;
474 }
475 *output = '\0';
476 /* Restore the 'output' start address */
477 output = outputBak;
478 len = strlen(output);
479 /* Clear the space which is located at the first character in buffer */
480 if (*outputBak == ' ') {
481 output++;
482 len--;
483 }
484 /* Copy out the buffer which is been operated already */
485 ret = strncpy_s(cmdOut, size, output, len);
486 if (ret != EOK) {
487 PRINT_ERR("%s,%d strncpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
488 (VOID)LOS_MemFree(m_aucSysMem0, output);
489 return OS_ERROR;
490 }
491 cmdOut[len] = '\0';
492
493 (VOID)LOS_MemFree(m_aucSysMem0, output);
494
495 return LOS_OK;
496 }
497
OsCmdKeyCheck(const CHAR * cmdKey)498 LITE_OS_SEC_TEXT_MINOR BOOL OsCmdKeyCheck(const CHAR *cmdKey)
499 {
500 const CHAR *temp = cmdKey;
501 enum Stat {
502 STAT_NONE,
503 STAT_DIGIT,
504 STAT_OTHER
505 } state = STAT_NONE;
506
507 if (strlen(cmdKey) >= CMD_KEY_LEN) {
508 return FALSE;
509 }
510
511 while (*temp != '\0') {
512 if (!((*temp <= '9') && (*temp >= '0')) &&
513 !((*temp <= 'z') && (*temp >= 'a')) &&
514 !((*temp <= 'Z') && (*temp >= 'A')) &&
515 (*temp != '_') && (*temp != '-')) {
516 return FALSE;
517 }
518
519 if ((*temp >= '0') && (*temp <= '9')) {
520 if (state == STAT_NONE) {
521 state = STAT_DIGIT;
522 }
523 } else {
524 state = STAT_OTHER;
525 }
526
527 temp++;
528 }
529
530 if (state == STAT_DIGIT) {
531 return FALSE;
532 }
533
534 return TRUE;
535 }
536
OsTabCompletion(CHAR * cmdKey,UINT32 * len)537 LITE_OS_SEC_TEXT_MINOR INT32 OsTabCompletion(CHAR *cmdKey, UINT32 *len)
538 {
539 INT32 count = 0;
540 CHAR *space = NULL;
541 CHAR *cmdMainStr = cmdKey;
542
543 if ((cmdKey == NULL) || (len == NULL)) {
544 return (INT32)OS_ERROR;
545 }
546
547 /* cut left space */
548 while (*cmdMainStr == 0x20) {
549 cmdMainStr++;
550 }
551
552 /* try to find space in remain */
553 space = strrchr(cmdMainStr, 0x20);
554 if ((space == NULL) && (*cmdMainStr != '\0')) {
555 count = OsTabMatchCmd(cmdKey, len);
556 }
557
558 if (count == 0) {
559 count = OsTabMatchFile(cmdKey, len);
560 }
561
562 return count;
563 }
564
OsCmdAscendingInsert(CmdItemNode * cmd)565 LITE_OS_SEC_TEXT_MINOR VOID OsCmdAscendingInsert(CmdItemNode *cmd)
566 {
567 CmdItemNode *cmdItem = NULL;
568 CmdItemNode *cmdNext = NULL;
569
570 if (cmd == NULL) {
571 return;
572 }
573
574 for (cmdItem = LOS_DL_LIST_ENTRY((&g_cmdInfo.cmdList.list)->pstPrev, CmdItemNode, list);
575 &cmdItem->list != &(g_cmdInfo.cmdList.list);) {
576 cmdNext = LOS_DL_LIST_ENTRY(cmdItem->list.pstPrev, CmdItemNode, list);
577 if (&cmdNext->list != &(g_cmdInfo.cmdList.list)) {
578 if ((strncmp(cmdItem->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) >= 0) &&
579 (strncmp(cmdNext->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) < 0)) {
580 LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));
581 return;
582 }
583 cmdItem = cmdNext;
584 } else {
585 if (strncmp(cmd->cmd->cmdKey, cmdItem->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) > 0) {
586 cmdItem = cmdNext;
587 }
588 break;
589 }
590 }
591
592 LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));
593 }
594
OsShellKeyInit(ShellCB * shellCB)595 LITE_OS_SEC_TEXT_MINOR UINT32 OsShellKeyInit(ShellCB *shellCB)
596 {
597 CmdKeyLink *cmdKeyLink = NULL;
598 CmdKeyLink *cmdHistoryLink = NULL;
599
600 if (shellCB == NULL) {
601 return OS_ERROR;
602 }
603 cmdKeyLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink));
604 if (cmdKeyLink == NULL) {
605 PRINT_ERR("Shell CmdKeyLink memory alloc error!\n");
606 return OS_ERROR;
607 }
608 cmdHistoryLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink));
609 if (cmdHistoryLink == NULL) {
610 (VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink);
611 PRINT_ERR("Shell CmdHistoryLink memory alloc error!\n");
612 return OS_ERROR;
613 }
614
615 cmdKeyLink->count = 0;
616 LOS_ListInit(&(cmdKeyLink->list));
617 shellCB->cmdKeyLink = (VOID *)cmdKeyLink;
618
619 cmdHistoryLink->count = 0;
620 LOS_ListInit(&(cmdHistoryLink->list));
621 shellCB->cmdHistoryKeyLink = (VOID *)cmdHistoryLink;
622 shellCB->cmdMaskKeyLink = (VOID *)cmdHistoryLink;
623 return LOS_OK;
624 }
625
OsShellKeyDeInit(CmdKeyLink * cmdKeyLink)626 LITE_OS_SEC_TEXT_MINOR VOID OsShellKeyDeInit(CmdKeyLink *cmdKeyLink)
627 {
628 CmdKeyLink *cmdtmp = NULL;
629 if (cmdKeyLink == NULL) {
630 return;
631 }
632
633 while (!LOS_ListEmpty(&(cmdKeyLink->list))) {
634 cmdtmp = LOS_DL_LIST_ENTRY(cmdKeyLink->list.pstNext, CmdKeyLink, list);
635 LOS_ListDelete(&cmdtmp->list);
636 (VOID)LOS_MemFree(m_aucSysMem0, cmdtmp);
637 }
638
639 cmdKeyLink->count = 0;
640 (VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink);
641 }
642
OsShellSysCmdRegister(VOID)643 LITE_OS_SEC_TEXT_MINOR UINT32 OsShellSysCmdRegister(VOID)
644 {
645 UINT32 i;
646 UINT8 *cmdItemGroup = NULL;
647 UINT32 index = ((UINTPTR)(&g_shellcmdEnd) - (UINTPTR)(&g_shellcmd[0])) / sizeof(CmdItem);
648 CmdItemNode *cmdItem = NULL;
649
650 cmdItemGroup = (UINT8 *)LOS_MemAlloc(m_aucSysMem0, index * sizeof(CmdItemNode));
651 if (cmdItemGroup == NULL) {
652 PRINT_ERR("[%s]System memory allocation failure!\n", __FUNCTION__);
653 return (UINT32)OS_ERROR;
654 }
655
656 for (i = 0; i < index; ++i) {
657 cmdItem = (CmdItemNode *)(cmdItemGroup + i * sizeof(CmdItemNode));
658 cmdItem->cmd = &g_shellcmd[i];
659 OsCmdAscendingInsert(cmdItem);
660 }
661 g_cmdInfo.listNum += index;
662 return LOS_OK;
663 }
664
OsShellCmdPush(const CHAR * string,CmdKeyLink * cmdKeyLink)665 LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdPush(const CHAR *string, CmdKeyLink *cmdKeyLink)
666 {
667 CmdKeyLink *cmdNewNode = NULL;
668 UINT32 len;
669
670 if ((string == NULL) || (strlen(string) == 0)) {
671 return;
672 }
673
674 len = strlen(string);
675 cmdNewNode = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink) + len + 1);
676 if (cmdNewNode == NULL) {
677 return;
678 }
679
680 (VOID)memset_s(cmdNewNode, sizeof(CmdKeyLink) + len + 1, 0, sizeof(CmdKeyLink) + len + 1);
681 if (strncpy_s(cmdNewNode->cmdString, len + 1, string, len)) {
682 (VOID)LOS_MemFree(m_aucSysMem0, cmdNewNode);
683 return;
684 }
685
686 LOS_ListTailInsert(&(cmdKeyLink->list), &(cmdNewNode->list));
687
688 return;
689 }
690
OsShellHistoryShow(UINT32 value,ShellCB * shellCB)691 LITE_OS_SEC_TEXT_MINOR VOID OsShellHistoryShow(UINT32 value, ShellCB *shellCB)
692 {
693 CmdKeyLink *cmdtmp = NULL;
694 CmdKeyLink *cmdNode = shellCB->cmdHistoryKeyLink;
695 CmdKeyLink *cmdMask = shellCB->cmdMaskKeyLink;
696 errno_t ret;
697
698 (VOID)pthread_mutex_lock(&shellCB->historyMutex);
699 if (value == CMD_KEY_DOWN) {
700 if (cmdMask == cmdNode) {
701 goto END;
702 }
703
704 cmdtmp = LOS_DL_LIST_ENTRY(cmdMask->list.pstNext, CmdKeyLink, list);
705 if (cmdtmp != cmdNode) {
706 cmdMask = cmdtmp;
707 } else {
708 goto END;
709 }
710 } else if (value == CMD_KEY_UP) {
711 cmdtmp = LOS_DL_LIST_ENTRY(cmdMask->list.pstPrev, CmdKeyLink, list);
712 if (cmdtmp != cmdNode) {
713 cmdMask = cmdtmp;
714 } else {
715 goto END;
716 }
717 }
718
719 while (shellCB->shellBufOffset--) {
720 PRINTK("\b \b");
721 }
722 PRINTK("%s", cmdMask->cmdString);
723 shellCB->shellBufOffset = strlen(cmdMask->cmdString);
724 (VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN);
725 ret = memcpy_s(shellCB->shellBuf, SHOW_MAX_LEN, cmdMask->cmdString, shellCB->shellBufOffset);
726 if (ret != EOK) {
727 PRINT_ERR("%s, %d memcpy failed!\n", __FUNCTION__, __LINE__);
728 goto END;
729 }
730 shellCB->cmdMaskKeyLink = (VOID *)cmdMask;
731
732 END:
733 (VOID)pthread_mutex_unlock(&shellCB->historyMutex);
734 return;
735 }
736
OsCmdExec(CmdParsed * cmdParsed,CHAR * cmdStr)737 LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdExec(CmdParsed *cmdParsed, CHAR *cmdStr)
738 {
739 UINT32 ret;
740 CmdCallBackFunc cmdHook = NULL;
741 CmdItemNode *curCmdItem = NULL;
742 UINT32 i;
743 const CHAR *cmdKey = NULL;
744
745 if ((cmdParsed == NULL) || (cmdStr == NULL) || (strlen(cmdStr) == 0)) {
746 return (UINT32)OS_ERROR;
747 }
748
749 ret = OsCmdParse(cmdStr, cmdParsed);
750 if (ret != LOS_OK) {
751 goto OUT;
752 }
753
754 LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(g_cmdInfo.cmdList.list), CmdItemNode, list) {
755 cmdKey = curCmdItem->cmd->cmdKey;
756 if ((cmdParsed->cmdType == curCmdItem->cmd->cmdType) &&
757 (strlen(cmdKey) == strlen(cmdParsed->cmdKeyword)) &&
758 (strncmp(cmdKey, (CHAR *)(cmdParsed->cmdKeyword), strlen(cmdKey)) == 0)) {
759 cmdHook = curCmdItem->cmd->cmdHook;
760 break;
761 }
762 }
763
764 ret = OS_ERROR;
765 if (cmdHook != NULL) {
766 ret = (cmdHook)(cmdParsed->paramCnt, (const CHAR **)cmdParsed->paramArray);
767 }
768
769 OUT:
770 for (i = 0; i < cmdParsed->paramCnt; i++) {
771 if (cmdParsed->paramArray[i] != NULL) {
772 (VOID)LOS_MemFree(m_aucSysMem0, cmdParsed->paramArray[i]);
773 cmdParsed->paramArray[i] = NULL;
774 }
775 }
776
777 return (UINT32)ret;
778 }
779
OsCmdInit(VOID)780 LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdInit(VOID)
781 {
782 UINT32 ret;
783 LOS_ListInit(&(g_cmdInfo.cmdList.list));
784 g_cmdInfo.listNum = 0;
785 g_cmdInfo.initMagicFlag = SHELL_INIT_MAGIC_FLAG;
786 ret = LOS_MuxInit(&g_cmdInfo.muxLock, NULL);
787 if (ret != LOS_OK) {
788 PRINT_ERR("Create mutex for shell cmd info failed\n");
789 return OS_ERROR;
790 }
791 return LOS_OK;
792 }
793
OsCmdItemCreate(CmdType cmdType,const CHAR * cmdKey,UINT32 paraNum,CmdCallBackFunc cmdProc)794 STATIC UINT32 OsCmdItemCreate(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
795 {
796 CmdItem *cmdItem = NULL;
797 CmdItemNode *cmdItemNode = NULL;
798
799 cmdItem = (CmdItem *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItem));
800 if (cmdItem == NULL) {
801 return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR;
802 }
803 (VOID)memset_s(cmdItem, sizeof(CmdItem), '\0', sizeof(CmdItem));
804
805 cmdItemNode = (CmdItemNode *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItemNode));
806 if (cmdItemNode == NULL) {
807 (VOID)LOS_MemFree(m_aucSysMem0, cmdItem);
808 return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR;
809 }
810 (VOID)memset_s(cmdItemNode, sizeof(CmdItemNode), '\0', sizeof(CmdItemNode));
811 cmdItemNode->cmd = cmdItem;
812 cmdItemNode->cmd->cmdHook = cmdProc;
813 cmdItemNode->cmd->paraNum = paraNum;
814 cmdItemNode->cmd->cmdType = cmdType;
815 cmdItemNode->cmd->cmdKey = cmdKey;
816
817 (VOID)LOS_MuxLock(&g_cmdInfo.muxLock, LOS_WAIT_FOREVER);
818 OsCmdAscendingInsert(cmdItemNode);
819 g_cmdInfo.listNum++;
820 (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock);
821
822 return LOS_OK;
823 }
824
825 /* open API */
osCmdReg(CmdType cmdType,const CHAR * cmdKey,UINT32 paraNum,CmdCallBackFunc cmdProc)826 LITE_OS_SEC_TEXT_MINOR UINT32 osCmdReg(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
827 {
828 CmdItemNode *cmdItemNode = NULL;
829
830 (VOID)LOS_MuxLock(&g_cmdInfo.muxLock, LOS_WAIT_FOREVER);
831 if (g_cmdInfo.initMagicFlag != SHELL_INIT_MAGIC_FLAG) {
832 (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock);
833 PRINT_ERR("[%s] shell is not yet initialized!\n", __FUNCTION__);
834 return OS_ERRNO_SHELL_NOT_INIT;
835 }
836 (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock);
837
838 if ((cmdProc == NULL) || (cmdKey == NULL) ||
839 (cmdType >= CMD_TYPE_BUTT) || (strlen(cmdKey) >= CMD_KEY_LEN) || !strlen(cmdKey)) {
840 return OS_ERRNO_SHELL_CMDREG_PARA_ERROR;
841 }
842
843 if (paraNum > CMD_MAX_PARAS) {
844 if (paraNum != XARGS) {
845 return OS_ERRNO_SHELL_CMDREG_PARA_ERROR;
846 }
847 }
848
849 if (OsCmdKeyCheck(cmdKey) != TRUE) {
850 return OS_ERRNO_SHELL_CMDREG_CMD_ERROR;
851 }
852
853 (VOID)LOS_MuxLock(&g_cmdInfo.muxLock, LOS_WAIT_FOREVER);
854 LOS_DL_LIST_FOR_EACH_ENTRY(cmdItemNode, &(g_cmdInfo.cmdList.list), CmdItemNode, list) {
855 if ((cmdType == cmdItemNode->cmd->cmdType) &&
856 ((strlen(cmdKey) == strlen(cmdItemNode->cmd->cmdKey)) &&
857 (strncmp((CHAR *)(cmdItemNode->cmd->cmdKey), cmdKey, strlen(cmdKey)) == 0))) {
858 (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock);
859 return OS_ERRNO_SHELL_CMDREG_CMD_EXIST;
860 }
861 }
862 (VOID)LOS_MuxUnlock(&g_cmdInfo.muxLock);
863
864 return OsCmdItemCreate(cmdType, cmdKey, paraNum, cmdProc);
865 }
866
867