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.5 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 43int rmdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 44int 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} 96