• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "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