diff options
| author | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-06-30 03:05:10 +0200 |
|---|---|---|
| committer | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-06-30 03:05:10 +0200 |
| commit | 62186910fa0c833f8a5716cb83581494adde1b4e (patch) | |
| tree | 5247b8b4fe73343c79e759f78ca165e94c368526 | |
| parent | 2f1a0685ea31bfa8da10bb077312451042c77324 (diff) | |
| download | plan9front-62186910fa0c833f8a5716cb83581494adde1b4e.tar.xz | |
hgfs: fix path mangeling bug, find dothg on startup
| -rw-r--r-- | sys/src/cmd/hgfs/dat.h | 4 | ||||
| -rw-r--r-- | sys/src/cmd/hgfs/fs.c | 112 | ||||
| -rw-r--r-- | sys/src/cmd/hgfs/revlog.c | 12 | ||||
| -rw-r--r-- | sys/src/cmd/hgfs/tree.c | 17 |
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; } |
