commit 2414057009d67a0aca89ca9ad97b16b14d367fc5 from: Stefan Sperling date: Sun Sep 09 15:19:27 2018 UTC make got_packfile_extract_object() accept a pack instead of a repo commit - 2090a03dadad63d6ea945cbe4abb19949b5aff44 commit + 2414057009d67a0aca89ca9ad97b16b14d367fc5 blob - 1202094f2e3f254a1ea8df5f77cbacd47b8ceccf blob + 549406dfabb371dffda19cf1c7976a64e1a4c9d6 --- lib/got_lib_pack.h +++ lib/got_lib_pack.h @@ -162,8 +162,8 @@ int got_packidx_get_object_idx(struct got_packidx *, s const struct got_error *got_packfile_open_object(struct got_object **, struct got_pack *, struct got_packidx *, int, struct got_object_id *); -const struct got_error *got_packfile_extract_object(FILE **, - struct got_object *, struct got_repository *); +const struct got_error *got_packfile_extract_object(struct got_pack *, + struct got_object *, FILE *); const struct got_error *got_packfile_extract_object_to_mem(uint8_t **, size_t *, struct got_object *, struct got_repository *); const struct got_error *got_pack_get_packfile_size(size_t *, const char *); blob - cf703fbcb757445a5e04d6a5673230301f5c4467 blob + a19cdc7ece99ae20df97577502b0da732fa3e59e --- lib/object.c +++ lib/object.c @@ -437,7 +437,48 @@ got_object_tree_get_entries(struct got_tree_object *tr { return &tree->entries; } + +static const struct got_error * +extract_packed_object(FILE **f, struct got_object *obj, + struct got_repository *repo) +{ + const struct got_error *err = NULL; + struct got_pack *pack; + int fd; + if ((obj->flags & GOT_OBJ_FLAG_PACKED) == 0) + return got_error(GOT_ERR_OBJ_NOT_PACKED); + + fd = got_opentempfd(); + if (fd == -1) + return got_error_from_errno(); + + *f = fdopen(fd, "w+"); + if (*f == NULL) { + err = got_error_from_errno(); + goto done; + } + + pack = got_repo_get_cached_pack(repo, obj->path_packfile); + if (pack == NULL) { + err = got_repo_cache_pack(&pack, repo, + obj->path_packfile, NULL); + if (err) + goto done; + } + + err = got_packfile_extract_object(pack, obj, *f); +done: + if (err) { + if (*f == NULL) + close(fd); + else + fclose(*f); + *f = NULL; + } + return err; +} + const struct got_error * got_object_blob_open(struct got_blob_object **blob, struct got_repository *repo, struct got_object *obj, size_t blocksize) @@ -460,7 +501,7 @@ got_object_blob_open(struct got_blob_object **blob, goto done; } if (obj->flags & GOT_OBJ_FLAG_PACKED) { - err = got_packfile_extract_object(&((*blob)->f), obj, repo); + err = extract_packed_object(&((*blob)->f), obj, repo); if (err) goto done; } else { blob - 7e576516d56d0110c55d47b2b8a36975ec86335a blob + 329d024506b82b9f8617ebc0bb30e490bf5d62a3 --- lib/pack.c +++ lib/pack.c @@ -1200,55 +1200,32 @@ done: } const struct got_error * -got_packfile_extract_object(FILE **f, struct got_object *obj, - struct got_repository *repo) +got_packfile_extract_object(struct got_pack *pack, struct got_object *obj, + FILE *outfile) { const struct got_error *err = NULL; - struct got_pack *pack; - *f = NULL; - if ((obj->flags & GOT_OBJ_FLAG_PACKED) == 0) return got_error(GOT_ERR_OBJ_NOT_PACKED); - pack = got_repo_get_cached_pack(repo, obj->path_packfile); - if (pack == NULL) { - err = got_repo_cache_pack(&pack, repo, obj->path_packfile, NULL); - if (err) - return err; - } - - *f = got_opentemp(); - if (*f == NULL) { - err = got_error_from_errno(); - goto done; - } - if ((obj->flags & GOT_OBJ_FLAG_DELTIFIED) == 0) { - if (obj->pack_offset >= pack->filesize) { - err = got_error(GOT_ERR_PACK_OFFSET); - goto done; - } + if (obj->pack_offset >= pack->filesize) + return got_error(GOT_ERR_PACK_OFFSET); if (pack->map) { size_t mapoff = (size_t)obj->pack_offset; err = got_inflate_to_file_mmap(&obj->size, pack->map, - mapoff, pack->filesize - mapoff, *f); + mapoff, pack->filesize - mapoff, outfile); } else { - if (lseek(pack->fd, obj->pack_offset, SEEK_SET) == -1) { - err = got_error_from_errno(); - goto done; - } - err = got_inflate_to_file_fd(&obj->size, pack->fd, *f); + if (lseek(pack->fd, obj->pack_offset, SEEK_SET) == -1) + return got_error_from_errno(); + err = got_inflate_to_file_fd(&obj->size, pack->fd, + outfile); } } else err = dump_delta_chain_to_file(&obj->size, &obj->deltas, pack, - *f); -done: - if (err && *f) { - fclose(*f); - *f = NULL; - } + outfile); + return err; }