commit b9f99abf2dc1885a21fad98979c86931832f1a0e from: Stefan Sperling date: Wed Mar 18 16:10:32 2020 UTC add imsg for fetch progress reporting; for now only contains reference info commit - ccbf9d19437064659ee579ef2113991f20285138 commit + b9f99abf2dc1885a21fad98979c86931832f1a0e blob - 59fe6e94625525b13953eb5216f966b0a6bd6cac blob + f02d6fb268ae009d8ca3e8aaf043bf0a8fcfdbcd --- lib/got_lib_privsep.h +++ lib/got_lib_privsep.h @@ -110,6 +110,7 @@ enum got_imsg_type { /* Messages related to networking. */ GOT_IMSG_FETCH_REQUEST, + GOT_IMSG_FETCH_PROGRESS, GOT_IMSG_FETCH_DONE, GOT_IMSG_IDXPACK_REQUEST, GOT_IMSG_IDXPACK_DONE, @@ -231,6 +232,13 @@ struct got_imsg_tag_object { * one or more GOT_IMSG_TAG_TAGMSG messages. */ } __attribute__((__packed__)); + +/* Structure for GOT_IMSG_FETCH_PROGRESS data. */ +struct got_imsg_fetch_progress { + /* Descirbes a reference which will be fetched. */ + uint8_t refid[SHA1_DIGEST_LENGTH]; + /* Followed by reference name in remaining data of imsg buffer. */ +}; /* Structure for GOT_IMSG_PACKIDX. */ struct got_imsg_packidx { @@ -315,6 +323,10 @@ const struct got_error *got_privsep_send_index_pack_re const struct got_error *got_privsep_send_index_pack_done(struct imsgbuf *); const struct got_error *got_privsep_wait_index_pack_done(struct imsgbuf *); const struct got_error *got_privsep_send_fetch_req(struct imsgbuf *, int); +const struct got_error *got_privsep_send_fetch_progress(struct imsgbuf *, + struct got_object_id *, const char *); +const struct got_error *got_privsep_recv_fetch_progress(struct got_object_id **, + char **, struct imsgbuf *); const struct got_error *got_privsep_send_fetch_done(struct imsgbuf *, struct got_object_id); const struct got_error *got_privsep_wait_fetch_done(struct imsgbuf *, blob - 5885ba74e308e577dc5b0e7da458e12336ffa30a blob + 31b226671d902d9feb7a77357d4802822eb1f0f5 --- lib/privsep.c +++ lib/privsep.c @@ -419,6 +419,39 @@ got_privsep_send_fetch_req(struct imsgbuf *ibuf, int f } const struct got_error * +got_privsep_send_fetch_progress(struct imsgbuf *ibuf, + struct got_object_id *refid, const char *refname) +{ + const struct got_error *err = NULL; + struct ibuf *wbuf; + size_t len, reflen = strlen(refname); + + len = sizeof(struct got_imsg_fetch_progress) + reflen; + if (len >= MAX_IMSGSIZE - IMSG_HEADER_SIZE) + return got_error(GOT_ERR_NO_SPACE); + + wbuf = imsg_create(ibuf, GOT_IMSG_FETCH_PROGRESS, 0, 0, len); + if (wbuf == NULL) + return got_error_from_errno("imsg_create FETCH_PROGRESS"); + + /* Keep in sync with struct got_imsg_fetch_progress definition! */ + if (imsg_add(wbuf, refid->sha1, SHA1_DIGEST_LENGTH) == -1) { + err = got_error_from_errno("imsg_add FETCH_PROGRESS"); + ibuf_free(wbuf); + return err; + } + if (imsg_add(wbuf, refname, reflen) == -1) { + err = got_error_from_errno("imsg_add FETCH_PROGRESS"); + ibuf_free(wbuf); + return err; + } + + wbuf->fd = -1; + imsg_close(ibuf, wbuf); + return flush_imsg(ibuf); +} + +const struct got_error * got_privsep_send_fetch_done(struct imsgbuf *ibuf, struct got_object_id hash) { if (imsg_compose(ibuf, GOT_IMSG_FETCH_DONE, 0, 0, -1, @@ -427,7 +460,57 @@ got_privsep_send_fetch_done(struct imsgbuf *ibuf, stru return flush_imsg(ibuf); } + const struct got_error * +got_privsep_recv_fetch_progress(struct got_object_id **refid, + char **refname, struct imsgbuf *ibuf) +{ + const struct got_error *err = NULL; + struct imsg imsg; + size_t datalen; + const size_t min_datalen = + MIN(sizeof(struct got_imsg_error), + sizeof(struct got_imsg_fetch_progress)); + + *refid = NULL; + *refname = NULL; + + err = got_privsep_recv_imsg(&imsg, ibuf, min_datalen); + if (err) + return err; + + datalen = imsg.hdr.len - IMSG_HEADER_SIZE; + switch (imsg.hdr.type) { + case GOT_IMSG_ERROR: + err = recv_imsg_error(&imsg, datalen); + break; + case GOT_IMSG_FETCH_PROGRESS: + *refid = malloc(sizeof(**refid)); + if (*refid == NULL) { + err = got_error_from_errno("malloc"); + break; + } + memcpy((*refid)->sha1, imsg.data, SHA1_DIGEST_LENGTH); + if (datalen <= SHA1_DIGEST_LENGTH) { + err = got_error(GOT_ERR_PRIVSEP_MSG); + break; + } + *refname = strndup(imsg.data + SHA1_DIGEST_LENGTH, + datalen - SHA1_DIGEST_LENGTH); + if (*refname == NULL) { + err = got_error_from_errno("strndup"); + break; + } + break; + default: + return got_error(GOT_ERR_PRIVSEP_MSG); + } + + imsg_free(&imsg); + return err; +} + +const struct got_error * got_privsep_wait_fetch_done(struct imsgbuf *ibuf, struct got_object_id *hash) { const struct got_error *err = NULL;