summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'toolbox/rm.c')
-rw-r--r--toolbox/rm.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/toolbox/rm.c b/toolbox/rm.c
new file mode 100644
index 000000000..bd6631181
--- /dev/null
+++ b/toolbox/rm.c
@@ -0,0 +1,92 @@
1#include <stdio.h>
2#include <unistd.h>
3#include <string.h>
4#include <errno.h>
5#include <dirent.h>
6#include <limits.h>
7#include <sys/stat.h>
8#include <sys/types.h>
9
10static int usage()
11{
12 fprintf(stderr,"rm [-rR] <target>\n");
13 return -1;
14}
15
16/* return -1 on failure, with errno set to the first error */
17static int unlink_recursive(const char* name)
18{
19 struct stat st;
20 DIR *dir;
21 struct dirent *de;
22 int fail = 0;
23
24 /* is it a file or directory? */
25 if (lstat(name, &st) < 0)
26 return -1;
27
28 /* a file, so unlink it */
29 if (!S_ISDIR(st.st_mode))
30 return unlink(name);
31
32 /* a directory, so open handle */
33 dir = opendir(name);
34 if (dir == NULL)
35 return -1;
36
37 /* recurse over components */
38 errno = 0;
39 while ((de = readdir(dir)) != NULL) {
40 char dn[PATH_MAX];
41 if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, "."))
42 continue;
43 sprintf(dn, "%s/%s", name, de->d_name);
44 if (unlink_recursive(dn) < 0) {
45 fail = 1;
46 break;
47 }
48 errno = 0;
49 }
50 /* in case readdir or unlink_recursive failed */
51 if (fail || errno < 0) {
52 int save = errno;
53 closedir(dir);
54 errno = save;
55 return -1;
56 }
57
58 /* close directory handle */
59 if (closedir(dir) < 0)
60 return -1;
61
62 /* delete target directory */
63 return rmdir(name);
64}
65
66int rm_main(int argc, char *argv[])
67{
68 int ret;
69 int i = 1;
70 int recursive = 0;
71
72 if (argc < 2)
73 return usage();
74
75 /* check if recursive */
76 if (argc >=2 && (!strcmp(argv[1], "-r") || !strcmp(argv[1], "-R"))) {
77 recursive = 1;
78 i = 2;
79 }
80
81 /* loop over the file/directory args */
82 for (; i < argc; i++) {
83 int ret = recursive ? unlink_recursive(argv[i]) : unlink(argv[i]);
84 if (ret < 0) {
85 fprintf(stderr, "rm failed for %s, %s\n", argv[i], strerror(errno));
86 return -1;
87 }
88 }
89
90 return 0;
91}
92