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