1 #include "logfsos.h"
2 #include "logfs.h"
3 #include "local.h"
4
5 char *
logfsserveropen(LogfsServer * server,u32int fid,uchar mode,Qid * qid)6 logfsserveropen(LogfsServer *server, u32int fid, uchar mode, Qid *qid)
7 {
8 Fid *f;
9 Entry *e;
10 ulong modemask;
11
12 if(server->trace > 1)
13 print("logfsserveropen(%ud, %d)\n", fid, mode);
14 f = logfsfidmapfindentry(server->fidmap, fid);
15 if(f == nil)
16 return logfsebadfid;
17 if(f->openmode >= 0)
18 return logfsefidopen;
19 e = f->entry;
20 SET(modemask);
21 switch(mode & 3) {
22 case OEXEC:
23 modemask = DMEXEC;
24 break;
25 case OREAD:
26 modemask = DMREAD;
27 break;
28 case OWRITE:
29 modemask = DMWRITE;
30 break;
31 case ORDWR:
32 modemask = DMWRITE | DMREAD;
33 break;
34 }
35 if(e->qid.type & QTDIR) {
36 if((modemask & DMWRITE) != 0 || (mode & (ORCLOSE | OTRUNC)) != 0)
37 return Eperm;
38 }
39 else {
40 if(mode & OTRUNC)
41 modemask |= DMWRITE;
42 if((mode & ORCLOSE) != 0 && !logfsuserpermcheck(server, e->parent, f, DMWRITE))
43 return Eperm;
44 }
45 if(!logfsuserpermcheck(server, e, f, modemask))
46 return Eperm;
47 if((e->qid.type & QTDIR) == 0 && (mode & OTRUNC) != 0 && (e->perm & DMAPPEND) == 0 && e->u.file.length != 0) {
48 LogMessage s;
49 char *errmsg;
50 s.type = LogfsLogTtrunc;
51 s.path = e->qid.path;
52 s.u.trunc.mtime = logfsnow();
53 s.u.trunc.cvers = e->u.file.cvers + 1;
54 s.u.trunc.muid = logfsisfindidfromname(server->is, f->uname);
55 errmsg = logfslog(server, 1, &s);
56 if(errmsg)
57 return errmsg;
58 e->muid = s.u.trunc.muid;
59 e->mtime = s.u.trunc.mtime;
60 e->qid.vers++;
61 e->u.file.cvers = s.u.trunc.cvers;
62 /*
63 * zap all data and extents
64 */
65 logfsextentlistwalk(e->u.file.extent, logfsunconditionallymarkfreeanddirty, server);
66 logfsextentlistreset(e->u.file.extent);
67 e->u.file.length = 0;
68 }
69 f->openmode = mode;
70 *qid = e->qid;
71 return nil;
72 }
73