diff --git a/sys/src/cmd/hgfs/dat.h b/sys/src/cmd/hgfs/dat.h index acab7db5e..17cc05e91 100644 --- a/sys/src/cmd/hgfs/dat.h +++ b/sys/src/cmd/hgfs/dat.h @@ -93,6 +93,7 @@ struct Revfile char *buf; int fd; + int doff; /* length of metadata to skip */ }; uchar nullid[HASHSZ]; diff --git a/sys/src/cmd/hgfs/fns.h b/sys/src/cmd/hgfs/fns.h index 7e875a6ab..42c6f736f 100644 --- a/sys/src/cmd/hgfs/fns.h +++ b/sys/src/cmd/hgfs/fns.h @@ -21,6 +21,7 @@ int revlogextract(Revlog *r, int rev, int ofd); uchar *revhash(Revlog *r, int rev); int hashrev(Revlog *r, uchar hash[]); int revlogopentemp(Revlog *r, int rev); +int fmetaheader(int fd); /* info */ Revinfo *loadrevinfo(Revlog *changelog, int rev); diff --git a/sys/src/cmd/hgfs/fs.c b/sys/src/cmd/hgfs/fs.c index 4b58a515c..7f9c37d6a 100644 --- a/sys/src/cmd/hgfs/fs.c +++ b/sys/src/cmd/hgfs/fs.c @@ -298,8 +298,15 @@ fsmkdir(Dir *d, int level, void *aux) if((rl = getrevlog(nd)) == nil) break; if((rev = hashrev(rl, nd->hash)) >= 0){ - if(level == Qtree) + if(level == Qtree){ + /* + * BUG: this is not correct. mercurial might + * prefix the data log with random \1\n escaped + * metadata strings (see fmetaheader()) and the flen + * *includes* the metadata part. m( + */ d->length = rl->map[rev].flen; + } ri = getrevinfo(rl->map[rev].linkrev); } closerevlog(rl); @@ -490,7 +497,13 @@ fswalk1(Fid *fid, char *name, Qid *qid) sname += 3; } snprint(buf, sizeof(buf), "%.*s", i, name); - i = atoi(sname); + if(*sname == 0) + i = 0; + else { + i = strtol(sname, &sname, 10); + if(i < 0 || *sname != '\0') + goto Notfound; + } sname = buf; goto Searchtree; } @@ -680,6 +693,7 @@ fsread(Req *r) responderror(r); return; } + rf->doff = fmetaheader(rf->fd); goto Fdgen; case Qwho: s = rf->info->who; @@ -706,8 +720,9 @@ fsread(Req *r) responderror(r); return; } + rf->doff = fmetaheader(rf->fd); Fdgen: - if((n = pread(rf->fd, r->ofcall.data, len, off)) < 0){ + if((n = pread(rf->fd, r->ofcall.data, len, off + rf->doff)) < 0){ responderror(r); return; } diff --git a/sys/src/cmd/hgfs/revlog.c b/sys/src/cmd/hgfs/revlog.c index 420a13307..ab4ef1d9f 100644 --- a/sys/src/cmd/hgfs/revlog.c +++ b/sys/src/cmd/hgfs/revlog.c @@ -281,3 +281,31 @@ revlogopentemp(Revlog *r, int rev) } return fd; } + +int +fmetaheader(int fd) +{ + static char magic[2] = { 0x01, 0x0A, }; + char buf[4096], *s, *p; + int o, n; + + o = 0; + while(o < sizeof(buf)){ + if((n = pread(fd, buf+o, sizeof(buf)-o, o)) <= 0) + break; + o += n; + if(o < sizeof(magic)) + continue; + if(memcmp(buf, magic, sizeof(magic)) != 0) + break; + s = buf + sizeof(magic); + while((s - buf) <= (o - sizeof(magic))){ + if((p = memchr(s, magic[0], o - (s - buf))) == nil) + break; + if(memcmp(p, magic, sizeof(magic)) == 0) + return (p - buf) + sizeof(magic); + s = p+1; + } + } + return 0; +}