xref: /inferno-os/liblogfs/open.c (revision 28942ead413418b56c5be78e8c4c400881fba72e)
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