git: 9front

Download patch

ref: 3d2157b65213009a234b3a9ba3383b71371698a1
parent: 8588e5d811ffcc277a2fa47da98888075f0f3d50
author: cinap_lenrek <cinap_lenrek@localhost>
date: Mon Jun 27 19:01:19 EDT 2011

hgfs: allow "tip" as revision, do perm checking

--- a/sys/src/cmd/hgfs/fs.c
+++ b/sys/src/cmd/hgfs/fs.c
@@ -147,10 +147,10 @@
 		break;
 	case Qtree:
 		nd = aux;
-		if(nd->hash){
-			q->type = 0;
-		} else {
+		if(nd->down){
 			q->type = QTDIR;
+		} else {
+			q->type = 0;
 		}
 		q->path = nd->path;
 		q->vers = 0;
@@ -300,6 +300,8 @@
 	int n, i, rev;
 	char *s;
 
+	if(strcmp(name, "tip") == 0)
+		return rl->nmap-1;
 	rev = strtol(name, &s, 10);
 	if(s > name && (*s == 0 || ispunct(*s)))
 		return rev;
@@ -452,7 +454,18 @@
 static void
 fsopen(Req *r)
 {
-	respond(r, nil);
+	Revfile *rf;
+
+	rf = r->fid->aux;
+	switch(r->ifcall.mode & 3){
+	case OEXEC:
+		if(rf->node == nil || rf->node->mode != 'x')
+			break;
+	case OREAD:
+		respond(r, nil);
+		return;
+	}
+	respond(r, "permission denied");
 }
 
 static int
@@ -495,88 +508,78 @@
 fsread(Req *r)
 {
 	Revfile *rf;
+	char buf[MAXPATH];
+	Revlog rl;
+	char *s;
+	int i, n;
 
 	rf = r->fid->aux;
-	if(r->fid->qid.type == QTDIR){
-		switch(rf->level){
-		default:
-			respond(r, "bug in fsread");
+	switch(rf->level){
+	case Qroot:
+		revlogupdate(&changelog);
+		revlogupdate(&manifest);
+		dirread9p(r, rootgen, nil);
+		respond(r, nil);
+		return;
+	case Qrev:
+		dirread9p(r, revgen, rf->info);
+		respond(r, nil);
+		return;
+	case Qrev1:
+	case Qrev2:
+		s = nil;
+		if(rf->buf)
+			goto Strgen;
+		if((i = hashrev(&changelog, rf->info->chash)) >= 0){
+			if(rf->level == Qrev1)
+				i = changelog.map[i].p1rev;
+			else
+				i = changelog.map[i].p2rev;
+			if(i >= 0)
+				snprint(s = buf, sizeof(buf), "%d.%H", i, changelog.map[i].hash);
+		}
+		goto Strgen;
+	case Qlog:
+		if(rf->fd >= 0)
+			goto Fdgen;
+		if((rf->fd = revlogopentemp(&changelog, hashrev(&changelog, rf->info->chash))) < 0){
+			responderror(r);
 			return;
-		case Qroot:
-			revlogupdate(&changelog);
-			revlogupdate(&manifest);
-
-			dirread9p(r, rootgen, nil);
-			respond(r, nil);
-			return;
-		case Qrev:
-			dirread9p(r, revgen, rf->info);
-			respond(r, nil);
-			return;
-		case Qtree:
-		case Qfiles:
-		case Qchanges:
+		}
+		goto Fdgen;
+	case Qwho:
+		s = rf->info->who;
+		goto Strgen;
+	case Qwhy:
+		s = rf->info->why;
+	Strgen:
+		if(rf->buf == nil)
+			rf->buf = s ? smprint("%s\n", s) : estrdup9p("");
+		readstr(r, rf->buf);
+		respond(r, nil);
+		return;
+	case Qtree:
+		if(rf->node->down){
+	case Qfiles:
+	case Qchanges:
 			dirread9p(r, treegen, rf->node->down);
 			respond(r, nil);
 			return;
 		}
-	} else {
-		char buf[MAXPATH];
-		Revlog rl;
-		char *s;
-		int i, n;
-
-		switch(rf->level){
-		default:
-			respond(r, "bug in fsread");
+		if(rf->fd >= 0)
+			goto Fdgen;
+		nodepath(seprint(buf, buf+sizeof(buf), ".hg/store/data"), buf+sizeof(buf), rf->node);
+		if(revlogopen(&rl, buf, OREAD) < 0){
+			responderror(r);
 			return;
-		case Qlog:
-			if(rf->fd >= 0)
-				break;
-			if((rf->fd = revlogopentemp(&changelog, hashrev(&changelog, rf->info->chash))) < 0){
-				responderror(r);
-				return;
-			}
-			break;
-		case Qrev1:
-		case Qrev2:
-			s = nil;
-			if((i = hashrev(&changelog, rf->info->chash)) >= 0){
-				if(rf->level == Qrev1)
-					i = changelog.map[i].p1rev;
-				else
-					i = changelog.map[i].p2rev;
-				if(i >= 0)
-					snprint(s = buf, sizeof(buf), "%d.%H", i, changelog.map[i].hash);
-			}
-			goto Strgen;
-		case Qwho:
-			s = rf->info->who;
-			goto Strgen;
-		case Qwhy:
-			s = rf->info->why;
-		Strgen:
-			if(rf->buf == nil)
-				rf->buf = s ? smprint("%s\n", s) : estrdup9p("");
-			readstr(r, rf->buf);
-			respond(r, nil);
-			return;
-		case Qtree:
-			if(rf->fd >= 0)
-				break;
-			nodepath(seprint(buf, buf+sizeof(buf), ".hg/store/data"), buf+sizeof(buf), rf->node);
-			if(revlogopen(&rl, buf, OREAD) < 0){
-				responderror(r);
-				return;
-			}
-			if((rf->fd = revlogopentemp(&rl, hashrev(&rl, rf->node->hash))) < 0){
-				responderror(r);
-				revlogclose(&rl);
-				return;
-			}
+		}
+		if((rf->fd = revlogopentemp(&rl, hashrev(&rl, rf->node->hash))) < 0){
+			responderror(r);
 			revlogclose(&rl);
-			break;
+			return;
 		}
+		revlogclose(&rl);
+	Fdgen:
 		if((n = pread(rf->fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset)) < 0){
 			responderror(r);
 			return;
@@ -583,7 +586,9 @@
 		}
 		r->ofcall.count = n;
 		respond(r, nil);
+		return;
 	}
+	respond(r, "bug in fsread");
 }
 
 Srv fs = 
--