Commit Diff


commit - a6ee240a22bfd91ad970ed354f494e38d9d4280b
commit + d2cdc63664daa5fa39c9a6398c33f3724650bfe9
blob - a3cf2526d4ee1971e59ae8f61e78f60326046405
blob + e4bbfb0c494e0df6e355a7bcc31c0af2d86a4b07
--- got/got.c
+++ got/got.c
@@ -38,6 +38,7 @@
 #include <paths.h>
 #include <regex.h>
 #include <getopt.h>
+#include <util.h>
 
 #include "got_version.h"
 #include "got_error.h"
@@ -969,10 +970,18 @@ done:
 }
 
 static const struct got_error *
-fetch_progress(void *arg, const char *message)
+fetch_progress(void *arg, const char *message, off_t packfile_size)
 {
-	char *servername = arg;
-	printf("\rserver %s: %s", servername, message);
+	int *did_something = arg;
+	char scaled[FMT_SCALED_STRSIZE];
+	
+	if (message) {
+		printf("\rserver: %s", message);
+		*did_something = 1;
+	} else if (packfile_size > 0 && fmt_scaled(packfile_size, scaled) == 0) {
+		printf("\rfetching... %*s", FMT_SCALED_STRSIZE, scaled);
+		*did_something = 1;
+	}
 	fflush(stdout);
 	return NULL;
 }
@@ -990,6 +999,7 @@ cmd_clone(int argc, char *argv[])
 	struct got_pathlist_entry *pe;
 	struct got_object_id *pack_hash = NULL;
 	int ch, fetchfd = -1;
+	int did_something = 0;
 
 	TAILQ_INIT(&refs);
 	TAILQ_INIT(&symrefs);
@@ -1045,9 +1055,11 @@ cmd_clone(int argc, char *argv[])
 		goto done;
 
 	err = got_fetch_pack(&pack_hash, &refs, &symrefs, fetchfd,
-	    repo, fetch_progress, host);
+	    repo, fetch_progress, &did_something);
 	if (err)
 		goto done;
+	if (did_something)
+		printf("\n");
 
 	err = got_object_id_str(&id_str, pack_hash);
 	if (err)
blob - e3e0144058ef5d5342ddef6dc9a0edd935474201
blob + 773e689afb160f0428740fef229371814d293eb0
--- include/got_fetch.h
+++ include/got_fetch.h
@@ -40,7 +40,7 @@ const struct got_error *got_fetch_connect(int *, const
 
 /* A callback function which gets invoked with progress information to print. */
 typedef const struct got_error *(*got_fetch_progress_cb)(void *,
-    const char *);
+    const char *, off_t);
 
 /*
  * Attempt to fetch a packfile from a server. This pack file will contain
blob - 15ecb2be5c719d2c618a30756def530640a9dad7
blob + 4936c368b72d20f0700da9ef791558f5eeb7ef03
--- lib/fetch.c
+++ lib/fetch.c
@@ -313,6 +313,7 @@ got_fetch_pack(struct got_object_id **pack_hash, struc
 	const char *repo_path = got_repo_get_path(repo);
 	struct got_pathlist_head have_refs;
 	struct got_pathlist_entry *pe;
+	off_t packfile_size = 0;
 	char *path;
 
 	*pack_hash = NULL;
@@ -385,13 +386,16 @@ got_fetch_pack(struct got_object_id **pack_hash, struc
 		goto done;
 	}
 
+	packfile_size = 0;
 	while (!done) {
 		struct got_object_id *id = NULL;
 		char *refname = NULL;
 		char *server_progress = NULL;
+		off_t packfile_size_cur;
 
 		err = got_privsep_recv_fetch_progress(&done,
-		    &id, &refname, symrefs, &server_progress, &ibuf);
+		    &id, &refname, symrefs, &server_progress,
+		    &packfile_size_cur, &ibuf);
 		if (err != NULL)
 			goto done;
 		if (done)
@@ -405,13 +409,19 @@ got_fetch_pack(struct got_object_id **pack_hash, struc
 			while ((s = strsep(&s0, "\r")) != NULL) {
 				if (*s == '\0')
 					continue;
-				err = progress_cb(progress_arg, s);
+				err = progress_cb(progress_arg, s, 0);
 				if (err)
 					break;
 			}
 			free(server_progress);
 			if (err)
 				goto done;
+		} else if (packfile_size_cur != packfile_size) {
+			err = progress_cb(progress_arg, NULL,
+			    packfile_size_cur);
+			if (err)
+				break;
+			packfile_size = packfile_size_cur;
 		}
 	}
 	if (waitpid(pid, &status, 0) == -1) {
blob - 5b5d6f6c9f80056a8ccc1e8fdc9b798eff0f2dc8
blob + c557473418f6733044e922f4df08164429fe995f
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
@@ -113,6 +113,7 @@ enum got_imsg_type {
 	GOT_IMSG_FETCH_SYMREFS,
 	GOT_IMSG_FETCH_REF,
 	GOT_IMSG_FETCH_SERVER_PROGRESS,
+	GOT_IMSG_FETCH_DOWNLOAD_PROGRESS,
 	GOT_IMSG_FETCH_DONE,
 	GOT_IMSG_IDXPACK_REQUEST,
 	GOT_IMSG_IDXPACK_DONE,
@@ -269,6 +270,12 @@ struct got_imsg_fetch_ref {
 	/* Followed by reference name in remaining data of imsg buffer. */
 };
 
