Commit 2414057009d67a0aca89ca9ad97b16b14d367fc5

Stefan Sperling 2018-09-09T17:19:27

make got_packfile_extract_object() accept a pack instead of a repo

diff --git a/lib/got_lib_pack.h b/lib/got_lib_pack.h
index 1202094..549406d 100644
--- a/lib/got_lib_pack.h
+++ b/lib/got_lib_pack.h
@@ -162,8 +162,8 @@ int got_packidx_get_object_idx(struct got_packidx *, struct got_object_id *);
 
 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 *);
diff --git a/lib/object.c b/lib/object.c
index cf703fb..a19cdc7 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -438,6 +438,47 @@ got_object_tree_get_entries(struct got_tree_object *tree)
 	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 {
diff --git a/lib/pack.c b/lib/pack.c
index 7e57651..329d024 100644
--- a/lib/pack.c
+++ b/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;
 }