hgfs: fix path mangeling bug, find dothg on startup

This commit is contained in:
cinap_lenrek 2011-06-30 03:05:10 +02:00
parent 2f1a0685ea
commit 62186910fa
4 changed files with 94 additions and 51 deletions

View file

@ -35,6 +35,8 @@ struct Revlog
{ {
Ref; Ref;
Revlog *next;
char *path; char *path;
int ifd; int ifd;
@ -67,7 +69,7 @@ struct Revinfo
char *who; char *who;
char *why; char *why;
long when; ulong when;
vlong logoff; vlong logoff;
vlong loglen; vlong loglen;

View file

@ -40,20 +40,31 @@ static char *nametab[] = {
static Revlog changelog; static Revlog changelog;
static Revlog manifest; static Revlog manifest;
static Revlog *revlogs;
static char dothg[MAXPATH];
static Revlog* static Revlog*
getrevlog(Revnode *nd) getrevlog(Revnode *nd)
{ {
char path[MAXPATH]; char buf[MAXPATH];
Revlog *rl; Revlog *rl;
nodepath(seprint(path, path+MAXPATH, ".hg/store/data"), path+MAXPATH, nd); 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)); rl = emalloc9p(sizeof(*rl));
memset(rl, 0, sizeof(*rl)); memset(rl, 0, sizeof(*rl));
if(revlogopen(rl, path, OREAD) < 0){ if(revlogopen(rl, buf, OREAD) < 0){
free(rl); free(rl);
return nil; return nil;
} }
rl->next = revlogs;
revlogs = rl;
} else
revlogupdate(rl);
incref(rl); incref(rl);
return rl; return rl;
} }
@ -61,10 +72,16 @@ getrevlog(Revnode *nd)
static void static void
closerevlog(Revlog *rl) closerevlog(Revlog *rl)
{ {
if(rl == nil) Revlog **pp;
return;
if(decref(rl)) if(rl == nil || decref(rl))
return; return;
for(pp = &revlogs; *pp; pp = &((*pp)->next)){
if(*pp == rl){
*pp = rl->next;
break;
}
}
revlogclose(rl); revlogclose(rl);
free(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 static void
fsmkdir(Dir *d, int level, void *aux) fsmkdir(Dir *d, int level, void *aux)
{ {
@ -205,7 +231,6 @@ fsmkdir(Dir *d, int level, void *aux)
if(d->qid.type == QTDIR) if(d->qid.type == QTDIR)
d->mode |= DMDIR | 0111; d->mode |= DMDIR | 0111;
s = nil;
ri = nil; ri = nil;
switch(level){ switch(level){
case Qroot: case Qroot:
@ -220,10 +245,9 @@ fsmkdir(Dir *d, int level, void *aux)
rev = changelog.map[rev].p1rev; rev = changelog.map[rev].p1rev;
else if(level == Qrev2) else if(level == Qrev2)
rev = changelog.map[rev].p2rev; rev = changelog.map[rev].p2rev;
if(rev >= 0) s = fsmkrevname(buf, sizeof(buf), rev);
snprint(s = buf, sizeof(buf), "%d.%H", rev, changelog.map[rev].hash);
if(level == Qrev){ if(level == Qrev){
d->name = estrdup9p(buf); d->name = estrdup9p(s);
break; break;
} }
goto Strgen; goto Strgen;
@ -252,9 +276,9 @@ fsmkdir(Dir *d, int level, void *aux)
case Qtree: case Qtree:
case Qtreerev: case Qtreerev:
nd = aux; nd = aux;
d->name = estrdup9p(nd->name); if(level == Qtree && nd->mode == 'x')
if(nd->mode == 'x')
d->mode |= 0111; d->mode |= 0111;
d->name = estrdup9p(nd->name);
if(nd->hash){ if(nd->hash){
Revlog *rl; Revlog *rl;
@ -363,10 +387,9 @@ static char*
fswalk1(Fid *fid, char *name, Qid *qid) fswalk1(Fid *fid, char *name, Qid *qid)
{ {
Revtree* (*loadfn)(Revlog *, Revlog *, Revinfo *); Revtree* (*loadfn)(Revlog *, Revlog *, Revinfo *);
char path[MAXPATH]; char buf[MAXPATH], *sname;
Revnode *nd; Revnode *nd;
Revfile *rf; Revfile *rf;
char *sname;
int i, level; int i, level;
if(!(fid->qid.type&QTDIR)) if(!(fid->qid.type&QTDIR))
@ -453,9 +476,9 @@ fswalk1(Fid *fid, char *name, Qid *qid)
level = Qtreerev; level = Qtreerev;
sname += 3; sname += 3;
} }
snprint(path, sizeof(path), "%.*s", i, name); snprint(buf, sizeof(buf), "%.*s", i, name);
i = atoi(sname); i = atoi(sname);
sname = path; sname = buf;
goto Searchtree; goto Searchtree;
} }
} }
@ -483,7 +506,7 @@ fswalk1(Fid *fid, char *name, Qid *qid)
nd->before = nb; nd->before = nb;
} }
nd = nb; nd = nb;
} else if(i || level != Qtree) } else if(name != sname)
goto Notfound; goto Notfound;
rf->node = nd; rf->node = nd;
rf->level = level; rf->level = level;
@ -593,9 +616,8 @@ treegen(int i, Dir *d, void *aux)
static void static void
fsread(Req *r) fsread(Req *r)
{ {
char buf[MAXPATH], *s;
Revfile *rf; Revfile *rf;
char buf[MAXPATH];
char *s;
int i, n; int i, n;
vlong off; vlong off;
int len; int len;
@ -620,18 +642,15 @@ fsread(Req *r)
s = nil; s = nil;
if(rf->buf) if(rf->buf)
goto Strgen; goto Strgen;
if((i = hashrev(&changelog, rf->info->chash)) >= 0){ i = hashrev(&changelog, rf->info->chash);
if(rf->level == Qrev1) if(rf->level == Qrev1)
i = changelog.map[i].p1rev; i = changelog.map[i].p1rev;
else else
i = changelog.map[i].p2rev; i = changelog.map[i].p2rev;
Revgen: Revgen:
if(i >= 0) s = fsmkrevname(buf, sizeof(buf), i);
snprint(s = buf, sizeof(buf), "%d.%H", i, changelog.map[i].hash);
}
goto Strgen; goto Strgen;
case Qtreerev: case Qtreerev:
s = nil;
if((i = hashrev(rf->rlog, rf->node->hash)) >= 0) if((i = hashrev(rf->rlog, rf->node->hash)) >= 0)
i = rf->rlog->map[i].linkrev; i = rf->rlog->map[i].linkrev;
goto Revgen; goto Revgen;
@ -699,7 +718,7 @@ Srv fs =
void void
usage(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"); exits("usage");
} }
@ -707,6 +726,7 @@ void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char *srv, *mtpt; char *srv, *mtpt;
char buf[MAXPATH];
inflateinit(); inflateinit();
fmtinstall('H', Hfmt); fmtinstall('H', Hfmt);
@ -728,9 +748,29 @@ main(int argc, char *argv[])
usage(); usage();
} ARGEND; } 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"); 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"); sysfatal("can't open menifest: %r\n");
postmountsrv(&fs, srv, mtpt, MREPL); postmountsrv(&fs, srv, mtpt, MREPL);

