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;
}
--
⑨