Commit Diff


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;