xref: /kernel/liteos_a/fs/vfs/vfs_cmd/vfs_shellcmd.c (revision 0d163575)
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 "los_config.h"
33#include "sys/mount.h"
34
35#ifdef LOSCFG_SHELL
36
37#include "los_typedef.h"
38#include "shell.h"
39#include "sys/stat.h"
40#include "stdlib.h"
41#include "unistd.h"
42#include "fcntl.h"
43#include "sys/statfs.h"
44#include "stdio.h"
45#include "pthread.h"
46
47#include "shcmd.h"
48#include "securec.h"
49#include "show.h"
50#include "los_syscall.h"
51
52#include "los_process_pri.h"
53#include <ctype.h>
54#include "fs/fs_operation.h"
55
56typedef enum {
57    RM_RECURSIVER,
58    RM_FILE,
59    RM_DIR,
60    CP_FILE,
61    CP_COUNT
62} wildcard_type;
63
64#define ERROR_OUT_IF(condition, message_function, handler) \
65    do { \
66        if (condition) { \
67            message_function; \
68            handler; \
69        } \
70    } while (0)
71
72static inline void set_err(int errcode, const char *err_message)
73{
74    set_errno(errcode);
75    perror(err_message);
76}
77
78int osShellCmdDoChdir(const char *path)
79{
80    char *fullpath = NULL;
81    char *fullpath_bak = NULL;
82    int ret;
83    char *shell_working_directory = OsShellGetWorkingDirectory();
84    if (shell_working_directory == NULL) {
85        return -1;
86    }
87
88    if (path == NULL) {
89        LOS_TaskLock();
90        PRINTK("%s\n", shell_working_directory);
91        LOS_TaskUnlock();
92
93        return 0;
94    }
95
96    ERROR_OUT_IF(strlen(path) > PATH_MAX, set_err(ENOTDIR, "cd error"), return -1);
97
98    ret = vfs_normalize_path(shell_working_directory, path, &fullpath);
99    ERROR_OUT_IF(ret < 0, set_err(-ret, "cd error"), return -1);
100
101    fullpath_bak = fullpath;
102    ret = chdir(fullpath);
103    if (ret < 0) {
104        free(fullpath_bak);
105        perror("cd");
106        return -1;
107    }
108
109    /* copy full path to working directory */
110
111    LOS_TaskLock();
112    ret = strncpy_s(shell_working_directory, PATH_MAX, fullpath, strlen(fullpath));
113    if (ret != EOK) {
114        free(fullpath_bak);
115        LOS_TaskUnlock();
116        return -1;
117    }
118    LOS_TaskUnlock();
119    /* release normalize directory path name */
120
121    free(fullpath_bak);
122
123    return 0;
124}
125
126int osShellCmdLs(int argc, const char **argv)
127{
128    char *fullpath = NULL;
129    const char *filename = NULL;
130    int ret;
131    char *shell_working_directory = OsShellGetWorkingDirectory();
132    if (shell_working_directory == NULL) {
133        return -1;
134    }
135
136    ERROR_OUT_IF(argc > 1, PRINTK("ls or ls [DIRECTORY]\n"), return -1);
137
138    if (argc == 0) {
139        ls(shell_working_directory);
140        return 0;
141    }
142
143    filename = argv[0];
144    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
145    ERROR_OUT_IF(ret < 0, set_err(-ret, "ls error"), return -1);
146
147    ls(fullpath);
148    free(fullpath);
149
150    return 0;
151}
152
153int osShellCmdCd(int argc, const char **argv)
154{
155    if (argc == 0) {
156        (void)osShellCmdDoChdir("/");
157        return 0;
158    }
159
160    (void)osShellCmdDoChdir(argv[0]);
161
162    return 0;
163}
164
165#define CAT_BUF_SIZE  512
166#define CAT_TASK_PRIORITY  10
167#define CAT_TASK_STACK_SIZE  0x3000
168pthread_mutex_t g_mutex_cat = PTHREAD_MUTEX_INITIALIZER;
169
170int osShellCmdDoCatShow(UINTPTR arg)
171{
172    int ret = 0;
173    char buf[CAT_BUF_SIZE];
174    size_t size, written, toWrite;
175    ssize_t cnt;
176    char *fullpath = (char *)arg;
177    FILE *ini = NULL;
178
179    (void)pthread_mutex_lock(&g_mutex_cat);
180    ini = fopen(fullpath, "r");
181    if (ini == NULL) {
182        ret = -1;
183        perror("cat error");
184        goto out;
185    }
186
187    do {
188        (void)memset_s(buf, sizeof(buf), 0, CAT_BUF_SIZE);
189        size = fread(buf, 1, CAT_BUF_SIZE, ini);
190        if ((int)size < 0) {
191            ret = -1;
192            perror("cat error");
193            goto out_with_fclose;
194        }
195
196        for (toWrite = size, written = 0; toWrite > 0;) {
197            cnt = write(1, buf + written, toWrite);
198            if (cnt == 0) {
199                /* avoid task-starvation */
200                (void)LOS_TaskDelay(1);
201                continue;
202            } else if (cnt < 0) {
203                perror("cat write error");
204                break;
205            }
206
207            written += cnt;
208            toWrite -= cnt;
209        }
210    }
211    while (size > 0);
212
213out_with_fclose:
214    (void)fclose(ini);
215out:
216    free(fullpath);
217    (void)pthread_mutex_unlock(&g_mutex_cat);
218    return ret;
219}
220
221int osShellCmdCat(int argc, const char **argv)
222{
223    char *fullpath = NULL;
224    int ret;
225    unsigned int ca_task;
226    struct Vnode *vnode = NULL;
227    TSK_INIT_PARAM_S init_param;
228    char *shell_working_directory = OsShellGetWorkingDirectory();
229    if (shell_working_directory == NULL) {
230        return -1;
231    }
232
233    ERROR_OUT_IF(argc != 1, PRINTK("cat [FILE]\n"), return -1);
234
235    ret = vfs_normalize_path(shell_working_directory, argv[0], &fullpath);
236    ERROR_OUT_IF(ret < 0, set_err(-ret, "cat error"), return -1);
237
238    VnodeHold();
239    ret = VnodeLookup(fullpath, &vnode, O_RDONLY);
240    if (ret != LOS_OK) {
241        set_errno(-ret);
242        perror("cat error");
243        VnodeDrop();
244        free(fullpath);
245        return -1;
246    }
247    if (vnode->type != VNODE_TYPE_REG) {
248        set_errno(EINVAL);
249        perror("cat error");
250        VnodeDrop();
251        free(fullpath);
252        return -1;
253    }
254    VnodeDrop();
255    (void)memset_s(&init_param, sizeof(init_param), 0, sizeof(TSK_INIT_PARAM_S));
256    init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)osShellCmdDoCatShow;
257    init_param.usTaskPrio   = CAT_TASK_PRIORITY;
258    init_param.auwArgs[0]   = (UINTPTR)fullpath;
259    init_param.uwStackSize  = CAT_TASK_STACK_SIZE;
260    init_param.pcName       = "shellcmd_cat";
261    init_param.uwResved     = LOS_TASK_STATUS_DETACHED | OS_TASK_FLAG_SPECIFIES_PROCESS;
262
263    ret = (int)LOS_TaskCreate(&ca_task, &init_param);
264    if (ret != LOS_OK) {
265        free(fullpath);
266    }
267
268    return ret;
269}
270
271static int nfs_mount_ref(const char *server_ip_and_path, const char *mount_path,
272                         unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount")));
273
274static unsigned long get_mountflags(const char *options)
275{
276    unsigned long mountfalgs = 0;
277    char *p;
278    while ((options != NULL) && (p = strsep((char**)&options, ",")) != NULL) {
279        if (strncmp(p, "ro", strlen("ro")) == 0) {
280            mountfalgs |= MS_RDONLY;
281        } else if (strncmp(p, "rw", strlen("rw")) == 0) {
282            mountfalgs &= ~MS_RDONLY;
283        } else if (strncmp(p, "nosuid", strlen("nosuid")) == 0) {
284            mountfalgs |= MS_NOSUID;
285        } else if (strncmp(p, "suid", strlen("suid")) == 0) {
286            mountfalgs &= ~MS_NOSUID;
287        } else {
288            continue;
289        }
290    }
291
292    return mountfalgs;
293}
294static inline void print_mount_usage(void)
295{
296    PRINTK("mount [DEVICE] [PATH] [NAME]\n");
297}
298
299int osShellCmdMount(int argc, const char **argv)
300{
301    int ret;
302    char *fullpath = NULL;
303    const char *filename = NULL;
304    unsigned int gid, uid;
305    char *data = NULL;
306    char *filessystemtype = NULL;
307    unsigned long mountfalgs;
308    char *shell_working_directory = OsShellGetWorkingDirectory();
309    if (shell_working_directory == NULL) {
310        return -1;
311    }
312
313    ERROR_OUT_IF(argc < 3, print_mount_usage(), return OS_FAIL);
314
315    if (strncmp(argv[0], "-t", 2) == 0 || strncmp(argv[0], "-o", 2) == 0) // 2: length of "-t"
316    {
317        if (argc < 4) { // 4: required number of parameters
318            PRINTK("mount -t/-o [DEVICE] [PATH] [NAME]\n");
319            return -1;
320        }
321
322        filename = argv[2]; // 2: index of file path
323        ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
324        ERROR_OUT_IF(ret < 0, set_err(-ret, "mount error"), return -1);
325
326        if (strncmp(argv[3], "nfs", 3) == 0) { // 3: index of fs type
327            if (argc <= 6) { // 6: arguments include uid or gid
328                uid = ((argc >= 5) && (argv[4] != NULL)) ? (unsigned int)strtoul(argv[4], (char **)NULL, 0) : 0;
329                gid = ((argc == 6) && (argv[5] != NULL)) ? (unsigned int)strtoul(argv[5], (char **)NULL, 0) : 0;
330
331                if (nfs_mount_ref != NULL) {
332                    ret = nfs_mount_ref(argv[1], fullpath, uid, gid);
333                    if (ret != LOS_OK) {
334                        PRINTK("mount -t [DEVICE] [PATH] [NAME]\n");
335                    }
336                } else {
337                    PRINTK("can't find nfs_mount\n");
338                }
339                free(fullpath);
340                return 0;
341            }
342        }
343
344        filessystemtype = (argc >= 4) ? (char *)argv[3] : NULL; /* 4: specify fs type, 3: fs type */
345        mountfalgs = (argc >= 5) ? get_mountflags((const char *)argv[4]) : 0; /* 4: usr option */
346        data = (argc >= 6) ? (char *)argv[5] : NULL; /* 5: usr option data, 6: six args needed for data */
347
348        if (strcmp(argv[1], "0") == 0) {
349            ret = mount((const char *)NULL, fullpath, filessystemtype, mountfalgs, data);
350        } else {
351            ret = mount(argv[1], fullpath, filessystemtype, mountfalgs, data); /* 3: fs type */
352        }
353        if (ret != LOS_OK) {
354            perror("mount error");
355        } else {
356            PRINTK("mount ok\n");
357        }
358    } else {
359        filename = argv[1];
360        ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
361        ERROR_OUT_IF(ret < 0, set_err(-ret, "mount error"), return -1);
362
363        if (strncmp(argv[2], "nfs", 3) == 0) { // 2: index of fs type, 3: length of "nfs"
364            if (argc <= 5) { // 5: arguments include gid and uid
365                uid = ((argc >= 4) && (argv[3] != NULL)) ? (unsigned int)strtoul(argv[3], (char **)NULL, 0) : 0;
366                gid = ((argc == 5) && (argv[4] != NULL)) ? (unsigned int)strtoul(argv[4], (char **)NULL, 0) : 0;
367
368                if (nfs_mount_ref != NULL) {
369                    ret = nfs_mount_ref(argv[0], fullpath, uid, gid);
370                    if (ret != LOS_OK) {
371                        PRINTK("mount [DEVICE] [PATH] [NAME]\n");
372                    }
373                } else {
374                    PRINTK("can't find nfs_mount\n");
375                }
376                free(fullpath);
377                return 0;
378            }
379
380            print_mount_usage();
381            free(fullpath);
382            return 0;
383        }
384
385        mountfalgs = (argc >= 4) ? get_mountflags((const char *)argv[3]) : 0;  /* 3: usr option */
386        data = (argc >= 5) ? (char *)argv[4] : NULL; /* 4: usr option data, 5: number of args needed for data */
387
388        if (strcmp(argv[0], "0") == 0) {
389            ret = mount((const char *)NULL, fullpath, argv[2], mountfalgs, data);
390        } else {
391            ret = mount(argv[0], fullpath, argv[2], mountfalgs, data);  /* 2: fs type */
392        }
393        if (ret != LOS_OK) {
394            perror("mount error");
395        } else {
396            PRINTK("mount ok\n");
397        }
398    }
399
400    free(fullpath);
401    return 0;
402}
403
404int osShellCmdUmount(int argc, const char **argv)
405{
406    int ret;
407    const char *filename = NULL;
408    char *fullpath = NULL;
409    char *target_path = NULL;
410    int cmp_num;
411    char *work_path = NULL;
412    char *shell_working_directory = OsShellGetWorkingDirectory();
413    if (shell_working_directory == NULL) {
414        return -1;
415    }
416    work_path = shell_working_directory;
417
418    ERROR_OUT_IF(argc == 0, PRINTK("umount [PATH]\n"), return 0);
419
420    filename = argv[0];
421    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
422    ERROR_OUT_IF(ret < 0, set_err(-ret, "umount error"), return -1);
423
424    target_path = fullpath;
425    cmp_num = strlen(fullpath);
426    ret = strncmp(work_path, target_path, cmp_num);
427    if (ret == 0) {
428        work_path += cmp_num;
429        if (*work_path == '/' || *work_path == '\0') {
430            set_errno(EBUSY);
431            perror("umount error");
432            free(fullpath);
433            return -1;
434        }
435    }
436
437    ret = umount(fullpath);
438    free(fullpath);
439    if (ret != LOS_OK) {
440        perror("umount error");
441        return 0;
442    }
443
444    PRINTK("umount ok\n");
445    return 0;
446}
447
448int osShellCmdMkdir(int argc, const char **argv)
449{
450    int ret;
451    char *fullpath = NULL;
452    const char *filename = NULL;
453    char *shell_working_directory = OsShellGetWorkingDirectory();
454    if (shell_working_directory == NULL) {
455        return -1;
456    }
457
458    ERROR_OUT_IF(argc != 1, PRINTK("mkdir [DIRECTORY]\n"), return 0);
459
460    filename = argv[0];
461    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
462    ERROR_OUT_IF(ret < 0, set_err(-ret, "mkdir error"), return -1);
463
464    ret = mkdir(fullpath, S_IRWXU | S_IRWXG | S_IRWXO);
465    if (ret == -1) {
466        perror("mkdir error");
467    }
468    free(fullpath);
469    return 0;
470}
471
472int osShellCmdPwd(int argc, const char **argv)
473{
474    char buf[SHOW_MAX_LEN] = {0};
475    DIR *dir = NULL;
476    char *shell_working_directory = OsShellGetWorkingDirectory();
477    if (shell_working_directory == NULL) {
478        return -1;
479    }
480
481    ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: pwd\n"), return -1);
482
483    dir = opendir(shell_working_directory);
484    if (dir == NULL) {
485        perror("pwd error");
486        return -1;
487    }
488
489    LOS_TaskLock();
490    if (strncpy_s(buf, SHOW_MAX_LEN, shell_working_directory, SHOW_MAX_LEN - 1) != EOK) {
491        LOS_TaskUnlock();
492        PRINTK("pwd error: strncpy_s error!\n");
493        (void)closedir(dir);
494        return -1;
495    }
496    LOS_TaskUnlock();
497
498    PRINTK("%s\n", buf);
499    (void)closedir(dir);
500    return 0;
501}
502
503static inline void print_statfs_usage(void)
504{
505    PRINTK("Usage  :\n");
506    PRINTK("    statfs <path>\n");
507    PRINTK("    path  : Mounted file system path that requires query information\n");
508    PRINTK("Example:\n");
509    PRINTK("    statfs /ramfs\n");
510}
511
512int osShellCmdStatfs(int argc, const char **argv)
513{
514    struct statfs sfs;
515    int result;
516    unsigned long long total_size, free_size;
517    char *fullpath = NULL;
518    const char *filename = NULL;
519    char *shell_working_directory = OsShellGetWorkingDirectory();
520    if (shell_working_directory == NULL) {
521        return -1;
522    }
523
524    ERROR_OUT_IF(argc != 1, PRINTK("statfs failed! Invalid argument!\n"), return -1);
525
526    (void)memset_s(&sfs, sizeof(sfs), 0, sizeof(sfs));
527
528    filename = argv[0];
529    result = vfs_normalize_path(shell_working_directory, filename, &fullpath);
530    ERROR_OUT_IF(result < 0, set_err(-result, "statfs error"), return -1);
531
532    result = statfs(fullpath, &sfs);
533    free(fullpath);
534
535    if (result != 0 || sfs.f_type == 0) {
536        PRINTK("statfs failed! Invalid argument!\n");
537        print_statfs_usage();
538        return -1;
539    }
540
541    total_size  = (unsigned long long)sfs.f_bsize * sfs.f_blocks;
542    free_size   = (unsigned long long)sfs.f_bsize * sfs.f_bfree;
543
544    PRINTK("statfs got:\n f_type     = %d\n cluster_size   = %d\n", sfs.f_type, sfs.f_bsize);
545    PRINTK(" total_clusters = %llu\n free_clusters  = %llu\n", sfs.f_blocks, sfs.f_bfree);
546    PRINTK(" avail_clusters = %llu\n f_namelen    = %d\n", sfs.f_bavail, sfs.f_namelen);
547    PRINTK("\n%s\n total size: %4llu Bytes\n free  size: %4llu Bytes\n", argv[0], total_size, free_size);
548
549    return 0;
550}
551
552int osShellCmdTouch(int argc, const char **argv)
553{
554    int ret;
555    int fd = -1;
556    char *fullpath = NULL;
557    const char *filename = NULL;
558    char *shell_working_directory = OsShellGetWorkingDirectory();
559    if (shell_working_directory == NULL) {
560        return -1;
561    }
562
563    ERROR_OUT_IF(argc != 1, PRINTK("touch [FILE]\n"), return -1);
564
565    filename = argv[0];
566    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
567    ERROR_OUT_IF(ret < 0, set_err(-ret, "touch error"), return -1);
568
569    fd = open(fullpath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
570    free(fullpath);
571    if (fd == -1) {
572        perror("touch error");
573        return -1;
574    }
575
576    (void)close(fd);
577    return 0;
578}
579
580#define CP_BUF_SIZE 4096
581pthread_mutex_t g_mutex_cp = PTHREAD_MUTEX_INITIALIZER;
582
583static int os_shell_cmd_do_cp(const char *src_filepath, const char *dst_filename)
584{
585    int  ret;
586    char *src_fullpath = NULL;
587    char *dst_fullpath = NULL;
588    const char *src_filename = NULL;
589    char *dst_filepath = NULL;
590    char *buf = NULL;
591    const char *filename = NULL;
592    ssize_t r_size, w_size;
593    int src_fd = -1;
594    int dst_fd = -1;
595    struct stat stat_buf;
596    mode_t src_mode;
597    char *shell_working_directory = OsShellGetWorkingDirectory();
598    if (shell_working_directory == NULL) {
599        return -1;
600    }
601
602    buf = (char *)malloc(CP_BUF_SIZE);
603    if (buf == NULL) {
604        PRINTK("cp error: Out of memory!\n");
605        return -1;
606    }
607
608    /* Get source fullpath. */
609
610    ret = vfs_normalize_path(shell_working_directory, src_filepath, &src_fullpath);
611    if (ret < 0) {
612        set_errno(-ret);
613        PRINTK("cp error: %s\n", strerror(errno));
614        free(buf);
615        return -1;
616    }
617
618    /* Is source path exist? */
619
620    ret = stat(src_fullpath, &stat_buf);
621    if (ret == -1) {
622        PRINTK("cp %s error: %s\n", src_fullpath, strerror(errno));
623        goto errout_with_srcpath;
624    }
625    src_mode = stat_buf.st_mode;
626    /* Is source path a directory? */
627
628    if (S_ISDIR(stat_buf.st_mode)) {
629        PRINTK("cp %s error: Source file can't be a directory.\n", src_fullpath);
630        goto errout_with_srcpath;
631    }
632
633    /* Get dest fullpath. */
634
635    dst_fullpath = strdup(dst_filename);
636    if (dst_fullpath == NULL) {
637        PRINTK("cp error: Out of memory.\n");
638        goto errout_with_srcpath;
639    }
640
641    /* Is dest path exist? */
642
643    ret = stat(dst_fullpath, &stat_buf);
644    if (ret == 0) {
645        /* Is dest path a directory? */
646
647        if (S_ISDIR(stat_buf.st_mode)) {
648            /* Get source file name without '/'. */
649
650            src_filename = src_filepath;
651            while (1) {
652                filename = strchr(src_filename, '/');
653                if (filename == NULL) {
654                    break;
655                }
656                src_filename = filename + 1;
657            }
658
659            /* Add the source file after dest path. */
660
661            ret = vfs_normalize_path(dst_fullpath, src_filename, &dst_filepath);
662            if (ret < 0) {
663                set_errno(-ret);
664                PRINTK("cp error. %s.\n", strerror(errno));
665                goto errout_with_path;
666            }
667            free(dst_fullpath);
668            dst_fullpath = dst_filepath;
669        }
670    }
671
672    /* Is dest file same as source file? */
673
674    if (strcmp(src_fullpath, dst_fullpath) == 0) {
675        PRINTK("cp error: '%s' and '%s' are the same file\n", src_fullpath, dst_fullpath);
676        goto errout_with_path;
677    }
678
679    /* Copy begins. */
680
681    (void)pthread_mutex_lock(&g_mutex_cp);
682    src_fd = open(src_fullpath, O_RDONLY);
683    if (src_fd < 0) {
684        PRINTK("cp error: can't open %s. %s.\n", src_fullpath, strerror(errno));
685        goto errout_with_mutex;
686    }
687
688    dst_fd = open(dst_fullpath, O_CREAT | O_WRONLY | O_TRUNC, src_mode);
689    if (dst_fd < 0) {
690        PRINTK("cp error: can't create %s. %s.\n", dst_fullpath, strerror(errno));
691        goto errout_with_srcfd;
692    }
693
694    do {
695        (void)memset_s(buf, CP_BUF_SIZE, 0, CP_BUF_SIZE);
696        r_size = read(src_fd, buf, CP_BUF_SIZE);
697        if (r_size < 0) {
698            PRINTK("cp %s %s failed. %s.\n", src_fullpath, dst_fullpath, strerror(errno));
699            goto errout_with_fd;
700        }
701        w_size = write(dst_fd, buf, r_size);
702        if (w_size != r_size) {
703            PRINTK("cp %s %s failed. %s.\n", src_fullpath, dst_fullpath, strerror(errno));
704            goto errout_with_fd;
705        }
706    } while (r_size == CP_BUF_SIZE);
707
708    /* Release resource. */
709
710    free(buf);
711    free(src_fullpath);
712    free(dst_fullpath);
713    (void)close(src_fd);
714    (void)close(dst_fd);
715    (void)pthread_mutex_unlock(&g_mutex_cp);
716    return LOS_OK;
717
718errout_with_fd:
719    (void)close(dst_fd);
720errout_with_srcfd:
721    (void)close(src_fd);
722errout_with_mutex:
723    (void)pthread_mutex_unlock(&g_mutex_cp);
724errout_with_path:
725    free(dst_fullpath);
726errout_with_srcpath:
727    free(src_fullpath);
728    free(buf);
729    return -1;
730}
731
732/* The separator and EOF for a directory fullpath: '/'and '\0' */
733
734#define SEPARATOR_EOF_LEN 2
735
736static int os_shell_cmd_do_rmdir(const char *pathname)
737{
738    struct dirent *dirent = NULL;
739    struct stat stat_info;
740    DIR *d = NULL;
741    char *fullpath = NULL;
742    int ret;
743
744    (void)memset_s(&stat_info, sizeof(stat_info), 0, sizeof(struct stat));
745    if (stat(pathname, &stat_info) != 0) {
746        return -1;
747    }
748
749    if (S_ISREG(stat_info.st_mode) || S_ISLNK(stat_info.st_mode)) {
750        return remove(pathname);
751    }
752    d = opendir(pathname);
753    if (d == NULL) {
754        return -1;
755    }
756    while (1) {
757        dirent = readdir(d);
758        if (dirent == NULL) {
759            break;
760        }
761        if (strcmp(dirent->d_name, "..") && strcmp(dirent->d_name, ".")) {
762            size_t fullpath_buf_size = strlen(pathname) + strlen(dirent->d_name) + SEPARATOR_EOF_LEN;
763            fullpath = (char *)malloc(fullpath_buf_size);
764            if (fullpath == NULL) {
765                PRINTK("malloc failure!\n");
766                (void)closedir(d);
767                return -1;
768            }
769            ret = snprintf_s(fullpath, fullpath_buf_size, fullpath_buf_size - 1, "%s/%s", pathname, dirent->d_name);
770            if (ret < 0) {
771                PRINTK("name is too long!\n");
772                free(fullpath);
773                (void)closedir(d);
774                return -1;
775            }
776            (void)os_shell_cmd_do_rmdir(fullpath);
777            free(fullpath);
778        }
779    }
780    (void)closedir(d);
781    return rmdir(pathname);
782}
783
784/*  Wildcard matching operations  */
785
786static int os_wildcard_match(const char *src, const char *filename)
787{
788    int ret;
789
790    if (*src != '\0') {
791        if (*filename == '*') {
792            while ((*filename == '*') || (*filename == '?')) {
793                filename++;
794            }
795
796            if (*filename == '\0') {
797                return 0;
798            }
799
800            while (*src != '\0' && !(*src == *filename)) {
801                src++;
802            }
803
804            if (*src == '\0') {
805                return -1;
806            }
807
808            ret = os_wildcard_match(src, filename);
809
810            while ((ret != 0) && (*(++src) != '\0')) {
811                if (*src == *filename) {
812                    ret = os_wildcard_match(src, filename);
813                }
814            }
815            return ret;
816        } else {
817            if ((*src == *filename) || (*filename == '?')) {
818                return os_wildcard_match(++src, ++filename);
819            }
820            return -1;
821        }
822    }
823
824    while (*filename != '\0') {
825        if (*filename != '*') {
826            return -1;
827        }
828        filename++;
829    }
830    return 0;
831}
832
833/*   To determine whether a wildcard character exists in a path   */
834
835static int os_is_containers_wildcard(const char *filename)
836{
837    while (*filename != '\0') {
838        if ((*filename == '*') || (*filename == '?')) {
839            return 1;
840        }
841        filename++;
842    }
843    return 0;
844}
845
846/*  Delete a matching file or directory  */
847
848static int os_wildcard_delete_file_or_dir(const char *fullpath, wildcard_type mark)
849{
850    int ret;
851
852    switch (mark) {
853        case RM_RECURSIVER:
854            ret = os_shell_cmd_do_rmdir(fullpath);
855            break;
856        case RM_FILE:
857            ret = unlink(fullpath);
858            break;
859        case RM_DIR:
860            ret = rmdir(fullpath);
861            break;
862        default:
863            return VFS_ERROR;
864    }
865    if (ret == -1) {
866        PRINTK("%s  ", fullpath);
867        perror("rm/rmdir error!");
868        return ret;
869    }
870
871    PRINTK("%s match successful!delete!\n", fullpath);
872    return 0;
873}
874
875/*  Split the path with wildcard characters  */
876
877static char* os_wildcard_split_path(char *fullpath, char **handle, char **wait)
878{
879    int n = 0;
880    int a = 0;
881    int b = 0;
882    int len  = strlen(fullpath);
883
884    for (n = 0; n < len; n++) {
885        if (fullpath[n] == '/') {
886            if (b != 0) {
887                fullpath[n] = '\0';
888                *wait = fullpath + n + 1;
889                break;
890            }
891            a = n;
892        } else if (fullpath[n] == '*' || fullpath[n] == '?') {
893            b = n;
894            fullpath[a] = '\0';
895            if (a == 0) {
896                *handle = fullpath + a + 1;
897                continue;
898            }
899            *handle = fullpath + a + 1;
900        }
901    }
902    return fullpath;
903}
904
905/*  Handling entry of the path with wildcard characters  */
906
907static int os_wildcard_extract_directory(char *fullpath, void *dst, wildcard_type mark)
908{
909    char separator[] = "/";
910    char src[PATH_MAX] = {0};
911    struct dirent *dirent = NULL;
912    char *f = NULL;
913    char *s = NULL;
914    char *t = NULL;
915    int ret = 0;
916    DIR *d = NULL;
917    struct stat stat_buf;
918    int deleteFlag = 0;
919
920    f = os_wildcard_split_path(fullpath, &s, &t);
921
922    if (s == NULL) {
923        if (mark == CP_FILE) {
924            ret = os_shell_cmd_do_cp(fullpath, dst);
925        } else if (mark == CP_COUNT) {
926            ret = stat(fullpath, &stat_buf);
927            if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))) {
928                (*(int *)dst)++;
929            }
930        } else {
931            ret = os_wildcard_delete_file_or_dir(fullpath, mark);
932        }
933        return ret;
934    }
935
936    d = (*f == '\0') ? opendir("/") : opendir(f);
937    if (d == NULL) {
938        perror("opendir error");
939        return VFS_ERROR;
940    }
941
942    while (1) {
943        dirent = readdir(d);
944        if (dirent == NULL) {
945            break;
946        }
947
948        ret = strcpy_s(src, PATH_MAX, f);
949        if (ret != EOK) {
950            goto closedir_out;
951        }
952
953        ret = os_wildcard_match(dirent->d_name, s);
954        if (ret == 0) {
955            ret = strcat_s(src, sizeof(src), separator);
956            if (ret != EOK) {
957                goto closedir_out;
958            }
959            ret = strcat_s(src, sizeof(src), dirent->d_name);
960            if (ret != EOK) {
961                goto closedir_out;
962            }
963            if (t == NULL) {
964                if (mark == CP_FILE) {
965                    ret = os_shell_cmd_do_cp(src, dst);
966                } else if (mark == CP_COUNT) {
967                    ret = stat(src, &stat_buf);
968                    if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))) {
969                        (*(int *)dst)++;
970                        if ((*(int *)dst) > 1) {
971                            break;
972                        }
973                    }
974                } else {
975                    ret = os_wildcard_delete_file_or_dir(src, mark);
976                    if (ret == 0) {
977                        deleteFlag = 1;
978                    }
979                }
980            } else {
981                ret = strcat_s(src, sizeof(src), separator);
982                if (ret != EOK) {
983                    goto closedir_out;
984                }
985                ret = strcat_s(src, sizeof(src), t);
986                if (ret != EOK) {
987                    goto closedir_out;
988                }
989                ret = os_wildcard_extract_directory(src, dst, mark);
990                if (mark == CP_COUNT && (*(int *)dst) > 1) {
991                    break;
992                }
993            }
994        }
995    }
996    (void)closedir(d);
997    if (deleteFlag == 1) {
998        ret = 0;
999    }
1000    return ret;
1001closedir_out:
1002    (void)closedir(d);
1003    return VFS_ERROR;
1004}
1005
1006int osShellCmdCp(int argc, const char **argv)
1007{
1008    int  ret;
1009    const char *src = NULL;
1010    const char *dst = NULL;
1011    char *src_fullpath = NULL;
1012    char *dst_fullpath = NULL;
1013    struct stat stat_buf;
1014    int count = 0;
1015    char *shell_working_directory = OsShellGetWorkingDirectory();
1016    if (shell_working_directory == NULL) {
1017        return -1;
1018    }
1019
1020    ERROR_OUT_IF(argc < 2, PRINTK("cp [SOURCEFILE] [DESTFILE]\n"), return -1);
1021
1022    src = argv[0];
1023    dst = argv[1];
1024
1025    /* Get source fullpath. */
1026
1027    ret = vfs_normalize_path(shell_working_directory, src, &src_fullpath);
1028    if (ret < 0) {
1029        set_errno(-ret);
1030        PRINTK("cp error:%s\n", strerror(errno));
1031        return -1;
1032    }
1033
1034    if (src[strlen(src) - 1] == '/') {
1035        PRINTK("cp %s error: Source file can't be a directory.\n", src);
1036        goto errout_with_srcpath;
1037    }
1038
1039    /* Get dest fullpath. */
1040
1041    ret = vfs_normalize_path(shell_working_directory, dst, &dst_fullpath);
1042    if (ret < 0) {
1043        set_errno(-ret);
1044        PRINTK("cp error: can't open %s. %s\n", dst, strerror(errno));
1045        goto errout_with_srcpath;
1046    }
1047
1048    /* Is dest path exist? */
1049
1050    ret = stat(dst_fullpath, &stat_buf);
1051    if (ret < 0) {
1052        /* Is dest path a directory? */
1053
1054        if (dst[strlen(dst) - 1] == '/') {
1055            PRINTK("cp error: %s, %s.\n", dst_fullpath, strerror(errno));
1056            goto errout_with_path;
1057        }
1058    } else {
1059        if ((S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)) && dst[strlen(dst) - 1] == '/') {
1060            PRINTK("cp error: %s is not a directory.\n", dst_fullpath);
1061            goto errout_with_path;
1062        }
1063    }
1064
1065    if (os_is_containers_wildcard(src_fullpath)) {
1066        if (ret < 0 || S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)) {
1067            char *src_copy = strdup(src_fullpath);
1068            if (src_copy == NULL) {
1069                PRINTK("cp error : Out of memory.\n");
1070                goto errout_with_path;
1071            }
1072            (void)os_wildcard_extract_directory(src_copy, &count, CP_COUNT);
1073            free(src_copy);
1074            if (count > 1) {
1075                PRINTK("cp error : %s is not a directory.\n", dst_fullpath);
1076                goto errout_with_path;
1077            }
1078        }
1079        ret = os_wildcard_extract_directory(src_fullpath, dst_fullpath, CP_FILE);
1080    } else {
1081        ret = os_shell_cmd_do_cp(src_fullpath, dst_fullpath);
1082    }
1083    free(dst_fullpath);
1084    free(src_fullpath);
1085    return ret;
1086
1087errout_with_path:
1088    free(dst_fullpath);
1089errout_with_srcpath:
1090    free(src_fullpath);
1091    return VFS_ERROR;
1092}
1093
1094static inline void print_rm_usage(void)
1095{
1096    PRINTK("rm [FILE] or rm [-r/-R] [FILE]\n");
1097}
1098
1099int osShellCmdRm(int argc, const char **argv)
1100{
1101    int  ret = 0;
1102    char *fullpath = NULL;
1103    const char *filename = NULL;
1104    char *shell_working_directory = OsShellGetWorkingDirectory();
1105    if (shell_working_directory == NULL) {
1106        return -1;
1107    }
1108
1109    ERROR_OUT_IF(argc != 1 && argc != 2, print_rm_usage(), return -1);
1110
1111    if (argc == 2) { // 2: arguments include "-r" or "-R"
1112        ERROR_OUT_IF(strcmp(argv[0], "-r") != 0 && strcmp(argv[0], "-R") != 0, print_rm_usage(), return -1);
1113
1114        filename = argv[1];
1115        ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1116        ERROR_OUT_IF(ret < 0, set_err(-ret, "rm error"), return -1);
1117
1118        if (os_is_containers_wildcard(fullpath)) {
1119            ret = os_wildcard_extract_directory(fullpath, NULL, RM_RECURSIVER);
1120        } else {
1121            ret = os_shell_cmd_do_rmdir(fullpath);
1122        }
1123    } else {
1124        filename = argv[0];
1125        ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1126        ERROR_OUT_IF(ret < 0, set_err(-ret, "rm error"), return -1);
1127
1128        if (os_is_containers_wildcard(fullpath)) {
1129            ret = os_wildcard_extract_directory(fullpath, NULL, RM_FILE);
1130        } else {
1131            ret = unlink(fullpath);
1132        }
1133    }
1134    if (ret == -1) {
1135        perror("rm error");
1136    }
1137    free(fullpath);
1138    return 0;
1139}
1140
1141int osShellCmdRmdir(int argc, const char **argv)
1142{
1143    int  ret;
1144    char *fullpath = NULL;
1145    const char *filename = NULL;
1146    char *shell_working_directory = OsShellGetWorkingDirectory();
1147    if (shell_working_directory == NULL) {
1148        return -1;
1149    }
1150
1151    ERROR_OUT_IF(argc == 0, PRINTK("rmdir [DIRECTORY]\n"), return -1);
1152
1153    filename = argv[0];
1154    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1155    ERROR_OUT_IF(ret < 0, set_err(-ret, "rmdir error"), return -1);
1156
1157    if (os_is_containers_wildcard(fullpath)) {
1158        ret = os_wildcard_extract_directory(fullpath, NULL, RM_DIR);
1159    } else {
1160        ret = rmdir(fullpath);
1161    }
1162    if (ret == -1) {
1163        PRINTK("rmdir %s failed. Error: %s.\n", fullpath, strerror(errno));
1164    }
1165    free(fullpath);
1166
1167    return 0;
1168}
1169
1170int osShellCmdSync(int argc, const char **argv)
1171{
1172    ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: sync\n"), return -1);
1173
1174    sync();
1175    return 0;
1176}
1177
1178int osShellCmdLsfd(int argc, const char **argv)
1179{
1180    ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: lsfd\n"), return -1);
1181
1182    lsfd();
1183
1184    return 0;
1185}
1186
1187int checkNum(const char *arg)
1188{
1189    int i = 0;
1190    if (arg == NULL) {
1191        return -1;
1192    }
1193    if (arg[0] == '-') {
1194        /* exclude the '-' */
1195
1196        i = 1;
1197    }
1198    for (; arg[i] != 0; i++) {
1199        if (!isdigit(arg[i])) {
1200            return -1;
1201        }
1202    }
1203    return 0;
1204}
1205
1206#ifdef LOSCFG_KERNEL_SYSCALL
1207int osShellCmdSu(int argc, const char **argv)
1208{
1209    int su_uid;
1210    int su_gid;
1211
1212    if (argc == 0) {
1213        /* for su root */
1214
1215        su_uid = 0;
1216        su_gid = 0;
1217    } else {
1218        ERROR_OUT_IF((argc != 2), PRINTK("su [uid_num] [gid_num]\n"), return -1);
1219        ERROR_OUT_IF((checkNum(argv[0]) != 0) || (checkNum(argv[1]) != 0), /* check argv is digit */
1220        PRINTK("check uid_num and gid_num is digit\n"), return -1);
1221
1222        su_uid = atoi(argv[0]);
1223        su_gid = atoi(argv[1]);
1224
1225        ERROR_OUT_IF((su_uid < 0) || (su_uid > 60000) || (su_gid < 0) ||
1226            (su_gid > 60000), PRINTK("uid_num or gid_num out of range!they should be [0~60000]\n"), return -1);
1227    }
1228
1229    SysSetUserID(su_uid);
1230    SysSetGroupID(su_gid);
1231    return 0;
1232}
1233#endif
1234
1235int osShellCmdChmod(int argc, const char **argv)
1236{
1237    int i = 0;
1238    int mode = 0;
1239    int ret;
1240    char *fullpath = NULL;
1241    const char *filename = NULL;
1242    struct IATTR attr = {0};
1243    char *shell_working_directory = NULL;
1244    const char *p = NULL;
1245#define MODE_BIT 3 /* 3 bits express 1 mode */
1246
1247    ERROR_OUT_IF((argc != 2), PRINTK("Usage: chmod <MODE> [FILE]\n"), return -1);
1248
1249    p = argv[0];
1250    while (p[i]) {
1251        if ((p[i] <= '7') && (p[i] >= '0')) {
1252            mode = ((uint)mode << MODE_BIT) | (uint)(p[i] - '0');
1253        } else {
1254            PRINTK("check the input <MODE>\n");
1255            return -1;
1256        }
1257        i++;
1258    }
1259    filename = argv[1];
1260
1261    shell_working_directory = OsShellGetWorkingDirectory();
1262    if (shell_working_directory == NULL) {
1263        return -1;
1264    }
1265    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1266    ERROR_OUT_IF(ret < 0, set_err(-ret, "chmod error\n"), return -1);
1267
1268    attr.attr_chg_mode = mode;
1269    attr.attr_chg_valid = CHG_MODE; /* change mode */
1270    ret = chattr(fullpath, &attr);
1271    if (ret < 0) {
1272        free(fullpath);
1273        PRINTK("chmod error! %s\n", strerror(errno));
1274        return ret;
1275    }
1276
1277    free(fullpath);
1278    return 0;
1279}
1280
1281int osShellCmdChown(int argc, const char **argv)
1282{
1283    int ret;
1284    char *fullpath = NULL;
1285    const char *filename = NULL;
1286    struct IATTR attr;
1287    uid_t owner = -1;
1288    gid_t group = -1;
1289    attr.attr_chg_valid = 0;
1290
1291    ERROR_OUT_IF(((argc != 2) && (argc != 3)), PRINTK("Usage: chown [OWNER] [GROUP] FILE\n"), return -1);
1292    if (argc == 2) { // 2: chown owner of file
1293        ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check OWNER is digit\n"), return -1);
1294        owner = atoi(argv[0]);
1295        filename = argv[1];
1296    }
1297    if (argc == 3) { // 3: chown both owner and group
1298        ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check OWNER is digit\n"), return -1);
1299        ERROR_OUT_IF((checkNum(argv[1]) != 0), PRINTK("check GROUP is digit\n"), return -1);
1300        owner = atoi(argv[0]);
1301        group = atoi(argv[1]);
1302        filename = argv[2];
1303    }
1304
1305    if (group != -1) {
1306        attr.attr_chg_gid = group;
1307        attr.attr_chg_valid |= CHG_GID;
1308    }
1309    if (owner != -1) {
1310        attr.attr_chg_uid = owner;
1311        attr.attr_chg_valid |= CHG_UID;
1312    }
1313
1314    char *shell_working_directory = OsShellGetWorkingDirectory();
1315    if (shell_working_directory == NULL) {
1316        return -1;
1317    }
1318    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1319    ERROR_OUT_IF(ret < 0, set_err(-ret, "chown error\n"), return -1);
1320
1321    ret = chattr(fullpath, &attr);
1322    if (ret < 0) {
1323        free(fullpath);
1324        PRINTK("chown error! %s\n", strerror(errno));
1325        return ret;
1326    }
1327
1328    free(fullpath);
1329    return 0;
1330}
1331
1332int osShellCmdChgrp(int argc, const char **argv)
1333{
1334    int ret;
1335    char *fullpath = NULL;
1336    const char *filename = NULL;
1337    struct IATTR attr;
1338    gid_t group;
1339    attr.attr_chg_valid = 0;
1340    ERROR_OUT_IF((argc != 2), PRINTK("Usage: chgrp GROUP FILE\n"), return -1);
1341    ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check GROUP is digit\n"), return -1);
1342    group = atoi(argv[0]);
1343    filename = argv[1];
1344
1345    if (group != -1) {
1346        attr.attr_chg_gid = group;
1347        attr.attr_chg_valid |= CHG_GID;
1348    }
1349
1350    char *shell_working_directory = OsShellGetWorkingDirectory();
1351    if (shell_working_directory == NULL) {
1352        return -1;
1353    }
1354    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1355    ERROR_OUT_IF(ret < 0, set_err(-ret, "chmod error"), return -1);
1356
1357    ret = chattr(fullpath, &attr);
1358    if (ret < 0) {
1359        free(fullpath);
1360        PRINTK("chgrp error! %s\n", strerror(errno));
1361        return ret;
1362    }
1363
1364    free(fullpath);
1365    return 0;
1366}
1367
1368#ifdef LOSCFG_SHELL_CMD_DEBUG
1369SHELLCMD_ENTRY(lsfd_shellcmd, CMD_TYPE_EX, "lsfd", XARGS, (CmdCallBackFunc)osShellCmdLsfd);
1370SHELLCMD_ENTRY(statfs_shellcmd, CMD_TYPE_EX, "statfs", XARGS, (CmdCallBackFunc)osShellCmdStatfs);
1371SHELLCMD_ENTRY(touch_shellcmd, CMD_TYPE_EX, "touch", XARGS, (CmdCallBackFunc)osShellCmdTouch);
1372#ifdef LOSCFG_KERNEL_SYSCALL
1373SHELLCMD_ENTRY(su_shellcmd, CMD_TYPE_EX, "su", XARGS, (CmdCallBackFunc)osShellCmdSu);
1374#endif
1375#endif
1376SHELLCMD_ENTRY(sync_shellcmd, CMD_TYPE_EX, "sync", XARGS, (CmdCallBackFunc)osShellCmdSync);
1377SHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CmdCallBackFunc)osShellCmdLs);
1378SHELLCMD_ENTRY(pwd_shellcmd, CMD_TYPE_EX, "pwd", XARGS, (CmdCallBackFunc)osShellCmdPwd);
1379SHELLCMD_ENTRY(cd_shellcmd, CMD_TYPE_EX, "cd", XARGS, (CmdCallBackFunc)osShellCmdCd);
1380SHELLCMD_ENTRY(cat_shellcmd, CMD_TYPE_EX, "cat", XARGS, (CmdCallBackFunc)osShellCmdCat);
1381SHELLCMD_ENTRY(rm_shellcmd, CMD_TYPE_EX, "rm", XARGS, (CmdCallBackFunc)osShellCmdRm);
1382SHELLCMD_ENTRY(rmdir_shellcmd, CMD_TYPE_EX, "rmdir", XARGS, (CmdCallBackFunc)osShellCmdRmdir);
1383SHELLCMD_ENTRY(mkdir_shellcmd, CMD_TYPE_EX, "mkdir", XARGS, (CmdCallBackFunc)osShellCmdMkdir);
1384SHELLCMD_ENTRY(chmod_shellcmd, CMD_TYPE_EX, "chmod", XARGS, (CmdCallBackFunc)osShellCmdChmod);
1385SHELLCMD_ENTRY(chown_shellcmd, CMD_TYPE_EX, "chown", XARGS, (CmdCallBackFunc)osShellCmdChown);
1386SHELLCMD_ENTRY(chgrp_shellcmd, CMD_TYPE_EX, "chgrp", XARGS, (CmdCallBackFunc)osShellCmdChgrp);
1387SHELLCMD_ENTRY(mount_shellcmd, CMD_TYPE_EX, "mount", XARGS, (CmdCallBackFunc)osShellCmdMount);
1388SHELLCMD_ENTRY(umount_shellcmd, CMD_TYPE_EX, "umount", XARGS, (CmdCallBackFunc)osShellCmdUmount);
1389SHELLCMD_ENTRY(cp_shellcmd, CMD_TYPE_EX, "cp", XARGS, (CmdCallBackFunc)osShellCmdCp);
1390#endif
1391