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