rm.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. char errbuf[ERRMAX];
  12. int ignerr = 0;
  13. void
  14. err(char *f)
  15. {
  16. if(!ignerr){
  17. errbuf[0] = '\0';
  18. errstr(errbuf, sizeof errbuf);
  19. fprint(2, "rm: %s: %s\n", f, errbuf);
  20. }
  21. }
  22. /*
  23. * f is a non-empty directory. Remove its contents and then it.
  24. */
  25. void
  26. rmdir(char *f)
  27. {
  28. char *name;
  29. int fd, i, j, n, ndir, nname;
  30. Dir *dirbuf;
  31. fd = open(f, OREAD);
  32. if(fd < 0){
  33. err(f);
  34. return;
  35. }
  36. n = dirreadall(fd, &dirbuf);
  37. close(fd);
  38. if(n < 0){
  39. err("dirreadall");
  40. return;
  41. }
  42. nname = strlen(f)+1+STATMAX+1; /* plenty! */
  43. name = malloc(nname);
  44. if(name == 0){
  45. err("memory allocation");
  46. return;
  47. }
  48. ndir = 0;
  49. for(i=0; i<n; i++){
  50. snprint(name, nname, "%s/%s", f, dirbuf[i].name);
  51. if(remove(name) != -1)
  52. dirbuf[i].qid.type = QTFILE; /* so we won't recurse */
  53. else{
  54. if(dirbuf[i].qid.type & QTDIR)
  55. ndir++;
  56. else
  57. err(name);
  58. }
  59. }
  60. if(ndir)
  61. for(j=0; j<n; j++)
  62. if(dirbuf[j].qid.type & QTDIR){
  63. snprint(name, nname, "%s/%s", f, dirbuf[j].name);
  64. rmdir(name);
  65. }
  66. if(remove(f) == -1)
  67. err(f);
  68. free(name);
  69. free(dirbuf);
  70. }
  71. void
  72. main(int argc, char *argv[])
  73. {
  74. int i;
  75. int recurse;
  76. char *f;
  77. Dir *db;
  78. ignerr = 0;
  79. recurse = 0;
  80. ARGBEGIN{
  81. case 'r':
  82. recurse = 1;
  83. break;
  84. case 'f':
  85. ignerr = 1;
  86. break;
  87. default:
  88. fprint(2, "usage: rm [-fr] file ...\n");
  89. exits("usage");
  90. }ARGEND
  91. for(i=0; i<argc; i++){
  92. f = argv[i];
  93. if(remove(f) != -1)
  94. continue;
  95. db = nil;
  96. if(recurse && (db=dirstat(f))!=nil && (db->qid.type&QTDIR))
  97. rmdir(f);
  98. else
  99. err(f);
  100. free(db);
  101. }
  102. exits(errbuf);
  103. }