10 |
/* BB_AUDIT SUSv3 compliant */ |
/* BB_AUDIT SUSv3 compliant */ |
11 |
/* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */ |
/* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */ |
12 |
|
|
13 |
#include <stdlib.h> |
#include "libbb.h" |
|
#include <unistd.h> |
|
|
#include <libgen.h> |
|
|
#include "busybox.h" |
|
14 |
|
|
15 |
int rmdir_main(int argc, char **argv) |
/* This is a NOFORK applet. Be very careful! */ |
16 |
|
|
17 |
|
|
18 |
|
#define PARENTS 0x01 |
19 |
|
#define IGNORE_NON_EMPTY 0x02 |
20 |
|
|
21 |
|
int rmdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
22 |
|
int rmdir_main(int argc UNUSED_PARAM, char **argv) |
23 |
{ |
{ |
24 |
int status = EXIT_SUCCESS; |
int status = EXIT_SUCCESS; |
25 |
int flags; |
int flags; |
|
int do_dot; |
|
26 |
char *path; |
char *path; |
27 |
|
|
28 |
flags = getopt32(argc, argv, "p"); |
#if ENABLE_FEATURE_RMDIR_LONG_OPTIONS |
29 |
|
static const char rmdir_longopts[] ALIGN1 = |
30 |
|
"parents\0" No_argument "p" |
31 |
|
/* Debian etch: many packages fail to be purged or installed |
32 |
|
* because they desperately want this option: */ |
33 |
|
"ignore-fail-on-non-empty\0" No_argument "\xff" |
34 |
|
; |
35 |
|
applet_long_options = rmdir_longopts; |
36 |
|
#endif |
37 |
|
flags = getopt32(argv, "p"); |
38 |
argv += optind; |
argv += optind; |
39 |
|
|
40 |
if (!*argv) { |
if (!*argv) { |
44 |
do { |
do { |
45 |
path = *argv; |
path = *argv; |
46 |
|
|
47 |
/* Record if the first char was a '.' so we can use dirname later. */ |
while (1) { |
|
do_dot = (*path == '.'); |
|
|
|
|
|
do { |
|
48 |
if (rmdir(path) < 0) { |
if (rmdir(path) < 0) { |
49 |
|
#if ENABLE_FEATURE_RMDIR_LONG_OPTIONS |
50 |
|
if ((flags & IGNORE_NON_EMPTY) && errno == ENOTEMPTY) |
51 |
|
break; |
52 |
|
#endif |
53 |
bb_perror_msg("'%s'", path); /* Match gnu rmdir msg. */ |
bb_perror_msg("'%s'", path); /* Match gnu rmdir msg. */ |
54 |
status = EXIT_FAILURE; |
status = EXIT_FAILURE; |
55 |
} else if (flags) { |
} else if (flags & PARENTS) { |
56 |
/* Note: path was not empty or null since rmdir succeeded. */ |
/* Note: path was not "" since rmdir succeeded. */ |
57 |
path = dirname(path); |
path = dirname(path); |
58 |
/* Path is now just the parent component. Note that dirname |
/* Path is now just the parent component. Dirname |
59 |
* returns "." if there are no parents. We must distinguish |
* returns "." if there are no parents. |
|
* this from the case of the original path starting with '.'. |
|
60 |
*/ |
*/ |
61 |
if (do_dot || (*path != '.') || path[1]) { |
if (NOT_LONE_CHAR(path, '.')) { |
62 |
continue; |
continue; |
63 |
} |
} |
64 |
} |
} |
65 |
break; |
break; |
66 |
} while (1); |
} |
|
|
|
67 |
} while (*++argv); |
} while (*++argv); |
68 |
|
|
69 |
return status; |
return status; |