12 snprint(path, sizeof(path), "/tmp/hg%.12d%.8lux", getpid(), id++);
13 return create(path, OEXCL|ORDWR|ORCLOSE, 0600);
17 revlogupdate(Revlog *r)
24 if(seek(r->ifd, r->ioff, 0) < 0)
26 for(rev=r->nmap;;rev++){
27 if(readn(r->ifd, buf, sizeof(buf)) != sizeof(buf))
30 r->map = realloc(r->map, sizeof(r->map[0])*(rev+16));
32 memset(m, 0, sizeof(*m));
33 m->hoff = (vlong)buf[0]<<40 |
42 m->flags = buf[6]<<8 | buf[7];
43 m->hlen = buf[8]<<24 | buf[9]<<16 | buf[10]<<8 | buf[11];
44 m->flen = buf[12]<<24 | buf[13]<<16 | buf[14]<<8 | buf[15];
45 m->baserev = buf[16]<<24 | buf[17]<<16 | buf[18]<<8 | buf[19];
46 m->linkrev = buf[20]<<24 | buf[21]<<16 | buf[22]<<8 | buf[23];
47 m->p1rev = buf[24]<<24 | buf[25]<<16 | buf[26]<<8 | buf[27];
48 m->p2rev = buf[28]<<24 | buf[29]<<16 | buf[30]<<8 | buf[31];
49 memmove(m->hash, buf+32, HASHSZ);
51 noff = r->ioff + sizeof(buf);
54 noff = seek(r->ifd, m->hoff + m->hlen, 0);
64 revlogopen(Revlog *r, char *path, int mode)
70 path = smprint("%s.i", path);
71 if((r->ifd = open(path, mode)) < 0){
75 path[strlen(path)-1] = 'd';
76 r->dfd = open(path, mode);
78 path[strlen(path)-2] = 0;
89 revlogclose(Revlog *r)
112 revhash(Revlog *r, int rev)
114 if(rev < 0 || rev >= r->nmap)
116 return r->map[rev].hash;
120 hashrev(Revlog *r, uchar hash[])
124 for(rev=0; rev<r->nmap; rev++)
125 if(memcmp(r->map[rev].hash, hash, HASHSZ) == 0)
131 prevlogrev(Revlog *r, int rev)
133 if(r->map[rev].baserev == rev)
139 prevbundlerev(Revlog *r, int rev)
141 if(r->map[rev].baserev == rev)
143 return r->map[rev].p1rev;
147 getchain1(Revlog *r, int rev, int *count, int (*next)(Revlog *, int))
151 if(rev < 0 || rev >= r->nmap){
154 chain = malloc(sizeof(chain[0]) * ((*count)+1));
159 if(chain = getchain1(r, (*next)(r, rev), count, next))
160 chain[(*count)++] = &r->map[rev];
166 getchain(Revlog *r, int rev, int (*next)(Revlog *, int))
169 return getchain1(r, rev, &count, next);
173 revlogextract(Revlog *r, int rev, int ofd)
175 int err, hfd, pfd, bfd;
186 if((chain = getchain(r, rev, prevlogrev)) == nil){
187 werrstr("bad patch chain");
191 off = seek(ofd, 0, 1);
193 werrstr("seek outfile: %r");
196 hfd = r->dfd < 0 ? r->ifd : r->dfd;
197 for(i=0; m = chain[i]; i++){
198 if(seek(hfd, m->hoff, 0) < 0){
199 werrstr("seek index: %r");
202 if(m == chain[0] && m->baserev == m->rev){
204 if(bfd >= 0 && bfd != ofd)
206 if((bfd = fmktemp()) < 0){
207 werrstr("create basefile: %r");
212 if(funzip(bfd, hfd, m->hlen) < 0){
213 werrstr("unzip basefile: %r");
218 if((pfd = fmktemp()) < 0){
219 werrstr("create patchfile: %r");
224 /* put a mark before the patch data */
225 snprint(buf, sizeof(buf), "%H", m->hash);
226 if(fpatchmark(pfd, buf) < 0){
227 werrstr("patchmark: %r");
231 if(funzip(pfd, hfd, m->hlen) < 0){
232 werrstr("unzip patchfile: %r");
239 if(pfd >= 0 && bfd >= 0 && bfd != ofd){
240 if(seek(pfd, 0, 0) < 0){
241 werrstr("seek patchfile: %r");
244 if(fpatch(ofd, bfd, pfd) < 0){
245 werrstr("patch: %r");
250 if(seek(ofd, off, 0) < 0){
251 werrstr("seek outfile: %r");
254 if(fhash(ofd, revhash(r, m->p1rev), revhash(r, m->p2rev), hash) < 0){
255 werrstr("hash outfile: %r");
258 if(memcmp(m->hash, hash, HASHSZ)){
259 werrstr("got bad hash");
267 if(bfd >= 0 && bfd != ofd)
275 revlogopentemp(Revlog *r, int rev)
279 if(r->tfd < 0 || rev != r->tid){
280 if((fd = fmktemp()) < 0)
282 if(revlogextract(r, rev, fd) < 0){
291 fd = dup(r->tfd, -1);
292 if(seek(fd, 0, 0) < 0){
302 static char magic[2] = { 0x01, 0x0A, };
303 char buf[4096], *s, *p;
307 while(o < sizeof(buf)){
308 if((n = pread(fd, buf+o, sizeof(buf)-o, o)) <= 0)
311 if(o < sizeof(magic))
313 if(memcmp(buf, magic, sizeof(magic)) != 0)
315 s = buf + sizeof(magic);
316 while((s - buf) <= (o - sizeof(magic))){
317 if((p = memchr(s, magic[0], o - (s - buf))) == nil)
319 if(memcmp(p, magic, sizeof(magic)) == 0)
320 return (p - buf) + sizeof(magic);