10d163575Sopenharmony_ci/*
20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
30d163575Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
40d163575Sopenharmony_ci *
50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
60d163575Sopenharmony_ci * are permitted provided that the following conditions are met:
70d163575Sopenharmony_ci *
80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
90d163575Sopenharmony_ci *    conditions and the following disclaimer.
100d163575Sopenharmony_ci *
110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
120d163575Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
130d163575Sopenharmony_ci *    provided with the distribution.
140d163575Sopenharmony_ci *
150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
160d163575Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
170d163575Sopenharmony_ci *    permission.
180d163575Sopenharmony_ci *
190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
300d163575Sopenharmony_ci */
310d163575Sopenharmony_ci
320d163575Sopenharmony_ci#include "los_config.h"
330d163575Sopenharmony_ci#include "sys/mount.h"
340d163575Sopenharmony_ci
350d163575Sopenharmony_ci#ifdef LOSCFG_SHELL
360d163575Sopenharmony_ci
370d163575Sopenharmony_ci#include "los_typedef.h"
380d163575Sopenharmony_ci#include "shell.h"
390d163575Sopenharmony_ci#include "sys/stat.h"
400d163575Sopenharmony_ci#include "stdlib.h"
410d163575Sopenharmony_ci#include "unistd.h"
420d163575Sopenharmony_ci#include "fcntl.h"
430d163575Sopenharmony_ci#include "sys/statfs.h"
440d163575Sopenharmony_ci#include "stdio.h"
450d163575Sopenharmony_ci#include "pthread.h"
460d163575Sopenharmony_ci
470d163575Sopenharmony_ci#include "shcmd.h"
480d163575Sopenharmony_ci#include "securec.h"
490d163575Sopenharmony_ci#include "show.h"
500d163575Sopenharmony_ci#include "los_syscall.h"
510d163575Sopenharmony_ci
520d163575Sopenharmony_ci#include "los_process_pri.h"
530d163575Sopenharmony_ci#include <ctype.h>
540d163575Sopenharmony_ci#include "fs/fs_operation.h"
550d163575Sopenharmony_ci
560d163575Sopenharmony_citypedef enum {
570d163575Sopenharmony_ci    RM_RECURSIVER,
580d163575Sopenharmony_ci    RM_FILE,
590d163575Sopenharmony_ci    RM_DIR,
600d163575Sopenharmony_ci    CP_FILE,
610d163575Sopenharmony_ci    CP_COUNT
620d163575Sopenharmony_ci} wildcard_type;
630d163575Sopenharmony_ci
640d163575Sopenharmony_ci#define ERROR_OUT_IF(condition, message_function, handler) \
650d163575Sopenharmony_ci    do { \
660d163575Sopenharmony_ci        if (condition) { \
670d163575Sopenharmony_ci            message_function; \
680d163575Sopenharmony_ci            handler; \
690d163575Sopenharmony_ci        } \
700d163575Sopenharmony_ci    } while (0)
710d163575Sopenharmony_ci
720d163575Sopenharmony_cistatic inline void set_err(int errcode, const char *err_message)
730d163575Sopenharmony_ci{
740d163575Sopenharmony_ci    set_errno(errcode);
750d163575Sopenharmony_ci    perror(err_message);
760d163575Sopenharmony_ci}
770d163575Sopenharmony_ci
780d163575Sopenharmony_ciint osShellCmdDoChdir(const char *path)
790d163575Sopenharmony_ci{
800d163575Sopenharmony_ci    char *fullpath = NULL;
810d163575Sopenharmony_ci    char *fullpath_bak = NULL;
820d163575Sopenharmony_ci    int ret;
830d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
840d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
850d163575Sopenharmony_ci        return -1;
860d163575Sopenharmony_ci    }
870d163575Sopenharmony_ci
880d163575Sopenharmony_ci    if (path == NULL) {
890d163575Sopenharmony_ci        LOS_TaskLock();
900d163575Sopenharmony_ci        PRINTK("%s\n", shell_working_directory);
910d163575Sopenharmony_ci        LOS_TaskUnlock();
920d163575Sopenharmony_ci
930d163575Sopenharmony_ci        return 0;
940d163575Sopenharmony_ci    }
950d163575Sopenharmony_ci
960d163575Sopenharmony_ci    ERROR_OUT_IF(strlen(path) > PATH_MAX, set_err(ENOTDIR, "cd error"), return -1);
970d163575Sopenharmony_ci
980d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, path, &fullpath);
990d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "cd error"), return -1);
1000d163575Sopenharmony_ci
1010d163575Sopenharmony_ci    fullpath_bak = fullpath;
1020d163575Sopenharmony_ci    ret = chdir(fullpath);
1030d163575Sopenharmony_ci    if (ret < 0) {
1040d163575Sopenharmony_ci        free(fullpath_bak);
1050d163575Sopenharmony_ci        perror("cd");
1060d163575Sopenharmony_ci        return -1;
1070d163575Sopenharmony_ci    }
1080d163575Sopenharmony_ci
1090d163575Sopenharmony_ci    /* copy full path to working directory */
1100d163575Sopenharmony_ci
1110d163575Sopenharmony_ci    LOS_TaskLock();
1120d163575Sopenharmony_ci    ret = strncpy_s(shell_working_directory, PATH_MAX, fullpath, strlen(fullpath));
1130d163575Sopenharmony_ci    if (ret != EOK) {
1140d163575Sopenharmony_ci        free(fullpath_bak);
1150d163575Sopenharmony_ci        LOS_TaskUnlock();
1160d163575Sopenharmony_ci        return -1;
1170d163575Sopenharmony_ci    }
1180d163575Sopenharmony_ci    LOS_TaskUnlock();
1190d163575Sopenharmony_ci    /* release normalize directory path name */
1200d163575Sopenharmony_ci
1210d163575Sopenharmony_ci    free(fullpath_bak);
1220d163575Sopenharmony_ci
1230d163575Sopenharmony_ci    return 0;
1240d163575Sopenharmony_ci}
1250d163575Sopenharmony_ci
1260d163575Sopenharmony_ciint osShellCmdLs(int argc, const char **argv)
1270d163575Sopenharmony_ci{
1280d163575Sopenharmony_ci    char *fullpath = NULL;
1290d163575Sopenharmony_ci    const char *filename = NULL;
1300d163575Sopenharmony_ci    int ret;
1310d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
1320d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
1330d163575Sopenharmony_ci        return -1;
1340d163575Sopenharmony_ci    }
1350d163575Sopenharmony_ci
1360d163575Sopenharmony_ci    ERROR_OUT_IF(argc > 1, PRINTK("ls or ls [DIRECTORY]\n"), return -1);
1370d163575Sopenharmony_ci
1380d163575Sopenharmony_ci    if (argc == 0) {
1390d163575Sopenharmony_ci        ls(shell_working_directory);
1400d163575Sopenharmony_ci        return 0;
1410d163575Sopenharmony_ci    }
1420d163575Sopenharmony_ci
1430d163575Sopenharmony_ci    filename = argv[0];
1440d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1450d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "ls error"), return -1);
1460d163575Sopenharmony_ci
1470d163575Sopenharmony_ci    ls(fullpath);
1480d163575Sopenharmony_ci    free(fullpath);
1490d163575Sopenharmony_ci
1500d163575Sopenharmony_ci    return 0;
1510d163575Sopenharmony_ci}
1520d163575Sopenharmony_ci
1530d163575Sopenharmony_ciint osShellCmdCd(int argc, const char **argv)
1540d163575Sopenharmony_ci{
1550d163575Sopenharmony_ci    if (argc == 0) {
1560d163575Sopenharmony_ci        (void)osShellCmdDoChdir("/");
1570d163575Sopenharmony_ci        return 0;
1580d163575Sopenharmony_ci    }
1590d163575Sopenharmony_ci
1600d163575Sopenharmony_ci    (void)osShellCmdDoChdir(argv[0]);
1610d163575Sopenharmony_ci
1620d163575Sopenharmony_ci    return 0;
1630d163575Sopenharmony_ci}
1640d163575Sopenharmony_ci
1650d163575Sopenharmony_ci#define CAT_BUF_SIZE  512
1660d163575Sopenharmony_ci#define CAT_TASK_PRIORITY  10
1670d163575Sopenharmony_ci#define CAT_TASK_STACK_SIZE  0x3000
1680d163575Sopenharmony_cipthread_mutex_t g_mutex_cat = PTHREAD_MUTEX_INITIALIZER;
1690d163575Sopenharmony_ci
1700d163575Sopenharmony_ciint osShellCmdDoCatShow(UINTPTR arg)
1710d163575Sopenharmony_ci{
1720d163575Sopenharmony_ci    int ret = 0;
1730d163575Sopenharmony_ci    char buf[CAT_BUF_SIZE];
1740d163575Sopenharmony_ci    size_t size, written, toWrite;
1750d163575Sopenharmony_ci    ssize_t cnt;
1760d163575Sopenharmony_ci    char *fullpath = (char *)arg;
1770d163575Sopenharmony_ci    FILE *ini = NULL;
1780d163575Sopenharmony_ci
1790d163575Sopenharmony_ci    (void)pthread_mutex_lock(&g_mutex_cat);
1800d163575Sopenharmony_ci    ini = fopen(fullpath, "r");
1810d163575Sopenharmony_ci    if (ini == NULL) {
1820d163575Sopenharmony_ci        ret = -1;
1830d163575Sopenharmony_ci        perror("cat error");
1840d163575Sopenharmony_ci        goto out;
1850d163575Sopenharmony_ci    }
1860d163575Sopenharmony_ci
1870d163575Sopenharmony_ci    do {
1880d163575Sopenharmony_ci        (void)memset_s(buf, sizeof(buf), 0, CAT_BUF_SIZE);
1890d163575Sopenharmony_ci        size = fread(buf, 1, CAT_BUF_SIZE, ini);
1900d163575Sopenharmony_ci        if ((int)size < 0) {
1910d163575Sopenharmony_ci            ret = -1;
1920d163575Sopenharmony_ci            perror("cat error");
1930d163575Sopenharmony_ci            goto out_with_fclose;
1940d163575Sopenharmony_ci        }
1950d163575Sopenharmony_ci
1960d163575Sopenharmony_ci        for (toWrite = size, written = 0; toWrite > 0;) {
1970d163575Sopenharmony_ci            cnt = write(1, buf + written, toWrite);
1980d163575Sopenharmony_ci            if (cnt == 0) {
1990d163575Sopenharmony_ci                /* avoid task-starvation */
2000d163575Sopenharmony_ci                (void)LOS_TaskDelay(1);
2010d163575Sopenharmony_ci                continue;
2020d163575Sopenharmony_ci            } else if (cnt < 0) {
2030d163575Sopenharmony_ci                perror("cat write error");
2040d163575Sopenharmony_ci                break;
2050d163575Sopenharmony_ci            }
2060d163575Sopenharmony_ci
2070d163575Sopenharmony_ci            written += cnt;
2080d163575Sopenharmony_ci            toWrite -= cnt;
2090d163575Sopenharmony_ci        }
2100d163575Sopenharmony_ci    }
2110d163575Sopenharmony_ci    while (size > 0);
2120d163575Sopenharmony_ci
2130d163575Sopenharmony_ciout_with_fclose:
2140d163575Sopenharmony_ci    (void)fclose(ini);
2150d163575Sopenharmony_ciout:
2160d163575Sopenharmony_ci    free(fullpath);
2170d163575Sopenharmony_ci    (void)pthread_mutex_unlock(&g_mutex_cat);
2180d163575Sopenharmony_ci    return ret;
2190d163575Sopenharmony_ci}
2200d163575Sopenharmony_ci
2210d163575Sopenharmony_ciint osShellCmdCat(int argc, const char **argv)
2220d163575Sopenharmony_ci{
2230d163575Sopenharmony_ci    char *fullpath = NULL;
2240d163575Sopenharmony_ci    int ret;
2250d163575Sopenharmony_ci    unsigned int ca_task;
2260d163575Sopenharmony_ci    struct Vnode *vnode = NULL;
2270d163575Sopenharmony_ci    TSK_INIT_PARAM_S init_param;
2280d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
2290d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
2300d163575Sopenharmony_ci        return -1;
2310d163575Sopenharmony_ci    }
2320d163575Sopenharmony_ci
2330d163575Sopenharmony_ci    ERROR_OUT_IF(argc != 1, PRINTK("cat [FILE]\n"), return -1);
2340d163575Sopenharmony_ci
2350d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, argv[0], &fullpath);
2360d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "cat error"), return -1);
2370d163575Sopenharmony_ci
2380d163575Sopenharmony_ci    VnodeHold();
2390d163575Sopenharmony_ci    ret = VnodeLookup(fullpath, &vnode, O_RDONLY);
2400d163575Sopenharmony_ci    if (ret != LOS_OK) {
2410d163575Sopenharmony_ci        set_errno(-ret);
2420d163575Sopenharmony_ci        perror("cat error");
2430d163575Sopenharmony_ci        VnodeDrop();
2440d163575Sopenharmony_ci        free(fullpath);
2450d163575Sopenharmony_ci        return -1;
2460d163575Sopenharmony_ci    }
2470d163575Sopenharmony_ci    if (vnode->type != VNODE_TYPE_REG) {
2480d163575Sopenharmony_ci        set_errno(EINVAL);
2490d163575Sopenharmony_ci        perror("cat error");
2500d163575Sopenharmony_ci        VnodeDrop();
2510d163575Sopenharmony_ci        free(fullpath);
2520d163575Sopenharmony_ci        return -1;
2530d163575Sopenharmony_ci    }
2540d163575Sopenharmony_ci    VnodeDrop();
2550d163575Sopenharmony_ci    (void)memset_s(&init_param, sizeof(init_param), 0, sizeof(TSK_INIT_PARAM_S));
2560d163575Sopenharmony_ci    init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)osShellCmdDoCatShow;
2570d163575Sopenharmony_ci    init_param.usTaskPrio   = CAT_TASK_PRIORITY;
2580d163575Sopenharmony_ci    init_param.auwArgs[0]   = (UINTPTR)fullpath;
2590d163575Sopenharmony_ci    init_param.uwStackSize  = CAT_TASK_STACK_SIZE;
2600d163575Sopenharmony_ci    init_param.pcName       = "shellcmd_cat";
2610d163575Sopenharmony_ci    init_param.uwResved     = LOS_TASK_STATUS_DETACHED | OS_TASK_FLAG_SPECIFIES_PROCESS;
2620d163575Sopenharmony_ci
2630d163575Sopenharmony_ci    ret = (int)LOS_TaskCreate(&ca_task, &init_param);
2640d163575Sopenharmony_ci    if (ret != LOS_OK) {
2650d163575Sopenharmony_ci        free(fullpath);
2660d163575Sopenharmony_ci    }
2670d163575Sopenharmony_ci
2680d163575Sopenharmony_ci    return ret;
2690d163575Sopenharmony_ci}
2700d163575Sopenharmony_ci
2710d163575Sopenharmony_cistatic int nfs_mount_ref(const char *server_ip_and_path, const char *mount_path,
2720d163575Sopenharmony_ci                         unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount")));
2730d163575Sopenharmony_ci
2740d163575Sopenharmony_cistatic unsigned long get_mountflags(const char *options)
2750d163575Sopenharmony_ci{
2760d163575Sopenharmony_ci    unsigned long mountfalgs = 0;
2770d163575Sopenharmony_ci    char *p;
2780d163575Sopenharmony_ci    while ((options != NULL) && (p = strsep((char**)&options, ",")) != NULL) {
2790d163575Sopenharmony_ci        if (strncmp(p, "ro", strlen("ro")) == 0) {
2800d163575Sopenharmony_ci            mountfalgs |= MS_RDONLY;
2810d163575Sopenharmony_ci        } else if (strncmp(p, "rw", strlen("rw")) == 0) {
2820d163575Sopenharmony_ci            mountfalgs &= ~MS_RDONLY;
2830d163575Sopenharmony_ci        } else if (strncmp(p, "nosuid", strlen("nosuid")) == 0) {
2840d163575Sopenharmony_ci            mountfalgs |= MS_NOSUID;
2850d163575Sopenharmony_ci        } else if (strncmp(p, "suid", strlen("suid")) == 0) {
2860d163575Sopenharmony_ci            mountfalgs &= ~MS_NOSUID;
2870d163575Sopenharmony_ci        } else {
2880d163575Sopenharmony_ci            continue;
2890d163575Sopenharmony_ci        }
2900d163575Sopenharmony_ci    }
2910d163575Sopenharmony_ci
2920d163575Sopenharmony_ci    return mountfalgs;
2930d163575Sopenharmony_ci}
2940d163575Sopenharmony_cistatic inline void print_mount_usage(void)
2950d163575Sopenharmony_ci{
2960d163575Sopenharmony_ci    PRINTK("mount [DEVICE] [PATH] [NAME]\n");
2970d163575Sopenharmony_ci}
2980d163575Sopenharmony_ci
2990d163575Sopenharmony_ciint osShellCmdMount(int argc, const char **argv)
3000d163575Sopenharmony_ci{
3010d163575Sopenharmony_ci    int ret;
3020d163575Sopenharmony_ci    char *fullpath = NULL;
3030d163575Sopenharmony_ci    const char *filename = NULL;
3040d163575Sopenharmony_ci    unsigned int gid, uid;
3050d163575Sopenharmony_ci    char *data = NULL;
3060d163575Sopenharmony_ci    char *filessystemtype = NULL;
3070d163575Sopenharmony_ci    unsigned long mountfalgs;
3080d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
3090d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
3100d163575Sopenharmony_ci        return -1;
3110d163575Sopenharmony_ci    }
3120d163575Sopenharmony_ci
3130d163575Sopenharmony_ci    ERROR_OUT_IF(argc < 3, print_mount_usage(), return OS_FAIL);
3140d163575Sopenharmony_ci
3150d163575Sopenharmony_ci    if (strncmp(argv[0], "-t", 2) == 0 || strncmp(argv[0], "-o", 2) == 0) // 2: length of "-t"
3160d163575Sopenharmony_ci    {
3170d163575Sopenharmony_ci        if (argc < 4) { // 4: required number of parameters
3180d163575Sopenharmony_ci            PRINTK("mount -t/-o [DEVICE] [PATH] [NAME]\n");
3190d163575Sopenharmony_ci            return -1;
3200d163575Sopenharmony_ci        }
3210d163575Sopenharmony_ci
3220d163575Sopenharmony_ci        filename = argv[2]; // 2: index of file path
3230d163575Sopenharmony_ci        ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
3240d163575Sopenharmony_ci        ERROR_OUT_IF(ret < 0, set_err(-ret, "mount error"), return -1);
3250d163575Sopenharmony_ci
3260d163575Sopenharmony_ci        if (strncmp(argv[3], "nfs", 3) == 0) { // 3: index of fs type
3270d163575Sopenharmony_ci            if (argc <= 6) { // 6: arguments include uid or gid
3280d163575Sopenharmony_ci                uid = ((argc >= 5) && (argv[4] != NULL)) ? (unsigned int)strtoul(argv[4], (char **)NULL, 0) : 0;
3290d163575Sopenharmony_ci                gid = ((argc == 6) && (argv[5] != NULL)) ? (unsigned int)strtoul(argv[5], (char **)NULL, 0) : 0;
3300d163575Sopenharmony_ci
3310d163575Sopenharmony_ci                if (nfs_mount_ref != NULL) {
3320d163575Sopenharmony_ci                    ret = nfs_mount_ref(argv[1], fullpath, uid, gid);
3330d163575Sopenharmony_ci                    if (ret != LOS_OK) {
3340d163575Sopenharmony_ci                        PRINTK("mount -t [DEVICE] [PATH] [NAME]\n");
3350d163575Sopenharmony_ci                    }
3360d163575Sopenharmony_ci                } else {
3370d163575Sopenharmony_ci                    PRINTK("can't find nfs_mount\n");
3380d163575Sopenharmony_ci                }
3390d163575Sopenharmony_ci                free(fullpath);
3400d163575Sopenharmony_ci                return 0;
3410d163575Sopenharmony_ci            }
3420d163575Sopenharmony_ci        }
3430d163575Sopenharmony_ci
3440d163575Sopenharmony_ci        filessystemtype = (argc >= 4) ? (char *)argv[3] : NULL; /* 4: specify fs type, 3: fs type */
3450d163575Sopenharmony_ci        mountfalgs = (argc >= 5) ? get_mountflags((const char *)argv[4]) : 0; /* 4: usr option */
3460d163575Sopenharmony_ci        data = (argc >= 6) ? (char *)argv[5] : NULL; /* 5: usr option data, 6: six args needed for data */
3470d163575Sopenharmony_ci
3480d163575Sopenharmony_ci        if (strcmp(argv[1], "0") == 0) {
3490d163575Sopenharmony_ci            ret = mount((const char *)NULL, fullpath, filessystemtype, mountfalgs, data);
3500d163575Sopenharmony_ci        } else {
3510d163575Sopenharmony_ci            ret = mount(argv[1], fullpath, filessystemtype, mountfalgs, data); /* 3: fs type */
3520d163575Sopenharmony_ci        }
3530d163575Sopenharmony_ci        if (ret != LOS_OK) {
3540d163575Sopenharmony_ci            perror("mount error");
3550d163575Sopenharmony_ci        } else {
3560d163575Sopenharmony_ci            PRINTK("mount ok\n");
3570d163575Sopenharmony_ci        }
3580d163575Sopenharmony_ci    } else {
3590d163575Sopenharmony_ci        filename = argv[1];
3600d163575Sopenharmony_ci        ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
3610d163575Sopenharmony_ci        ERROR_OUT_IF(ret < 0, set_err(-ret, "mount error"), return -1);
3620d163575Sopenharmony_ci
3630d163575Sopenharmony_ci        if (strncmp(argv[2], "nfs", 3) == 0) { // 2: index of fs type, 3: length of "nfs"
3640d163575Sopenharmony_ci            if (argc <= 5) { // 5: arguments include gid and uid
3650d163575Sopenharmony_ci                uid = ((argc >= 4) && (argv[3] != NULL)) ? (unsigned int)strtoul(argv[3], (char **)NULL, 0) : 0;
3660d163575Sopenharmony_ci                gid = ((argc == 5) && (argv[4] != NULL)) ? (unsigned int)strtoul(argv[4], (char **)NULL, 0) : 0;
3670d163575Sopenharmony_ci
3680d163575Sopenharmony_ci                if (nfs_mount_ref != NULL) {
3690d163575Sopenharmony_ci                    ret = nfs_mount_ref(argv[0], fullpath, uid, gid);
3700d163575Sopenharmony_ci                    if (ret != LOS_OK) {
3710d163575Sopenharmony_ci                        PRINTK("mount [DEVICE] [PATH] [NAME]\n");
3720d163575Sopenharmony_ci                    }
3730d163575Sopenharmony_ci                } else {
3740d163575Sopenharmony_ci                    PRINTK("can't find nfs_mount\n");
3750d163575Sopenharmony_ci                }
3760d163575Sopenharmony_ci                free(fullpath);
3770d163575Sopenharmony_ci                return 0;
3780d163575Sopenharmony_ci            }
3790d163575Sopenharmony_ci
3800d163575Sopenharmony_ci            print_mount_usage();
3810d163575Sopenharmony_ci            free(fullpath);
3820d163575Sopenharmony_ci            return 0;
3830d163575Sopenharmony_ci        }
3840d163575Sopenharmony_ci
3850d163575Sopenharmony_ci        mountfalgs = (argc >= 4) ? get_mountflags((const char *)argv[3]) : 0;  /* 3: usr option */
3860d163575Sopenharmony_ci        data = (argc >= 5) ? (char *)argv[4] : NULL; /* 4: usr option data, 5: number of args needed for data */
3870d163575Sopenharmony_ci
3880d163575Sopenharmony_ci        if (strcmp(argv[0], "0") == 0) {
3890d163575Sopenharmony_ci            ret = mount((const char *)NULL, fullpath, argv[2], mountfalgs, data);
3900d163575Sopenharmony_ci        } else {
3910d163575Sopenharmony_ci            ret = mount(argv[0], fullpath, argv[2], mountfalgs, data);  /* 2: fs type */
3920d163575Sopenharmony_ci        }
3930d163575Sopenharmony_ci        if (ret != LOS_OK) {
3940d163575Sopenharmony_ci            perror("mount error");
3950d163575Sopenharmony_ci        } else {
3960d163575Sopenharmony_ci            PRINTK("mount ok\n");
3970d163575Sopenharmony_ci        }
3980d163575Sopenharmony_ci    }
3990d163575Sopenharmony_ci
4000d163575Sopenharmony_ci    free(fullpath);
4010d163575Sopenharmony_ci    return 0;
4020d163575Sopenharmony_ci}
4030d163575Sopenharmony_ci
4040d163575Sopenharmony_ciint osShellCmdUmount(int argc, const char **argv)
4050d163575Sopenharmony_ci{
4060d163575Sopenharmony_ci    int ret;
4070d163575Sopenharmony_ci    const char *filename = NULL;
4080d163575Sopenharmony_ci    char *fullpath = NULL;
4090d163575Sopenharmony_ci    char *target_path = NULL;
4100d163575Sopenharmony_ci    int cmp_num;
4110d163575Sopenharmony_ci    char *work_path = NULL;
4120d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
4130d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
4140d163575Sopenharmony_ci        return -1;
4150d163575Sopenharmony_ci    }
4160d163575Sopenharmony_ci    work_path = shell_working_directory;
4170d163575Sopenharmony_ci
4180d163575Sopenharmony_ci    ERROR_OUT_IF(argc == 0, PRINTK("umount [PATH]\n"), return 0);
4190d163575Sopenharmony_ci
4200d163575Sopenharmony_ci    filename = argv[0];
4210d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
4220d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "umount error"), return -1);
4230d163575Sopenharmony_ci
4240d163575Sopenharmony_ci    target_path = fullpath;
4250d163575Sopenharmony_ci    cmp_num = strlen(fullpath);
4260d163575Sopenharmony_ci    ret = strncmp(work_path, target_path, cmp_num);
4270d163575Sopenharmony_ci    if (ret == 0) {
4280d163575Sopenharmony_ci        work_path += cmp_num;
4290d163575Sopenharmony_ci        if (*work_path == '/' || *work_path == '\0') {
4300d163575Sopenharmony_ci            set_errno(EBUSY);
4310d163575Sopenharmony_ci            perror("umount error");
4320d163575Sopenharmony_ci            free(fullpath);
4330d163575Sopenharmony_ci            return -1;
4340d163575Sopenharmony_ci        }
4350d163575Sopenharmony_ci    }
4360d163575Sopenharmony_ci
4370d163575Sopenharmony_ci    ret = umount(fullpath);
4380d163575Sopenharmony_ci    free(fullpath);
4390d163575Sopenharmony_ci    if (ret != LOS_OK) {
4400d163575Sopenharmony_ci        perror("umount error");
4410d163575Sopenharmony_ci        return 0;
4420d163575Sopenharmony_ci    }
4430d163575Sopenharmony_ci
4440d163575Sopenharmony_ci    PRINTK("umount ok\n");
4450d163575Sopenharmony_ci    return 0;
4460d163575Sopenharmony_ci}
4470d163575Sopenharmony_ci
4480d163575Sopenharmony_ciint osShellCmdMkdir(int argc, const char **argv)
4490d163575Sopenharmony_ci{
4500d163575Sopenharmony_ci    int ret;
4510d163575Sopenharmony_ci    char *fullpath = NULL;
4520d163575Sopenharmony_ci    const char *filename = NULL;
4530d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
4540d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
4550d163575Sopenharmony_ci        return -1;
4560d163575Sopenharmony_ci    }
4570d163575Sopenharmony_ci
4580d163575Sopenharmony_ci    ERROR_OUT_IF(argc != 1, PRINTK("mkdir [DIRECTORY]\n"), return 0);
4590d163575Sopenharmony_ci
4600d163575Sopenharmony_ci    filename = argv[0];
4610d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
4620d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "mkdir error"), return -1);
4630d163575Sopenharmony_ci
4640d163575Sopenharmony_ci    ret = mkdir(fullpath, S_IRWXU | S_IRWXG | S_IRWXO);
4650d163575Sopenharmony_ci    if (ret == -1) {
4660d163575Sopenharmony_ci        perror("mkdir error");
4670d163575Sopenharmony_ci    }
4680d163575Sopenharmony_ci    free(fullpath);
4690d163575Sopenharmony_ci    return 0;
4700d163575Sopenharmony_ci}
4710d163575Sopenharmony_ci
4720d163575Sopenharmony_ciint osShellCmdPwd(int argc, const char **argv)
4730d163575Sopenharmony_ci{
4740d163575Sopenharmony_ci    char buf[SHOW_MAX_LEN] = {0};
4750d163575Sopenharmony_ci    DIR *dir = NULL;
4760d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
4770d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
4780d163575Sopenharmony_ci        return -1;
4790d163575Sopenharmony_ci    }
4800d163575Sopenharmony_ci
4810d163575Sopenharmony_ci    ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: pwd\n"), return -1);
4820d163575Sopenharmony_ci
4830d163575Sopenharmony_ci    dir = opendir(shell_working_directory);
4840d163575Sopenharmony_ci    if (dir == NULL) {
4850d163575Sopenharmony_ci        perror("pwd error");
4860d163575Sopenharmony_ci        return -1;
4870d163575Sopenharmony_ci    }
4880d163575Sopenharmony_ci
4890d163575Sopenharmony_ci    LOS_TaskLock();
4900d163575Sopenharmony_ci    if (strncpy_s(buf, SHOW_MAX_LEN, shell_working_directory, SHOW_MAX_LEN - 1) != EOK) {
4910d163575Sopenharmony_ci        LOS_TaskUnlock();
4920d163575Sopenharmony_ci        PRINTK("pwd error: strncpy_s error!\n");
4930d163575Sopenharmony_ci        (void)closedir(dir);
4940d163575Sopenharmony_ci        return -1;
4950d163575Sopenharmony_ci    }
4960d163575Sopenharmony_ci    LOS_TaskUnlock();
4970d163575Sopenharmony_ci
4980d163575Sopenharmony_ci    PRINTK("%s\n", buf);
4990d163575Sopenharmony_ci    (void)closedir(dir);
5000d163575Sopenharmony_ci    return 0;
5010d163575Sopenharmony_ci}
5020d163575Sopenharmony_ci
5030d163575Sopenharmony_cistatic inline void print_statfs_usage(void)
5040d163575Sopenharmony_ci{
5050d163575Sopenharmony_ci    PRINTK("Usage  :\n");
5060d163575Sopenharmony_ci    PRINTK("    statfs <path>\n");
5070d163575Sopenharmony_ci    PRINTK("    path  : Mounted file system path that requires query information\n");
5080d163575Sopenharmony_ci    PRINTK("Example:\n");
5090d163575Sopenharmony_ci    PRINTK("    statfs /ramfs\n");
5100d163575Sopenharmony_ci}
5110d163575Sopenharmony_ci
5120d163575Sopenharmony_ciint osShellCmdStatfs(int argc, const char **argv)
5130d163575Sopenharmony_ci{
5140d163575Sopenharmony_ci    struct statfs sfs;
5150d163575Sopenharmony_ci    int result;
5160d163575Sopenharmony_ci    unsigned long long total_size, free_size;
5170d163575Sopenharmony_ci    char *fullpath = NULL;
5180d163575Sopenharmony_ci    const char *filename = NULL;
5190d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
5200d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
5210d163575Sopenharmony_ci        return -1;
5220d163575Sopenharmony_ci    }
5230d163575Sopenharmony_ci
5240d163575Sopenharmony_ci    ERROR_OUT_IF(argc != 1, PRINTK("statfs failed! Invalid argument!\n"), return -1);
5250d163575Sopenharmony_ci
5260d163575Sopenharmony_ci    (void)memset_s(&sfs, sizeof(sfs), 0, sizeof(sfs));
5270d163575Sopenharmony_ci
5280d163575Sopenharmony_ci    filename = argv[0];
5290d163575Sopenharmony_ci    result = vfs_normalize_path(shell_working_directory, filename, &fullpath);
5300d163575Sopenharmony_ci    ERROR_OUT_IF(result < 0, set_err(-result, "statfs error"), return -1);
5310d163575Sopenharmony_ci
5320d163575Sopenharmony_ci    result = statfs(fullpath, &sfs);
5330d163575Sopenharmony_ci    free(fullpath);
5340d163575Sopenharmony_ci
5350d163575Sopenharmony_ci    if (result != 0 || sfs.f_type == 0) {
5360d163575Sopenharmony_ci        PRINTK("statfs failed! Invalid argument!\n");
5370d163575Sopenharmony_ci        print_statfs_usage();
5380d163575Sopenharmony_ci        return -1;
5390d163575Sopenharmony_ci    }
5400d163575Sopenharmony_ci
5410d163575Sopenharmony_ci    total_size  = (unsigned long long)sfs.f_bsize * sfs.f_blocks;
5420d163575Sopenharmony_ci    free_size   = (unsigned long long)sfs.f_bsize * sfs.f_bfree;
5430d163575Sopenharmony_ci
5440d163575Sopenharmony_ci    PRINTK("statfs got:\n f_type     = %d\n cluster_size   = %d\n", sfs.f_type, sfs.f_bsize);
5450d163575Sopenharmony_ci    PRINTK(" total_clusters = %llu\n free_clusters  = %llu\n", sfs.f_blocks, sfs.f_bfree);
5460d163575Sopenharmony_ci    PRINTK(" avail_clusters = %llu\n f_namelen    = %d\n", sfs.f_bavail, sfs.f_namelen);
5470d163575Sopenharmony_ci    PRINTK("\n%s\n total size: %4llu Bytes\n free  size: %4llu Bytes\n", argv[0], total_size, free_size);
5480d163575Sopenharmony_ci
5490d163575Sopenharmony_ci    return 0;
5500d163575Sopenharmony_ci}
5510d163575Sopenharmony_ci
5520d163575Sopenharmony_ciint osShellCmdTouch(int argc, const char **argv)
5530d163575Sopenharmony_ci{
5540d163575Sopenharmony_ci    int ret;
5550d163575Sopenharmony_ci    int fd = -1;
5560d163575Sopenharmony_ci    char *fullpath = NULL;
5570d163575Sopenharmony_ci    const char *filename = NULL;
5580d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
5590d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
5600d163575Sopenharmony_ci        return -1;
5610d163575Sopenharmony_ci    }
5620d163575Sopenharmony_ci
5630d163575Sopenharmony_ci    ERROR_OUT_IF(argc != 1, PRINTK("touch [FILE]\n"), return -1);
5640d163575Sopenharmony_ci
5650d163575Sopenharmony_ci    filename = argv[0];
5660d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
5670d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "touch error"), return -1);
5680d163575Sopenharmony_ci
5690d163575Sopenharmony_ci    fd = open(fullpath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
5700d163575Sopenharmony_ci    free(fullpath);
5710d163575Sopenharmony_ci    if (fd == -1) {
5720d163575Sopenharmony_ci        perror("touch error");
5730d163575Sopenharmony_ci        return -1;
5740d163575Sopenharmony_ci    }
5750d163575Sopenharmony_ci
5760d163575Sopenharmony_ci    (void)close(fd);
5770d163575Sopenharmony_ci    return 0;
5780d163575Sopenharmony_ci}
5790d163575Sopenharmony_ci
5800d163575Sopenharmony_ci#define CP_BUF_SIZE 4096
5810d163575Sopenharmony_cipthread_mutex_t g_mutex_cp = PTHREAD_MUTEX_INITIALIZER;
5820d163575Sopenharmony_ci
5830d163575Sopenharmony_cistatic int os_shell_cmd_do_cp(const char *src_filepath, const char *dst_filename)
5840d163575Sopenharmony_ci{
5850d163575Sopenharmony_ci    int  ret;
5860d163575Sopenharmony_ci    char *src_fullpath = NULL;
5870d163575Sopenharmony_ci    char *dst_fullpath = NULL;
5880d163575Sopenharmony_ci    const char *src_filename = NULL;
5890d163575Sopenharmony_ci    char *dst_filepath = NULL;
5900d163575Sopenharmony_ci    char *buf = NULL;
5910d163575Sopenharmony_ci    const char *filename = NULL;
5920d163575Sopenharmony_ci    ssize_t r_size, w_size;
5930d163575Sopenharmony_ci    int src_fd = -1;
5940d163575Sopenharmony_ci    int dst_fd = -1;
5950d163575Sopenharmony_ci    struct stat stat_buf;
5960d163575Sopenharmony_ci    mode_t src_mode;
5970d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
5980d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
5990d163575Sopenharmony_ci        return -1;
6000d163575Sopenharmony_ci    }
6010d163575Sopenharmony_ci
6020d163575Sopenharmony_ci    buf = (char *)malloc(CP_BUF_SIZE);
6030d163575Sopenharmony_ci    if (buf == NULL) {
6040d163575Sopenharmony_ci        PRINTK("cp error: Out of memory!\n");
6050d163575Sopenharmony_ci        return -1;
6060d163575Sopenharmony_ci    }
6070d163575Sopenharmony_ci
6080d163575Sopenharmony_ci    /* Get source fullpath. */
6090d163575Sopenharmony_ci
6100d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, src_filepath, &src_fullpath);
6110d163575Sopenharmony_ci    if (ret < 0) {
6120d163575Sopenharmony_ci        set_errno(-ret);
6130d163575Sopenharmony_ci        PRINTK("cp error: %s\n", strerror(errno));
6140d163575Sopenharmony_ci        free(buf);
6150d163575Sopenharmony_ci        return -1;
6160d163575Sopenharmony_ci    }
6170d163575Sopenharmony_ci
6180d163575Sopenharmony_ci    /* Is source path exist? */
6190d163575Sopenharmony_ci
6200d163575Sopenharmony_ci    ret = stat(src_fullpath, &stat_buf);
6210d163575Sopenharmony_ci    if (ret == -1) {
6220d163575Sopenharmony_ci        PRINTK("cp %s error: %s\n", src_fullpath, strerror(errno));
6230d163575Sopenharmony_ci        goto errout_with_srcpath;
6240d163575Sopenharmony_ci    }
6250d163575Sopenharmony_ci    src_mode = stat_buf.st_mode;
6260d163575Sopenharmony_ci    /* Is source path a directory? */
6270d163575Sopenharmony_ci
6280d163575Sopenharmony_ci    if (S_ISDIR(stat_buf.st_mode)) {
6290d163575Sopenharmony_ci        PRINTK("cp %s error: Source file can't be a directory.\n", src_fullpath);
6300d163575Sopenharmony_ci        goto errout_with_srcpath;
6310d163575Sopenharmony_ci    }
6320d163575Sopenharmony_ci
6330d163575Sopenharmony_ci    /* Get dest fullpath. */
6340d163575Sopenharmony_ci
6350d163575Sopenharmony_ci    dst_fullpath = strdup(dst_filename);
6360d163575Sopenharmony_ci    if (dst_fullpath == NULL) {
6370d163575Sopenharmony_ci        PRINTK("cp error: Out of memory.\n");
6380d163575Sopenharmony_ci        goto errout_with_srcpath;
6390d163575Sopenharmony_ci    }
6400d163575Sopenharmony_ci
6410d163575Sopenharmony_ci    /* Is dest path exist? */
6420d163575Sopenharmony_ci
6430d163575Sopenharmony_ci    ret = stat(dst_fullpath, &stat_buf);
6440d163575Sopenharmony_ci    if (ret == 0) {
6450d163575Sopenharmony_ci        /* Is dest path a directory? */
6460d163575Sopenharmony_ci
6470d163575Sopenharmony_ci        if (S_ISDIR(stat_buf.st_mode)) {
6480d163575Sopenharmony_ci            /* Get source file name without '/'. */
6490d163575Sopenharmony_ci
6500d163575Sopenharmony_ci            src_filename = src_filepath;
6510d163575Sopenharmony_ci            while (1) {
6520d163575Sopenharmony_ci                filename = strchr(src_filename, '/');
6530d163575Sopenharmony_ci                if (filename == NULL) {
6540d163575Sopenharmony_ci                    break;
6550d163575Sopenharmony_ci                }
6560d163575Sopenharmony_ci                src_filename = filename + 1;
6570d163575Sopenharmony_ci            }
6580d163575Sopenharmony_ci
6590d163575Sopenharmony_ci            /* Add the source file after dest path. */
6600d163575Sopenharmony_ci
6610d163575Sopenharmony_ci            ret = vfs_normalize_path(dst_fullpath, src_filename, &dst_filepath);
6620d163575Sopenharmony_ci            if (ret < 0) {
6630d163575Sopenharmony_ci                set_errno(-ret);
6640d163575Sopenharmony_ci                PRINTK("cp error. %s.\n", strerror(errno));
6650d163575Sopenharmony_ci                goto errout_with_path;
6660d163575Sopenharmony_ci            }
6670d163575Sopenharmony_ci            free(dst_fullpath);
6680d163575Sopenharmony_ci            dst_fullpath = dst_filepath;
6690d163575Sopenharmony_ci        }
6700d163575Sopenharmony_ci    }
6710d163575Sopenharmony_ci
6720d163575Sopenharmony_ci    /* Is dest file same as source file? */
6730d163575Sopenharmony_ci
6740d163575Sopenharmony_ci    if (strcmp(src_fullpath, dst_fullpath) == 0) {
6750d163575Sopenharmony_ci        PRINTK("cp error: '%s' and '%s' are the same file\n", src_fullpath, dst_fullpath);
6760d163575Sopenharmony_ci        goto errout_with_path;
6770d163575Sopenharmony_ci    }
6780d163575Sopenharmony_ci
6790d163575Sopenharmony_ci    /* Copy begins. */
6800d163575Sopenharmony_ci
6810d163575Sopenharmony_ci    (void)pthread_mutex_lock(&g_mutex_cp);
6820d163575Sopenharmony_ci    src_fd = open(src_fullpath, O_RDONLY);
6830d163575Sopenharmony_ci    if (src_fd < 0) {
6840d163575Sopenharmony_ci        PRINTK("cp error: can't open %s. %s.\n", src_fullpath, strerror(errno));
6850d163575Sopenharmony_ci        goto errout_with_mutex;
6860d163575Sopenharmony_ci    }
6870d163575Sopenharmony_ci
6880d163575Sopenharmony_ci    dst_fd = open(dst_fullpath, O_CREAT | O_WRONLY | O_TRUNC, src_mode);
6890d163575Sopenharmony_ci    if (dst_fd < 0) {
6900d163575Sopenharmony_ci        PRINTK("cp error: can't create %s. %s.\n", dst_fullpath, strerror(errno));
6910d163575Sopenharmony_ci        goto errout_with_srcfd;
6920d163575Sopenharmony_ci    }
6930d163575Sopenharmony_ci
6940d163575Sopenharmony_ci    do {
6950d163575Sopenharmony_ci        (void)memset_s(buf, CP_BUF_SIZE, 0, CP_BUF_SIZE);
6960d163575Sopenharmony_ci        r_size = read(src_fd, buf, CP_BUF_SIZE);
6970d163575Sopenharmony_ci        if (r_size < 0) {
6980d163575Sopenharmony_ci            PRINTK("cp %s %s failed. %s.\n", src_fullpath, dst_fullpath, strerror(errno));
6990d163575Sopenharmony_ci            goto errout_with_fd;
7000d163575Sopenharmony_ci        }
7010d163575Sopenharmony_ci        w_size = write(dst_fd, buf, r_size);
7020d163575Sopenharmony_ci        if (w_size != r_size) {
7030d163575Sopenharmony_ci            PRINTK("cp %s %s failed. %s.\n", src_fullpath, dst_fullpath, strerror(errno));
7040d163575Sopenharmony_ci            goto errout_with_fd;
7050d163575Sopenharmony_ci        }
7060d163575Sopenharmony_ci    } while (r_size == CP_BUF_SIZE);
7070d163575Sopenharmony_ci
7080d163575Sopenharmony_ci    /* Release resource. */
7090d163575Sopenharmony_ci
7100d163575Sopenharmony_ci    free(buf);
7110d163575Sopenharmony_ci    free(src_fullpath);
7120d163575Sopenharmony_ci    free(dst_fullpath);
7130d163575Sopenharmony_ci    (void)close(src_fd);
7140d163575Sopenharmony_ci    (void)close(dst_fd);
7150d163575Sopenharmony_ci    (void)pthread_mutex_unlock(&g_mutex_cp);
7160d163575Sopenharmony_ci    return LOS_OK;
7170d163575Sopenharmony_ci
7180d163575Sopenharmony_cierrout_with_fd:
7190d163575Sopenharmony_ci    (void)close(dst_fd);
7200d163575Sopenharmony_cierrout_with_srcfd:
7210d163575Sopenharmony_ci    (void)close(src_fd);
7220d163575Sopenharmony_cierrout_with_mutex:
7230d163575Sopenharmony_ci    (void)pthread_mutex_unlock(&g_mutex_cp);
7240d163575Sopenharmony_cierrout_with_path:
7250d163575Sopenharmony_ci    free(dst_fullpath);
7260d163575Sopenharmony_cierrout_with_srcpath:
7270d163575Sopenharmony_ci    free(src_fullpath);
7280d163575Sopenharmony_ci    free(buf);
7290d163575Sopenharmony_ci    return -1;
7300d163575Sopenharmony_ci}
7310d163575Sopenharmony_ci
7320d163575Sopenharmony_ci/* The separator and EOF for a directory fullpath: '/'and '\0' */
7330d163575Sopenharmony_ci
7340d163575Sopenharmony_ci#define SEPARATOR_EOF_LEN 2
7350d163575Sopenharmony_ci
7360d163575Sopenharmony_cistatic int os_shell_cmd_do_rmdir(const char *pathname)
7370d163575Sopenharmony_ci{
7380d163575Sopenharmony_ci    struct dirent *dirent = NULL;
7390d163575Sopenharmony_ci    struct stat stat_info;
7400d163575Sopenharmony_ci    DIR *d = NULL;
7410d163575Sopenharmony_ci    char *fullpath = NULL;
7420d163575Sopenharmony_ci    int ret;
7430d163575Sopenharmony_ci
7440d163575Sopenharmony_ci    (void)memset_s(&stat_info, sizeof(stat_info), 0, sizeof(struct stat));
7450d163575Sopenharmony_ci    if (stat(pathname, &stat_info) != 0) {
7460d163575Sopenharmony_ci        return -1;
7470d163575Sopenharmony_ci    }
7480d163575Sopenharmony_ci
7490d163575Sopenharmony_ci    if (S_ISREG(stat_info.st_mode) || S_ISLNK(stat_info.st_mode)) {
7500d163575Sopenharmony_ci        return remove(pathname);
7510d163575Sopenharmony_ci    }
7520d163575Sopenharmony_ci    d = opendir(pathname);
7530d163575Sopenharmony_ci    if (d == NULL) {
7540d163575Sopenharmony_ci        return -1;
7550d163575Sopenharmony_ci    }
7560d163575Sopenharmony_ci    while (1) {
7570d163575Sopenharmony_ci        dirent = readdir(d);
7580d163575Sopenharmony_ci        if (dirent == NULL) {
7590d163575Sopenharmony_ci            break;
7600d163575Sopenharmony_ci        }
7610d163575Sopenharmony_ci        if (strcmp(dirent->d_name, "..") && strcmp(dirent->d_name, ".")) {
7620d163575Sopenharmony_ci            size_t fullpath_buf_size = strlen(pathname) + strlen(dirent->d_name) + SEPARATOR_EOF_LEN;
7630d163575Sopenharmony_ci            fullpath = (char *)malloc(fullpath_buf_size);
7640d163575Sopenharmony_ci            if (fullpath == NULL) {
7650d163575Sopenharmony_ci                PRINTK("malloc failure!\n");
7660d163575Sopenharmony_ci                (void)closedir(d);
7670d163575Sopenharmony_ci                return -1;
7680d163575Sopenharmony_ci            }
7690d163575Sopenharmony_ci            ret = snprintf_s(fullpath, fullpath_buf_size, fullpath_buf_size - 1, "%s/%s", pathname, dirent->d_name);
7700d163575Sopenharmony_ci            if (ret < 0) {
7710d163575Sopenharmony_ci                PRINTK("name is too long!\n");
7720d163575Sopenharmony_ci                free(fullpath);
7730d163575Sopenharmony_ci                (void)closedir(d);
7740d163575Sopenharmony_ci                return -1;
7750d163575Sopenharmony_ci            }
7760d163575Sopenharmony_ci            (void)os_shell_cmd_do_rmdir(fullpath);
7770d163575Sopenharmony_ci            free(fullpath);
7780d163575Sopenharmony_ci        }
7790d163575Sopenharmony_ci    }
7800d163575Sopenharmony_ci    (void)closedir(d);
7810d163575Sopenharmony_ci    return rmdir(pathname);
7820d163575Sopenharmony_ci}
7830d163575Sopenharmony_ci
7840d163575Sopenharmony_ci/*  Wildcard matching operations  */
7850d163575Sopenharmony_ci
7860d163575Sopenharmony_cistatic int os_wildcard_match(const char *src, const char *filename)
7870d163575Sopenharmony_ci{
7880d163575Sopenharmony_ci    int ret;
7890d163575Sopenharmony_ci
7900d163575Sopenharmony_ci    if (*src != '\0') {
7910d163575Sopenharmony_ci        if (*filename == '*') {
7920d163575Sopenharmony_ci            while ((*filename == '*') || (*filename == '?')) {
7930d163575Sopenharmony_ci                filename++;
7940d163575Sopenharmony_ci            }
7950d163575Sopenharmony_ci
7960d163575Sopenharmony_ci            if (*filename == '\0') {
7970d163575Sopenharmony_ci                return 0;
7980d163575Sopenharmony_ci            }
7990d163575Sopenharmony_ci
8000d163575Sopenharmony_ci            while (*src != '\0' && !(*src == *filename)) {
8010d163575Sopenharmony_ci                src++;
8020d163575Sopenharmony_ci            }
8030d163575Sopenharmony_ci
8040d163575Sopenharmony_ci            if (*src == '\0') {
8050d163575Sopenharmony_ci                return -1;
8060d163575Sopenharmony_ci            }
8070d163575Sopenharmony_ci
8080d163575Sopenharmony_ci            ret = os_wildcard_match(src, filename);
8090d163575Sopenharmony_ci
8100d163575Sopenharmony_ci            while ((ret != 0) && (*(++src) != '\0')) {
8110d163575Sopenharmony_ci                if (*src == *filename) {
8120d163575Sopenharmony_ci                    ret = os_wildcard_match(src, filename);
8130d163575Sopenharmony_ci                }
8140d163575Sopenharmony_ci            }
8150d163575Sopenharmony_ci            return ret;
8160d163575Sopenharmony_ci        } else {
8170d163575Sopenharmony_ci            if ((*src == *filename) || (*filename == '?')) {
8180d163575Sopenharmony_ci                return os_wildcard_match(++src, ++filename);
8190d163575Sopenharmony_ci            }
8200d163575Sopenharmony_ci            return -1;
8210d163575Sopenharmony_ci        }
8220d163575Sopenharmony_ci    }
8230d163575Sopenharmony_ci
8240d163575Sopenharmony_ci    while (*filename != '\0') {
8250d163575Sopenharmony_ci        if (*filename != '*') {
8260d163575Sopenharmony_ci            return -1;
8270d163575Sopenharmony_ci        }
8280d163575Sopenharmony_ci        filename++;
8290d163575Sopenharmony_ci    }
8300d163575Sopenharmony_ci    return 0;
8310d163575Sopenharmony_ci}
8320d163575Sopenharmony_ci
8330d163575Sopenharmony_ci/*   To determine whether a wildcard character exists in a path   */
8340d163575Sopenharmony_ci
8350d163575Sopenharmony_cistatic int os_is_containers_wildcard(const char *filename)
8360d163575Sopenharmony_ci{
8370d163575Sopenharmony_ci    while (*filename != '\0') {
8380d163575Sopenharmony_ci        if ((*filename == '*') || (*filename == '?')) {
8390d163575Sopenharmony_ci            return 1;
8400d163575Sopenharmony_ci        }
8410d163575Sopenharmony_ci        filename++;
8420d163575Sopenharmony_ci    }
8430d163575Sopenharmony_ci    return 0;
8440d163575Sopenharmony_ci}
8450d163575Sopenharmony_ci
8460d163575Sopenharmony_ci/*  Delete a matching file or directory  */
8470d163575Sopenharmony_ci
8480d163575Sopenharmony_cistatic int os_wildcard_delete_file_or_dir(const char *fullpath, wildcard_type mark)
8490d163575Sopenharmony_ci{
8500d163575Sopenharmony_ci    int ret;
8510d163575Sopenharmony_ci
8520d163575Sopenharmony_ci    switch (mark) {
8530d163575Sopenharmony_ci        case RM_RECURSIVER:
8540d163575Sopenharmony_ci            ret = os_shell_cmd_do_rmdir(fullpath);
8550d163575Sopenharmony_ci            break;
8560d163575Sopenharmony_ci        case RM_FILE:
8570d163575Sopenharmony_ci            ret = unlink(fullpath);
8580d163575Sopenharmony_ci            break;
8590d163575Sopenharmony_ci        case RM_DIR:
8600d163575Sopenharmony_ci            ret = rmdir(fullpath);
8610d163575Sopenharmony_ci            break;
8620d163575Sopenharmony_ci        default:
8630d163575Sopenharmony_ci            return VFS_ERROR;
8640d163575Sopenharmony_ci    }
8650d163575Sopenharmony_ci    if (ret == -1) {
8660d163575Sopenharmony_ci        PRINTK("%s  ", fullpath);
8670d163575Sopenharmony_ci        perror("rm/rmdir error!");
8680d163575Sopenharmony_ci        return ret;
8690d163575Sopenharmony_ci    }
8700d163575Sopenharmony_ci
8710d163575Sopenharmony_ci    PRINTK("%s match successful!delete!\n", fullpath);
8720d163575Sopenharmony_ci    return 0;
8730d163575Sopenharmony_ci}
8740d163575Sopenharmony_ci
8750d163575Sopenharmony_ci/*  Split the path with wildcard characters  */
8760d163575Sopenharmony_ci
8770d163575Sopenharmony_cistatic char* os_wildcard_split_path(char *fullpath, char **handle, char **wait)
8780d163575Sopenharmony_ci{
8790d163575Sopenharmony_ci    int n = 0;
8800d163575Sopenharmony_ci    int a = 0;
8810d163575Sopenharmony_ci    int b = 0;
8820d163575Sopenharmony_ci    int len  = strlen(fullpath);
8830d163575Sopenharmony_ci
8840d163575Sopenharmony_ci    for (n = 0; n < len; n++) {
8850d163575Sopenharmony_ci        if (fullpath[n] == '/') {
8860d163575Sopenharmony_ci            if (b != 0) {
8870d163575Sopenharmony_ci                fullpath[n] = '\0';
8880d163575Sopenharmony_ci                *wait = fullpath + n + 1;
8890d163575Sopenharmony_ci                break;
8900d163575Sopenharmony_ci            }
8910d163575Sopenharmony_ci            a = n;
8920d163575Sopenharmony_ci        } else if (fullpath[n] == '*' || fullpath[n] == '?') {
8930d163575Sopenharmony_ci            b = n;
8940d163575Sopenharmony_ci            fullpath[a] = '\0';
8950d163575Sopenharmony_ci            if (a == 0) {
8960d163575Sopenharmony_ci                *handle = fullpath + a + 1;
8970d163575Sopenharmony_ci                continue;
8980d163575Sopenharmony_ci            }
8990d163575Sopenharmony_ci            *handle = fullpath + a + 1;
9000d163575Sopenharmony_ci        }
9010d163575Sopenharmony_ci    }
9020d163575Sopenharmony_ci    return fullpath;
9030d163575Sopenharmony_ci}
9040d163575Sopenharmony_ci
9050d163575Sopenharmony_ci/*  Handling entry of the path with wildcard characters  */
9060d163575Sopenharmony_ci
9070d163575Sopenharmony_cistatic int os_wildcard_extract_directory(char *fullpath, void *dst, wildcard_type mark)
9080d163575Sopenharmony_ci{
9090d163575Sopenharmony_ci    char separator[] = "/";
9100d163575Sopenharmony_ci    char src[PATH_MAX] = {0};
9110d163575Sopenharmony_ci    struct dirent *dirent = NULL;
9120d163575Sopenharmony_ci    char *f = NULL;
9130d163575Sopenharmony_ci    char *s = NULL;
9140d163575Sopenharmony_ci    char *t = NULL;
9150d163575Sopenharmony_ci    int ret = 0;
9160d163575Sopenharmony_ci    DIR *d = NULL;
9170d163575Sopenharmony_ci    struct stat stat_buf;
9180d163575Sopenharmony_ci    int deleteFlag = 0;
9190d163575Sopenharmony_ci
9200d163575Sopenharmony_ci    f = os_wildcard_split_path(fullpath, &s, &t);
9210d163575Sopenharmony_ci
9220d163575Sopenharmony_ci    if (s == NULL) {
9230d163575Sopenharmony_ci        if (mark == CP_FILE) {
9240d163575Sopenharmony_ci            ret = os_shell_cmd_do_cp(fullpath, dst);
9250d163575Sopenharmony_ci        } else if (mark == CP_COUNT) {
9260d163575Sopenharmony_ci            ret = stat(fullpath, &stat_buf);
9270d163575Sopenharmony_ci            if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))) {
9280d163575Sopenharmony_ci                (*(int *)dst)++;
9290d163575Sopenharmony_ci            }
9300d163575Sopenharmony_ci        } else {
9310d163575Sopenharmony_ci            ret = os_wildcard_delete_file_or_dir(fullpath, mark);
9320d163575Sopenharmony_ci        }
9330d163575Sopenharmony_ci        return ret;
9340d163575Sopenharmony_ci    }
9350d163575Sopenharmony_ci
9360d163575Sopenharmony_ci    d = (*f == '\0') ? opendir("/") : opendir(f);
9370d163575Sopenharmony_ci    if (d == NULL) {
9380d163575Sopenharmony_ci        perror("opendir error");
9390d163575Sopenharmony_ci        return VFS_ERROR;
9400d163575Sopenharmony_ci    }
9410d163575Sopenharmony_ci
9420d163575Sopenharmony_ci    while (1) {
9430d163575Sopenharmony_ci        dirent = readdir(d);
9440d163575Sopenharmony_ci        if (dirent == NULL) {
9450d163575Sopenharmony_ci            break;
9460d163575Sopenharmony_ci        }
9470d163575Sopenharmony_ci
9480d163575Sopenharmony_ci        ret = strcpy_s(src, PATH_MAX, f);
9490d163575Sopenharmony_ci        if (ret != EOK) {
9500d163575Sopenharmony_ci            goto closedir_out;
9510d163575Sopenharmony_ci        }
9520d163575Sopenharmony_ci
9530d163575Sopenharmony_ci        ret = os_wildcard_match(dirent->d_name, s);
9540d163575Sopenharmony_ci        if (ret == 0) {
9550d163575Sopenharmony_ci            ret = strcat_s(src, sizeof(src), separator);
9560d163575Sopenharmony_ci            if (ret != EOK) {
9570d163575Sopenharmony_ci                goto closedir_out;
9580d163575Sopenharmony_ci            }
9590d163575Sopenharmony_ci            ret = strcat_s(src, sizeof(src), dirent->d_name);
9600d163575Sopenharmony_ci            if (ret != EOK) {
9610d163575Sopenharmony_ci                goto closedir_out;
9620d163575Sopenharmony_ci            }
9630d163575Sopenharmony_ci            if (t == NULL) {
9640d163575Sopenharmony_ci                if (mark == CP_FILE) {
9650d163575Sopenharmony_ci                    ret = os_shell_cmd_do_cp(src, dst);
9660d163575Sopenharmony_ci                } else if (mark == CP_COUNT) {
9670d163575Sopenharmony_ci                    ret = stat(src, &stat_buf);
9680d163575Sopenharmony_ci                    if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))) {
9690d163575Sopenharmony_ci                        (*(int *)dst)++;
9700d163575Sopenharmony_ci                        if ((*(int *)dst) > 1) {
9710d163575Sopenharmony_ci                            break;
9720d163575Sopenharmony_ci                        }
9730d163575Sopenharmony_ci                    }
9740d163575Sopenharmony_ci                } else {
9750d163575Sopenharmony_ci                    ret = os_wildcard_delete_file_or_dir(src, mark);
9760d163575Sopenharmony_ci                    if (ret == 0) {
9770d163575Sopenharmony_ci                        deleteFlag = 1;
9780d163575Sopenharmony_ci                    }
9790d163575Sopenharmony_ci                }
9800d163575Sopenharmony_ci            } else {
9810d163575Sopenharmony_ci                ret = strcat_s(src, sizeof(src), separator);
9820d163575Sopenharmony_ci                if (ret != EOK) {
9830d163575Sopenharmony_ci                    goto closedir_out;
9840d163575Sopenharmony_ci                }
9850d163575Sopenharmony_ci                ret = strcat_s(src, sizeof(src), t);
9860d163575Sopenharmony_ci                if (ret != EOK) {
9870d163575Sopenharmony_ci                    goto closedir_out;
9880d163575Sopenharmony_ci                }
9890d163575Sopenharmony_ci                ret = os_wildcard_extract_directory(src, dst, mark);
9900d163575Sopenharmony_ci                if (mark == CP_COUNT && (*(int *)dst) > 1) {
9910d163575Sopenharmony_ci                    break;
9920d163575Sopenharmony_ci                }
9930d163575Sopenharmony_ci            }
9940d163575Sopenharmony_ci        }
9950d163575Sopenharmony_ci    }
9960d163575Sopenharmony_ci    (void)closedir(d);
9970d163575Sopenharmony_ci    if (deleteFlag == 1) {
9980d163575Sopenharmony_ci        ret = 0;
9990d163575Sopenharmony_ci    }
10000d163575Sopenharmony_ci    return ret;
10010d163575Sopenharmony_ciclosedir_out:
10020d163575Sopenharmony_ci    (void)closedir(d);
10030d163575Sopenharmony_ci    return VFS_ERROR;
10040d163575Sopenharmony_ci}
10050d163575Sopenharmony_ci
10060d163575Sopenharmony_ciint osShellCmdCp(int argc, const char **argv)
10070d163575Sopenharmony_ci{
10080d163575Sopenharmony_ci    int  ret;
10090d163575Sopenharmony_ci    const char *src = NULL;
10100d163575Sopenharmony_ci    const char *dst = NULL;
10110d163575Sopenharmony_ci    char *src_fullpath = NULL;
10120d163575Sopenharmony_ci    char *dst_fullpath = NULL;
10130d163575Sopenharmony_ci    struct stat stat_buf;
10140d163575Sopenharmony_ci    int count = 0;
10150d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
10160d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
10170d163575Sopenharmony_ci        return -1;
10180d163575Sopenharmony_ci    }
10190d163575Sopenharmony_ci
10200d163575Sopenharmony_ci    ERROR_OUT_IF(argc < 2, PRINTK("cp [SOURCEFILE] [DESTFILE]\n"), return -1);
10210d163575Sopenharmony_ci
10220d163575Sopenharmony_ci    src = argv[0];
10230d163575Sopenharmony_ci    dst = argv[1];
10240d163575Sopenharmony_ci
10250d163575Sopenharmony_ci    /* Get source fullpath. */
10260d163575Sopenharmony_ci
10270d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, src, &src_fullpath);
10280d163575Sopenharmony_ci    if (ret < 0) {
10290d163575Sopenharmony_ci        set_errno(-ret);
10300d163575Sopenharmony_ci        PRINTK("cp error:%s\n", strerror(errno));
10310d163575Sopenharmony_ci        return -1;
10320d163575Sopenharmony_ci    }
10330d163575Sopenharmony_ci
10340d163575Sopenharmony_ci    if (src[strlen(src) - 1] == '/') {
10350d163575Sopenharmony_ci        PRINTK("cp %s error: Source file can't be a directory.\n", src);
10360d163575Sopenharmony_ci        goto errout_with_srcpath;
10370d163575Sopenharmony_ci    }
10380d163575Sopenharmony_ci
10390d163575Sopenharmony_ci    /* Get dest fullpath. */
10400d163575Sopenharmony_ci
10410d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, dst, &dst_fullpath);
10420d163575Sopenharmony_ci    if (ret < 0) {
10430d163575Sopenharmony_ci        set_errno(-ret);
10440d163575Sopenharmony_ci        PRINTK("cp error: can't open %s. %s\n", dst, strerror(errno));
10450d163575Sopenharmony_ci        goto errout_with_srcpath;
10460d163575Sopenharmony_ci    }
10470d163575Sopenharmony_ci
10480d163575Sopenharmony_ci    /* Is dest path exist? */
10490d163575Sopenharmony_ci
10500d163575Sopenharmony_ci    ret = stat(dst_fullpath, &stat_buf);
10510d163575Sopenharmony_ci    if (ret < 0) {
10520d163575Sopenharmony_ci        /* Is dest path a directory? */
10530d163575Sopenharmony_ci
10540d163575Sopenharmony_ci        if (dst[strlen(dst) - 1] == '/') {
10550d163575Sopenharmony_ci            PRINTK("cp error: %s, %s.\n", dst_fullpath, strerror(errno));
10560d163575Sopenharmony_ci            goto errout_with_path;
10570d163575Sopenharmony_ci        }
10580d163575Sopenharmony_ci    } else {
10590d163575Sopenharmony_ci        if ((S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)) && dst[strlen(dst) - 1] == '/') {
10600d163575Sopenharmony_ci            PRINTK("cp error: %s is not a directory.\n", dst_fullpath);
10610d163575Sopenharmony_ci            goto errout_with_path;
10620d163575Sopenharmony_ci        }
10630d163575Sopenharmony_ci    }
10640d163575Sopenharmony_ci
10650d163575Sopenharmony_ci    if (os_is_containers_wildcard(src_fullpath)) {
10660d163575Sopenharmony_ci        if (ret < 0 || S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)) {
10670d163575Sopenharmony_ci            char *src_copy = strdup(src_fullpath);
10680d163575Sopenharmony_ci            if (src_copy == NULL) {
10690d163575Sopenharmony_ci                PRINTK("cp error : Out of memory.\n");
10700d163575Sopenharmony_ci                goto errout_with_path;
10710d163575Sopenharmony_ci            }
10720d163575Sopenharmony_ci            (void)os_wildcard_extract_directory(src_copy, &count, CP_COUNT);
10730d163575Sopenharmony_ci            free(src_copy);
10740d163575Sopenharmony_ci            if (count > 1) {
10750d163575Sopenharmony_ci                PRINTK("cp error : %s is not a directory.\n", dst_fullpath);
10760d163575Sopenharmony_ci                goto errout_with_path;
10770d163575Sopenharmony_ci            }
10780d163575Sopenharmony_ci        }
10790d163575Sopenharmony_ci        ret = os_wildcard_extract_directory(src_fullpath, dst_fullpath, CP_FILE);
10800d163575Sopenharmony_ci    } else {
10810d163575Sopenharmony_ci        ret = os_shell_cmd_do_cp(src_fullpath, dst_fullpath);
10820d163575Sopenharmony_ci    }
10830d163575Sopenharmony_ci    free(dst_fullpath);
10840d163575Sopenharmony_ci    free(src_fullpath);
10850d163575Sopenharmony_ci    return ret;
10860d163575Sopenharmony_ci
10870d163575Sopenharmony_cierrout_with_path:
10880d163575Sopenharmony_ci    free(dst_fullpath);
10890d163575Sopenharmony_cierrout_with_srcpath:
10900d163575Sopenharmony_ci    free(src_fullpath);
10910d163575Sopenharmony_ci    return VFS_ERROR;
10920d163575Sopenharmony_ci}
10930d163575Sopenharmony_ci
10940d163575Sopenharmony_cistatic inline void print_rm_usage(void)
10950d163575Sopenharmony_ci{
10960d163575Sopenharmony_ci    PRINTK("rm [FILE] or rm [-r/-R] [FILE]\n");
10970d163575Sopenharmony_ci}
10980d163575Sopenharmony_ci
10990d163575Sopenharmony_ciint osShellCmdRm(int argc, const char **argv)
11000d163575Sopenharmony_ci{
11010d163575Sopenharmony_ci    int  ret = 0;
11020d163575Sopenharmony_ci    char *fullpath = NULL;
11030d163575Sopenharmony_ci    const char *filename = NULL;
11040d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
11050d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
11060d163575Sopenharmony_ci        return -1;
11070d163575Sopenharmony_ci    }
11080d163575Sopenharmony_ci
11090d163575Sopenharmony_ci    ERROR_OUT_IF(argc != 1 && argc != 2, print_rm_usage(), return -1);
11100d163575Sopenharmony_ci
11110d163575Sopenharmony_ci    if (argc == 2) { // 2: arguments include "-r" or "-R"
11120d163575Sopenharmony_ci        ERROR_OUT_IF(strcmp(argv[0], "-r") != 0 && strcmp(argv[0], "-R") != 0, print_rm_usage(), return -1);
11130d163575Sopenharmony_ci
11140d163575Sopenharmony_ci        filename = argv[1];
11150d163575Sopenharmony_ci        ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
11160d163575Sopenharmony_ci        ERROR_OUT_IF(ret < 0, set_err(-ret, "rm error"), return -1);
11170d163575Sopenharmony_ci
11180d163575Sopenharmony_ci        if (os_is_containers_wildcard(fullpath)) {
11190d163575Sopenharmony_ci            ret = os_wildcard_extract_directory(fullpath, NULL, RM_RECURSIVER);
11200d163575Sopenharmony_ci        } else {
11210d163575Sopenharmony_ci            ret = os_shell_cmd_do_rmdir(fullpath);
11220d163575Sopenharmony_ci        }
11230d163575Sopenharmony_ci    } else {
11240d163575Sopenharmony_ci        filename = argv[0];
11250d163575Sopenharmony_ci        ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
11260d163575Sopenharmony_ci        ERROR_OUT_IF(ret < 0, set_err(-ret, "rm error"), return -1);
11270d163575Sopenharmony_ci
11280d163575Sopenharmony_ci        if (os_is_containers_wildcard(fullpath)) {
11290d163575Sopenharmony_ci            ret = os_wildcard_extract_directory(fullpath, NULL, RM_FILE);
11300d163575Sopenharmony_ci        } else {
11310d163575Sopenharmony_ci            ret = unlink(fullpath);
11320d163575Sopenharmony_ci        }
11330d163575Sopenharmony_ci    }
11340d163575Sopenharmony_ci    if (ret == -1) {
11350d163575Sopenharmony_ci        perror("rm error");
11360d163575Sopenharmony_ci    }
11370d163575Sopenharmony_ci    free(fullpath);
11380d163575Sopenharmony_ci    return 0;
11390d163575Sopenharmony_ci}
11400d163575Sopenharmony_ci
11410d163575Sopenharmony_ciint osShellCmdRmdir(int argc, const char **argv)
11420d163575Sopenharmony_ci{
11430d163575Sopenharmony_ci    int  ret;
11440d163575Sopenharmony_ci    char *fullpath = NULL;
11450d163575Sopenharmony_ci    const char *filename = NULL;
11460d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
11470d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
11480d163575Sopenharmony_ci        return -1;
11490d163575Sopenharmony_ci    }
11500d163575Sopenharmony_ci
11510d163575Sopenharmony_ci    ERROR_OUT_IF(argc == 0, PRINTK("rmdir [DIRECTORY]\n"), return -1);
11520d163575Sopenharmony_ci
11530d163575Sopenharmony_ci    filename = argv[0];
11540d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
11550d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "rmdir error"), return -1);
11560d163575Sopenharmony_ci
11570d163575Sopenharmony_ci    if (os_is_containers_wildcard(fullpath)) {
11580d163575Sopenharmony_ci        ret = os_wildcard_extract_directory(fullpath, NULL, RM_DIR);
11590d163575Sopenharmony_ci    } else {
11600d163575Sopenharmony_ci        ret = rmdir(fullpath);
11610d163575Sopenharmony_ci    }
11620d163575Sopenharmony_ci    if (ret == -1) {
11630d163575Sopenharmony_ci        PRINTK("rmdir %s failed. Error: %s.\n", fullpath, strerror(errno));
11640d163575Sopenharmony_ci    }
11650d163575Sopenharmony_ci    free(fullpath);
11660d163575Sopenharmony_ci
11670d163575Sopenharmony_ci    return 0;
11680d163575Sopenharmony_ci}
11690d163575Sopenharmony_ci
11700d163575Sopenharmony_ciint osShellCmdSync(int argc, const char **argv)
11710d163575Sopenharmony_ci{
11720d163575Sopenharmony_ci    ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: sync\n"), return -1);
11730d163575Sopenharmony_ci
11740d163575Sopenharmony_ci    sync();
11750d163575Sopenharmony_ci    return 0;
11760d163575Sopenharmony_ci}
11770d163575Sopenharmony_ci
11780d163575Sopenharmony_ciint osShellCmdLsfd(int argc, const char **argv)
11790d163575Sopenharmony_ci{
11800d163575Sopenharmony_ci    ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: lsfd\n"), return -1);
11810d163575Sopenharmony_ci
11820d163575Sopenharmony_ci    lsfd();
11830d163575Sopenharmony_ci
11840d163575Sopenharmony_ci    return 0;
11850d163575Sopenharmony_ci}
11860d163575Sopenharmony_ci
11870d163575Sopenharmony_ciint checkNum(const char *arg)
11880d163575Sopenharmony_ci{
11890d163575Sopenharmony_ci    int i = 0;
11900d163575Sopenharmony_ci    if (arg == NULL) {
11910d163575Sopenharmony_ci        return -1;
11920d163575Sopenharmony_ci    }
11930d163575Sopenharmony_ci    if (arg[0] == '-') {
11940d163575Sopenharmony_ci        /* exclude the '-' */
11950d163575Sopenharmony_ci
11960d163575Sopenharmony_ci        i = 1;
11970d163575Sopenharmony_ci    }
11980d163575Sopenharmony_ci    for (; arg[i] != 0; i++) {
11990d163575Sopenharmony_ci        if (!isdigit(arg[i])) {
12000d163575Sopenharmony_ci            return -1;
12010d163575Sopenharmony_ci        }
12020d163575Sopenharmony_ci    }
12030d163575Sopenharmony_ci    return 0;
12040d163575Sopenharmony_ci}
12050d163575Sopenharmony_ci
12060d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_SYSCALL
12070d163575Sopenharmony_ciint osShellCmdSu(int argc, const char **argv)
12080d163575Sopenharmony_ci{
12090d163575Sopenharmony_ci    int su_uid;
12100d163575Sopenharmony_ci    int su_gid;
12110d163575Sopenharmony_ci
12120d163575Sopenharmony_ci    if (argc == 0) {
12130d163575Sopenharmony_ci        /* for su root */
12140d163575Sopenharmony_ci
12150d163575Sopenharmony_ci        su_uid = 0;
12160d163575Sopenharmony_ci        su_gid = 0;
12170d163575Sopenharmony_ci    } else {
12180d163575Sopenharmony_ci        ERROR_OUT_IF((argc != 2), PRINTK("su [uid_num] [gid_num]\n"), return -1);
12190d163575Sopenharmony_ci        ERROR_OUT_IF((checkNum(argv[0]) != 0) || (checkNum(argv[1]) != 0), /* check argv is digit */
12200d163575Sopenharmony_ci        PRINTK("check uid_num and gid_num is digit\n"), return -1);
12210d163575Sopenharmony_ci
12220d163575Sopenharmony_ci        su_uid = atoi(argv[0]);
12230d163575Sopenharmony_ci        su_gid = atoi(argv[1]);
12240d163575Sopenharmony_ci
12250d163575Sopenharmony_ci        ERROR_OUT_IF((su_uid < 0) || (su_uid > 60000) || (su_gid < 0) ||
12260d163575Sopenharmony_ci            (su_gid > 60000), PRINTK("uid_num or gid_num out of range!they should be [0~60000]\n"), return -1);
12270d163575Sopenharmony_ci    }
12280d163575Sopenharmony_ci
12290d163575Sopenharmony_ci    SysSetUserID(su_uid);
12300d163575Sopenharmony_ci    SysSetGroupID(su_gid);
12310d163575Sopenharmony_ci    return 0;
12320d163575Sopenharmony_ci}
12330d163575Sopenharmony_ci#endif
12340d163575Sopenharmony_ci
12350d163575Sopenharmony_ciint osShellCmdChmod(int argc, const char **argv)
12360d163575Sopenharmony_ci{
12370d163575Sopenharmony_ci    int i = 0;
12380d163575Sopenharmony_ci    int mode = 0;
12390d163575Sopenharmony_ci    int ret;
12400d163575Sopenharmony_ci    char *fullpath = NULL;
12410d163575Sopenharmony_ci    const char *filename = NULL;
12420d163575Sopenharmony_ci    struct IATTR attr = {0};
12430d163575Sopenharmony_ci    char *shell_working_directory = NULL;
12440d163575Sopenharmony_ci    const char *p = NULL;
12450d163575Sopenharmony_ci#define MODE_BIT 3 /* 3 bits express 1 mode */
12460d163575Sopenharmony_ci
12470d163575Sopenharmony_ci    ERROR_OUT_IF((argc != 2), PRINTK("Usage: chmod <MODE> [FILE]\n"), return -1);
12480d163575Sopenharmony_ci
12490d163575Sopenharmony_ci    p = argv[0];
12500d163575Sopenharmony_ci    while (p[i]) {
12510d163575Sopenharmony_ci        if ((p[i] <= '7') && (p[i] >= '0')) {
12520d163575Sopenharmony_ci            mode = ((uint)mode << MODE_BIT) | (uint)(p[i] - '0');
12530d163575Sopenharmony_ci        } else {
12540d163575Sopenharmony_ci            PRINTK("check the input <MODE>\n");
12550d163575Sopenharmony_ci            return -1;
12560d163575Sopenharmony_ci        }
12570d163575Sopenharmony_ci        i++;
12580d163575Sopenharmony_ci    }
12590d163575Sopenharmony_ci    filename = argv[1];
12600d163575Sopenharmony_ci
12610d163575Sopenharmony_ci    shell_working_directory = OsShellGetWorkingDirectory();
12620d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
12630d163575Sopenharmony_ci        return -1;
12640d163575Sopenharmony_ci    }
12650d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
12660d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "chmod error\n"), return -1);
12670d163575Sopenharmony_ci
12680d163575Sopenharmony_ci    attr.attr_chg_mode = mode;
12690d163575Sopenharmony_ci    attr.attr_chg_valid = CHG_MODE; /* change mode */
12700d163575Sopenharmony_ci    ret = chattr(fullpath, &attr);
12710d163575Sopenharmony_ci    if (ret < 0) {
12720d163575Sopenharmony_ci        free(fullpath);
12730d163575Sopenharmony_ci        PRINTK("chmod error! %s\n", strerror(errno));
12740d163575Sopenharmony_ci        return ret;
12750d163575Sopenharmony_ci    }
12760d163575Sopenharmony_ci
12770d163575Sopenharmony_ci    free(fullpath);
12780d163575Sopenharmony_ci    return 0;
12790d163575Sopenharmony_ci}
12800d163575Sopenharmony_ci
12810d163575Sopenharmony_ciint osShellCmdChown(int argc, const char **argv)
12820d163575Sopenharmony_ci{
12830d163575Sopenharmony_ci    int ret;
12840d163575Sopenharmony_ci    char *fullpath = NULL;
12850d163575Sopenharmony_ci    const char *filename = NULL;
12860d163575Sopenharmony_ci    struct IATTR attr;
12870d163575Sopenharmony_ci    uid_t owner = -1;
12880d163575Sopenharmony_ci    gid_t group = -1;
12890d163575Sopenharmony_ci    attr.attr_chg_valid = 0;
12900d163575Sopenharmony_ci
12910d163575Sopenharmony_ci    ERROR_OUT_IF(((argc != 2) && (argc != 3)), PRINTK("Usage: chown [OWNER] [GROUP] FILE\n"), return -1);
12920d163575Sopenharmony_ci    if (argc == 2) { // 2: chown owner of file
12930d163575Sopenharmony_ci        ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check OWNER is digit\n"), return -1);
12940d163575Sopenharmony_ci        owner = atoi(argv[0]);
12950d163575Sopenharmony_ci        filename = argv[1];
12960d163575Sopenharmony_ci    }
12970d163575Sopenharmony_ci    if (argc == 3) { // 3: chown both owner and group
12980d163575Sopenharmony_ci        ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check OWNER is digit\n"), return -1);
12990d163575Sopenharmony_ci        ERROR_OUT_IF((checkNum(argv[1]) != 0), PRINTK("check GROUP is digit\n"), return -1);
13000d163575Sopenharmony_ci        owner = atoi(argv[0]);
13010d163575Sopenharmony_ci        group = atoi(argv[1]);
13020d163575Sopenharmony_ci        filename = argv[2];
13030d163575Sopenharmony_ci    }
13040d163575Sopenharmony_ci
13050d163575Sopenharmony_ci    if (group != -1) {
13060d163575Sopenharmony_ci        attr.attr_chg_gid = group;
13070d163575Sopenharmony_ci        attr.attr_chg_valid |= CHG_GID;
13080d163575Sopenharmony_ci    }
13090d163575Sopenharmony_ci    if (owner != -1) {
13100d163575Sopenharmony_ci        attr.attr_chg_uid = owner;
13110d163575Sopenharmony_ci        attr.attr_chg_valid |= CHG_UID;
13120d163575Sopenharmony_ci    }
13130d163575Sopenharmony_ci
13140d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
13150d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
13160d163575Sopenharmony_ci        return -1;
13170d163575Sopenharmony_ci    }
13180d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
13190d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "chown error\n"), return -1);
13200d163575Sopenharmony_ci
13210d163575Sopenharmony_ci    ret = chattr(fullpath, &attr);
13220d163575Sopenharmony_ci    if (ret < 0) {
13230d163575Sopenharmony_ci        free(fullpath);
13240d163575Sopenharmony_ci        PRINTK("chown error! %s\n", strerror(errno));
13250d163575Sopenharmony_ci        return ret;
13260d163575Sopenharmony_ci    }
13270d163575Sopenharmony_ci
13280d163575Sopenharmony_ci    free(fullpath);
13290d163575Sopenharmony_ci    return 0;
13300d163575Sopenharmony_ci}
13310d163575Sopenharmony_ci
13320d163575Sopenharmony_ciint osShellCmdChgrp(int argc, const char **argv)
13330d163575Sopenharmony_ci{
13340d163575Sopenharmony_ci    int ret;
13350d163575Sopenharmony_ci    char *fullpath = NULL;
13360d163575Sopenharmony_ci    const char *filename = NULL;
13370d163575Sopenharmony_ci    struct IATTR attr;
13380d163575Sopenharmony_ci    gid_t group;
13390d163575Sopenharmony_ci    attr.attr_chg_valid = 0;
13400d163575Sopenharmony_ci    ERROR_OUT_IF((argc != 2), PRINTK("Usage: chgrp GROUP FILE\n"), return -1);
13410d163575Sopenharmony_ci    ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check GROUP is digit\n"), return -1);
13420d163575Sopenharmony_ci    group = atoi(argv[0]);
13430d163575Sopenharmony_ci    filename = argv[1];
13440d163575Sopenharmony_ci
13450d163575Sopenharmony_ci    if (group != -1) {
13460d163575Sopenharmony_ci        attr.attr_chg_gid = group;
13470d163575Sopenharmony_ci        attr.attr_chg_valid |= CHG_GID;
13480d163575Sopenharmony_ci    }
13490d163575Sopenharmony_ci
13500d163575Sopenharmony_ci    char *shell_working_directory = OsShellGetWorkingDirectory();
13510d163575Sopenharmony_ci    if (shell_working_directory == NULL) {
13520d163575Sopenharmony_ci        return -1;
13530d163575Sopenharmony_ci    }
13540d163575Sopenharmony_ci    ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
13550d163575Sopenharmony_ci    ERROR_OUT_IF(ret < 0, set_err(-ret, "chmod error"), return -1);
13560d163575Sopenharmony_ci
13570d163575Sopenharmony_ci    ret = chattr(fullpath, &attr);
13580d163575Sopenharmony_ci    if (ret < 0) {
13590d163575Sopenharmony_ci        free(fullpath);
13600d163575Sopenharmony_ci        PRINTK("chgrp error! %s\n", strerror(errno));
13610d163575Sopenharmony_ci        return ret;
13620d163575Sopenharmony_ci    }
13630d163575Sopenharmony_ci
13640d163575Sopenharmony_ci    free(fullpath);
13650d163575Sopenharmony_ci    return 0;
13660d163575Sopenharmony_ci}
13670d163575Sopenharmony_ci
13680d163575Sopenharmony_ci#ifdef LOSCFG_SHELL_CMD_DEBUG
13690d163575Sopenharmony_ciSHELLCMD_ENTRY(lsfd_shellcmd, CMD_TYPE_EX, "lsfd", XARGS, (CmdCallBackFunc)osShellCmdLsfd);
13700d163575Sopenharmony_ciSHELLCMD_ENTRY(statfs_shellcmd, CMD_TYPE_EX, "statfs", XARGS, (CmdCallBackFunc)osShellCmdStatfs);
13710d163575Sopenharmony_ciSHELLCMD_ENTRY(touch_shellcmd, CMD_TYPE_EX, "touch", XARGS, (CmdCallBackFunc)osShellCmdTouch);
13720d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_SYSCALL
13730d163575Sopenharmony_ciSHELLCMD_ENTRY(su_shellcmd, CMD_TYPE_EX, "su", XARGS, (CmdCallBackFunc)osShellCmdSu);
13740d163575Sopenharmony_ci#endif
13750d163575Sopenharmony_ci#endif
13760d163575Sopenharmony_ciSHELLCMD_ENTRY(sync_shellcmd, CMD_TYPE_EX, "sync", XARGS, (CmdCallBackFunc)osShellCmdSync);
13770d163575Sopenharmony_ciSHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CmdCallBackFunc)osShellCmdLs);
13780d163575Sopenharmony_ciSHELLCMD_ENTRY(pwd_shellcmd, CMD_TYPE_EX, "pwd", XARGS, (CmdCallBackFunc)osShellCmdPwd);
13790d163575Sopenharmony_ciSHELLCMD_ENTRY(cd_shellcmd, CMD_TYPE_EX, "cd", XARGS, (CmdCallBackFunc)osShellCmdCd);
13800d163575Sopenharmony_ciSHELLCMD_ENTRY(cat_shellcmd, CMD_TYPE_EX, "cat", XARGS, (CmdCallBackFunc)osShellCmdCat);
13810d163575Sopenharmony_ciSHELLCMD_ENTRY(rm_shellcmd, CMD_TYPE_EX, "rm", XARGS, (CmdCallBackFunc)osShellCmdRm);
13820d163575Sopenharmony_ciSHELLCMD_ENTRY(rmdir_shellcmd, CMD_TYPE_EX, "rmdir", XARGS, (CmdCallBackFunc)osShellCmdRmdir);
13830d163575Sopenharmony_ciSHELLCMD_ENTRY(mkdir_shellcmd, CMD_TYPE_EX, "mkdir", XARGS, (CmdCallBackFunc)osShellCmdMkdir);
13840d163575Sopenharmony_ciSHELLCMD_ENTRY(chmod_shellcmd, CMD_TYPE_EX, "chmod", XARGS, (CmdCallBackFunc)osShellCmdChmod);
13850d163575Sopenharmony_ciSHELLCMD_ENTRY(chown_shellcmd, CMD_TYPE_EX, "chown", XARGS, (CmdCallBackFunc)osShellCmdChown);
13860d163575Sopenharmony_ciSHELLCMD_ENTRY(chgrp_shellcmd, CMD_TYPE_EX, "chgrp", XARGS, (CmdCallBackFunc)osShellCmdChgrp);
13870d163575Sopenharmony_ciSHELLCMD_ENTRY(mount_shellcmd, CMD_TYPE_EX, "mount", XARGS, (CmdCallBackFunc)osShellCmdMount);
13880d163575Sopenharmony_ciSHELLCMD_ENTRY(umount_shellcmd, CMD_TYPE_EX, "umount", XARGS, (CmdCallBackFunc)osShellCmdUmount);
13890d163575Sopenharmony_ciSHELLCMD_ENTRY(cp_shellcmd, CMD_TYPE_EX, "cp", XARGS, (CmdCallBackFunc)osShellCmdCp);
13900d163575Sopenharmony_ci#endif
1391