rm.c 1.5 KB

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