Blob


1 #include <u.h>
2 #include <libc.h>
4 #define rmdir p9rmdir
6 char errbuf[ERRMAX];
7 int ignerr = 0;
9 static void
10 err(char *f)
11 {
12 if(!ignerr){
13 errbuf[0] = '\0';
14 errstr(errbuf, sizeof errbuf);
15 fprint(2, "rm: %s: %s\n", f, errbuf);
16 }
17 }
19 /*
20 * f is a non-empty directory. Remove its contents and then it.
21 */
22 void
23 rmdir(char *f)
24 {
25 char *name;
26 int fd, i, j, n, ndir, nname;
27 Dir *dirbuf;
29 fd = open(f, OREAD);
30 if(fd < 0){
31 err(f);
32 return;
33 }
34 n = dirreadall(fd, &dirbuf);
35 close(fd);
36 if(n < 0){
37 err("dirreadall");
38 return;
39 }
41 nname = strlen(f)+1+STATMAX+1; /* plenty! */
42 name = malloc(nname);
43 if(name == 0){
44 err("memory allocation");
45 return;
46 }
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;
79 ignerr = 0;
80 recurse = 0;
81 ARGBEGIN{
82 case 'r':
83 recurse = 1;
84 break;
85 case 'f':
86 ignerr = 1;
87 break;
88 default:
89 fprint(2, "usage: rm [-fr] file ...\n");
90 exits("usage");
91 }ARGEND
92 for(i=0; i<argc; i++){
93 f = argv[i];
94 if(remove(f) != -1)
95 continue;
96 db = nil;
97 if(recurse && (db=dirstat(f))!=nil && (db->qid.type&QTDIR))
98 rmdir(f);
99 else
100 err(f);
101 free(db);
103 exits(errbuf);