+/* Structure for GOT_IMSG_FETCH_DOWNLOAD_PROGRESS data. */
+struct got_imsg_fetch_download_progress {
+	/* Number of packfile data bytes downloaded so far. */
+	off_t packfile_bytes;
+};
+
 /* Structure for GOT_IMSG_PACKIDX. */
 struct got_imsg_packidx {
 	size_t len;
@@ -359,9 +366,11 @@ const struct got_error *got_privsep_send_fetch_ref(str
     struct got_object_id *, const char *);
 const struct got_error *got_privsep_send_fetch_server_progress(struct imsgbuf *,
     const char *, size_t);
+const struct got_error *got_privsep_send_fetch_download_progress(struct imsgbuf *,
+    off_t);
 const struct got_error *got_privsep_recv_fetch_progress(int *,
     struct got_object_id **, char **, struct got_pathlist_head *,
-    char **, struct imsgbuf *);
+    char **, off_t *, struct imsgbuf *);
 const struct got_error *got_privsep_send_fetch_done(struct imsgbuf *,
     struct got_object_id);
 const struct got_error *got_privsep_get_imsg_obj(struct got_object **,
blob - 6aabc63d20518ccca1b4c176ee56c4af7e7f9adc
blob + 96c8759b3613fda441384c283df161cf5059f8fa
--- lib/privsep.c
+++ lib/privsep.c
@@ -583,6 +583,17 @@ got_privsep_send_fetch_server_progress(struct imsgbuf 
 	    msg, msglen) == -1)
 		return got_error_from_errno(
 		    "imsg_compose FETCH_SERVER_PROGRESS");
+
+	return flush_imsg(ibuf);
+}
+
+const struct got_error *
+got_privsep_send_fetch_download_progress(struct imsgbuf *ibuf, off_t bytes)
+{
+	if (imsg_compose(ibuf, GOT_IMSG_FETCH_DOWNLOAD_PROGRESS, 0, 0, -1,
+	    &bytes, sizeof(bytes)) == -1)
+		return got_error_from_errno(
+		    "imsg_compose FETCH_DOWNLOAD_PROGRESS");
 
 	return flush_imsg(ibuf);
 }
@@ -600,7 +611,7 @@ got_privsep_send_fetch_done(struct imsgbuf *ibuf, stru
 const struct got_error *
 got_privsep_recv_fetch_progress(int *done, struct got_object_id **id,
     char **refname, struct got_pathlist_head *symrefs, char **server_progress,
-    struct imsgbuf *ibuf)
+    off_t *packfile_size, struct imsgbuf *ibuf)
 {
 	const struct got_error *err = NULL;
 	struct imsg imsg;
@@ -720,6 +731,13 @@ got_privsep_recv_fetch_progress(int *done, struct got_
 			}
 		}
 		break;
+	case GOT_IMSG_FETCH_DOWNLOAD_PROGRESS:
+		if (datalen < sizeof(*packfile_size)) {
+			err = got_error(GOT_ERR_PRIVSEP_MSG);
+			break;
+		}
+		memcpy(packfile_size, imsg.data, sizeof(*packfile_size));
+		break;
 	case GOT_IMSG_FETCH_DONE:
 		*id = malloc(sizeof(**id));
 		if (*id == NULL) {
blob - 17c615163a853c4b5c228a07100bafca24dce381
blob + 14fb915c5bf3a3ec428cfafcae915f83694cc47b
--- libexec/got-fetch-pack/got-fetch-pack.c
+++ libexec/got-fetch-pack/got-fetch-pack.c
@@ -774,6 +774,9 @@ fetch_pack(int fd, int packfd, struct got_object_id *p
 			goto done;
 		}
 		packsz += w;
+		err = got_privsep_send_fetch_download_progress(ibuf, packsz);
+		if (err)
+			goto done;
 	}
 	if (lseek(packfd, 0, SEEK_SET) == -1) {
 		err = got_error_from_errno("lseek");