@include packns = @names c32be { struct pack_header { @0x0 uint32 hdr_signature; @0x4 uint32 hdr_version; @0x8 uint32 hdr_entries; @0xc; }; enum object_type { OBJ_BAD = -1, OBJ_NONE = 0, OBJ_COMMIT = 1, OBJ_TREE = 2, OBJ_BLOB = 3, OBJ_TAG = 4, /* 5 for future expansion */ OBJ_OFS_DELTA = 6, OBJ_REF_DELTA = 7, OBJ_ANY, OBJ_MAX, }; typedef char sha1[20]; }; gittypename = [ "", "commit", "tree", "blob", "tag", "", "ofsdelta", "refsdelta" ]; @record gitobj { offset, bytes, sha1, type }; @define mkstrdom(str) { @local dom; dom = mkdom(c32le, mksas(str)); return (unsigned char*){dom}0; } @define decodesha(md) { @local i, x, rv; x = "0123456780abcdef"; rv = mkstr(2*20); for(i = 0; i < 20; i++){ rv[i*2] = x[md[i]>>4]; rv[i*2+1] = x[md[i]&0xf]; } return rv; } @define patchdelta(src, delta) { @local data, cmd, size, out, i, cp_off, src_size, cp_size; @local src_buf, dst_buf, dst_size, fd; src_buf = mkstrdom(src); src_size = strlen(src); data = mkstrdom(delta); top = data+strlen(delta); // printf("\npatching delta (%d byte src, %d byte delta)\n", // strlen(src), strlen(delta)); /* get size of original source */ size = 0; i = 0; do { cmd = *data++; size |= (cmd&~0x80)< src_size || cp_size > size) break; memcpy(out, (char *) src_buf + cp_off, cp_size); out += cp_size; size -= cp_size; } else if (cmd) { if (cmd > size) break; memcpy(out, data, cmd); out += cmd; data += cmd; size -= cmd; } else { /* * cmd == 0 is reserved for future encoding * extensions. In the mean time we must fail when * encountering them (might be data corruption). */ error("unexpected delta opcode 0"); } } return getbytes(dst_buf, dst_size); } @define dumppack(pack) { @local p, q, i, c, b, type, size, zsize, infl, obj, off, ref, roff; @local sha1tab, offtab, deltaq, s1, go, dep; p = (struct pack`pack_header*){pack}0; q = (char*)&p->hdr_signature; printf("signature: "); for(i = 0; i < 4; i++) printf("%c", q[i]); printf("\n"); printf("version: %d\n", (char*)p->hdr_version); printf("entries: %d\n", (char*)p->hdr_entries); sha1tab = mktab(); offtab = mktab(); deltaq = []; q = (unsigned char*)(p+1); for(i = 0; i < p->hdr_entries; i++){ off = q; c = *q++; type = (c>>4)&7; size = (c&15); shift = 4; while(c&0x80){ // printf("c = %x, size=%d, shift=%d\n", c, size, shift); c = *q++; size += (c&0x7f)<