summaryrefslogtreecommitdiffstats
path: root/src/pacman/download.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman/download.c')
-rw-r--r--src/pacman/download.c182
1 files changed, 104 insertions, 78 deletions
diff --git a/src/pacman/download.c b/src/pacman/download.c
index 1b28cccf..17d0cf21 100644
--- a/src/pacman/download.c
+++ b/src/pacman/download.c
@@ -28,7 +28,6 @@
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
-#include <ftplib.h>
#include <libintl.h>
#include <alpm.h>
@@ -40,112 +39,139 @@
#include "conf.h"
/* progress bar */
-char sync_fnm[PM_DLFNM_LEN+1];
-int offset;
-struct timeval t0, t;
-float rate;
-int xfered1;
-unsigned int eta_h, eta_m, eta_s;
+float rate_last;
+int xfered_last;
+struct timeval last_time;
+struct timeval initial_time;
/* pacman options */
extern config_t *config;
extern unsigned int maxcols;
-int log_progress(netbuf *ctl, int xfered, void *arg)
+#define FILENAME_TRIM_LEN 21
+#define UPDATE_SPEED_SEC 0.1
+
+void log_progress(const char *filename, int xfered, int total)
{
- int fsz = *(int*)arg;
- int pct = ((float)(xfered+offset) / fsz) * 100;
- static int lastpct=0;
- unsigned int i, cur;
- struct timeval t1;
- float timediff;
- /* a little hard to conceal easter eggs in open-source software, but
- * they're still fun. ;)
- */
- int chomp;
- static unsigned short mouth;
- static unsigned int lastcur = 0;
+ static int lasthash = 0, mouth = 0;
+ int i, hash;
+ long chomp = 0;
+ char *fname, *p;
+ unsigned int progresslen = maxcols - 57;
+ int percent = ((float)xfered) / ((float)total) * 100;
+ struct timeval current_time;
+ float rate = 0.0;
+ unsigned int eta_h = 0, eta_m = 0, eta_s = 0;
+ float total_timediff, timediff;
- /* we don't need that parameter */
- ctl=NULL;
+ if(xfered == 0) {
+ gettimeofday(&initial_time, NULL);
+ gettimeofday(&last_time, NULL);
+ xfered_last = 0;
+ rate_last = 0.0;
+ }
- if(config->noprogressbar || (pct == 100 && lastpct == 100)) {
- return(1);
+ if(config->noprogressbar) {
+ return;
}
- alpm_get_option(PM_OPT_CHOMP, (long *)&chomp);
+ /* a little hard to conceal easter eggs in open-source software, but they're still fun. ;) */
+ alpm_get_option(PM_OPT_CHOMP, &chomp);
- gettimeofday(&t1, NULL);
- if(xfered+offset == fsz) {
- t = t0;
+ gettimeofday(&current_time, NULL);
+ total_timediff = current_time.tv_sec-initial_time.tv_sec
+ + (float)(current_time.tv_usec-initial_time.tv_usec) / 1000000;
+ timediff = current_time.tv_sec-last_time.tv_sec
+ + (float)(current_time.tv_usec-last_time.tv_usec) / 1000000;
+
+ if(xfered == total) {
+ /* compute final values */
+ rate = total / (total_timediff * 1024);
+ eta_s = (int)total_timediff;
+ } else if(timediff < UPDATE_SPEED_SEC) {
+ /* we avoid computing the ETA on too small periods of time, so that
+ results are more significant */
+ return;
+ } else {
+ rate = (xfered - xfered_last) / (timediff * 1024);
+ rate = (rate + 2*rate_last) / 3;
+ eta_s = (total - xfered) / (rate * 1024);
}
- timediff = t1.tv_sec-t.tv_sec + (float)(t1.tv_usec-t.tv_usec) / 1000000;
-
- if(xfered+offset == fsz) {
- /* average download rate */
- rate = xfered / (timediff * 1024);
- /* total download time */
- eta_s = (int)timediff;
- eta_h = eta_s / 3600;
- eta_s -= eta_h * 3600;
- eta_m = eta_s / 60;
- eta_s -= eta_m * 60;
- } else if(timediff > 1) {
- /* we avoid computing the rate & ETA on too small periods of time, so that
- results are more significant */
- rate = (xfered-xfered1) / (timediff * 1024);
- xfered1 = xfered;
- gettimeofday(&t, NULL);
- eta_s = (fsz-(xfered+offset)) / (rate * 1024);
- eta_h = eta_s / 3600;
- eta_s -= eta_h * 3600;
- eta_m = eta_s / 60;
- eta_s -= eta_m * 60;
+
+ rate_last = rate;
+ last_time = current_time;
+ xfered_last = xfered;
+
+ /* fix up time for display */
+ eta_h = eta_s / 3600;
+ eta_s -= eta_h * 3600;
+ eta_m = eta_s / 60;
+ eta_s -= eta_m * 60;
+
+ fname = strdup(filename);
+ if((p = strstr(fname, PM_EXT_PKG)) || (p = strstr(fname, PM_EXT_DB))) {
+ *p = '\0';
+ }
+ if(strlen(fname) > FILENAME_TRIM_LEN) {
+ fname[FILENAME_TRIM_LEN] = '\0';
}
- if(rate > 1000) {
- printf("%*s %6dK %6.0fK/s %02d:%02d:%02d [", PM_DLFNM_LEN, sync_fnm, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
- } else {
- printf("%*s %6dK %6.1fK/s %02d:%02d:%02d [", PM_DLFNM_LEN, sync_fnm, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
+ /* hide the cursor i - prevent flicker
+ printf("\033[?25l\033[?1c");
+ */
+
+ /*
+ * DL rate cap, for printf formatting - this should be sane for a while
+ * if anything we can change to MB/s if we need a higher rate
+ */
+ if(rate > 9999.9) {
+ rate = 9999.9;
}
- cur = (int)((maxcols-57)*pct/100);
- for(i = 0; i < maxcols-57; i++) {
+
+ printf(" %-*s %6dK %#6.1fK/s %02d:%02d:%02d [", FILENAME_TRIM_LEN, fname, xfered/1024, rate, eta_h, eta_m, eta_s);
+
+ free(fname);
+
+ hash = percent*progresslen/100;
+ for(i = progresslen; i > 0; --i) {
if(chomp) {
- if(i < cur) {
+ if(i > progresslen - hash) {
printf("-");
- } else {
- if(i == cur) {
- if(lastcur == cur) {
- if(mouth) {
- printf("\033[1;33mC\033[m");
- } else {
- printf("\033[1;33mc\033[m");
- }
+ } else if(i == progresslen - hash) {
+ if(lasthash == hash) {
+ if(mouth) {
+ printf("\033[1;33mC\033[m");
} else {
- mouth = mouth == 1 ? 0 : 1;
- if(mouth) {
- printf("\033[1;33mC\033[m");
- } else {
- printf("\033[1;33mc\033[m");
- }
+ printf("\033[1;33mc\033[m");
}
} else {
- printf("\033[0;37m*\033[m");
+ lasthash = hash;
+ mouth = mouth == 1 ? 0 : 1;
+ if(mouth) {
+ printf("\033[1;33mC\033[m");
+ } else {
+ printf("\033[1;33mc\033[m");
+ }
}
+ } else if(i%3 == 0) {
+ printf("\033[0;37mo\033[m");
+ } else {
+ printf("\033[0;37m \033[m");
}
+ } else if(i > progresslen - hash) {
+ printf("#");
} else {
- (i < cur) ? printf("#") : printf(" ");
+ printf("-");
}
}
- printf("] %3d%%\r", pct);
- if(lastpct != 100 && pct == 100) {
+ printf("] %3d%%\r", percent);
+
+ if(percent == 100) {
printf("\n");
}
- lastcur = cur;
- lastpct = pct;
fflush(stdout);
- return(1);
+ return;
}
/* vim: set ts=2 sw=2 noet: */