hush: if we did match "LINENO" or "OPTIND", stop further comparisons
[oweals/busybox.git] / coreutils / rmdir.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * rmdir implementation for busybox
4  *
5  * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
6  *
7  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8  */
9 //config:config RMDIR
10 //config:       bool "rmdir (3.4 kb)"
11 //config:       default y
12 //config:       help
13 //config:       rmdir is used to remove empty directories.
14
15 //applet:IF_RMDIR(APPLET_NOFORK(rmdir, rmdir, BB_DIR_BIN, BB_SUID_DROP, rmdir))
16
17 //kbuild:lib-$(CONFIG_RMDIR) += rmdir.o
18
19 /* BB_AUDIT SUSv3 compliant */
20 /* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */
21
22 //usage:#define rmdir_trivial_usage
23 //usage:       "[OPTIONS] DIRECTORY..."
24 //usage:#define rmdir_full_usage "\n\n"
25 //usage:       "Remove DIRECTORY if it is empty\n"
26 //usage:     "\n        -p      Include parents"
27 //usage:        IF_LONG_OPTS(
28 //usage:     "\n        --ignore-fail-on-non-empty"
29 //usage:        )
30 //usage:
31 //usage:#define rmdir_example_usage
32 //usage:       "# rmdir /tmp/foo\n"
33
34 #include "libbb.h"
35
36 /* This is a NOFORK applet. Be very careful! */
37
38
39 #define PARENTS          (1 << 0)
40 #define VERBOSE          ((1 << 1) * ENABLE_FEATURE_VERBOSE)
41 #define IGNORE_NON_EMPTY ((1 << 2) * ENABLE_LONG_OPTS)
42
43 int rmdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
44 int rmdir_main(int argc UNUSED_PARAM, char **argv)
45 {
46         int status = EXIT_SUCCESS;
47         int flags;
48         char *path;
49
50         flags = getopt32long(argv, "pv",
51                 "parents\0"                  No_argument "p"
52                 /* Debian etch: many packages fail to be purged or installed
53                  * because they desperately want this option: */
54                 "ignore-fail-on-non-empty\0" No_argument "\xff"
55                 IF_FEATURE_VERBOSE(
56                 "verbose\0"                  No_argument "v"
57                 )
58         );
59         argv += optind;
60
61         if (!*argv) {
62                 bb_show_usage();
63         }
64
65         do {
66                 path = *argv;
67
68                 while (1) {
69                         if (flags & VERBOSE) {
70                                 printf("rmdir: removing directory, '%s'\n", path);
71                         }
72
73                         if (rmdir(path) < 0) {
74 #if ENABLE_LONG_OPTS
75                                 if ((flags & IGNORE_NON_EMPTY) && errno == ENOTEMPTY)
76                                         break;
77 #endif
78                                 bb_perror_msg("'%s'", path);  /* Match gnu rmdir msg. */
79                                 status = EXIT_FAILURE;
80                         } else if (flags & PARENTS) {
81                                 /* Note: path was not "" since rmdir succeeded. */
82                                 path = dirname(path);
83                                 /* Path is now just the parent component.  Dirname
84                                  * returns "." if there are no parents.
85                                  */
86                                 if (NOT_LONE_CHAR(path, '.')) {
87                                         continue;
88                                 }
89                         }
90                         break;
91                 }
92         } while (*++argv);
93
94         return status;
95 }