read packed trees with privsep
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
diff --git a/lib/got_lib_object_parse.h b/lib/got_lib_object_parse.h
index 901a18c..b427544 100644
--- a/lib/got_lib_object_parse.h
+++ b/lib/got_lib_object_parse.h
@@ -42,3 +42,5 @@ const struct got_error *got_object_packed_read_privsep(struct got_object **,
struct got_object_id *);
const struct got_error *got_object_read_packed_commit_privsep(
struct got_commit_object **, struct got_object *, struct got_pack *);
+const struct got_error *got_object_read_packed_tree_privsep(
+ struct got_tree_object **, struct got_object *, struct got_pack *);
diff --git a/lib/object.c b/lib/object.c
index f98a68d..dd27607 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -328,27 +328,6 @@ got_object_qid_alloc(struct got_object_qid **qid, struct got_object_id *id)
return NULL;
}
-static const struct got_error *
-extract_packed_object_to_mem(uint8_t **buf, size_t *len,
- struct got_object *obj, struct got_repository *repo)
-{
- const struct got_error *err = NULL;
- struct got_pack *pack;
-
- 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;
- }
-
- return got_packfile_extract_object_to_mem(buf, len, obj, pack);
-}
-
const struct got_error *
got_object_commit_open(struct got_commit_object **commit,
struct got_repository *repo, struct got_object *obj)
@@ -407,14 +386,15 @@ got_object_tree_open(struct got_tree_object **tree,
return got_error(GOT_ERR_OBJ_TYPE);
if (obj->flags & GOT_OBJ_FLAG_PACKED) {
- uint8_t *buf;
- size_t len;
- err = extract_packed_object_to_mem(&buf, &len, obj, repo);
- if (err)
- return err;
- obj->size = len;
- err = got_object_parse_tree(tree, buf, len);
- free(buf);
+ struct got_pack *pack;
+ 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;
+ }
+ err = got_object_read_packed_tree_privsep(tree, obj, pack);
} else {
int fd;
err = open_loose_object(&fd, obj, repo);
diff --git a/lib/object_parse.c b/lib/object_parse.c
index 823f934..ae91d51 100644
--- a/lib/object_parse.c
+++ b/lib/object_parse.c
@@ -824,6 +824,19 @@ got_object_read_tree_privsep(struct got_tree_object **tree,
return request_tree(tree, repo, obj, obj_fd);
}
+const struct got_error *
+got_object_read_packed_tree_privsep(struct got_tree_object **tree,
+ struct got_object *obj, struct got_pack *pack)
+{
+ const struct got_error *err = NULL;
+
+ err = got_privsep_send_obj_req(pack->privsep_child->ibuf, -1, obj);
+ if (err)
+ return err;
+
+ return got_privsep_recv_tree(tree, pack->privsep_child->ibuf);
+}
+
static const struct got_error *
request_blob(size_t *size, int outfd, int infd, struct got_repository *repo)
{
diff --git a/lib/privsep.c b/lib/privsep.c
index 068c8e8..faa53d4 100644
--- a/lib/privsep.c
+++ b/lib/privsep.c
@@ -278,7 +278,7 @@ got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, struct got_object *obj)
iobj.flags = obj->flags;
iobj.hdrlen = obj->hdrlen;
iobj.size = obj->size;
- iobj.ndeltas = 0;
+ iobj.ndeltas = obj->deltas.nentries;
if (iobj.flags & GOT_OBJ_FLAG_PACKED)
iobj.pack_offset = obj->pack_offset;
diff --git a/libexec/got-read-pack/got-read-pack.c b/libexec/got-read-pack/got-read-pack.c
index 19b70b7..8110b5f 100644
--- a/libexec/got-read-pack/got-read-pack.c
+++ b/libexec/got-read-pack/got-read-pack.c
@@ -107,7 +107,39 @@ static const struct got_error *
tree_request(struct imsg *imsg, struct imsgbuf *ibuf, struct got_pack *pack,
struct got_packidx *packidx)
{
- return got_error(GOT_ERR_NOT_IMPL);
+ const struct got_error *err = NULL;
+ struct got_object *obj = NULL;
+ struct got_tree_object *tree = NULL;
+ uint8_t *buf;
+ size_t len;
+
+ err = got_privsep_get_imsg_obj(&obj, imsg, ibuf);
+ if (err)
+ return err;
+
+ if (obj->type != GOT_OBJ_TYPE_TREE)
+ return got_error(GOT_ERR_OBJ_TYPE);
+
+ err = got_packfile_extract_object_to_mem(&buf, &len, obj, pack);
+ if (err)
+ return err;
+
+ obj->size = len;
+ err = got_object_parse_tree(&tree, buf, len);
+ free(buf);
+
+ err = got_privsep_send_tree(ibuf, tree);
+ if (obj)
+ got_object_close(obj);
+ got_object_tree_close(tree);
+ if (err) {
+ if (err->code == GOT_ERR_PRIVSEP_PIPE)
+ err = NULL;
+ else
+ got_privsep_send_error(ibuf, err);
+ }
+
+ return err;
}
static const struct got_error *