]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/upas/fs/remove.c
upas/fs: fix more locking bugs, remove debugging clutter, remove planb mbox code
[plan9front.git] / sys / src / cmd / upas / fs / remove.c
1 #include "common.h"
2 #include "dat.h"
3
4 #define deprint(...)    /* eprint(__VA_ARGS__) */
5
6 extern int dirskip(Dir*, uvlong*);
7
8 static int
9 ismbox(char *path)
10 {
11         char buf[512];
12         int fd, r;
13
14         fd = open(path, OREAD);
15         if(fd == -1)
16                 return 0;
17         r = 1;
18         if(read(fd, buf, sizeof buf) < 28 + 5)
19                 r = 0;
20         else if(strncmp(buf, "From ", 5))
21                 r = 0;
22         close(fd);
23         return r;
24 }
25
26 static int
27 isindex(Dir *d)
28 {
29         char *p;
30
31         p = strrchr(d->name, '.');
32         if(!p)
33                 return -1;
34         if(strcmp(p, ".idx") || strcmp(p, ".imp"))
35                 return 1;
36         return 0;
37 }
38
39 static int
40 idiotcheck(char *path, Dir *d, int getindex)
41 {
42         uvlong v;
43
44         if(d->mode & DMDIR)
45                 return 0;
46         if(strncmp(d->name, "L.", 2) == 0)
47                 return 0;
48         if(getindex && isindex(d))
49                 return 0;
50         if(!dirskip(d, &v) || ismbox(path))
51                 return 0;
52         return -1;
53 }
54
55 int
56 vremove(char *buf)
57 {
58         deprint("rm %s\n", buf);
59         return remove(buf);
60 }
61
62 static int
63 rm(char *dir, int flags, int level)
64 {
65         char buf[Pathlen];
66         int i, n, r, fd, isdir, rflag;
67         Dir *d;
68
69         d = dirstat(dir);
70         isdir = d->mode & DMDIR;
71         free(d);
72         if(!isdir)
73                 return 0;
74         fd = open(dir, OREAD);
75         if(fd == -1)
76                 return -1;
77         n = dirreadall(fd, &d);
78         close(fd);
79         r = 0;
80         rflag = flags & Rrecur;
81         for(i = 0; i < n; i++){
82                 snprint(buf, sizeof buf, "%s/%s", dir, d[i].name);
83                 if(rflag)
84                         r |= rm(buf, flags, level + 1);
85                 if(idiotcheck(buf, d + i, level + rflag) == -1)
86                         continue;
87                 if(vremove(buf) != 0)
88                         r = -1;
89         }
90         free(d);
91         return r;
92 }
93
94 void
95 rmidx(char *buf, int flags)
96 {
97         char buf2[Pathlen];
98
99         snprint(buf2, sizeof buf2, "%s.idx", buf);
100         vremove(buf2);
101         if((flags & Rtrunc) == 0){
102                 snprint(buf2, sizeof buf2, "%s.imp", buf);
103                 vremove(buf2);
104         }
105 }
106
107 char*
108 localremove(Mailbox *mb, int flags)
109 {
110         char *msg, *path;
111         int r, isdir;
112         Dir *d;
113         static char err[2*Pathlen];
114
115         path = mb->path;
116         if((d = dirstat(path)) == 0){
117                 snprint(err, sizeof err, "%s: doesn't exist\n", path);
118                 return 0;
119         }
120         isdir = d->mode & DMDIR;
121         free(d);
122         msg = "deleting";
123         if(flags & Rtrunc)
124                 msg = "truncating";
125         deprint("%s: %s\n", msg, path);
126
127         /* must match folder.c:/^openfolder */
128         r = rm(path, flags, 0);
129         if((flags & Rtrunc) == 0)
130                 r = vremove(path);
131         else if(!isdir)
132                 close(r = open(path, OWRITE|OTRUNC));
133
134         rmidx(path, flags);
135
136         if(r == -1){
137                 snprint(err, sizeof err, "%s: can't %s\n", path, msg);
138                 return err;
139         }
140         return 0;
141 }