aboutsummaryrefslogtreecommitdiff
path: root/coreutils/rmdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/rmdir.c')
-rw-r--r--coreutils/rmdir.c70
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;
}