git: 9front

Download patch

ref: fde9e53b87da3ce9e9f13d2990fe40df05bb702e
parent: bd6a204be950f57f950b9553a90571ead0bd33ba
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Wed Jun 29 23:05:10 EDT 2011

hgfs: fix path mangeling bug, find dothg on startup

--- a/sys/src/cmd/hgfs/dat.h
+++ b/sys/src/cmd/hgfs/dat.h
@@ -35,6 +35,8 @@
 {
 	Ref;
 
+	Revlog	*next;
+
 	char	*path;
 
 	int	ifd;
@@ -67,7 +69,7 @@
 
 	char	*who;
 	char	*why;
-	long	when;
+	ulong	when;
 
 	vlong	logoff;
 	vlong	loglen;
--- a/sys/src/cmd/hgfs/fs.c
+++ b/sys/src/cmd/hgfs/fs.c
@@ -40,20 +40,31 @@
 
 static Revlog changelog;
 static Revlog manifest;
+static Revlog *revlogs;
 
+static char dothg[MAXPATH];
+
 static Revlog*
 getrevlog(Revnode *nd)
 {
-	char path[MAXPATH];
+	char buf[MAXPATH];
 	Revlog *rl;
 
-	nodepath(seprint(path, path+MAXPATH, ".hg/store/data"), path+MAXPATH, nd);
-	rl = emalloc9p(sizeof(*rl));
-	memset(rl, 0, sizeof(*rl));
-	if(revlogopen(rl, path, OREAD) < 0){
-		free(rl);
-		return nil;
-	}
+	nodepath(seprint(buf, buf+sizeof(buf), "%s/store/data", dothg), buf+sizeof(buf), nd);
+	for(rl = revlogs; rl; rl = rl->next)
+		if(strcmp(buf, rl->path) == 0)
+			break;
+	if(rl == nil){
+		rl = emalloc9p(sizeof(*rl));
+		memset(rl, 0, sizeof(*rl));
+		if(revlogopen(rl, buf, OREAD) < 0){
+			free(rl);
+			return nil;
+		}
+		rl->next = revlogs;
+		revlogs = rl;
+	} else
+		revlogupdate(rl);
 	incref(rl);
 	return rl;
 }
@@ -61,10 +72,16 @@
 static void
 closerevlog(Revlog *rl)
 {
-	if(rl == nil)
+	Revlog **pp;
+
+	if(rl == nil || decref(rl))
 		return;
-	if(decref(rl))
-		return;
+	for(pp = &revlogs; *pp; pp = &((*pp)->next)){
+		if(*pp == rl){
+			*pp = rl->next;
+			break;
+		}
+	}
 	revlogclose(rl);
 	free(rl);
 }
@@ -189,6 +206,15 @@
 	}
 }
 
+static char*
+fsmkrevname(char *buf, int nbuf, int rev)
+{
+	if(rev < 0 || rev >= changelog.nmap)
+		return nil;
+	snprint(buf, nbuf, "%d.%H", rev, changelog.map[rev].hash);
+	return buf;
+}
+
 static void
 fsmkdir(Dir *d, int level, void *aux)
 {
@@ -205,7 +231,6 @@
 	if(d->qid.type == QTDIR)
 		d->mode |= DMDIR | 0111;
 
-	s = nil;
 	ri = nil;
 	switch(level){
 	case Qroot:
@@ -220,10 +245,9 @@
 			rev = changelog.map[rev].p1rev;
 		else if(level == Qrev2)
 			rev = changelog.map[rev].p2rev;
-		if(rev >= 0)
-			snprint(s = buf, sizeof(buf), "%d.%H", rev, changelog.map[rev].hash);
+		s = fsmkrevname(buf, sizeof(buf), rev);
 		if(level == Qrev){
-			d->name = estrdup9p(buf);
+			d->name = estrdup9p(s);
 			break;
 		}
 		goto Strgen;
@@ -252,9 +276,9 @@
 	case Qtree:
 	case Qtreerev:
 		nd = aux;
-		d->name = estrdup9p(nd->name);
-		if(nd->mode == 'x')
+		if(level == Qtree && nd->mode == 'x')
 			d->mode |= 0111;
+		d->name = estrdup9p(nd->name);
 		if(nd->hash){
 			Revlog *rl;
 
@@ -363,10 +387,9 @@
 fswalk1(Fid *fid, char *name, Qid *qid)
 {
 	Revtree* (*loadfn)(Revlog *, Revlog *, Revinfo *);
-	char path[MAXPATH];
+	char buf[MAXPATH], *sname;
 	Revnode *nd;
 	Revfile *rf;
-	char *sname;
 	int i, level;
 
 	if(!(fid->qid.type&QTDIR))
@@ -453,9 +476,9 @@
 							level = Qtreerev;
 							sname += 3;
 						}
-						snprint(path, sizeof(path), "%.*s", i, name);
+						snprint(buf, sizeof(buf), "%.*s", i, name);
 						i = atoi(sname);
-						sname = path;
+						sname = buf;
 						goto Searchtree;
 					}
 				}
@@ -483,7 +506,7 @@
 					nd->before = nb;
 				}
 				nd = nb;
-			} else if(i || level != Qtree)
+			} else if(name != sname)
 				goto Notfound;
 			rf->node = nd;
 			rf->level = level;
