From: Ivy Foster <[email protected]>

When curl calls alpm's dlcb, alpm calls the frontend's cb with the
following (dlsize, totalsize) arguments:

0, -1: initialize
0, 0: no change since last call
x {x>0, x<y}, y {y>0}: data downloaded, total size known
x {x>0}, x: download finished

If total size is not known, do not call frontend cb (no change to
original behavior); alpm's callback shouldn't be called if there is a
download error.

See agregory's original spec here:
https://wiki.archlinux.org/index.php/User:Apg#download_callback
---
 lib/libalpm/dload.c   | 22 ++++++++++++++++------
 src/pacman/callback.c | 19 +++++++++++--------
 2 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index 31ae82c..f4e6a27 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -126,14 +126,24 @@ static int dload_progress_cb(void *file, double dltotal, 
double dlnow,
        }
 
        /* initialize the progress bar here to avoid displaying it when
-        * a repo is up to date and nothing gets downloaded */
-       if(payload->prevprogress == 0) {
-               payload->handle->dlcb(payload->remote_name, 0, (off_t)dltotal);
-       }
-
+        * a repo is up to date and nothing gets downloaded.
+        * payload->handle->dlcb will receive the remote_name
+        * and the following arguments:
+        * 0, -1: download initialized
+        * 0, 0: non-download event
+        * x {x>0}, x: download complete
+        * x {x>0, x<y}, y {y > 0}: download progress, expected total is known 
*/
+       if(current_size == total_size) {
+               payload->handle->dlcb(payload->remote_name, (off_t)dlnow, 
(off_t)dltotal);
+       } else if(!payload->prevprogress) {
+               payload->handle->dlcb(payload->remote_name, 0, -1);
+       } else if(payload->prevprogress == current_size) {
+               payload->handle->dlcb(payload->remote_name, 0, 0);
+       } else {
        /* do NOT include initial_size since it wasn't part of the package's
         * download_size (nor included in the total download size callback) */
-       payload->handle->dlcb(payload->remote_name, (off_t)dlnow, 
(off_t)dltotal);
+               payload->handle->dlcb(payload->remote_name, (off_t)dlnow, 
(off_t)dltotal);
+       }
 
        payload->prevprogress = current_size;
 
diff --git a/src/pacman/callback.c b/src/pacman/callback.c
index ab3e14f..7f72b84 100644
--- a/src/pacman/callback.c
+++ b/src/pacman/callback.c
@@ -678,8 +678,13 @@ void cb_dl_progress(const char *filename, off_t 
file_xfered, off_t file_total)
 
        const unsigned short cols = getcols();
 
-       if(config->noprogressbar || cols == 0 || file_total == -1) {
-               if(file_xfered == 0) {
+       /* Nothing has changed since last callback; stop here */
+       if(file_xfered == 0 && file_total == 0) {
+               return;
+       }
+
+       if(config->noprogressbar || cols == 0) {
+               if(file_xfered == 0 && file_total == -1) {
                        printf(_("downloading %s...\n"), filename);
                        fflush(stdout);
                }
@@ -710,14 +715,9 @@ void cb_dl_progress(const char *filename, off_t 
file_xfered, off_t file_total)
                total = file_total;
        }
 
-       /* bogus values : stop here */
-       if(xfered > total || xfered < 0) {
-               return;
-       }
-
        /* this is basically a switch on xfered: 0, total, and
         * anything else */
-       if(file_xfered == 0) {
+       if(file_xfered == 0 && file_total == -1) {
                /* set default starting values, ensure we only call this once
                 * if TotalDownload is enabled */
                if(!totaldownload || (totaldownload && list_xfered == 0)) {
@@ -726,6 +726,9 @@ void cb_dl_progress(const char *filename, off_t 
file_xfered, off_t file_total)
                        rate_last = 0.0;
                        get_update_timediff(1);
                }
+       } else if(xfered > total || xfered < 0) {
+               /* bogus values : stop here */
+               return;
        } else if(file_xfered == file_total) {
                /* compute final values */
                int64_t timediff = get_time_ms() - initial_time;
-- 
2.9.0

Reply via email to