1*28942eadSforsyth #include "logfsos.h"
237da2899SCharles.Forsyth #include "logfs.h"
337da2899SCharles.Forsyth #include "local.h"
437da2899SCharles.Forsyth
537da2899SCharles.Forsyth char *
logfsserveropen(LogfsServer * server,u32int fid,uchar mode,Qid * qid)637da2899SCharles.Forsyth logfsserveropen(LogfsServer *server, u32int fid, uchar mode, Qid *qid)
737da2899SCharles.Forsyth {
837da2899SCharles.Forsyth Fid *f;
937da2899SCharles.Forsyth Entry *e;
1037da2899SCharles.Forsyth ulong modemask;
1137da2899SCharles.Forsyth
1237da2899SCharles.Forsyth if(server->trace > 1)
1337da2899SCharles.Forsyth print("logfsserveropen(%ud, %d)\n", fid, mode);
1437da2899SCharles.Forsyth f = logfsfidmapfindentry(server->fidmap, fid);
1537da2899SCharles.Forsyth if(f == nil)
1637da2899SCharles.Forsyth return logfsebadfid;
1737da2899SCharles.Forsyth if(f->openmode >= 0)
1837da2899SCharles.Forsyth return logfsefidopen;
1937da2899SCharles.Forsyth e = f->entry;
2037da2899SCharles.Forsyth SET(modemask);
2137da2899SCharles.Forsyth switch(mode & 3) {
2237da2899SCharles.Forsyth case OEXEC:
2337da2899SCharles.Forsyth modemask = DMEXEC;
2437da2899SCharles.Forsyth break;
2537da2899SCharles.Forsyth case OREAD:
2637da2899SCharles.Forsyth modemask = DMREAD;
2737da2899SCharles.Forsyth break;
2837da2899SCharles.Forsyth case OWRITE:
2937da2899SCharles.Forsyth modemask = DMWRITE;
3037da2899SCharles.Forsyth break;
3137da2899SCharles.Forsyth case ORDWR:
3237da2899SCharles.Forsyth modemask = DMWRITE | DMREAD;
3337da2899SCharles.Forsyth break;
3437da2899SCharles.Forsyth }
3537da2899SCharles.Forsyth if(e->qid.type & QTDIR) {
3637da2899SCharles.Forsyth if((modemask & DMWRITE) != 0 || (mode & (ORCLOSE | OTRUNC)) != 0)
3737da2899SCharles.Forsyth return Eperm;
3837da2899SCharles.Forsyth }
3937da2899SCharles.Forsyth else {
4037da2899SCharles.Forsyth if(mode & OTRUNC)
4137da2899SCharles.Forsyth modemask |= DMWRITE;
4237da2899SCharles.Forsyth if((mode & ORCLOSE) != 0 && !logfsuserpermcheck(server, e->parent, f, DMWRITE))
4337da2899SCharles.Forsyth return Eperm;
4437da2899SCharles.Forsyth }
4537da2899SCharles.Forsyth if(!logfsuserpermcheck(server, e, f, modemask))
4637da2899SCharles.Forsyth return Eperm;
4737da2899SCharles.Forsyth if((e->qid.type & QTDIR) == 0 && (mode & OTRUNC) != 0 && (e->perm & DMAPPEND) == 0 && e->u.file.length != 0) {
4837da2899SCharles.Forsyth LogMessage s;
4937da2899SCharles.Forsyth char *errmsg;
5037da2899SCharles.Forsyth s.type = LogfsLogTtrunc;
5137da2899SCharles.Forsyth s.path = e->qid.path;
5237da2899SCharles.Forsyth s.u.trunc.mtime = logfsnow();
5337da2899SCharles.Forsyth s.u.trunc.cvers = e->u.file.cvers + 1;
5437da2899SCharles.Forsyth s.u.trunc.muid = logfsisfindidfromname(server->is, f->uname);
5537da2899SCharles.Forsyth errmsg = logfslog(server, 1, &s);
5637da2899SCharles.Forsyth if(errmsg)
5737da2899SCharles.Forsyth return errmsg;
5837da2899SCharles.Forsyth e->muid = s.u.trunc.muid;
5937da2899SCharles.Forsyth e->mtime = s.u.trunc.mtime;
6037da2899SCharles.Forsyth e->qid.vers++;
6137da2899SCharles.Forsyth e->u.file.cvers = s.u.trunc.cvers;
6237da2899SCharles.Forsyth /*
6337da2899SCharles.Forsyth * zap all data and extents
6437da2899SCharles.Forsyth */
6537da2899SCharles.Forsyth logfsextentlistwalk(e->u.file.extent, logfsunconditionallymarkfreeanddirty, server);
6637da2899SCharles.Forsyth logfsextentlistreset(e->u.file.extent);
6737da2899SCharles.Forsyth e->u.file.length = 0;
6837da2899SCharles.Forsyth }
6937da2899SCharles.Forsyth f->openmode = mode;
7037da2899SCharles.Forsyth *qid = e->qid;
7137da2899SCharles.Forsyth return nil;
7237da2899SCharles.Forsyth }
73