commit a487c1d081edc5ee689dc37477c2740bfbefc127 from: Stefan Sperling date: Sun Jan 14 16:49:25 2018 UTC refactor dump_packed_object() a bit; no functional change commit - 740c5444001b083fe9c04d809ceec9015bb075fc commit + a487c1d081edc5ee689dc37477c2740bfbefc127 blob - 65bbcded88384d5d5c7e151f84e6271868044a5d blob + ebe18b51f48a920944e61349e59e0a689b6ef282 --- include/got_error.h +++ include/got_error.h @@ -33,6 +33,7 @@ #define GOT_ERR_PACKIDX_CSUM 15 #define GOT_ERR_BAD_PACKFILE 16 #define GOT_ERR_NO_OBJ 17 +#define GOT_ERR_NOT_IMPL 18 static const struct got_error { int code; @@ -56,6 +57,7 @@ static const struct got_error { { GOT_ERR_PACKIDX_CSUM, "pack index file checksum error" }, { GOT_ERR_BAD_PACKFILE, "bad pack file" }, { GOT_ERR_NO_OBJ, "object not found" }, + { GOT_ERR_NOT_IMPL, "feature not implemented" }, }; const struct got_error * got_error(int code); blob - 1d72c45b4b45fd02412f79ffadcea87f2b55a0e3 blob + dc94a559b6db4076da4c7b2c80a70f615e39aa0b --- lib/pack.c +++ lib/pack.c @@ -328,89 +328,107 @@ read_packfile_hdr(FILE *f, struct got_packidx_v2_hdr * } static const struct got_error * -dump_packed_object(FILE **f, FILE *packfile, off_t offset) +dump_plain_object(FILE *infile, uint8_t type, uint64_t size, FILE *outfile) { - const struct got_error *err = NULL; - const char *template = "/tmp/got.XXXXXXXXXX"; - uint64_t size = 0; - uint8_t type = 0; - uint8_t sizeN; - int i; - size_t n; - const char *type_tag; + const char *type_tag = got_object_get_type_tag(type); + size_t n; - *f = got_opentemp(); - if (*f == NULL) { - err = got_error(GOT_ERR_FILE_OPEN); - goto done; - } + if (type_tag == NULL) + return got_error(GOT_ERR_OBJ_TYPE); - if (fseeko(packfile, offset, SEEK_SET) != 0) { - err = got_error_from_errno(); - goto done; + fprintf(outfile, "%s %llu", type_tag, size); + fputc('\0', outfile); + + while (size > 0) { + uint8_t data[2048]; + size_t len = MIN(size, sizeof(data)); + + n = fread(data, len, 1, infile); + if (n != 1) + return got_ferror(infile, GOT_ERR_BAD_PACKIDX); + + n = fwrite(data, len, 1, outfile); + if (n != 1) + return got_ferror(outfile, GOT_ERR_BAD_PACKIDX); + + size -= len; } - i = 0; + return NULL; +} + +static const struct got_error * +decode_type_and_size(uint8_t *type, uint64_t *size, FILE *packfile) +{ + uint8_t t = 0; + uint64_t s = 0; + uint8_t sizeN; + size_t n; + int i = 0; + do { /* We do not support size values which don't fit in 64 bit. */ - if (i > 9) { - err = got_error(GOT_ERR_NO_SPACE); - goto done; - } + if (i > 9) + return got_error(GOT_ERR_NO_SPACE); n = fread(&sizeN, sizeof(sizeN), 1, packfile); - if (n != 1) { - err = got_ferror(packfile, GOT_ERR_BAD_PACKIDX); - goto done; - } + if (n != 1) + return got_ferror(packfile, GOT_ERR_BAD_PACKIDX); if (i == 0) { - type = (sizeN & GOT_PACK_OBJ_SIZE0_TYPE_MASK) >> + t = (sizeN & GOT_PACK_OBJ_SIZE0_TYPE_MASK) >> GOT_PACK_OBJ_SIZE0_TYPE_MASK_SHIFT; - size = (sizeN & GOT_PACK_OBJ_SIZE0_VAL_MASK); + s = (sizeN & GOT_PACK_OBJ_SIZE0_VAL_MASK); } else { size_t shift = 4 + 7 * (i - 1); - size |= ((sizeN & GOT_PACK_OBJ_SIZE_VAL_MASK) << shift); + s |= ((sizeN & GOT_PACK_OBJ_SIZE_VAL_MASK) << shift); } i++; } while (sizeN & GOT_PACK_OBJ_SIZE_MORE); - if (type == GOT_OBJ_TYPE_OFFSET_DELTA) - printf("object type OFFSET_DELTA not yet implemented\n"); - else if (type == GOT_OBJ_TYPE_REF_DELTA) - printf("object type REF_DELTA not yet implemented\n"); - else if (type == GOT_OBJ_TYPE_TAG) - printf("object type TAG not yet implemented\n"); + *type = t; + *size = s; + return NULL; +} - type_tag = got_object_get_type_tag(type); - if (type_tag == NULL) { - err = got_error(GOT_ERR_BAD_OBJ_HDR); +static const struct got_error * +dump_packed_object(FILE **f, FILE *packfile, off_t offset) +{ + const struct got_error *err = NULL; + const char *template = "/tmp/got.XXXXXXXXXX"; + uint8_t type; + uint64_t size; + FILE *outfile = NULL; + + *f = got_opentemp(); + if (*f == NULL) { + err = got_error(GOT_ERR_FILE_OPEN); goto done; } - fprintf(*f, "%s %llu", type_tag, size); - fputc('\0', *f); + if (fseeko(packfile, offset, SEEK_SET) != 0) { + err = got_error_from_errno(); + goto done; + } - while (size > 0) { - uint8_t data[2048]; - size_t len = MIN(size, sizeof(data)); + err = decode_type_and_size(&type, &size, packfile); + if (err) + goto done; - n = fread(data, len, 1, packfile); - if (n != 1) { - err = got_ferror(packfile, GOT_ERR_BAD_PACKIDX); - goto done; - } - - n = fwrite(data, len, 1, *f); - if (n != 1) { - err = got_ferror(*f, GOT_ERR_BAD_PACKIDX); - goto done; - } - - size -= len; + switch (type) { + case GOT_OBJ_TYPE_COMMIT: + case GOT_OBJ_TYPE_TREE: + case GOT_OBJ_TYPE_BLOB: + err = dump_plain_object(packfile, type, size, *f); + break; + case GOT_OBJ_TYPE_REF_DELTA: + case GOT_OBJ_TYPE_TAG: + case GOT_OBJ_TYPE_OFFSET_DELTA: + default: + err = got_error(GOT_ERR_NOT_IMPL); + goto done; } - printf("object type is %d\n", type); rewind(*f); done: if (err && *f)