@@ -593,9 +616,8 @@
 static void
 fsread(Req *r)
 {
+	char buf[MAXPATH], *s;
 	Revfile *rf;
-	char buf[MAXPATH];
-	char *s;
 	int i, n;
 	vlong off;
 	int len;
@@ -620,18 +642,15 @@
 		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;
+		i = hashrev(&changelog, rf->info->chash);
+		if(rf->level == Qrev1)
+			i = changelog.map[i].p1rev;
+		else
+			i = changelog.map[i].p2rev;
 	Revgen:
-			if(i >= 0)
-				snprint(s = buf, sizeof(buf), "%d.%H", i, changelog.map[i].hash);
-		}
+		s = fsmkrevname(buf, sizeof(buf), i);
 		goto Strgen;
 	case Qtreerev:
-		s = nil;
 		if((i = hashrev(rf->rlog, rf->node->hash)) >= 0)
 			i = rf->rlog->map[i].linkrev;
 		goto Revgen;
@@ -699,7 +718,7 @@
 void
 usage(void)
 {
-	fprint(2, "usage: %s [-D] [-m mtpt] [-s srv]\n", argv0);
+	fprint(2, "usage: %s [-D] [-m mtpt] [-s srv] [root]\n", argv0);
 	exits("usage");
 }
 
@@ -707,6 +726,7 @@
 main(int argc, char *argv[])
 {
 	char *srv, *mtpt;
+	char buf[MAXPATH];
 
 	inflateinit();
 	fmtinstall('H', Hfmt);
@@ -728,9 +748,29 @@
 		usage();
 	} ARGEND;
 
-	if(revlogopen(&changelog, ".hg/store/00changelog", OREAD) < 0)
+	if(*argv){
+		snprint(dothg, sizeof(dothg), "%s/.hg", *argv);
+	}else{
+		if(getwd(buf, sizeof(buf)) == nil)
+			sysfatal("can't get working dir: %r");
+		for(;;){
+			char *s;
+
+			snprint(dothg, sizeof(dothg), "%s/.hg", buf);
+			if(access(dothg, AEXIST) == 0)
+				break;
+			if((s = strrchr(buf, '/')) == nil)
+				break;
+			*s = 0;
+		}
+	}
+	cleanname(dothg);
+
+	snprint(buf, sizeof(buf), "%s/store/00changelog", dothg);
+	if(revlogopen(&changelog, buf, OREAD) < 0)
 		sysfatal("can't open changelog: %r\n");
-	if(revlogopen(&manifest, ".hg/store/00manifest", OREAD) < 0)
+	snprint(buf, sizeof(buf), "%s/store/00manifest", dothg);
+	if(revlogopen(&manifest, buf, OREAD) < 0)
 		sysfatal("can't open menifest: %r\n");
 
 	postmountsrv(&fs, srv, mtpt, MREPL);
--- a/sys/src/cmd/hgfs/revlog.c
+++ b/sys/src/cmd/hgfs/revlog.c
@@ -18,6 +18,7 @@
 {
 	uchar buf[64];
 	Revmap *m;
+	vlong noff;
 	int rev;
 
 	if(seek(r->ifd, r->ioff, 0) < 0)
@@ -47,11 +48,14 @@
 		m->p2rev = buf[28]<<24 | buf[29]<<16 | buf[30]<<8 | buf[31];
 		memmove(m->hash, buf+32, HASHSZ);
 
+		noff = r->ioff + sizeof(buf);
 		if(r->dfd < 0){
-			m->hoff = seek(r->ifd, 0, 1);
-			r->ioff = seek(r->ifd, m->hlen, 1);
-		} else
-			r->ioff = seek(r->ifd, 0, 1);
+			m->hoff = noff;
+			noff = seek(r->ifd, m->hoff + m->hlen, 0);
+			if(noff < 0)
+				break;
+		}
+		r->ioff = noff;
 	}
 	r->nmap = rev;
 }
--- a/sys/src/cmd/hgfs/tree.c
+++ b/sys/src/cmd/hgfs/tree.c
@@ -13,7 +13,7 @@
 		"lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
 	};
 	char *p;
-	int i;
+	int i, l;
 
 	if(nd == nil || nd->name == nil)
 		return s;
@@ -21,10 +21,11 @@
 	s = seprint(nodepath(s, e, nd->up), e, "/");
 
 	p = nd->name;
-	for(i=0; i<nelem(frogs); i++)
-		if(strncmp(frogs[i], p, strlen(frogs[i])) == 0)
+	for(i=0; i<nelem(frogs); i++){
+		l = strlen(frogs[i]);
+		if((strncmp(frogs[i], p, l) == 0) && (p[l] == 0 || p[l] == '.'))
 			return seprint(s, e, "%.2s~%.2x%s", p, p[2], p+3);
-
+	}
 	for(; s+4 < e && *p; p++){
 		if(*p == '_'){
 			*s++ = '_';
@@ -50,20 +51,16 @@
 	char *s;
 
 	d = malloc(sizeof(*d) + (hash ? HASHSZ : 0) + (name ? strlen(name)+1 : 0));
-	d->up = d->down = d->next = d->before = nil;
+	memset(d, 0, sizeof(*d));
 	s = (char*)&d[1];
 	if(hash){
 		d->path = *((uvlong*)hash);
 		memmove(d->hash = (uchar*)s, hash, HASHSZ);
 		s += HASHSZ;
-	} else {
+	}else
 		d->path = 1;
-		d->hash = nil;
-	}
 	if(name)
 		strcpy(d->name = s, name);
-	else
-		d->name = nil;
 	d->mode = mode;
 	return d;
 }
--