• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2022 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 "show.h"
34 #include "shmsg.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 
42 #if (LOSCFG_DEBUG_TOOLS == 1)
43 #include "los_debugtools.h"
44 #endif
45 
46 #if (LOSCFG_KERNEL_TRACE == 1)
47 #include "los_trace_pri.h"
48 #endif
49 
50 #define SHELL_INIT_MAGIC_FLAG 0xABABABAB
51 
52 STATIC CmdModInfo cmdInfo;
53 ShellCB *g_shellCB = NULL;
54 CmdItem g_shellcmdAll[] = {
55     {CMD_TYPE_STD, "date", XARGS, (CmdCallBackFunc)OsShellCmdDate},
56     {CMD_TYPE_EX, "task", 1, (CmdCallBackFunc)OsShellCmdDumpTask},
57     {CMD_TYPE_EX, "free", XARGS, (CmdCallBackFunc)OsShellCmdFree},
58 #if (LOSCFG_MEM_WATERLINE == 1)
59     {CMD_TYPE_EX, "memusage", XARGS, (CmdCallBackFunc)OsShellCmdWaterLine},
60 #endif
61 #ifdef LWIP_SHELLCMD_ENABLE
62     {CMD_TYPE_EX, "ifconfig", XARGS, (CmdCallBackFunc)lwip_ifconfig},
63     {CMD_TYPE_EX, "ping", XARGS, (CmdCallBackFunc)OsShellPing},
64 #endif
65 #if (LOSCFG_FS_VFS == 1)
66     {CMD_TYPE_EX, "touch", XARGS, (CmdCallBackFunc)OsShellCmdTouch},
67     {CMD_TYPE_EX, "ls", XARGS, (CmdCallBackFunc)OsShellCmdLs},
68     {CMD_TYPE_EX, "pwd", XARGS, (CmdCallBackFunc)OsShellCmdPwd},
69     {CMD_TYPE_EX, "cd", XARGS, (CmdCallBackFunc)OsShellCmdCd},
70     {CMD_TYPE_EX, "cat", XARGS, (CmdCallBackFunc)OsShellCmdCat},
71     {CMD_TYPE_EX, "rm", XARGS, (CmdCallBackFunc)OsShellCmdRm},
72     {CMD_TYPE_EX, "rmdir", XARGS, (CmdCallBackFunc)OsShellCmdRmdir},
73     {CMD_TYPE_EX, "mkdir", XARGS, (CmdCallBackFunc)OsShellCmdMkdir},
74     {CMD_TYPE_EX, "cp", XARGS, (CmdCallBackFunc)OsShellCmdCp},
75 #endif
76 #if (LOSCFG_DEBUG_TOOLS == 1)
77     {CMD_TYPE_EX, "stack", 1, (CmdCallBackFunc)OsShellCmdStackDump},
78     {CMD_TYPE_EX, "hwi", 1, (CmdCallBackFunc)OsShellCmdHwiDump},
79     {CMD_TYPE_EX, "st", 1, (CmdCallBackFunc)OsShellCmdSchedTrace},
80 #endif
81     {CMD_TYPE_EX, "help", 0, (CmdCallBackFunc)OsShellCmdHelp},
82 #if (LOSCFG_KERNEL_TRACE == 1)
83     {CMD_TYPE_EX, "trace_start", 0, (CmdCallBackFunc)LOS_TraceStart},
84     {CMD_TYPE_EX, "trace_stop",  0, (CmdCallBackFunc)LOS_TraceStop},
85     {CMD_TYPE_EX, "trace_mask",  1, (CmdCallBackFunc)OsShellCmdTraceSetMask},
86     {CMD_TYPE_EX, "trace_reset", 0, (CmdCallBackFunc)LOS_TraceReset},
87     {CMD_TYPE_EX, "trace_dump", 1, (CmdCallBackFunc)OsShellCmdTraceDump},
88 #endif
89 };
90 
OsCmdInfoGet(VOID)91 CmdModInfo *OsCmdInfoGet(VOID)
92 {
93     return &cmdInfo;
94 }
95 
96 /*
97  * Description: Pass in the string and clear useless space ,which include:
98  *                1) The overmatch space which is not be marked by Quote's area
99  *                   Squeeze the overmatch space into one space
100  *                2) Clear all space before first valid character
101  * Input:       cmdKey : Pass in the buff string, which is ready to be operated
102  *              cmdOut : Pass out the buffer string ,which has already been operated
103  *              size : cmdKey length
104  */
OsCmdKeyShift(const CHAR * cmdKey,CHAR * cmdOut,UINT32 size)105 LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdKeyShift(const CHAR *cmdKey, CHAR *cmdOut, UINT32 size)
106 {
107     CHAR *output = NULL;
108     CHAR *outputBak = NULL;
109     UINT32 len;
110     INT32 ret;
111     BOOL quotes = FALSE;
112 
113     if ((cmdKey == NULL) || (cmdOut == NULL)) {
114         return (UINT32)OS_ERROR;
115     }
116 
117     len = strlen(cmdKey);
118     if (len >= size) {
119         return (UINT32)OS_ERROR;
120     }
121     output = (CHAR*)LOS_MemAlloc(m_aucSysMem0, len + 1);
122     if (output == NULL) {
123         PRINTK("malloc failure in %s[%d]", __FUNCTION__, __LINE__);
124         return (UINT32)OS_ERROR;
125     }
126     (VOID)memset_s(output, len + 1, 0, len + 1);
127     /* Backup the 'output' start address */
128     outputBak = output;
129     /* Scan each charactor in 'cmdKey',and squeeze the overmuch space and ignore invalid charactor */
130     for (; *cmdKey != '\0'; cmdKey++) {
131         /* Detected a Double Quotes, switch the matching status */
132         if (*(cmdKey) == '\"') {
133             SWITCH_QUOTES_STATUS(quotes);
134         }
135         /* Ignore the current charactor in following situation */
136         /* 1) Quotes matching status is FALSE (which said that the space is not been marked by double quotes) */
137         /* 2) Current charactor is a space */
138         /* 3) Next charactor is a space too, or the string is been seeked to the end already(\0) */
139         /* 4) Invalid charactor, such as single quotes */
140         if ((*cmdKey == ' ') && ((*(cmdKey + 1) == ' ') || (*(cmdKey + 1) == '\0')) && QUOTES_STATUS_CLOSE(quotes)) {
141             continue;
142         }
143         if (*cmdKey == '\'') {
144             continue;
145         }
146         *output = *cmdKey;
147         output++;
148     }
149     *output = '\0';
150     /* Restore the 'output' start address */
151     output = outputBak;
152     len = strlen(output);
153     /* Clear the space which is located at the first charactor in buffer */
154     if (*outputBak == ' ') {
155         output++;
156         len--;
157     }
158     /* Copy out the buffer which is been operated already */
159     ret = strncpy_s(cmdOut, size, output, len);
160     if (ret != EOK) {
161         PRINT_ERR("%s,%d strncpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
162         (VOID)LOS_MemFree(m_aucSysMem0, output);
163         return OS_ERROR;
164     }
165     cmdOut[len] = '\0';
166 
167     (VOID)LOS_MemFree(m_aucSysMem0, output);
168 
169     return LOS_OK;
170 }
171 
OsCmdKeyCheck(const CHAR * cmdKey)172 LITE_OS_SEC_TEXT_MINOR BOOL OsCmdKeyCheck(const CHAR *cmdKey)
173 {
174     const CHAR *temp = cmdKey;
175     enum Stat {
176         STAT_NONE,
177         STAT_DIGIT,
178         STAT_OTHER
179     } state = STAT_NONE;
180 
181     if (strlen(cmdKey) >= CMD_KEY_LEN) {
182         return FALSE;
183     }
184 
185     while (*temp != '\0') {
186         if (!((*temp <= '9') && (*temp >= '0')) &&
187             !((*temp <= 'z') && (*temp >= 'a')) &&
188             !((*temp <= 'Z') && (*temp >= 'A')) &&
189             (*temp != '_') && (*temp != '-')) {
190             return FALSE;
191         }
192 
193         if ((*temp >= '0') && (*temp <= '9')) {
194             if (state == STAT_NONE) {
195                 state = STAT_DIGIT;
196             }
197         } else {
198             state = STAT_OTHER;
199         }
200 
201         temp++;
202     }
203 
204     if (state == STAT_DIGIT) {
205         return FALSE;
206     }
207 
208     return TRUE;
209 }
210 
OsCmdAscendingInsert(CmdItemNode * cmd)211 LITE_OS_SEC_TEXT_MINOR VOID OsCmdAscendingInsert(CmdItemNode *cmd)
212 {
213     CmdItemNode *cmdItem = NULL;
214     CmdItemNode *cmdNext = NULL;
215 
216     if (cmd == NULL) {
217         return;
218     }
219 
220     for (cmdItem = LOS_DL_LIST_ENTRY((&cmdInfo.cmdList.list)->pstPrev, CmdItemNode, list);
221         &cmdItem->list != &(cmdInfo.cmdList.list);) {
222         cmdNext = LOS_DL_LIST_ENTRY(cmdItem->list.pstPrev, CmdItemNode, list);
223         if (&cmdNext->list != &(cmdInfo.cmdList.list)) {
224             if ((strncmp(cmdItem->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) >= 0) &&
225                 (strncmp(cmdNext->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) < 0)) {
226                 LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));
227                 return;
228             }
229             cmdItem = cmdNext;
230         } else {
231             if (strncmp(cmd->cmd->cmdKey, cmdItem->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) > 0) {
232                 cmdItem = cmdNext;
233             }
234             break;
235         }
236     }
237 
238     LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));
239 }
240 
OsShellKeyInit(ShellCB * shellCB)241 LITE_OS_SEC_TEXT_MINOR UINT32 OsShellKeyInit(ShellCB *shellCB)
242 {
243     CmdKeyLink *cmdKeyLink = NULL;
244     CmdKeyLink *cmdHistoryLink = NULL;
245 
246     if (shellCB == NULL) {
247         return OS_ERROR;
248     }
249     cmdKeyLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink));
250     if (cmdKeyLink == NULL) {
251         PRINT_ERR("Shell CmdKeyLink memory alloc error!\n");
252         return OS_ERROR;
253     }
254     cmdHistoryLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink));
255     if (cmdHistoryLink == NULL) {
256         (VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink);
257         PRINT_ERR("Shell CmdHistoryLink memory alloc error!\n");
258         return OS_ERROR;
259     }
260 
261     cmdKeyLink->count = 0;
262     LOS_ListInit(&(cmdKeyLink->list));
263     shellCB->cmdKeyLink = (VOID *)cmdKeyLink;
264 
265     cmdHistoryLink->count = 0;
266     LOS_ListInit(&(cmdHistoryLink->list));
267     shellCB->cmdHistoryKeyLink = (VOID *)cmdHistoryLink;
268     shellCB->cmdMaskKeyLink = (VOID *)cmdHistoryLink;
269     return LOS_OK;
270 }
271 
OsShellKeyDeInit(CmdKeyLink * cmdKeyLink)272 LITE_OS_SEC_TEXT_MINOR VOID OsShellKeyDeInit(CmdKeyLink *cmdKeyLink)
273 {
274     CmdKeyLink *cmdtmp = NULL;
275     if (cmdKeyLink == NULL) {
276         return;
277     }
278 
279     while (!LOS_ListEmpty(&(cmdKeyLink->list))) {
280         cmdtmp = LOS_DL_LIST_ENTRY(cmdKeyLink->list.pstNext, CmdKeyLink, list);
281         LOS_ListDelete(&cmdtmp->list);
282         (VOID)LOS_MemFree(m_aucSysMem0, cmdtmp);
283     }
284 
285     cmdKeyLink->count = 0;
286     (VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink);
287 }
288 
OsShellSysCmdRegister(VOID)289 LITE_OS_SEC_TEXT_MINOR UINT32 OsShellSysCmdRegister(VOID)
290 {
291     UINT32 i;
292     UINT8 *cmdItemGroup = NULL;
293     UINT32 index = sizeof(g_shellcmdAll) / sizeof(CmdItem);
294     CmdItemNode *cmdItem = NULL;
295 
296     cmdItemGroup = (UINT8 *)LOS_MemAlloc(m_aucSysMem0, index * sizeof(CmdItemNode));
297     if (cmdItemGroup == NULL) {
298         PRINT_ERR("[%s]System memory allocation failure!\n", __FUNCTION__);
299         return (UINT32)OS_ERROR;
300     }
301 
302     for (i = 0; i < index; ++i) {
303         cmdItem = (CmdItemNode *)(cmdItemGroup + i * sizeof(CmdItemNode));
304         cmdItem->cmd = &g_shellcmdAll[i];
305         OsCmdAscendingInsert(cmdItem);
306     }
307     cmdInfo.listNum += index;
308     return LOS_OK;
309 }
310 
OsCmdExec(CmdParsed * cmdParsed)311 LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdExec(CmdParsed *cmdParsed)
312 {
313     UINT32 ret;
314     CmdCallBackFunc cmdHook = NULL;
315     CmdItemNode *curCmdItem = NULL;
316     UINT32 i;
317     const CHAR *cmdKey = NULL;
318 
319     if (cmdParsed == NULL) {
320         return (UINT32)OS_ERROR;
321     }
322 
323     LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(cmdInfo.cmdList.list), CmdItemNode, list) {
324         cmdKey = curCmdItem->cmd->cmdKey;
325         if ((cmdParsed->cmdType == curCmdItem->cmd->cmdType) &&
326             (strlen(cmdKey) == strlen(cmdParsed->cmdKeyword)) &&
327             (strncmp(cmdKey, (CHAR *)(cmdParsed->cmdKeyword), strlen(cmdKey)) == 0)) {
328             cmdHook = curCmdItem->cmd->cmdHook;
329             break;
330         }
331     }
332 
333     ret = OS_ERROR;
334     if (cmdHook != NULL) {
335         ret = (cmdHook)(cmdParsed->paramCnt, (const CHAR **)cmdParsed->paramArray);
336     }
337 
338     for (i = 0; i < cmdParsed->paramCnt; i++) {
339         if (cmdParsed->paramArray[i] != NULL) {
340             (VOID)LOS_MemFree(m_aucSysMem0, cmdParsed->paramArray[i]);
341             cmdParsed->paramArray[i] = NULL;
342         }
343     }
344 
345     return (UINT32)ret;
346 }
347 
OsGetShellCb(VOID)348 ShellCB *OsGetShellCb(VOID)
349 {
350     return g_shellCB;
351 }
352 
OsShellGetWorkingDirtectory(VOID)353 CHAR *OsShellGetWorkingDirtectory(VOID)
354 {
355     return OsGetShellCb()->shellWorkingDirectory;
356 }
357 
OsShellCBInit(VOID)358 VOID OsShellCBInit(VOID)
359 {
360     INT32 ret;
361     ShellCB *shellCB = NULL;
362 
363     shellCB = (ShellCB *)malloc(sizeof(ShellCB));
364     if (shellCB == NULL) {
365         goto ERR_OUT1;
366     }
367     ret = memset_s(shellCB, sizeof(ShellCB), 0, sizeof(ShellCB));
368     if (ret != SH_OK) {
369         goto ERR_OUT1;
370     }
371 
372     ret = (INT32)OsShellKeyInit(shellCB);
373     if (ret != SH_OK) {
374         goto ERR_OUT1;
375     }
376     (VOID)strncpy_s(shellCB->shellWorkingDirectory, PATH_MAX, "/", 2); /* 2:space for "/" */
377 
378     g_shellCB = shellCB;
379     return;
380 
381 ERR_OUT1:
382     (VOID)free(shellCB);
383     return;
384 }
385 
OsCmdInit(VOID)386 LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdInit(VOID)
387 {
388     UINT32 ret;
389     LOS_ListInit(&(cmdInfo.cmdList.list));
390     cmdInfo.listNum = 0;
391     cmdInfo.initMagicFlag = SHELL_INIT_MAGIC_FLAG;
392     ret = LOS_MuxCreate(&cmdInfo.muxLock);
393     if (ret != LOS_OK) {
394         PRINT_ERR("Create mutex for shell cmd info failed\n");
395         return OS_ERROR;
396     }
397     OsShellCBInit();
398 
399     return LOS_OK;
400 }
401 
OsCmdItemCreate(CmdType cmdType,const CHAR * cmdKey,UINT32 paraNum,CmdCallBackFunc cmdProc)402 STATIC UINT32 OsCmdItemCreate(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
403 {
404     CmdItem *cmdItem = NULL;
405     CmdItemNode *cmdItemNode = NULL;
406 
407     cmdItem = (CmdItem *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItem));
408     if (cmdItem == NULL) {
409         return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR;
410     }
411     (VOID)memset_s(cmdItem, sizeof(CmdItem), '\0', sizeof(CmdItem));
412 
413     cmdItemNode = (CmdItemNode *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItemNode));
414     if (cmdItemNode == NULL) {
415         (VOID)LOS_MemFree(m_aucSysMem0, cmdItem);
416         return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR;
417     }
418     (VOID)memset_s(cmdItemNode, sizeof(CmdItemNode), '\0', sizeof(CmdItemNode));
419     cmdItemNode->cmd = cmdItem;
420     cmdItemNode->cmd->cmdHook = cmdProc;
421     cmdItemNode->cmd->paraNum = paraNum;
422     cmdItemNode->cmd->cmdType = cmdType;
423     cmdItemNode->cmd->cmdKey = cmdKey;
424 
425     (VOID)LOS_MuxPend(cmdInfo.muxLock, LOS_WAIT_FOREVER);
426     OsCmdAscendingInsert(cmdItemNode);
427     cmdInfo.listNum++;
428     (VOID)LOS_MuxPost(cmdInfo.muxLock);
429 
430     return LOS_OK;
431 }
432 
433 /* open API */
osCmdReg(CmdType cmdType,const CHAR * cmdKey,UINT32 paraNum,CmdCallBackFunc cmdProc)434 LITE_OS_SEC_TEXT_MINOR UINT32 osCmdReg(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
435 {
436     CmdItemNode *cmdItemNode = NULL;
437 
438     (VOID)LOS_MuxPend(cmdInfo.muxLock, LOS_WAIT_FOREVER);
439     if (cmdInfo.initMagicFlag != SHELL_INIT_MAGIC_FLAG) {
440         (VOID)LOS_MuxPost(cmdInfo.muxLock);
441         PRINT_ERR("[%s] shell is not yet initialized!\n", __FUNCTION__);
442         return OS_ERRNO_SHELL_NOT_INIT;
443     }
444     (VOID)LOS_MuxPost(cmdInfo.muxLock);
445 
446     if ((cmdProc == NULL) || (cmdKey == NULL) ||
447         (cmdType >= CMD_TYPE_BUTT) || (strlen(cmdKey) >= CMD_KEY_LEN) || !strlen(cmdKey)) {
448         return OS_ERRNO_SHELL_CMDREG_PARA_ERROR;
449     }
450 
451     if (paraNum > CMD_MAX_PARAS) {
452         if (paraNum != XARGS) {
453             return OS_ERRNO_SHELL_CMDREG_PARA_ERROR;
454         }
455     }
456 
457     if (OsCmdKeyCheck(cmdKey) != TRUE) {
458         return OS_ERRNO_SHELL_CMDREG_CMD_ERROR;
459     }
460 
461     (VOID)LOS_MuxPend(cmdInfo.muxLock, LOS_WAIT_FOREVER);
462     LOS_DL_LIST_FOR_EACH_ENTRY(cmdItemNode, &(cmdInfo.cmdList.list), CmdItemNode, list) {
463         if ((cmdType == cmdItemNode->cmd->cmdType) &&
464             ((strlen(cmdKey) == strlen(cmdItemNode->cmd->cmdKey)) &&
465             (strncmp((CHAR *)(cmdItemNode->cmd->cmdKey), cmdKey, strlen(cmdKey)) == 0))) {
466             (VOID)LOS_MuxPost(cmdInfo.muxLock);
467             return OS_ERRNO_SHELL_CMDREG_CMD_EXIST;
468         }
469     }
470     (VOID)LOS_MuxPost(cmdInfo.muxLock);
471 
472     return OsCmdItemCreate(cmdType, cmdKey, paraNum, cmdProc);
473 }
474 
475