Blame


1 64f7506b 2006-02-24 devnull #include <u.h>
2 64f7506b 2006-02-24 devnull #include <libc.h>
3 64f7506b 2006-02-24 devnull #include <authsrv.h>
4 64f7506b 2006-02-24 devnull #include <fcall.h>
5 64f7506b 2006-02-24 devnull #include "tapefs.h"
6 64f7506b 2006-02-24 devnull
7 64f7506b 2006-02-24 devnull Fid *fids;
8 64f7506b 2006-02-24 devnull Ram *ram;
9 64f7506b 2006-02-24 devnull int mfd[2];
10 64f7506b 2006-02-24 devnull char *user;
11 64f7506b 2006-02-24 devnull uchar mdata[Maxbuf+IOHDRSZ];
12 64f7506b 2006-02-24 devnull int messagesize = Maxbuf+IOHDRSZ;
13 64f7506b 2006-02-24 devnull Fcall rhdr;
14 64f7506b 2006-02-24 devnull Fcall thdr;
15 64f7506b 2006-02-24 devnull ulong path;
16 64f7506b 2006-02-24 devnull Idmap *uidmap;
17 64f7506b 2006-02-24 devnull Idmap *gidmap;
18 64f7506b 2006-02-24 devnull int replete;
19 38c7eb9b 2006-05-21 devnull int blocksize; /* for 32v */
20 64f7506b 2006-02-24 devnull int verbose;
21 64f7506b 2006-02-24 devnull int newtap; /* tap with time in sec */
22 64f7506b 2006-02-24 devnull
23 64f7506b 2006-02-24 devnull Fid * newfid(int);
24 64f7506b 2006-02-24 devnull int ramstat(Ram*, uchar*, int);
25 64f7506b 2006-02-24 devnull void io(void);
26 64f7506b 2006-02-24 devnull void usage(void);
27 64f7506b 2006-02-24 devnull int perm(int);
28 64f7506b 2006-02-24 devnull
29 64f7506b 2006-02-24 devnull char *rflush(Fid*), *rversion(Fid*), *rauth(Fid*),
30 64f7506b 2006-02-24 devnull *rattach(Fid*), *rwalk(Fid*),
31 64f7506b 2006-02-24 devnull *ropen(Fid*), *rcreate(Fid*),
32 64f7506b 2006-02-24 devnull *rread(Fid*), *rwrite(Fid*), *rclunk(Fid*),
33 64f7506b 2006-02-24 devnull *rremove(Fid*), *rstat(Fid*), *rwstat(Fid*);
34 64f7506b 2006-02-24 devnull
35 cbeb0b26 2006-04-01 devnull char *(*fcalls[Tmax])(Fid*);
36 cbeb0b26 2006-04-01 devnull void
37 cbeb0b26 2006-04-01 devnull initfcalls(void)
38 cbeb0b26 2006-04-01 devnull {
39 cbeb0b26 2006-04-01 devnull fcalls[Tflush]= rflush;
40 cbeb0b26 2006-04-01 devnull fcalls[Tversion]= rversion;
41 cbeb0b26 2006-04-01 devnull fcalls[Tauth]= rauth;
42 cbeb0b26 2006-04-01 devnull fcalls[Tattach]= rattach;
43 cbeb0b26 2006-04-01 devnull fcalls[Twalk]= rwalk;
44 cbeb0b26 2006-04-01 devnull fcalls[Topen]= ropen;
45 cbeb0b26 2006-04-01 devnull fcalls[Tcreate]= rcreate;
46 cbeb0b26 2006-04-01 devnull fcalls[Tread]= rread;
47 cbeb0b26 2006-04-01 devnull fcalls[Twrite]= rwrite;
48 cbeb0b26 2006-04-01 devnull fcalls[Tclunk]= rclunk;
49 cbeb0b26 2006-04-01 devnull fcalls[Tremove]= rremove;
50 cbeb0b26 2006-04-01 devnull fcalls[Tstat]= rstat;
51 cbeb0b26 2006-04-01 devnull fcalls[Twstat]= rwstat;
52 cbeb0b26 2006-04-01 devnull }
53 64f7506b 2006-02-24 devnull
54 64f7506b 2006-02-24 devnull char Eperm[] = "permission denied";
55 64f7506b 2006-02-24 devnull char Enotdir[] = "not a directory";
56 64f7506b 2006-02-24 devnull char Enoauth[] = "tapefs: authentication not required";
57 64f7506b 2006-02-24 devnull char Enotexist[] = "file does not exist";
58 64f7506b 2006-02-24 devnull char Einuse[] = "file in use";
59 64f7506b 2006-02-24 devnull char Eexist[] = "file exists";
60 64f7506b 2006-02-24 devnull char Enotowner[] = "not owner";
61 64f7506b 2006-02-24 devnull char Eisopen[] = "file already open for I/O";
62 64f7506b 2006-02-24 devnull char Excl[] = "exclusive use file already open";
63 64f7506b 2006-02-24 devnull char Ename[] = "illegal name";
64 64f7506b 2006-02-24 devnull
65 64f7506b 2006-02-24 devnull void
66 64f7506b 2006-02-24 devnull notifyf(void *a, char *s)
67 64f7506b 2006-02-24 devnull {
68 64f7506b 2006-02-24 devnull USED(a);
69 64f7506b 2006-02-24 devnull if(strncmp(s, "interrupt", 9) == 0)
70 64f7506b 2006-02-24 devnull noted(NCONT);
71 64f7506b 2006-02-24 devnull noted(NDFLT);
72 64f7506b 2006-02-24 devnull }
73 64f7506b 2006-02-24 devnull
74 64f7506b 2006-02-24 devnull void
75 64f7506b 2006-02-24 devnull main(int argc, char *argv[])
76 64f7506b 2006-02-24 devnull {
77 64f7506b 2006-02-24 devnull Ram *r;
78 118dfa98 2008-05-06 rsc char *defmnt, *defsrv;
79 64f7506b 2006-02-24 devnull int p[2];
80 64f7506b 2006-02-24 devnull char buf[TICKREQLEN];
81 64f7506b 2006-02-24 devnull
82 64f7506b 2006-02-24 devnull fmtinstall('F', fcallfmt);
83 cbeb0b26 2006-04-01 devnull initfcalls();
84 64f7506b 2006-02-24 devnull
85 118dfa98 2008-05-06 rsc defmnt = nil;
86 118dfa98 2008-05-06 rsc defsrv = nil;
87 64f7506b 2006-02-24 devnull ARGBEGIN{
88 64f7506b 2006-02-24 devnull case 'm':
89 64f7506b 2006-02-24 devnull defmnt = ARGF();
90 118dfa98 2008-05-06 rsc break;
91 118dfa98 2008-05-06 rsc case 's':
92 118dfa98 2008-05-06 rsc defsrv = ARGF();
93 64f7506b 2006-02-24 devnull break;
94 64f7506b 2006-02-24 devnull case 'p': /* password file */
95 64f7506b 2006-02-24 devnull uidmap = getpass(ARGF());
96 64f7506b 2006-02-24 devnull break;
97 64f7506b 2006-02-24 devnull case 'g': /* group file */
98 64f7506b 2006-02-24 devnull gidmap = getpass(ARGF());
99 64f7506b 2006-02-24 devnull break;
100 64f7506b 2006-02-24 devnull case 'v':
101 64f7506b 2006-02-24 devnull verbose++;
102 64f7506b 2006-02-24 devnull
103 64f7506b 2006-02-24 devnull case 'n':
104 64f7506b 2006-02-24 devnull newtap++;
105 64f7506b 2006-02-24 devnull break;
106 64f7506b 2006-02-24 devnull default:
107 64f7506b 2006-02-24 devnull usage();
108 64f7506b 2006-02-24 devnull }ARGEND
109 64f7506b 2006-02-24 devnull
110 64f7506b 2006-02-24 devnull if(argc==0)
111 64f7506b 2006-02-24 devnull error("no file to mount");
112 64f7506b 2006-02-24 devnull user = getuser();
113 64f7506b 2006-02-24 devnull if(user == nil)
114 64f7506b 2006-02-24 devnull user = "dmr";
115 64f7506b 2006-02-24 devnull ram = r = (Ram *)emalloc(sizeof(Ram));
116 64f7506b 2006-02-24 devnull r->busy = 1;
117 64f7506b 2006-02-24 devnull r->data = 0;
118 64f7506b 2006-02-24 devnull r->ndata = 0;
119 64f7506b 2006-02-24 devnull r->perm = DMDIR | 0775;
120 64f7506b 2006-02-24 devnull r->qid.path = 0;
121 64f7506b 2006-02-24 devnull r->qid.vers = 0;
122 64f7506b 2006-02-24 devnull r->qid.type = QTDIR;
123 64f7506b 2006-02-24 devnull r->parent = 0;
124 64f7506b 2006-02-24 devnull r->child = 0;
125 64f7506b 2006-02-24 devnull r->next = 0;
126 64f7506b 2006-02-24 devnull r->user = user;
127 64f7506b 2006-02-24 devnull r->group = user;
128 64f7506b 2006-02-24 devnull r->atime = time(0);
129 64f7506b 2006-02-24 devnull r->mtime = r->atime;
130 64f7506b 2006-02-24 devnull r->replete = 0;
131 64f7506b 2006-02-24 devnull r->name = estrdup(".");
132 64f7506b 2006-02-24 devnull populate(argv[0]);
133 64f7506b 2006-02-24 devnull r->replete |= replete;
134 64f7506b 2006-02-24 devnull if(pipe(p) < 0)
135 64f7506b 2006-02-24 devnull error("pipe failed");
136 64f7506b 2006-02-24 devnull mfd[0] = mfd[1] = p[0];
137 64f7506b 2006-02-24 devnull notify(notifyf);
138 64f7506b 2006-02-24 devnull
139 64f7506b 2006-02-24 devnull switch(rfork(RFFDG|RFPROC|RFNAMEG|RFNOTEG)){
140 64f7506b 2006-02-24 devnull case -1:
141 64f7506b 2006-02-24 devnull error("fork");
142 64f7506b 2006-02-24 devnull case 0:
143 64f7506b 2006-02-24 devnull close(p[1]);
144 64f7506b 2006-02-24 devnull notify(notifyf);
145 64f7506b 2006-02-24 devnull io();
146 64f7506b 2006-02-24 devnull break;
147 64f7506b 2006-02-24 devnull default:
148 64f7506b 2006-02-24 devnull close(p[0]); /* don't deadlock if child fails */
149 118dfa98 2008-05-06 rsc if(post9pservice(p[1], defsrv, defmnt) < 0){
150 118dfa98 2008-05-06 rsc sprint(buf, "post9pservice: %r");
151 64f7506b 2006-02-24 devnull error(buf);
152 64f7506b 2006-02-24 devnull }
153 64f7506b 2006-02-24 devnull }
154 64f7506b 2006-02-24 devnull exits(0);
155 64f7506b 2006-02-24 devnull }
156 64f7506b 2006-02-24 devnull
157 64f7506b 2006-02-24 devnull char*
158 64f7506b 2006-02-24 devnull rversion(Fid *unused)
159 64f7506b 2006-02-24 devnull {
160 64f7506b 2006-02-24 devnull Fid *f;
161 64f7506b 2006-02-24 devnull
162 64f7506b 2006-02-24 devnull USED(unused);
163 64f7506b 2006-02-24 devnull
164 64f7506b 2006-02-24 devnull if(rhdr.msize < 256)
165 64f7506b 2006-02-24 devnull return "version: message too small";
166 64f7506b 2006-02-24 devnull if(rhdr.msize > messagesize)
167 64f7506b 2006-02-24 devnull rhdr.msize = messagesize;
168 64f7506b 2006-02-24 devnull else
169 64f7506b 2006-02-24 devnull messagesize = rhdr.msize;
170 64f7506b 2006-02-24 devnull thdr.msize = messagesize;
171 64f7506b 2006-02-24 devnull if(strncmp(rhdr.version, "9P2000", 6) != 0)
172 64f7506b 2006-02-24 devnull return "unrecognized 9P version";
173 64f7506b 2006-02-24 devnull thdr.version = "9P2000";
174 64f7506b 2006-02-24 devnull
175 64f7506b 2006-02-24 devnull for(f = fids; f; f = f->next)
176 64f7506b 2006-02-24 devnull if(f->busy)
177 64f7506b 2006-02-24 devnull rclunk(f);
178 64f7506b 2006-02-24 devnull return 0;
179 64f7506b 2006-02-24 devnull }
180 64f7506b 2006-02-24 devnull
181 64f7506b 2006-02-24 devnull char*
182 64f7506b 2006-02-24 devnull rauth(Fid *unused)
183 64f7506b 2006-02-24 devnull {
184 64f7506b 2006-02-24 devnull USED(unused);
185 64f7506b 2006-02-24 devnull
186 64f7506b 2006-02-24 devnull return Enoauth;
187 64f7506b 2006-02-24 devnull }
188 64f7506b 2006-02-24 devnull
189 64f7506b 2006-02-24 devnull char*
190 64f7506b 2006-02-24 devnull rflush(Fid *f)
191 64f7506b 2006-02-24 devnull {
192 64f7506b 2006-02-24 devnull USED(f);
193 64f7506b 2006-02-24 devnull return 0;
194 64f7506b 2006-02-24 devnull }
195 64f7506b 2006-02-24 devnull
196 64f7506b 2006-02-24 devnull char*
197 64f7506b 2006-02-24 devnull rattach(Fid *f)
198 64f7506b 2006-02-24 devnull {
199 64f7506b 2006-02-24 devnull /* no authentication! */
200 64f7506b 2006-02-24 devnull f->busy = 1;
201 64f7506b 2006-02-24 devnull f->rclose = 0;
202 64f7506b 2006-02-24 devnull f->ram = ram;
203 64f7506b 2006-02-24 devnull thdr.qid = f->ram->qid;
204 64f7506b 2006-02-24 devnull if(rhdr.uname[0])
205 64f7506b 2006-02-24 devnull f->user = strdup(rhdr.uname);
206 64f7506b 2006-02-24 devnull else
207 64f7506b 2006-02-24 devnull f->user = "none";
208 64f7506b 2006-02-24 devnull return 0;
209 64f7506b 2006-02-24 devnull }
210 64f7506b 2006-02-24 devnull
211 64f7506b 2006-02-24 devnull char*
212 64f7506b 2006-02-24 devnull rwalk(Fid *f)
213 64f7506b 2006-02-24 devnull {
214 64f7506b 2006-02-24 devnull Fid *nf;
215 64f7506b 2006-02-24 devnull Ram *r;
216 64f7506b 2006-02-24 devnull char *err;
217 64f7506b 2006-02-24 devnull char *name;
218 64f7506b 2006-02-24 devnull Ram *dir;
219 64f7506b 2006-02-24 devnull int i;
220 64f7506b 2006-02-24 devnull
221 64f7506b 2006-02-24 devnull nf = nil;
222 64f7506b 2006-02-24 devnull if(f->ram->busy == 0)
223 64f7506b 2006-02-24 devnull return Enotexist;
224 64f7506b 2006-02-24 devnull if(f->open)
225 64f7506b 2006-02-24 devnull return Eisopen;
226 64f7506b 2006-02-24 devnull if(rhdr.newfid != rhdr.fid){
227 64f7506b 2006-02-24 devnull nf = newfid(rhdr.newfid);
228 64f7506b 2006-02-24 devnull nf->busy = 1;
229 64f7506b 2006-02-24 devnull nf->open = 0;
230 64f7506b 2006-02-24 devnull nf->rclose = 0;
231 64f7506b 2006-02-24 devnull nf->ram = f->ram;
232 64f7506b 2006-02-24 devnull nf->user = f->user; /* no ref count; the leakage is minor */
233 64f7506b 2006-02-24 devnull f = nf;
234 64f7506b 2006-02-24 devnull }
235 64f7506b 2006-02-24 devnull
236 64f7506b 2006-02-24 devnull thdr.nwqid = 0;
237 64f7506b 2006-02-24 devnull err = nil;
238 64f7506b 2006-02-24 devnull r = f->ram;
239 64f7506b 2006-02-24 devnull
240 64f7506b 2006-02-24 devnull if(rhdr.nwname > 0){
241 64f7506b 2006-02-24 devnull for(i=0; i<rhdr.nwname; i++){
242 64f7506b 2006-02-24 devnull if((r->qid.type & QTDIR) == 0){
243 64f7506b 2006-02-24 devnull err = Enotdir;
244 64f7506b 2006-02-24 devnull break;
245 64f7506b 2006-02-24 devnull }
246 64f7506b 2006-02-24 devnull if(r->busy == 0){
247 64f7506b 2006-02-24 devnull err = Enotexist;
248 64f7506b 2006-02-24 devnull break;
249 64f7506b 2006-02-24 devnull }
250 64f7506b 2006-02-24 devnull r->atime = time(0);
251 64f7506b 2006-02-24 devnull name = rhdr.wname[i];
252 64f7506b 2006-02-24 devnull dir = r;
253 64f7506b 2006-02-24 devnull if(!perm(Pexec)){
254 64f7506b 2006-02-24 devnull err = Eperm;
255 64f7506b 2006-02-24 devnull break;
256 64f7506b 2006-02-24 devnull }
257 64f7506b 2006-02-24 devnull if(strcmp(name, "..") == 0){
258 64f7506b 2006-02-24 devnull r = dir->parent;
259 64f7506b 2006-02-24 devnull Accept:
260 64f7506b 2006-02-24 devnull if(i == MAXWELEM){
261 64f7506b 2006-02-24 devnull err = "name too long";
262 64f7506b 2006-02-24 devnull break;
263 64f7506b 2006-02-24 devnull }
264 64f7506b 2006-02-24 devnull thdr.wqid[thdr.nwqid++] = r->qid;
265 64f7506b 2006-02-24 devnull continue;
266 64f7506b 2006-02-24 devnull }
267 64f7506b 2006-02-24 devnull if(!dir->replete)
268 64f7506b 2006-02-24 devnull popdir(dir);
269 64f7506b 2006-02-24 devnull for(r=dir->child; r; r=r->next)
270 64f7506b 2006-02-24 devnull if(r->busy && strcmp(name, r->name)==0)
271 64f7506b 2006-02-24 devnull goto Accept;
272 64f7506b 2006-02-24 devnull break; /* file not found */
273 64f7506b 2006-02-24 devnull }
274 64f7506b 2006-02-24 devnull
275 64f7506b 2006-02-24 devnull if(i==0 && err == nil)
276 64f7506b 2006-02-24 devnull err = Enotexist;
277 64f7506b 2006-02-24 devnull }
278 64f7506b 2006-02-24 devnull
279 64f7506b 2006-02-24 devnull if(err!=nil || thdr.nwqid<rhdr.nwname){
280 64f7506b 2006-02-24 devnull if(nf){
281 64f7506b 2006-02-24 devnull nf->busy = 0;
282 64f7506b 2006-02-24 devnull nf->open = 0;
283 64f7506b 2006-02-24 devnull nf->ram = 0;
284 64f7506b 2006-02-24 devnull }
285 64f7506b 2006-02-24 devnull }else if(thdr.nwqid == rhdr.nwname)
286 64f7506b 2006-02-24 devnull f->ram = r;
287 64f7506b 2006-02-24 devnull
288 64f7506b 2006-02-24 devnull return err;
289 64f7506b 2006-02-24 devnull
290 64f7506b 2006-02-24 devnull }
291 64f7506b 2006-02-24 devnull
292 64f7506b 2006-02-24 devnull char *
293 64f7506b 2006-02-24 devnull ropen(Fid *f)
294 64f7506b 2006-02-24 devnull {
295 64f7506b 2006-02-24 devnull Ram *r;
296 64f7506b 2006-02-24 devnull int mode, trunc;
297 64f7506b 2006-02-24 devnull
298 64f7506b 2006-02-24 devnull if(f->open)
299 64f7506b 2006-02-24 devnull return Eisopen;
300 64f7506b 2006-02-24 devnull r = f->ram;
301 64f7506b 2006-02-24 devnull if(r->busy == 0)
302 64f7506b 2006-02-24 devnull return Enotexist;
303 64f7506b 2006-02-24 devnull if(r->perm & DMEXCL)
304 64f7506b 2006-02-24 devnull if(r->open)
305 64f7506b 2006-02-24 devnull return Excl;
306 64f7506b 2006-02-24 devnull mode = rhdr.mode;
307 64f7506b 2006-02-24 devnull if(r->qid.type & QTDIR){
308 64f7506b 2006-02-24 devnull if(mode != OREAD)
309 64f7506b 2006-02-24 devnull return Eperm;
310 64f7506b 2006-02-24 devnull thdr.qid = r->qid;
311 64f7506b 2006-02-24 devnull return 0;
312 64f7506b 2006-02-24 devnull }
313 64f7506b 2006-02-24 devnull if(mode & ORCLOSE)
314 64f7506b 2006-02-24 devnull return Eperm;
315 64f7506b 2006-02-24 devnull trunc = mode & OTRUNC;
316 64f7506b 2006-02-24 devnull mode &= OPERM;
317 64f7506b 2006-02-24 devnull if(mode==OWRITE || mode==ORDWR || trunc)
318 64f7506b 2006-02-24 devnull if(!perm(Pwrite))
319 64f7506b 2006-02-24 devnull return Eperm;
320 64f7506b 2006-02-24 devnull if(mode==OREAD || mode==ORDWR)
321 64f7506b 2006-02-24 devnull if(!perm(Pread))
322 64f7506b 2006-02-24 devnull return Eperm;
323 64f7506b 2006-02-24 devnull if(mode==OEXEC)
324 64f7506b 2006-02-24 devnull if(!perm(Pexec))
325 64f7506b 2006-02-24 devnull return Eperm;
326 64f7506b 2006-02-24 devnull if(trunc && (r->perm&DMAPPEND)==0){
327 64f7506b 2006-02-24 devnull r->ndata = 0;
328 64f7506b 2006-02-24 devnull dotrunc(r);
329 64f7506b 2006-02-24 devnull r->qid.vers++;
330 64f7506b 2006-02-24 devnull }
331 64f7506b 2006-02-24 devnull thdr.qid = r->qid;
332 64f7506b 2006-02-24 devnull thdr.iounit = messagesize-IOHDRSZ;
333 64f7506b 2006-02-24 devnull f->open = 1;
334 64f7506b 2006-02-24 devnull r->open++;
335 64f7506b 2006-02-24 devnull return 0;
336 64f7506b 2006-02-24 devnull }
337 64f7506b 2006-02-24 devnull
338 64f7506b 2006-02-24 devnull char *
339 64f7506b 2006-02-24 devnull rcreate(Fid *f)
340 64f7506b 2006-02-24 devnull {
341 64f7506b 2006-02-24 devnull USED(f);
342 64f7506b 2006-02-24 devnull
343 64f7506b 2006-02-24 devnull return Eperm;
344 64f7506b 2006-02-24 devnull }
345 64f7506b 2006-02-24 devnull
346 64f7506b 2006-02-24 devnull char*
347 64f7506b 2006-02-24 devnull rread(Fid *f)
348 64f7506b 2006-02-24 devnull {
349 64f7506b 2006-02-24 devnull int i, len;
350 64f7506b 2006-02-24 devnull Ram *r;
351 64f7506b 2006-02-24 devnull char *buf;
352 64f7506b 2006-02-24 devnull uvlong off, end;
353 64f7506b 2006-02-24 devnull int n, cnt;
354 64f7506b 2006-02-24 devnull
355 64f7506b 2006-02-24 devnull if(f->ram->busy == 0)
356 64f7506b 2006-02-24 devnull return Enotexist;
357 64f7506b 2006-02-24 devnull n = 0;
358 64f7506b 2006-02-24 devnull thdr.count = 0;
359 64f7506b 2006-02-24 devnull off = rhdr.offset;
360 64f7506b 2006-02-24 devnull end = rhdr.offset + rhdr.count;
361 64f7506b 2006-02-24 devnull cnt = rhdr.count;
362 64f7506b 2006-02-24 devnull if(cnt > messagesize-IOHDRSZ)
363 64f7506b 2006-02-24 devnull cnt = messagesize-IOHDRSZ;
364 64f7506b 2006-02-24 devnull buf = thdr.data;
365 64f7506b 2006-02-24 devnull if(f->ram->qid.type & QTDIR){
366 64f7506b 2006-02-24 devnull if(!f->ram->replete)
367 64f7506b 2006-02-24 devnull popdir(f->ram);
368 64f7506b 2006-02-24 devnull for(i=0,r=f->ram->child; r!=nil && i<end; r=r->next){
369 64f7506b 2006-02-24 devnull if(!r->busy)
370 64f7506b 2006-02-24 devnull continue;
371 64f7506b 2006-02-24 devnull len = ramstat(r, (uchar*)buf+n, cnt-n);
372 64f7506b 2006-02-24 devnull if(len <= BIT16SZ)
373 64f7506b 2006-02-24 devnull break;
374 64f7506b 2006-02-24 devnull if(i >= off)
375 64f7506b 2006-02-24 devnull n += len;
376 64f7506b 2006-02-24 devnull i += len;
377 64f7506b 2006-02-24 devnull }
378 64f7506b 2006-02-24 devnull thdr.count = n;
379 64f7506b 2006-02-24 devnull return 0;
380 64f7506b 2006-02-24 devnull }
381 64f7506b 2006-02-24 devnull r = f->ram;
382 64f7506b 2006-02-24 devnull if(off >= r->ndata)
383 64f7506b 2006-02-24 devnull return 0;
384 64f7506b 2006-02-24 devnull r->atime = time(0);
385 64f7506b 2006-02-24 devnull n = cnt;
386 64f7506b 2006-02-24 devnull if(off+n > r->ndata)
387 64f7506b 2006-02-24 devnull n = r->ndata - off;
388 64f7506b 2006-02-24 devnull thdr.data = doread(r, off, n);
389 64f7506b 2006-02-24 devnull thdr.count = n;
390 64f7506b 2006-02-24 devnull return 0;
391 64f7506b 2006-02-24 devnull }
392 64f7506b 2006-02-24 devnull
393 64f7506b 2006-02-24 devnull char*
394 64f7506b 2006-02-24 devnull rwrite(Fid *f)
395 64f7506b 2006-02-24 devnull {
396 64f7506b 2006-02-24 devnull Ram *r;
397 64f7506b 2006-02-24 devnull ulong off;
398 64f7506b 2006-02-24 devnull int cnt;
399 64f7506b 2006-02-24 devnull
400 64f7506b 2006-02-24 devnull r = f->ram;
401 64f7506b 2006-02-24 devnull if(dopermw(f->ram)==0)
402 64f7506b 2006-02-24 devnull return Eperm;
403 64f7506b 2006-02-24 devnull if(r->busy == 0)
404 64f7506b 2006-02-24 devnull return Enotexist;
405 64f7506b 2006-02-24 devnull off = rhdr.offset;
406 64f7506b 2006-02-24 devnull if(r->perm & DMAPPEND)
407 64f7506b 2006-02-24 devnull off = r->ndata;
408 64f7506b 2006-02-24 devnull cnt = rhdr.count;
409 64f7506b 2006-02-24 devnull if(r->qid.type & QTDIR)
410 64f7506b 2006-02-24 devnull return "file is a directory";
411 64f7506b 2006-02-24 devnull if(off > 100*1024*1024) /* sanity check */
412 64f7506b 2006-02-24 devnull return "write too big";
413 64f7506b 2006-02-24 devnull dowrite(r, rhdr.data, off, cnt);
414 64f7506b 2006-02-24 devnull r->qid.vers++;
415 64f7506b 2006-02-24 devnull r->mtime = time(0);
416 64f7506b 2006-02-24 devnull thdr.count = cnt;
417 64f7506b 2006-02-24 devnull return 0;
418 64f7506b 2006-02-24 devnull }
419 64f7506b 2006-02-24 devnull
420 64f7506b 2006-02-24 devnull char *
421 64f7506b 2006-02-24 devnull rclunk(Fid *f)
422 64f7506b 2006-02-24 devnull {
423 64f7506b 2006-02-24 devnull if(f->open)
424 64f7506b 2006-02-24 devnull f->ram->open--;
425 64f7506b 2006-02-24 devnull f->busy = 0;
426 64f7506b 2006-02-24 devnull f->open = 0;
427 64f7506b 2006-02-24 devnull f->ram = 0;
428 64f7506b 2006-02-24 devnull return 0;
429 64f7506b 2006-02-24 devnull }
430 64f7506b 2006-02-24 devnull
431 64f7506b 2006-02-24 devnull char *
432 64f7506b 2006-02-24 devnull rremove(Fid *f)
433 64f7506b 2006-02-24 devnull {
434 64f7506b 2006-02-24 devnull USED(f);
435 64f7506b 2006-02-24 devnull return Eperm;
436 64f7506b 2006-02-24 devnull }
437 64f7506b 2006-02-24 devnull
438 64f7506b 2006-02-24 devnull char *
439 64f7506b 2006-02-24 devnull rstat(Fid *f)
440 64f7506b 2006-02-24 devnull {
441 64f7506b 2006-02-24 devnull if(f->ram->busy == 0)
442 64f7506b 2006-02-24 devnull return Enotexist;
443 64f7506b 2006-02-24 devnull thdr.nstat = ramstat(f->ram, thdr.stat, messagesize-IOHDRSZ);
444 64f7506b 2006-02-24 devnull return 0;
445 64f7506b 2006-02-24 devnull }
446 64f7506b 2006-02-24 devnull
447 64f7506b 2006-02-24 devnull char *
448 64f7506b 2006-02-24 devnull rwstat(Fid *f)
449 64f7506b 2006-02-24 devnull {
450 64f7506b 2006-02-24 devnull if(f->ram->busy == 0)
451 64f7506b 2006-02-24 devnull return Enotexist;
452 64f7506b 2006-02-24 devnull return Eperm;
453 64f7506b 2006-02-24 devnull }
454 64f7506b 2006-02-24 devnull
455 64f7506b 2006-02-24 devnull int
456 64f7506b 2006-02-24 devnull ramstat(Ram *r, uchar *buf, int nbuf)
457 64f7506b 2006-02-24 devnull {
458 64f7506b 2006-02-24 devnull Dir dir;
459 64f7506b 2006-02-24 devnull
460 64f7506b 2006-02-24 devnull dir.name = r->name;
461 64f7506b 2006-02-24 devnull dir.qid = r->qid;
462 64f7506b 2006-02-24 devnull dir.mode = r->perm;
463 64f7506b 2006-02-24 devnull dir.length = r->ndata;
464 64f7506b 2006-02-24 devnull dir.uid = r->user;
465 64f7506b 2006-02-24 devnull dir.gid = r->group;
466 64f7506b 2006-02-24 devnull dir.muid = r->user;
467 64f7506b 2006-02-24 devnull dir.atime = r->atime;
468 64f7506b 2006-02-24 devnull dir.mtime = r->mtime;
469 64f7506b 2006-02-24 devnull return convD2M(&dir, buf, nbuf);
470 64f7506b 2006-02-24 devnull }
471 64f7506b 2006-02-24 devnull
472 64f7506b 2006-02-24 devnull Fid *
473 64f7506b 2006-02-24 devnull newfid(int fid)
474 64f7506b 2006-02-24 devnull {
475 64f7506b 2006-02-24 devnull Fid *f, *ff;
476 64f7506b 2006-02-24 devnull
477 64f7506b 2006-02-24 devnull ff = 0;
478 64f7506b 2006-02-24 devnull for(f = fids; f; f = f->next)
479 64f7506b 2006-02-24 devnull if(f->fid == fid)
480 64f7506b 2006-02-24 devnull return f;
481 64f7506b 2006-02-24 devnull else if(!ff && !f->busy)
482 64f7506b 2006-02-24 devnull ff = f;
483 64f7506b 2006-02-24 devnull if(ff){
484 64f7506b 2006-02-24 devnull ff->fid = fid;
485 64f7506b 2006-02-24 devnull ff->open = 0;
486 64f7506b 2006-02-24 devnull ff->busy = 1;
487 64f7506b 2006-02-24 devnull }
488 64f7506b 2006-02-24 devnull f = emalloc(sizeof *f);
489 64f7506b 2006-02-24 devnull f->ram = 0;
490 64f7506b 2006-02-24 devnull f->fid = fid;
491 64f7506b 2006-02-24 devnull f->busy = 1;
492 64f7506b 2006-02-24 devnull f->open = 0;
493 64f7506b 2006-02-24 devnull f->next = fids;
494 64f7506b 2006-02-24 devnull fids = f;
495 64f7506b 2006-02-24 devnull return f;
496 64f7506b 2006-02-24 devnull }
497 64f7506b 2006-02-24 devnull
498 64f7506b 2006-02-24 devnull void
499 64f7506b 2006-02-24 devnull io(void)
500 64f7506b 2006-02-24 devnull {
501 64f7506b 2006-02-24 devnull char *err;
502 64f7506b 2006-02-24 devnull int n, nerr;
503 64f7506b 2006-02-24 devnull char buf[ERRMAX];
504 64f7506b 2006-02-24 devnull
505 64f7506b 2006-02-24 devnull errstr(buf, sizeof buf);
506 64f7506b 2006-02-24 devnull for(nerr=0, buf[0]='\0'; nerr<100; nerr++){
507 64f7506b 2006-02-24 devnull /*
508 64f7506b 2006-02-24 devnull * reading from a pipe or a network device
509 64f7506b 2006-02-24 devnull * will give an error after a few eof reads
510 64f7506b 2006-02-24 devnull * however, we cannot tell the difference
511 64f7506b 2006-02-24 devnull * between a zero-length read and an interrupt
512 64f7506b 2006-02-24 devnull * on the processes writing to us,
513 64f7506b 2006-02-24 devnull * so we wait for the error
514 64f7506b 2006-02-24 devnull */
515 64f7506b 2006-02-24 devnull n = read9pmsg(mfd[0], mdata, sizeof mdata);
516 64f7506b 2006-02-24 devnull if(n==0)
517 64f7506b 2006-02-24 devnull continue;
518 64f7506b 2006-02-24 devnull if(n < 0){
519 64f7506b 2006-02-24 devnull if(buf[0]=='\0')
520 64f7506b 2006-02-24 devnull errstr(buf, sizeof buf);
521 64f7506b 2006-02-24 devnull continue;
522 64f7506b 2006-02-24 devnull }
523 64f7506b 2006-02-24 devnull nerr = 0;
524 64f7506b 2006-02-24 devnull buf[0] = '\0';
525 64f7506b 2006-02-24 devnull if(convM2S(mdata, n, &rhdr) != n)
526 64f7506b 2006-02-24 devnull error("convert error in convM2S");
527 64f7506b 2006-02-24 devnull
528 64f7506b 2006-02-24 devnull if(verbose)
529 64f7506b 2006-02-24 devnull fprint(2, "tapefs: <=%F\n", &rhdr);/**/
530 64f7506b 2006-02-24 devnull
531 64f7506b 2006-02-24 devnull thdr.data = (char*)mdata + IOHDRSZ;
532 64f7506b 2006-02-24 devnull thdr.stat = mdata + IOHDRSZ;
533 64f7506b 2006-02-24 devnull if(!fcalls[rhdr.type])
534 64f7506b 2006-02-24 devnull err = "bad fcall type";
535 64f7506b 2006-02-24 devnull else
536 64f7506b 2006-02-24 devnull err = (*fcalls[rhdr.type])(newfid(rhdr.fid));
537 64f7506b 2006-02-24 devnull if(err){
538 64f7506b 2006-02-24 devnull thdr.type = Rerror;
539 64f7506b 2006-02-24 devnull thdr.ename = err;
540 64f7506b 2006-02-24 devnull }else{
541 64f7506b 2006-02-24 devnull thdr.type = rhdr.type + 1;
542 64f7506b 2006-02-24 devnull thdr.fid = rhdr.fid;
543 64f7506b 2006-02-24 devnull }
544 64f7506b 2006-02-24 devnull thdr.tag = rhdr.tag;
545 64f7506b 2006-02-24 devnull n = convS2M(&thdr, mdata, messagesize);
546 64f7506b 2006-02-24 devnull if(n <= 0)
547 64f7506b 2006-02-24 devnull error("convert error in convS2M");
548 64f7506b 2006-02-24 devnull if(verbose)
549 64f7506b 2006-02-24 devnull fprint(2, "tapefs: =>%F\n", &thdr);/**/
550 64f7506b 2006-02-24 devnull if(write(mfd[1], mdata, n) != n)
551 64f7506b 2006-02-24 devnull error("mount write");
552 64f7506b 2006-02-24 devnull }
553 64f7506b 2006-02-24 devnull if(buf[0]=='\0' || strstr(buf, "hungup"))
554 64f7506b 2006-02-24 devnull exits("");
555 64f7506b 2006-02-24 devnull fprint(2, "%s: mount read: %s\n", argv0, buf);
556 64f7506b 2006-02-24 devnull exits(buf);
557 64f7506b 2006-02-24 devnull }
558 64f7506b 2006-02-24 devnull
559 64f7506b 2006-02-24 devnull int
560 64f7506b 2006-02-24 devnull perm(int p)
561 64f7506b 2006-02-24 devnull {
562 64f7506b 2006-02-24 devnull if(p==Pwrite)
563 64f7506b 2006-02-24 devnull return 0;
564 64f7506b 2006-02-24 devnull return 1;
565 64f7506b 2006-02-24 devnull }
566 64f7506b 2006-02-24 devnull
567 64f7506b 2006-02-24 devnull void
568 64f7506b 2006-02-24 devnull error(char *s)
569 64f7506b 2006-02-24 devnull {
570 64f7506b 2006-02-24 devnull fprint(2, "%s: %s: ", argv0, s);
571 64f7506b 2006-02-24 devnull perror("");
572 64f7506b 2006-02-24 devnull exits(s);
573 64f7506b 2006-02-24 devnull }
574 64f7506b 2006-02-24 devnull
575 64f7506b 2006-02-24 devnull char*
576 64f7506b 2006-02-24 devnull estrdup(char *s)
577 64f7506b 2006-02-24 devnull {
578 64f7506b 2006-02-24 devnull char *t;
579 64f7506b 2006-02-24 devnull
580 64f7506b 2006-02-24 devnull t = emalloc(strlen(s)+1);
581 64f7506b 2006-02-24 devnull strcpy(t, s);
582 64f7506b 2006-02-24 devnull return t;
583 64f7506b 2006-02-24 devnull }
584 64f7506b 2006-02-24 devnull
585 64f7506b 2006-02-24 devnull void *
586 64f7506b 2006-02-24 devnull emalloc(ulong n)
587 64f7506b 2006-02-24 devnull {
588 64f7506b 2006-02-24 devnull void *p;
589 64f7506b 2006-02-24 devnull p = mallocz(n, 1);
590 64f7506b 2006-02-24 devnull if(!p)
591 64f7506b 2006-02-24 devnull error("out of memory");
592 64f7506b 2006-02-24 devnull return p;
593 64f7506b 2006-02-24 devnull }
594 64f7506b 2006-02-24 devnull
595 64f7506b 2006-02-24 devnull void *
596 64f7506b 2006-02-24 devnull erealloc(void *p, ulong n)
597 64f7506b 2006-02-24 devnull {
598 64f7506b 2006-02-24 devnull p = realloc(p, n);
599 64f7506b 2006-02-24 devnull if(!p)
600 64f7506b 2006-02-24 devnull error("out of memory");
601 64f7506b 2006-02-24 devnull return p;
602 64f7506b 2006-02-24 devnull }
603 64f7506b 2006-02-24 devnull
604 64f7506b 2006-02-24 devnull void
605 64f7506b 2006-02-24 devnull usage(void)
606 64f7506b 2006-02-24 devnull {
607 64f7506b 2006-02-24 devnull fprint(2, "usage: %s [-s] [-m mountpoint]\n", argv0);
608 64f7506b 2006-02-24 devnull exits("usage");
609 64f7506b 2006-02-24 devnull }