diff options
Diffstat (limited to 'coreutils/rmdir.c')
-rw-r--r-- | coreutils/rmdir.c | 70 |
1 files changed, 61 insertions, 9 deletions
diff --git a/coreutils/rmdir.c b/coreutils/rmdir.c index 2c280376f..cac27cac9 100644 --- a/coreutils/rmdir.c +++ b/coreutils/rmdir.c @@ -22,24 +22,76 @@ * */ -#include <stdio.h> -#include <errno.h> +#include <getopt.h> #include <unistd.h> #include <stdlib.h> + #include "busybox.h" -extern int rmdir_main(int argc, char **argv) + +/* Return true if a path is composed of multiple components. */ + +static int +multiple_components_p (const char *path) +{ + const char *s = path; + + while (s[0] != '\0' && s[0] != '/') + s++; + + while (s[0] == '/') + s++; + + return (s[0] != '\0'); +} + + +/* Remove a directory. Returns 0 if successful, -1 on error. */ + +static int +remove_directory (char *path, int flags) +{ + if (!(flags & FILEUTILS_RECUR)) { + if (rmdir (path) < 0) { + perror_msg ("unable to remove `%s'", path); + return -1; + } + } else { + if (remove_directory (path, 0) < 0) + return -1; + + if (multiple_components_p (path)) + if (remove_directory (dirname (path), flags) < 0) + return -1; + } + + return 0; +} + + +extern int +rmdir_main (int argc, char **argv) { int status = EXIT_SUCCESS; + int flags = 0; + int i, opt; - if (argc == 1 || **(argv + 1) == '-') + while ((opt = getopt (argc, argv, "p")) != -1) + switch (opt) { + case 'p': + flags |= FILEUTILS_RECUR; + break; + + default: + show_usage (); + } + + if (optind == argc) show_usage(); - while (--argc > 0) { - if (rmdir(*(++argv)) == -1) { - perror_msg("%s", *argv); + for (i = optind; i < argc; i++) + if (remove_directory (argv[i], flags) < 0) status = EXIT_FAILURE; - } - } + return status; } |