View file

@ -18,6 +18,7 @@ revlogupdate(Revlog *r)
{ {
uchar buf[64]; uchar buf[64];
Revmap *m; Revmap *m;
vlong noff;
int rev; int rev;
if(seek(r->ifd, r->ioff, 0) < 0) 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]; m->p2rev = buf[28]<<24 | buf[29]<<16 | buf[30]<<8 | buf[31];
memmove(m->hash, buf+32, HASHSZ); memmove(m->hash, buf+32, HASHSZ);
noff = r->ioff + sizeof(buf);
if(r->dfd < 0){ if(r->dfd < 0){
m->hoff = seek(r->ifd, 0, 1); m->hoff = noff;
r->ioff = seek(r->ifd, m->hlen, 1); noff = seek(r->ifd, m->hoff + m->hlen, 0);
} else if(noff < 0)
r->ioff = seek(r->ifd, 0, 1); break;
}
r->ioff = noff;
} }
r->nmap = rev; r->nmap = rev;
} }

View file

@ -13,7 +13,7 @@ nodepath(char *s, char *e, Revnode *nd)
"lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
}; };
char *p; char *p;
int i; int i, l;
if(nd == nil || nd->name == nil) if(nd == nil || nd->name == nil)
return s; return s;
@ -21,10 +21,11 @@ nodepath(char *s, char *e, Revnode *nd)
s = seprint(nodepath(s, e, nd->up), e, "/"); s = seprint(nodepath(s, e, nd->up), e, "/");
p = nd->name; p = nd->name;
for(i=0; i<nelem(frogs); i++) for(i=0; i<nelem(frogs); i++){
if(strncmp(frogs[i], p, strlen(frogs[i])) == 0) 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); return seprint(s, e, "%.2s~%.2x%s", p, p[2], p+3);
}
for(; s+4 < e && *p; p++){ for(; s+4 < e && *p; p++){
if(*p == '_'){ if(*p == '_'){
*s++ = '_'; *s++ = '_';
@ -50,20 +51,16 @@ mknode(char *name, uchar *hash, char mode)
char *s; char *s;
d = malloc(sizeof(*d) + (hash ? HASHSZ : 0) + (name ? strlen(name)+1 : 0)); 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]; s = (char*)&d[1];
if(hash){ if(hash){
d->path = *((uvlong*)hash); d->path = *((uvlong*)hash);
memmove(d->hash = (uchar*)s, hash, HASHSZ); memmove(d->hash = (uchar*)s, hash, HASHSZ);
s += HASHSZ; s += HASHSZ;
} else { }else
d->path = 1; d->path = 1;
d->hash = nil;
}
if(name) if(name)
strcpy(d->name = s, name); strcpy(d->name = s, name);
else
d->name = nil;
d->mode = mode; d->mode = mode;
return d; return d;
} }