Blame


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