hgfs: fix path mangeling bug, find dothg on startup
This commit is contained in:
parent
2f1a0685ea
commit
62186910fa
4 changed files with 94 additions and 51 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue