3
0

rmdir.c 2.3 KB

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