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