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