14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1992-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * *
204887Schin ***********************************************************************/
214887Schin #pragma prototyped
224887Schin /*
234887Schin * Glenn Fowler
244887Schin * AT&T Research
254887Schin *
264887Schin * rmdir
274887Schin */
284887Schin
294887Schin static const char usage[] =
304887Schin "[-?\n@(#)$Id: rmdir (AT&T Research) 2006-08-24 $\n]"
314887Schin USAGE_LICENSE
324887Schin "[+NAME?rmdir - remove empty directories]"
334887Schin "[+DESCRIPTION?\brmdir\b deletes each given directory. The directory "
344887Schin "must be empty; containing no entries other than \b.\b or \b..\b. "
354887Schin "If a directory and a subdirectory of that directory are specified "
364887Schin "as operands, the subdirectory must be specified before the parent "
374887Schin "so that the parent directory will be empty when \brmdir\b attempts "
384887Schin "to remove it.]"
394887Schin "[e:ignore-fail-on-non-empty?Ignore each non-empty directory failure.]"
404887Schin "[p:parents?Remove each explicit \adirectory\a argument directory that "
414887Schin "becomes empty after its child directories are removed.]"
424887Schin "[s:suppress?Suppress the message printed on the standard error when "
434887Schin "\b-p\b is in effect.]"
444887Schin "\n"
454887Schin "\ndirectory ...\n"
464887Schin "\n"
474887Schin "[+EXIT STATUS?]{"
484887Schin "[+0?All directories deleted successfully.]"
494887Schin "[+>0?One or more directories could not be deleted.]"
504887Schin "}"
514887Schin "[+SEE ALSO?\bmkdir\b(1), \brm\b(1), \brmdir\b(2), \bunlink\b(2)]"
524887Schin ;
534887Schin
544887Schin #include <cmd.h>
554887Schin
564887Schin int
b_rmdir(int argc,char ** argv,void * context)574887Schin b_rmdir(int argc, char** argv, void* context)
584887Schin {
594887Schin register char* dir;
604887Schin register char* end;
614887Schin register int n;
624887Schin int eflag = 0;
634887Schin int pflag = 0;
644887Schin int sflag = 0;
654887Schin
664887Schin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
674887Schin while (n = optget(argv, usage)) switch (n)
684887Schin {
694887Schin case 'e':
704887Schin eflag = 1;
714887Schin break;
724887Schin case 'p':
734887Schin pflag = 1;
744887Schin break;
754887Schin case 's':
764887Schin sflag = 1;
774887Schin break;
784887Schin case ':':
794887Schin error(2, "%s", opt_info.arg);
804887Schin break;
814887Schin case '?':
824887Schin error(ERROR_usage(2), "%s", opt_info.arg);
834887Schin break;
844887Schin }
854887Schin argv += opt_info.index;
864887Schin if (error_info.errors || !*argv)
874887Schin error(ERROR_usage(2), "%s", optusage(NiL));
884887Schin if (!pflag)
894887Schin sflag = 0;
904887Schin while (dir = *argv++)
914887Schin {
924887Schin end = dir;
934887Schin if (pflag) end += strlen(dir);
944887Schin n = 0;
954887Schin for (;;)
964887Schin {
974887Schin if (rmdir(dir) < 0)
984887Schin {
994887Schin if (!eflag || errno != EEXIST
1004887Schin #ifdef ENOTEMPTY
1014887Schin && errno != ENOTEMPTY
1024887Schin #endif
1034887Schin )
1044887Schin {
1054887Schin if (sflag)
1064887Schin error_info.errors++;
1074887Schin else
1084887Schin error(ERROR_system(0), "%s: cannot remove", dir);
1094887Schin }
1104887Schin break;
1114887Schin }
1124887Schin if (n) *end = '/';
1134887Schin else n = 1;
1144887Schin do if (end <= dir) goto next; while (*--end != '/');
1154887Schin do if (end <= dir) goto next; while (*(end - 1) == '/' && end--);
1164887Schin *end = 0;
1174887Schin }
1184887Schin next: ;
1194887Schin }
1204887Schin return(error_info.errors != 0);
1214887Schin }
1224887Schin
123