/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1992-2009 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.opensource.org/licenses/cpl1.0.txt * * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * David Korn * * * ***********************************************************************/ #pragma prototyped /* * Glenn Fowler * AT&T Research * * rmdir */ static const char usage[] = "[-?\n@(#)$Id: rmdir (AT&T Research) 2006-08-24 $\n]" USAGE_LICENSE "[+NAME?rmdir - remove empty directories]" "[+DESCRIPTION?\brmdir\b deletes each given directory. The directory " "must be empty; containing no entries other than \b.\b or \b..\b. " "If a directory and a subdirectory of that directory are specified " "as operands, the subdirectory must be specified before the parent " "so that the parent directory will be empty when \brmdir\b attempts " "to remove it.]" "[e:ignore-fail-on-non-empty?Ignore each non-empty directory failure.]" "[p:parents?Remove each explicit \adirectory\a argument directory that " "becomes empty after its child directories are removed.]" "[s:suppress?Suppress the message printed on the standard error when " "\b-p\b is in effect.]" "\n" "\ndirectory ...\n" "\n" "[+EXIT STATUS?]{" "[+0?All directories deleted successfully.]" "[+>0?One or more directories could not be deleted.]" "}" "[+SEE ALSO?\bmkdir\b(1), \brm\b(1), \brmdir\b(2), \bunlink\b(2)]" ; #include int b_rmdir(int argc, char** argv, void* context) { register char* dir; register char* end; register int n; int eflag = 0; int pflag = 0; int sflag = 0; cmdinit(argc, argv, context, ERROR_CATALOG, 0); while (n = optget(argv, usage)) switch (n) { case 'e': eflag = 1; break; case 'p': pflag = 1; break; case 's': sflag = 1; break; case ':': error(2, "%s", opt_info.arg); break; case '?': error(ERROR_usage(2), "%s", opt_info.arg); break; } argv += opt_info.index; if (error_info.errors || !*argv) error(ERROR_usage(2), "%s", optusage(NiL)); if (!pflag) sflag = 0; while (dir = *argv++) { end = dir; if (pflag) end += strlen(dir); n = 0; for (;;) { if (rmdir(dir) < 0) { if (!eflag || errno != EEXIST #ifdef ENOTEMPTY && errno != ENOTEMPTY #endif ) { if (sflag) error_info.errors++; else error(ERROR_system(0), "%s: cannot remove", dir); } break; } if (n) *end = '/'; else n = 1; do if (end <= dir) goto next; while (*--end != '/'); do if (end <= dir) goto next; while (*(end - 1) == '/' && end--); *end = 0; } next: ; } return(error_info.errors != 0); }