1 #include <stdio.h>
2 #include <dirent.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <unistd.h>
6 #include <sys/stat.h>
7 #include <aos/cli.h>
8 #include <stdbool.h>
9 #include <fcntl.h>
10 #include <stdlib.h>
11 #include <path_helper.h>
12
show_help(void)13 static void show_help(void)
14 {
15 aos_cli_printf("Usage:\n"
16 "rm <file1> [<file2>...]\n"
17 "rm -r <dir>\n");
18 }
19
rrmdir(const char * path)20 int rrmdir(const char *path)
21 {
22 struct stat s;
23 DIR *pdir = NULL;
24 struct dirent *entry = NULL;
25 int ret = -1;
26 char *dir, *p;
27
28 if (!path)
29 return -EINVAL;
30
31 dir = strdup(path);
32 p = dir + strlen(dir) - 1;
33 while ((*p == '/') && (p > dir)) {
34 *p = '\0';
35 p--;
36 }
37
38 if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
39 aos_cli_printf("%s is neither existed nor a directory\n", dir);
40 goto out;
41 }
42
43 pdir = opendir(dir);
44 if (!pdir) {
45 aos_cli_printf("opendir %s failed - %s\n", dir, strerror(errno));
46 goto out;
47 }
48
49 ret = 0;
50 while ((ret == 0) && (entry = readdir(pdir))) {
51 char fpath[128];
52
53 snprintf(fpath, 128, "%s/%s", dir, entry->d_name);
54
55 ret = stat(fpath, &s);
56 if (ret) {
57 aos_cli_printf("stat %s failed\n", fpath);
58 break;
59 }
60
61 if (!strcmp(entry->d_name, "."))
62 continue;
63 if (!strcmp(entry->d_name, ".."))
64 continue;
65
66 if (S_ISDIR(s.st_mode))
67 ret = rrmdir(fpath);
68 else
69 ret = unlink(fpath);
70 }
71
72 closedir(pdir);
73 if (ret == 0) {
74 ret = rmdir(dir);
75 if (ret)
76 aos_cli_printf("rmdir %s failed\n", dir);
77 }
78 out:
79 free(dir);
80 return ret;
81 }
82
83 #define RM_FLAG_RECURSION (1 << 0)
rm_main(int argc,char ** argv)84 static int rm_main(int argc, char **argv)
85 {
86 int opts = 0, flags = 0, index, ret = 0;
87
88 optind = 0;
89 while ((opts = getopt(argc, argv, ":r")) != EOF) {
90 switch (opts) {
91 case 'r':
92 flags |= RM_FLAG_RECURSION;
93 break;
94 case '?':
95 aos_cli_printf("invalid option %c\n", optopt);
96 return -1;
97 case ':':
98 aos_cli_printf("option -%c requires an argument\n", optopt);
99 show_help();
100 return -1;
101 }
102 }
103
104 argc -= optind;
105 argv += optind;
106
107 if (argc < 1) {
108 show_help();
109 return -1;
110 }
111
112 for (index = 0; index < argc; index++) {
113 struct stat s;
114 char *path = argv[index];
115 char abspath[256] = {0};
116
117 path = get_realpath(path, abspath, sizeof(abspath));
118 if (!path) {
119 aos_cli_printf("Failed to get real path!\r\n");
120 return -1;
121 }
122
123 if (!stat(path, &s) && S_ISREG(s.st_mode)) {
124 ret |= unlink(path);
125 aos_cli_printf("remove %s\n", path);
126 continue;
127 }
128
129 if (flags & RM_FLAG_RECURSION) {
130 aos_cli_printf("remove dir %s\n", path);
131 ret |= rrmdir(path);
132 continue;
133 }
134
135 ret |= -ENOENT;
136 aos_cli_printf("%s is neither existed nor a directory\n", path);
137 }
138
139 return ret;
140 }
141 ALIOS_CLI_CMD_REGISTER(rm_main, rm, remove file);
142