blob: cc2dea010ce5bfa3eed40ff16ab1fb85a896c019
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 | |
10 | /* BB_AUDIT SUSv3 compliant */ |
11 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */ |
12 | |
13 | //usage:#define rmdir_trivial_usage |
14 | //usage: "[OPTIONS] DIRECTORY..." |
15 | //usage:#define rmdir_full_usage "\n\n" |
16 | //usage: "Remove DIRECTORY if it is empty\n" |
17 | //usage: IF_FEATURE_RMDIR_LONG_OPTIONS( |
18 | //usage: "\n -p|--parents Include parents" |
19 | //usage: "\n --ignore-fail-on-non-empty" |
20 | //usage: ) |
21 | //usage: IF_NOT_FEATURE_RMDIR_LONG_OPTIONS( |
22 | //usage: "\n -p Include parents" |
23 | //usage: ) |
24 | //usage: |
25 | //usage:#define rmdir_example_usage |
26 | //usage: "# rmdir /tmp/foo\n" |
27 | |
28 | #include "libbb.h" |
29 | |
30 | /* This is a NOFORK applet. Be very careful! */ |
31 | |
32 | |
33 | #define PARENTS (1 << 0) |
34 | //efine VERBOSE (1 << 1) //accepted but ignored |
35 | #define IGNORE_NON_EMPTY (1 << 2) |
36 | |
37 | int rmdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
38 | int rmdir_main(int argc UNUSED_PARAM, char **argv) |
39 | { |
40 | int status = EXIT_SUCCESS; |
41 | int flags; |
42 | char *path; |
43 | |
44 | #if ENABLE_FEATURE_RMDIR_LONG_OPTIONS |
45 | static const char rmdir_longopts[] ALIGN1 = |
46 | "parents\0" No_argument "p" |
47 | "verbose\0" No_argument "v" |
48 | /* Debian etch: many packages fail to be purged or installed |
49 | * because they desperately want this option: */ |
50 | "ignore-fail-on-non-empty\0" No_argument "\xff" |
51 | ; |
52 | applet_long_options = rmdir_longopts; |
53 | #endif |
54 | flags = getopt32(argv, "pv"); |
55 | argv += optind; |
56 | |
57 | if (!*argv) { |
58 | bb_show_usage(); |
59 | } |
60 | |
61 | do { |
62 | path = *argv; |
63 | |
64 | while (1) { |
65 | if (rmdir(path) < 0) { |
66 | #if ENABLE_FEATURE_RMDIR_LONG_OPTIONS |
67 | if ((flags & IGNORE_NON_EMPTY) && errno == ENOTEMPTY) |
68 | break; |
69 | #endif |
70 | bb_perror_msg("'%s'", path); /* Match gnu rmdir msg. */ |
71 | status = EXIT_FAILURE; |
72 | } else if (flags & PARENTS) { |
73 | /* Note: path was not "" since rmdir succeeded. */ |
74 | path = dirname(path); |
75 | /* Path is now just the parent component. Dirname |
76 | * returns "." if there are no parents. |
77 | */ |
78 | if (NOT_LONE_CHAR(path, '.')) { |
79 | continue; |
80 | } |
81 | } |
82 | break; |
83 | } |
84 | } while (*++argv); |
85 | |
86 | return status; |
87 | } |
88 |