commit - 8704c7cea5c81c45015529a58461bf8b49f9c4d9
commit + 59d1e4a0a9c19debc27746357d97084b59a76db8
blob - 989af7a5c391e8d6a066b2235aecd6c3246aa0d3
blob + 44f8ac073b1d120169e3ef344f1caca1022da938
--- lib/got_lib_object.h
+++ lib/got_lib_object.h
int refcnt; /* > 0 if open and/or cached */
};
+struct got_raw_object {
+ FILE *f;
+ uint8_t *data;
+ off_t size;
+ size_t hdrlen;
+ size_t blocksize;
+ uint8_t *read_buf;
+};
+
struct got_commit_object {
struct got_object_id *tree_id;
unsigned int nparents;
struct got_repository *);
const struct got_error *got_object_open(struct got_object **,
struct got_repository *, struct got_object_id *);
+const struct got_error *got_object_raw_open(struct got_raw_object **,
+ struct got_repository *, struct got_object_id *, size_t);
+void got_object_raw_rewind(struct got_raw_object *);
+size_t got_object_raw_get_hdrlen(struct got_raw_object *);
+const uint8_t *got_object_raw_get_read_buf(struct got_raw_object *);
+const struct got_error * got_object_raw_read_block(size_t *,
+ struct got_raw_object *);
+const struct got_error *got_object_raw_close(struct got_raw_object *);
const struct got_error *got_object_open_by_id_str(struct got_object **,
struct got_repository *, const char *);
void got_object_close(struct got_object *);
blob - 8dbb8d0ba06da245e90c69b5db067658d496e0b0
blob + dc1687fd0232a98260fd1d1f91425364de21521b
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
GOT_IMSG_GOTCONFIG_STR_VAL,
GOT_IMSG_GOTCONFIG_REMOTES,
GOT_IMSG_GOTCONFIG_REMOTE,
+
+ /* Raw object access. Uncompress object data but do not parse it. */
+ GOT_IMSG_RAW_OBJECT_REQUEST,
+ GOT_IMSG_RAW_OBJECT_OUTFD,
+ GOT_IMSG_PACKED_RAW_OBJECT_REQUEST,
+ GOT_IMSG_RAW_OBJECT,
};
/* Structure for GOT_IMSG_ERROR. */
(MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof(struct got_imsg_blob))
};
+/* Structure for GOT_IMSG_RAW_OBJECT. */
+struct got_imsg_raw_obj {
+ off_t size;
+ size_t hdrlen;
+
+ /*
+ * If size <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX, object data follows
+ * in the imsg buffer. Otherwise, object data has been written to a
+ * file descriptor passed via the GOT_IMSG_RAW_OBJECT_OUTFD imsg.
+ */
+#define GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX \
+ (MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof(struct got_imsg_raw_obj))
+};
/* Structure for GOT_IMSG_TAG data. */
struct got_imsg_tag_object {
} __attribute__((__packed__));
/*
- * Structure for GOT_IMSG_PACKED_OBJECT_REQUEST data.
+ * Structure for GOT_IMSG_PACKED_OBJECT_REQUEST and
+ * GOT_IMSG_PACKED_RAW_OBJECT_REQUEST data.
*/
struct got_imsg_packed_object {
uint8_t id[SHA1_DIGEST_LENGTH];
const struct got_error *got_privsep_send_ack(struct imsgbuf *);
const struct got_error *got_privsep_wait_ack(struct imsgbuf *);
const struct got_error *got_privsep_send_obj_req(struct imsgbuf *, int);
+const struct got_error *got_privsep_send_raw_obj_req(struct imsgbuf *, int);
+const struct got_error *got_privsep_send_raw_obj_outfd(struct imsgbuf *, int);
const struct got_error *got_privsep_send_commit_req(struct imsgbuf *, int,
struct got_object_id *, int);
const struct got_error *got_privsep_send_tree_req(struct imsgbuf *, int,
struct imsg *, struct imsgbuf *);
const struct got_error *got_privsep_recv_obj(struct got_object **,
struct imsgbuf *);
+const struct got_error *got_privsep_send_raw_obj(struct imsgbuf *, off_t,
+ size_t, uint8_t *);
+const struct got_error *got_privsep_recv_raw_obj(uint8_t **, off_t *, size_t *,
+ struct imsgbuf *);
const struct got_error *got_privsep_send_commit(struct imsgbuf *,
struct got_commit_object *);
const struct got_error *got_privsep_recv_commit(struct got_commit_object **,
struct got_pack *, struct got_packidx *);
const struct got_error *got_privsep_send_packed_obj_req(struct imsgbuf *, int,
struct got_object_id *);
+const struct got_error *got_privsep_send_packed_raw_obj_req(struct imsgbuf *,
+ int, struct got_object_id *);
const struct got_error *got_privsep_send_pack_child_ready(struct imsgbuf *);
const struct got_error *got_privsep_send_gitconfig_parse_req(struct imsgbuf *,
blob - b85e7651429752168e6f8eff2b764fe8bba2d501
blob + 7f6e445581c8690ccc1c4cc83d42a1ce5959a605
--- lib/object.c
+++ lib/object.c
return NULL;
}
+static const struct got_error *
+request_packed_object_raw(uint8_t **outbuf, off_t *size, size_t *hdrlen,
+ int outfd, struct got_pack *pack, int idx, struct got_object_id *id)
+{
+ const struct got_error *err = NULL;
+ struct imsgbuf *ibuf = pack->privsep_child->ibuf;
+ int outfd_child;
+ int basefd, accumfd; /* temporary files for delta application */
+
+ basefd = got_opentempfd();
+ if (basefd == -1)
+ return got_error_from_errno("got_opentempfd");
+
+ accumfd = got_opentempfd();
+ if (accumfd == -1) {
+ close(basefd);
+ return got_error_from_errno("got_opentempfd");
+ }
+
+ outfd_child = dup(outfd);
+ if (outfd_child == -1) {
+ err = got_error_from_errno("dup");
+ close(basefd);
+ close(accumfd);
+ return err;
+ }
+
+ err = got_privsep_send_packed_raw_obj_req(ibuf, idx, id);
+ if (err) {
+ close(basefd);
+ close(accumfd);
+ close(outfd_child);
+ return err;
+ }
+
+ err = got_privsep_send_raw_obj_outfd(ibuf, outfd_child);
+ if (err) {
+ close(basefd);
+ close(accumfd);
+ return err;
+ }
+
+
+ err = got_privsep_send_tmpfd(pack->privsep_child->ibuf,
+ basefd);
+ if (err) {
+ close(accumfd);
+ return err;
+ }
+
+ err = got_privsep_send_tmpfd(pack->privsep_child->ibuf,
+ accumfd);
+ if (err)
+ return err;
+
+ err = got_privsep_recv_raw_obj(outbuf, size, hdrlen, ibuf);
+ if (err)
+ return err;
+
+ return NULL;
+}
+
static void
set_max_datasize(void)
{
{
const struct got_error *err = NULL;
- if (pack->privsep_child)
- return request_packed_object(obj, pack, idx, id);
+ if (pack->privsep_child == NULL) {
+ err = start_pack_privsep_child(pack, packidx);
+ if (err)
+ return err;
+ }
- err = start_pack_privsep_child(pack, packidx);
- if (err)
- return err;
-
return request_packed_object(obj, pack, idx, id);
}
+static const struct got_error *
+read_packed_object_raw_privsep(uint8_t **outbuf, off_t *size, size_t *hdrlen,
+ int outfd, struct got_pack *pack, struct got_packidx *packidx, int idx,
+ struct got_object_id *id)
+{
+ const struct got_error *err = NULL;
+ if (pack->privsep_child == NULL) {
+ err = start_pack_privsep_child(pack, packidx);
+ if (err)
+ return err;
+ }
+
+ return request_packed_object_raw(outbuf, size, hdrlen, outfd, pack,
+ idx, id);
+}
+
static const struct got_error *
open_packed_object(struct got_object **obj, struct got_object_id *id,
struct got_repository *repo)
}
static const struct got_error *
-read_object_header_privsep(struct got_object **obj, struct got_repository *repo,
- int obj_fd)
+request_raw_object(uint8_t **outbuf, off_t *size, size_t *hdrlen, int outfd,
+ struct got_repository *repo, int infd)
{
- const struct got_error *err;
+ const struct got_error *err = NULL;
+ struct imsgbuf *ibuf;
+ int outfd_child;
+
+ ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].ibuf;
+
+ outfd_child = dup(outfd);
+ if (outfd_child == -1)
+ return got_error_from_errno("dup");
+
+ err = got_privsep_send_raw_obj_req(ibuf, infd);
+ if (err)
+ return err;
+
+ err = got_privsep_send_raw_obj_outfd(ibuf, outfd_child);
+ if (err)
+ return err;
+
+ return got_privsep_recv_raw_obj(outbuf, size, hdrlen, ibuf);
+}
+
+static const struct got_error *
+start_read_object_child(struct got_repository *repo)
+{
+ const struct got_error *err = NULL;
int imsg_fds[2];
pid_t pid;
struct imsgbuf *ibuf;
- if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].imsg_fd != -1)
- return request_object(obj, repo, obj_fd);
-
ibuf = calloc(1, sizeof(*ibuf));
if (ibuf == NULL)
return got_error_from_errno("calloc");
free(ibuf);
return err;
}
+
repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].imsg_fd =
imsg_fds[0];
repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].pid = pid;
imsg_init(ibuf, imsg_fds[0]);
repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].ibuf = ibuf;
+ return NULL;
+}
+
+static const struct got_error *
+read_object_header_privsep(struct got_object **obj, struct got_repository *repo,
+ int obj_fd)
+{
+ const struct got_error *err;
+
+ if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].imsg_fd != -1)
+ return request_object(obj, repo, obj_fd);
+
+ err = start_read_object_child(repo);
+ if (err)
+ return err;
+
return request_object(obj, repo, obj_fd);
}
+static const struct got_error *
+read_object_raw_privsep(uint8_t **outbuf, off_t *size, size_t *hdrlen,
+ int outfd, struct got_repository *repo, int obj_fd)
+{
+ const struct got_error *err;
+
+ if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].imsg_fd != -1)
+ return request_raw_object(outbuf, size, hdrlen, outfd, repo,
+ obj_fd);
+
+ err = start_read_object_child(repo);
+ if (err)
+ return err;
+
+ return request_raw_object(outbuf, size, hdrlen, outfd, repo, obj_fd);
+}
const struct got_error *
got_object_open(struct got_object **obj, struct got_repository *repo,
done:
free(path);
return err;
+}
+const struct got_error *
+got_object_raw_open(struct got_raw_object **obj, struct got_repository *repo,
+ struct got_object_id *id, size_t blocksize)
+{
+ const struct got_error *err = NULL;
+ struct got_packidx *packidx = NULL;
+ int idx;
+ uint8_t *outbuf = NULL;
+ int outfd = -1;
+ off_t size = 0;
+ size_t hdrlen = 0;
+ char *path_packfile = NULL;
+
+ *obj = NULL;
+
+ outfd = got_opentempfd();
+ if (outfd == -1)
+ return got_error_from_errno("got_opentempfd");
+
+ err = got_repo_search_packidx(&packidx, &idx, repo, id);
+ if (err == NULL) {
+ struct got_pack *pack = NULL;
+
+ err = get_packfile_path(&path_packfile, packidx);
+ if (err)
+ goto done;
+
+ pack = got_repo_get_cached_pack(repo, path_packfile);
+ if (pack == NULL) {
+ err = got_repo_cache_pack(&pack, repo, path_packfile,
+ packidx);
+ if (err)
+ goto done;
+ }
+ err = read_packed_object_raw_privsep(&outbuf, &size, &hdrlen,
+ outfd, pack, packidx, idx, id);
+ } else if (err->code == GOT_ERR_NO_OBJ) {
+ int fd;
+
+ err = open_loose_object(&fd, id, repo);
+ if (err)
+ goto done;
+ err = read_object_raw_privsep(&outbuf, &size, &hdrlen, outfd,
+ repo, fd);
+ }
+
+ if (hdrlen > size) {
+ err = got_error(GOT_ERR_BAD_OBJ_HDR);
+ goto done;
+ }
+
+ *obj = calloc(1, sizeof(**obj));
+ if (*obj == NULL) {
+ err = got_error_from_errno("calloc");
+ goto done;
+ }
+
+ (*obj)->read_buf = malloc(blocksize);
+ if ((*obj)->read_buf == NULL) {
+ err = got_error_from_errno("malloc");
+ goto done;
+ }
+
+ if (outbuf) {
+ if (close(outfd) == -1) {
+ err = got_error_from_errno("close");
+ goto done;
+ }
+ outfd = -1;
+ (*obj)->f = fmemopen(outbuf, hdrlen + size, "r");
+ if ((*obj)->f == NULL) {
+ err = got_error_from_errno("fdopen");
+ goto done;
+ }
+ (*obj)->data = outbuf;
+ } else {
+ struct stat sb;
+ if (fstat(outfd, &sb) == -1) {
+ err = got_error_from_errno("fstat");
+ goto done;
+ }
+
+ if (sb.st_size != size) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ goto done;
+ }
+
+ (*obj)->f = fdopen(outfd, "r");
+ if ((*obj)->f == NULL) {
+ err = got_error_from_errno("fdopen");
+ goto done;
+ }
+ outfd = -1;
+ (*obj)->data = NULL;
+ }
+ (*obj)->hdrlen = hdrlen;
+ (*obj)->size = size;
+ (*obj)->blocksize = blocksize;
+done:
+ free(path_packfile);
+ if (err) {
+ if (*obj) {
+ got_object_raw_close(*obj);
+ *obj = NULL;
+ }
+ if (outfd != -1)
+ close(outfd);
+ free(outbuf);
+ }
+ return err;
}
+void
+got_object_raw_rewind(struct got_raw_object *obj)
+{
+ if (obj->f)
+ rewind(obj->f);
+}
+
+size_t
+got_object_raw_get_hdrlen(struct got_raw_object *obj)
+{
+ return obj->hdrlen;
+}
+
+const uint8_t *
+got_object_raw_get_read_buf(struct got_raw_object *obj)
+{
+ return obj->read_buf;
+}
+
+const struct got_error *
+got_object_raw_read_block(size_t *outlenp, struct got_raw_object *obj)
+{
+ size_t n;
+
+ n = fread(obj->read_buf, 1, obj->blocksize, obj->f);
+ if (n == 0 && ferror(obj->f))
+ return got_ferror(obj->f, GOT_ERR_IO);
+ *outlenp = n;
+ return NULL;
+}
+
+const struct got_error *
+got_object_raw_close(struct got_raw_object *obj)
+{
+ const struct got_error *err = NULL;
+
+ free(obj->read_buf);
+ if (obj->f != NULL && fclose(obj->f) == EOF && err == NULL)
+ err = got_error_from_errno("fclose");
+ free(obj->data);
+ free(obj);
+ return err;
+}
+
const struct got_error *
got_object_open_by_id_str(struct got_object **obj, struct got_repository *repo,
const char *id_str)
blob - 2a8fcc8c9e2afd1ce22356056ac095e73d2c28c3
blob + df3a4a17cfe53a165183f57fb4a0eebe62acab91
--- lib/privsep.c
+++ lib/privsep.c
if (imsg_compose(ibuf, GOT_IMSG_OBJECT_REQUEST, 0, 0, fd, NULL, 0)
== -1)
return got_error_from_errno("imsg_compose OBJECT_REQUEST");
+
+ return flush_imsg(ibuf);
+}
+
+const struct got_error *
+got_privsep_send_raw_obj_req(struct imsgbuf *ibuf, int fd)
+{
+ if (imsg_compose(ibuf, GOT_IMSG_RAW_OBJECT_REQUEST, 0, 0, fd, NULL, 0)
+ == -1)
+ return got_error_from_errno("imsg_compose RAW_OBJECT_REQUEST");
+
+ return flush_imsg(ibuf);
+}
+
+const struct got_error *
+got_privsep_send_raw_obj_outfd(struct imsgbuf *ibuf, int outfd)
+{
+ const struct got_error *err = NULL;
+
+ if (imsg_compose(ibuf, GOT_IMSG_RAW_OBJECT_OUTFD, 0, 0, outfd, NULL, 0)
+ == -1) {
+ err = got_error_from_errno("imsg_compose RAW_OBJECT_OUTFD");
+ close(outfd);
+ return err;
+ }
+
+ return flush_imsg(ibuf);
+}
+
+const struct got_error *
+got_privsep_send_raw_obj(struct imsgbuf *ibuf, off_t size, size_t hdrlen,
+ uint8_t *data)
+{
+ const struct got_error *err = NULL;
+ struct got_imsg_raw_obj iobj;
+ size_t len = sizeof(iobj);
+ struct ibuf *wbuf;
+ iobj.hdrlen = hdrlen;
+ iobj.size = size;
+
+ if (data && size <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX)
+ len += (size_t)size;
+
+ wbuf = imsg_create(ibuf, GOT_IMSG_RAW_OBJECT, 0, 0, len);
+ if (wbuf == NULL) {
+ err = got_error_from_errno("imsg_create RAW_OBJECT");
+ return err;
+ }
+
+ if (imsg_add(wbuf, &iobj, sizeof(iobj)) == -1) {
+ err = got_error_from_errno("imsg_add RAW_OBJECT");
+ ibuf_free(wbuf);
+ return err;
+ }
+
+ if (data && size <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX) {
+ if (imsg_add(wbuf, data, size) == -1) {
+ err = got_error_from_errno("imsg_add RAW_OBJECT");
+ ibuf_free(wbuf);
+ return err;
+ }
+ }
+
+ wbuf->fd = -1;
+ imsg_close(ibuf, wbuf);
+
return flush_imsg(ibuf);
}
const struct got_error *
+got_privsep_recv_raw_obj(uint8_t **outbuf, off_t *size, size_t *hdrlen,
+ struct imsgbuf *ibuf)
+{
+ const struct got_error *err = NULL;
+ struct imsg imsg;
+ struct got_imsg_raw_obj *iobj;
+ size_t datalen;
+
+ *outbuf = NULL;
+
+ err = got_privsep_recv_imsg(&imsg, ibuf, 0);
+ if (err)
+ return err;
+
+ datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
+
+ switch (imsg.hdr.type) {
+ case GOT_IMSG_RAW_OBJECT:
+ if (datalen < sizeof(*iobj)) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ break;
+ }
+ iobj = imsg.data;
+ *size = iobj->size;
+ *hdrlen = iobj->hdrlen;
+
+ if (datalen == sizeof(*iobj)) {
+ /* Data has been written to file descriptor. */
+ break;
+ }
+
+ if (*size > GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ break;
+ }
+
+ *outbuf = malloc(*size);
+ if (*outbuf == NULL) {
+ err = got_error_from_errno("malloc");
+ break;
+ }
+ memcpy(*outbuf, imsg.data + sizeof(*iobj), *size);
+ break;
+ default:
+ err = got_error(GOT_ERR_PRIVSEP_MSG);
+ break;
+ }
+
+ imsg_free(&imsg);
+
+ return err;
+}
+
+const struct got_error *
got_privsep_send_commit_req(struct imsgbuf *ibuf, int fd,
struct got_object_id *id, int pack_idx)
{
}
const struct got_error *
+got_privsep_send_packed_raw_obj_req(struct imsgbuf *ibuf, int idx,
+ struct got_object_id *id)
+{
+ struct got_imsg_packed_object iobj;
+
+ iobj.idx = idx;
+ memcpy(iobj.id, id->sha1, sizeof(iobj.id));
+
+ if (imsg_compose(ibuf, GOT_IMSG_PACKED_RAW_OBJECT_REQUEST, 0, 0, -1,
+ &iobj, sizeof(iobj)) == -1)
+ return got_error_from_errno("imsg_compose "
+ "PACKED_OBJECT_REQUEST");
+
+ return flush_imsg(ibuf);
+}
+
+const struct got_error *
got_privsep_send_gitconfig_parse_req(struct imsgbuf *ibuf, int fd)
{
const struct got_error *err = NULL;
blob - 96f238defd60d0d973d36d4b4e6c4a60845cefa6
blob + 1d8cea7e965300fd88bff54f9fcfd727a5a12b7c
--- libexec/got-read-object/got-read-object.c
+++ libexec/got-read-object/got-read-object.c
sigint_received = 1;
}
+static const struct got_error *
+send_raw_obj(struct imsgbuf *ibuf, struct got_object *obj, int fd, int outfd)
+{
+ const struct got_error *err = NULL;
+ uint8_t *data = NULL;
+ size_t len = 0, consumed;
+ FILE *f;
+
+ if (lseek(fd, SEEK_SET, 0) == -1) {
+ err = got_error_from_errno("lseek");
+ close(fd);
+ return err;
+ }
+
+ f = fdopen(fd, "r");
+ if (f == NULL) {
+ err = got_error_from_errno("fdopen");
+ close(fd);
+ return err;
+ }
+
+ if (obj->size <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX)
+ err = got_inflate_to_mem(&data, &len, &consumed, f);
+ else
+ err = got_inflate_to_fd(&len, f, outfd);
+ if (err)
+ goto done;
+
+ if (len < obj->hdrlen || len != obj->hdrlen + obj->size) {
+ fprintf(stderr, "len=%zd obj->hdrlen=%zd obj->size=%zd\n", len, obj->hdrlen, obj->size);
+ err = got_error(GOT_ERR_BAD_OBJ_HDR);
+ goto done;
+ }
+
+ err = got_privsep_send_raw_obj(ibuf, len, obj->hdrlen, data);
+done:
+ free(data);
+ if (fclose(f) == EOF && err == NULL)
+ err = got_error_from_errno("fclose");
+
+ return err;
+}
+
int
main(int argc, char *argv[])
{
if (imsg.hdr.type == GOT_IMSG_STOP)
break;
- if (imsg.hdr.type != GOT_IMSG_OBJECT_REQUEST) {
+ if (imsg.hdr.type != GOT_IMSG_OBJECT_REQUEST &&
+ imsg.hdr.type != GOT_IMSG_RAW_OBJECT_REQUEST) {
err = got_error(GOT_ERR_PRIVSEP_MSG);
goto done;
}
goto done;
}
+ if (imsg.fd == -1) {
+ err = got_error(GOT_ERR_PRIVSEP_NO_FD);
+ goto done;
+ }
+
err = got_object_read_header(&obj, imsg.fd);
if (err)
goto done;
- err = got_privsep_send_obj(&ibuf, obj);
+ if (imsg.hdr.type == GOT_IMSG_RAW_OBJECT_REQUEST) {
+ struct imsg imsg_outfd;
+ err = got_privsep_recv_imsg(&imsg_outfd, &ibuf, 0);
+ if (err) {
+ if (imsg_outfd.hdr.len == 0)
+ err = NULL;
+ goto done;
+ }
+
+ if (imsg_outfd.hdr.type == GOT_IMSG_STOP) {
+ imsg_free(&imsg_outfd);
+ goto done;
+ }
+
+ if (imsg_outfd.hdr.type != GOT_IMSG_RAW_OBJECT_OUTFD) {
+ err = got_error(GOT_ERR_PRIVSEP_MSG);
+ imsg_free(&imsg_outfd);
+ goto done;
+ }
+
+ datalen = imsg_outfd.hdr.len - IMSG_HEADER_SIZE;
+ if (datalen != 0) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ imsg_free(&imsg_outfd);
+ goto done;
+ }
+ if (imsg_outfd.fd == -1) {
+ err = got_error(GOT_ERR_PRIVSEP_NO_FD);
+ imsg_free(&imsg_outfd);
+ goto done;
+ }
+ err = send_raw_obj(&ibuf, obj, imsg.fd, imsg_outfd.fd);
+ imsg.fd = -1; /* imsg.fd is owned by send_raw_obj() */
+ imsg_free(&imsg_outfd);
+ if (err)
+ goto done;
+ } else
+ err = got_privsep_send_obj(&ibuf, obj);
done:
- if (close(imsg.fd) == -1 && err == NULL)
+ if (imsg.fd != -1 && close(imsg.fd) == -1 && err == NULL)
err = got_error_from_errno("close");
imsg_free(&imsg);
if (obj)
blob - dd8568736e94cba3323acae81feb8506fe869f9f
blob + 30756b439f8433c9f8b8f391bd93db8ddd6feb9f
--- libexec/got-read-pack/got-read-pack.c
+++ libexec/got-read-pack/got-read-pack.c
}
static const struct got_error *
+raw_object_request(struct imsg *imsg, struct imsgbuf *ibuf, struct got_pack *pack,
+ struct got_packidx *packidx, struct got_object_cache *objcache)
+{
+ const struct got_error *err = NULL;
+ uint8_t *buf = NULL;
+ uint64_t size = 0;
+ FILE *outfile = NULL, *basefile = NULL, *accumfile = NULL;
+ struct got_imsg_packed_object iobj;
+ struct got_object *obj;
+ struct got_object_id id;
+ size_t datalen;
+
+ datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
+ if (datalen != sizeof(iobj))
+ return got_error(GOT_ERR_PRIVSEP_LEN);
+ memcpy(&iobj, imsg->data, sizeof(iobj));
+ memcpy(id.sha1, iobj.id, SHA1_DIGEST_LENGTH);
+
+ obj = got_object_cache_get(objcache, &id);
+ if (obj) {
+ obj->refcnt++;
+ } else {
+ err = open_object(&obj, pack, packidx, iobj.idx, &id,
+ objcache);
+ if (err)
+ return err;
+ }
+
+ err = receive_file(&outfile, ibuf, GOT_IMSG_RAW_OBJECT_OUTFD);
+ if (err)
+ return err;
+ err = receive_file(&basefile, ibuf, GOT_IMSG_TMPFD);
+ if (err)
+ goto done;
+ err = receive_file(&accumfile, ibuf, GOT_IMSG_TMPFD);
+ if (err)
+ goto done;
+
+ if (obj->flags & GOT_OBJ_FLAG_DELTIFIED) {
+ err = got_pack_get_max_delta_object_size(&size, obj, pack);
+ if (err)
+ goto done;
+ } else
+ size = obj->size;
+
+ if (size <= GOT_PRIVSEP_INLINE_OBJECT_DATA_MAX)
+ err = got_packfile_extract_object_to_mem(&buf, &obj->size,
+ obj, pack);
+ else
+ err = got_packfile_extract_object(pack, obj, outfile, basefile,
+ accumfile);
+ if (err)
+ goto done;
+
+ err = got_privsep_send_raw_obj(ibuf, size, obj->hdrlen, buf);
+done:
+ free(buf);
+ if (outfile && fclose(outfile) == EOF && err == NULL)
+ err = got_error_from_errno("fclose");
+ if (basefile && fclose(basefile) == EOF && err == NULL)
+ err = got_error_from_errno("fclose");
+ if (accumfile && fclose(accumfile) == EOF && err == NULL)
+ err = got_error_from_errno("fclose");
+ got_object_close(obj);
+ if (err && err->code != GOT_ERR_PRIVSEP_PIPE)
+ got_privsep_send_error(ibuf, err);
+
+ return err;
+}
+
+
+
+static const struct got_error *
receive_packidx(struct got_packidx **packidx, struct imsgbuf *ibuf)
{
const struct got_error *err = NULL;
err = object_request(&imsg, &ibuf, pack, packidx,
&objcache);
break;
+ case GOT_IMSG_PACKED_RAW_OBJECT_REQUEST:
+ err = raw_object_request(&imsg, &ibuf, pack, packidx,
+ &objcache);
+ break;
case GOT_IMSG_COMMIT_REQUEST:
err = commit_request(&imsg, &ibuf, pack, packidx,
&objcache);