Commit d6bda086e66c6fbfd9f3507048713d2e5942fbb2

Stefan Sperling 2018-09-10T13:10:30

send deltas when requesting packed object extraction

diff --git a/lib/privsep.c b/lib/privsep.c
index fbd2510..74df15b 100644
--- a/lib/privsep.c
+++ b/lib/privsep.c
@@ -214,9 +214,49 @@ got_privsep_send_stop(int fd)
 	return err;
 }
 
+static const struct got_error *
+send_delta(struct got_delta *delta, struct imsgbuf *ibuf)
+{
+	struct got_imsg_delta idelta;
+	size_t offset, remain;
+
+	idelta.offset = delta->offset;
+	idelta.tslen = delta->tslen;
+	idelta.type = delta->type;
+	idelta.size = delta->size;
+	idelta.data_offset = delta->data_offset;
+	idelta.delta_len = delta->delta_len;
+
+	if (imsg_compose(ibuf, GOT_IMSG_DELTA, 0, 0, -1,
+	    &idelta, sizeof(idelta)) == -1)
+		return got_error_from_errno();
+
+	if (imsg_flush(ibuf) == -1)
+		return got_error_from_errno();
+
+	offset = 0;
+	remain = delta->delta_len;
+	while (remain > 0) {
+		size_t n = MIN(MAX_IMSGSIZE - IMSG_HEADER_SIZE, remain);
+
+		if (imsg_compose(ibuf, GOT_IMSG_DELTA_STREAM, 0, 0, -1,
+		    delta->delta_buf + offset, n) == -1)
+			return got_error_from_errno();
+
+		if (imsg_flush(ibuf) == -1)
+			return got_error_from_errno();
+
+		offset += n;
+		remain -= n;
+	}
+
+	return NULL;
+}
+
 const struct got_error *
 got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, struct got_object *obj)
 {
+	const struct got_error *err = NULL;
 	struct got_imsg_object iobj, *iobjp = NULL;
 	size_t iobj_size = 0;
 	int imsg_code = GOT_IMSG_OBJECT_REQUEST;
@@ -229,6 +269,7 @@ got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, struct got_object *obj)
 		case GOT_OBJ_TYPE_COMMIT:
 			imsg_code = GOT_IMSG_COMMIT_REQUEST;
 			break;
+		/* Blobs are handled in got_privsep_send_blob_req(). */
 		default:
 			return got_error(GOT_ERR_OBJ_TYPE);
 		}
@@ -248,7 +289,20 @@ got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, struct got_object *obj)
 	if (imsg_compose(ibuf, imsg_code, 0, 0, fd, iobjp, iobj_size) == -1)
 		return got_error_from_errno();
 
-	return flush_imsg(ibuf);
+	err = flush_imsg(ibuf);
+	if (err)
+		return err;
+
+	if (obj && obj->flags & GOT_OBJ_FLAG_DELTIFIED) {
+		struct got_delta *delta;
+		SIMPLEQ_FOREACH(delta, &obj->deltas.entries, entry) {
+			err = send_delta(delta, ibuf);
+			if (err)
+				break;
+		}
+	}
+
+	return err;
 }
 
 const struct got_error *
@@ -278,45 +332,6 @@ got_privsep_send_blob_req(struct imsgbuf *ibuf, int outfd, int infd)
 	return flush_imsg(ibuf);
 }
 
-static const struct got_error *
-send_delta(struct got_delta *delta, struct imsgbuf *ibuf)
-{
-	struct got_imsg_delta idelta;
-	size_t offset, remain;
-
-	idelta.offset = delta->offset;
-	idelta.tslen = delta->tslen;
-	idelta.type = delta->type;
-	idelta.size = delta->size;
-	idelta.data_offset = delta->data_offset;
-	idelta.delta_len = delta->delta_len;
-
-	if (imsg_compose(ibuf, GOT_IMSG_DELTA, 0, 0, -1,
-	    &idelta, sizeof(idelta)) == -1)
-		return got_error_from_errno();
-
-	if (imsg_flush(ibuf) == -1)
-		return got_error_from_errno();
-
-	offset = 0;
-	remain = delta->delta_len;
-	while (remain > 0) {
-		size_t n = MIN(MAX_IMSGSIZE - IMSG_HEADER_SIZE, remain);
-
-		if (imsg_compose(ibuf, GOT_IMSG_DELTA_STREAM, 0, 0, -1,
-		    delta->delta_buf + offset, n) == -1)
-			return got_error_from_errno();
-
-		if (imsg_flush(ibuf) == -1)
-			return got_error_from_errno();
-
-		offset += n;
-		remain -= n;
-	}
-
-	return NULL;
-}
-
 const struct got_error *
 got_privsep_send_obj(struct imsgbuf *ibuf, struct got_object *obj)
 {