summaryrefslogtreecommitdiffstats
path: root/src/pacman/downloadprog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman/downloadprog.c')
-rw-r--r--src/pacman/downloadprog.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/src/pacman/downloadprog.c b/src/pacman/downloadprog.c
new file mode 100644
index 00000000..0de34d3d
--- /dev/null
+++ b/src/pacman/downloadprog.c
@@ -0,0 +1,177 @@
+/*
+ * downloadprog.c
+ *
+ * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#include "config.h"
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <libintl.h>
+
+#include <alpm.h>
+/* pacman */
+#include "util.h"
+#include "log.h"
+#include "list.h"
+#include "downloadprog.h"
+#include "conf.h"
+
+/* progress bar */
+float rate_last;
+int xfered_last;
+struct timeval last_time;
+struct timeval initial_time;
+
+/* pacman options */
+extern config_t *config;
+
+extern unsigned int maxcols;
+
+#define FILENAME_TRIM_LEN 21
+#define UPDATE_SPEED_SEC 0.1
+
+void log_progress(const char *filename, int xfered, int total)
+{
+ 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;
+
+ if(xfered == 0) {
+ gettimeofday(&initial_time, NULL);
+ gettimeofday(&last_time, NULL);
+ xfered_last = 0;
+ rate_last = 0.0;
+ }
+
+ if(config->noprogressbar) {
+ return;
+ }
+
+ /* a little hard to conceal easter eggs in open-source software, but they're still fun. ;) */
+ alpm_get_option(PM_OPT_CHOMP, &chomp);
+
+ 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);
+ }
+
+ 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';
+ }
+
+ /* 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;
+ }
+
+ 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 > progresslen - hash) {
+ printf("-");
+ } else if(i == progresslen - hash) {
+ if(lasthash == hash) {
+ if(mouth) {
+ printf("\033[1;33mC\033[m");
+ } else {
+ printf("\033[1;33mc\033[m");
+ }
+ } else {
+ 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 {
+ printf("-");
+ }
+ }
+ printf("] %3d%%\r", percent);
+
+ if(percent == 100) {
+ printf("\n");
+ }
+ fflush(stdout);
+ return;
+}
+
+/* vim: set ts=2 sw=2 noet: */