summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@centraldogma>2011-06-30 03:05:10 +0200
committercinap_lenrek <cinap_lenrek@centraldogma>2011-06-30 03:05:10 +0200
commit62186910fa0c833f8a5716cb83581494adde1b4e (patch)
tree5247b8b4fe73343c79e759f78ca165e94c368526
parent2f1a0685ea31bfa8da10bb077312451042c77324 (diff)
downloadplan9front-62186910fa0c833f8a5716cb83581494adde1b4e.tar.xz
hgfs: fix path mangeling bug, find dothg on startup
-rw-r--r--sys/src/cmd/hgfs/dat.h4
-rw-r--r--sys/src/cmd/hgfs/fs.c112
-rw-r--r--sys/src/cmd/hgfs/revlog.c12
-rw-r--r--sys/src/cmd/hgfs/tree.c17
4 files changed, 94 insertions, 51 deletions
diff --git a/sys/src/cmd/hgfs/dat.h b/sys/src/cmd/hgfs/dat.h
index b2f0be931..2a0ee580e 100644
--- a/sys/src/cmd/hgfs/dat.h
+++ b/sys/src/cmd/hgfs/dat.h
@@ -35,6 +35,8 @@ struct Revlog
{
Ref;
+ Revlog *next;
+
char *path;
int ifd;
@@ -67,7 +69,7 @@ struct Revinfo
char *who;
char *why;
- long when;
+ ulong when;
vlong logoff;
vlong loglen;
diff --git a/sys/src/cmd/hgfs/fs.c b/sys/src/cmd/hgfs/fs.c
index 142f8863a..c63048127 100644
--- a/sys/src/cmd/hgfs/fs.c
+++ b/sys/src/cmd/hgfs/fs.c
@@ -40,20 +40,31 @@ static char *nametab[] = {
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 @@ getrevlog(Revnode *nd)
static void
closerevlog(Revlog *rl)
{
- if(rl == nil)
- return;
- if(decref(rl))
+ Revlog **pp;
+
+ if(rl == nil || 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 @@ fsmkqid(Qid *q, int level, void *aux)
}
}
+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 @@ fsmkdir(Dir *d, int level, void *aux)
if(d->qid.type == QTDIR)
d->mode |= DMDIR | 0111;
- s = nil;
ri = nil;
switch(level){
case Qroot:
@@ -220,10 +245,9 @@ fsmkdir(Dir *d, int level, void *aux)
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 @@ fsmkdir(Dir *d, int level, void *aux)
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 @@ static char*
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 @@ fswalk1(Fid *fid, char *name, Qid *qid)
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 @@ fswalk1(Fid *fid, char *name, Qid *qid)
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 @@ treegen(int i, Dir *d, void *aux)
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 @@ fsread(Req *r)
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 @@ Srv fs =
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 @@ void
main(int argc, char *argv[])
{
char *srv, *mtpt;
+ char buf[MAXPATH];
inflateinit();
fmtinstall('H', Hfmt);
@@ -728,9 +748,29 @@ main(int argc, char *argv[])
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);
diff --git a/sys/src/cmd/hgfs/revlog.c b/sys/src/cmd/hgfs/revlog.c
index b45a4063f..0d3c44136 100644
--- a/sys/src/cmd/hgfs/revlog.c
+++ b/sys/src/cmd/hgfs/revlog.c
@@ -18,6 +18,7 @@ revlogupdate(Revlog *r)
{
uchar buf[64];
Revmap *m;
+ vlong noff;
int rev;
if(seek(r->ifd, r->ioff, 0) < 0)
@@ -47,11 +48,14 @@ revlogupdate(Revlog *r)
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;
}
diff --git a/sys/src/cmd/hgfs/tree.c b/sys/src/cmd/hgfs/tree.c
index 62a3ab97f..517d7ad54 100644
--- a/sys/src/cmd/hgfs/tree.c
+++ b/sys/src/cmd/hgfs/tree.c
@@ -13,7 +13,7 @@ nodepath(char *s, char *e, Revnode *nd)
"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 @@ nodepath(char *s, char *e, Revnode *nd)
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 @@ mknode(char *name, uchar *hash, char mode)
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;
}