3
0

remove_file.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Mini remove_file implementation for busybox
  4. *
  5. * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  8. */
  9. #include <stdio.h>
  10. #include <time.h>
  11. #include <utime.h>
  12. #include <dirent.h>
  13. #include <errno.h>
  14. #include <unistd.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <getopt.h>
  18. #include "libbb.h"
  19. int remove_file(const char *path, int flags)
  20. {
  21. struct stat path_stat;
  22. int path_exists = 1;
  23. if (lstat(path, &path_stat) < 0) {
  24. if (errno != ENOENT) {
  25. bb_perror_msg("cannot stat '%s'", path);
  26. return -1;
  27. }
  28. path_exists = 0;
  29. }
  30. if (!path_exists) {
  31. if (!(flags & FILEUTILS_FORCE)) {
  32. bb_perror_msg("cannot remove '%s'", path);
  33. return -1;
  34. }
  35. return 0;
  36. }
  37. if (S_ISDIR(path_stat.st_mode)) {
  38. DIR *dp;
  39. struct dirent *d;
  40. int status = 0;
  41. if (!(flags & FILEUTILS_RECUR)) {
  42. bb_error_msg("%s: is a directory", path);
  43. return -1;
  44. }
  45. if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 &&
  46. isatty(0)) ||
  47. (flags & FILEUTILS_INTERACTIVE)) {
  48. fprintf(stderr, "%s: descend into directory '%s'? ", applet_name,
  49. path);
  50. if (!bb_ask_confirmation())
  51. return 0;
  52. }
  53. if ((dp = opendir(path)) == NULL) {
  54. return -1;
  55. }
  56. while ((d = readdir(dp)) != NULL) {
  57. char *new_path;
  58. new_path = concat_subpath_file(path, d->d_name);
  59. if(new_path == NULL)
  60. continue;
  61. if (remove_file(new_path, flags) < 0)
  62. status = -1;
  63. free(new_path);
  64. }
  65. if (closedir(dp) < 0) {
  66. bb_perror_msg("cannot close '%s'", path);
  67. return -1;
  68. }
  69. if (flags & FILEUTILS_INTERACTIVE) {
  70. fprintf(stderr, "%s: remove directory '%s'? ", applet_name, path);
  71. if (!bb_ask_confirmation())
  72. return status;
  73. }
  74. if (rmdir(path) < 0) {
  75. bb_perror_msg("cannot remove '%s'", path);
  76. return -1;
  77. }
  78. return status;
  79. } else {
  80. if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 &&
  81. !S_ISLNK(path_stat.st_mode) &&
  82. isatty(0)) ||
  83. (flags & FILEUTILS_INTERACTIVE)) {
  84. fprintf(stderr, "%s: remove '%s'? ", applet_name, path);
  85. if (!bb_ask_confirmation())
  86. return 0;
  87. }
  88. if (unlink(path) < 0) {
  89. bb_perror_msg("cannot remove '%s'", path);
  90. return -1;
  91. }
  92. return 0;
  93. }
  94. }