diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index c4f6cc0..d75c690 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -113,15 +113,31 @@ int alpm_logaction(const char *fmt, ...);
  * Downloading
  */
 
+typedef struct _pm_download_status_t {
+	const char *url;
+	const char *filename;
+	const char *displayname;
+
+	int download_count;
+	int download_current;
+
+	struct timeval file_started;
+	off_t file_initial;
+	off_t file_xfered;
+	off_t file_total;
+
+	struct timeval total_started;
+	/* note: total progress always starts from 0. */
+	off_t total_xfered;
+	off_t total_total;
+} pm_download_status_t;
+
 /** Type of download progress callbacks.
  * @param filename the name of the file being downloaded
  * @param xfered the number of transferred bytes
  * @param total the total number of bytes to transfer
  */
-typedef void (*alpm_cb_download)(const char *filename,
-		off_t xfered, off_t total);
-
-typedef void (*alpm_cb_totaldl)(off_t total);
+typedef void (*alpm_cb_download)(const pm_download_status_t *status);
 
 /** A callback for downloading files
  * @param url the URL of the file to be downloaded
@@ -159,11 +175,6 @@ alpm_cb_fetch alpm_option_get_fetchcb(void);
 /** Sets the downloading callback. */
 int alpm_option_set_fetchcb(alpm_cb_fetch cb);
 
-/** Returns the callback used to report total download size. */
-alpm_cb_totaldl alpm_option_get_totaldlcb(void);
-/** Sets the callback used to report total download size. */
-int alpm_option_set_totaldlcb(alpm_cb_totaldl cb);
-
 /** Returns the root of the destination filesystem. */
 const char *alpm_option_get_root(void);
 /** Sets the root of the destination filesystem. */
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index c27854c..f370237 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -42,10 +42,6 @@
 #include "util.h"
 #include "handle.h"
 
-#ifdef HAVE_LIBCURL
-static double prevprogress; /* last download amount */
-#endif
-
 static const char *get_filename(const char *url)
 {
 	char *filename = strrchr(url, '/');
@@ -78,11 +74,11 @@ static void inthandler(int signum)
 	dload_interrupted = 1;
 }
 
-static int curl_progress(void *file, double dltotal, double dlnow,
+static int curl_progress(void *data, double dltotal, double dlnow,
 		double ultotal, double ulnow)
 {
-	struct fileinfo *dlfile = (struct fileinfo *)file;
-	double current_size, total_size;
+	pm_download_status_t *status = data;
+	off_t newly_downloaded;
 
 	/* unused parameters */
 	(void)ultotal;
@@ -98,23 +94,14 @@ static int curl_progress(void *file, double dltotal, double dlnow,
 		return 0;
 	}
 
-	current_size = dlfile->initial_size + dlnow;
-	total_size = dlfile->initial_size + dltotal;
-
-	if(DOUBLE_EQ(dltotal, 0) || DOUBLE_EQ(prevprogress, total_size)) {
-		return 0;
-	}
-
-	/* initialize the progress bar here to avoid displaying it when
-	 * a repo is up to date and nothing gets downloaded */
-	if(DOUBLE_EQ(prevprogress, 0)) {
-		handle->dlcb(dlfile->filename, 0, (long)dltotal);
-	}
-
-	handle->dlcb(dlfile->filename, (long)current_size, (long)total_size);
+	/* TODO probably don't need to do this every time... */
+	status->file_total = status->file_initial + (off_t)dltotal;
 
-	prevprogress = current_size;
+	newly_downloaded = (off_t)dlnow - status->file_xfered;
+	status->file_xfered += newly_downloaded;
+	status->total_xfered += newly_downloaded;
 
+	handle->dlcb(status);
 	return 0;
 }
 
@@ -170,7 +157,6 @@ static int curl_download_internal(const char *url, const char *localpath,
 	long timecond, remote_time;
 	double remote_size, bytes_dl;
 	struct sigaction sig_pipe[2], sig_int[2];
-	struct fileinfo dlfile;
 
 	dlfile.initial_size = 0.0;
 	dlfile.filename = get_filename(url);
@@ -318,7 +304,8 @@ int _alpm_download(const char *url, const char *localpath,
 {
 	if(handle->fetchcb == NULL) {
 #ifdef HAVE_LIBCURL
-		return curl_download_internal(url, localpath, force, allow_resume, errors_ok);
+		return curl_download_internal(url, localpath, force,
+				allow_resume, errors_ok);
 #else
 		RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
 #endif
diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h
index f4fd14c..d9256e5 100644
--- a/lib/libalpm/dload.h
+++ b/lib/libalpm/dload.h
@@ -25,12 +25,6 @@
 
 #include <time.h>
 
-/* internal structure for communicating with curl progress callback */
-struct fileinfo {
-	const char *filename;
-	double initial_size;
-};
-
 int _alpm_download(const char *url, const char *localpath,
 		int force, int allow_resume, int errors_ok);
 
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 6bc5f27..46537d4 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -121,15 +121,6 @@ alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb()
 	return handle->fetchcb;
 }
 
-alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb()
-{
-	if(handle == NULL) {
-		pm_errno = PM_ERR_HANDLE_NULL;
-		return NULL;
-	}
-	return handle->totaldlcb;
-}
-
 const char SYMEXPORT *alpm_option_get_root()
 {
 	if(handle == NULL) {
@@ -295,13 +286,6 @@ int SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb)
 	return 0;
 }
 
-int SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb)
-{
-	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
-	handle->totaldlcb = cb;
-	return 0;
-}
-
 int SYMEXPORT alpm_option_set_root(const char *root)
 {
 	struct stat st;
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index aa00b6f..bc80f52 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -50,7 +50,6 @@ typedef struct _pmhandle_t {
 	/* callback functions */
 	alpm_cb_log logcb;      /* Log callback function */
 	alpm_cb_download dlcb;  /* Download callback function */
-	alpm_cb_totaldl totaldlcb;  /* Total download callback function */
 	alpm_cb_fetch fetchcb; /* Download file callback function */
 
 	/* filesystem paths */
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 4b42af4..0f06e36 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -265,6 +265,8 @@ static int compute_download_size(pmpkg_t *newpkg)
 	fname = alpm_pkg_get_filename(newpkg);
 	ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1));
 	fpath = _alpm_filecache_find(fname);
+	
+	/* TODO: if not fpath, then $fpath.part checked next */
 
 	if(fpath) {
 		FREE(fpath);
@@ -283,7 +285,7 @@ static int compute_download_size(pmpkg_t *newpkg)
 			size = dltsize;
 		} else {
 			_alpm_log(PM_LOG_DEBUG, "using package size\n");
-			size = alpm_pkg_get_size(newpkg);
+			size = pkgsize;
 			alpm_list_free(newpkg->delta_path);
 			newpkg->delta_path = NULL;
 		}
@@ -732,21 +734,16 @@ static int download_files(pmtrans_t *trans, alpm_list_t **deltas)
 	alpm_list_t *i, *j;
 	alpm_list_t *files = NULL;
 	int errors = 0;
+	pm_download_status_t status;
 
 	cachedir = _alpm_filecache_setup();
 	trans->state = STATE_DOWNLOADING;
+	memset(&status, 0, sizeof(status));
 
-	/* Total progress - figure out the total download size if required to
-	 * pass to the callback. This function is called once, and it is up to the
-	 * frontend to compute incremental progress. */
-	if(handle->totaldlcb) {
-		off_t total_size = (off_t)0;
-		/* sum up the download size for each package and store total */
-		for(i = trans->add; i; i = i->next) {
-			pmpkg_t *spkg = i->data;
-			total_size += spkg->download_size;
-		}
-		handle->totaldlcb(total_size);
+	/* sum up the download size for each package and store total */
+	for(i = trans->add; i; i = i->next) {
+		pmpkg_t *spkg = i->data;
+		status.total_total += spkg->download_size;
 	}
 
 	/* group sync records by repository and download */
@@ -824,10 +821,6 @@ static int download_files(pmtrans_t *trans, alpm_list_t **deltas)
 		pkg->download_size = 0;
 	}
 
-	/* clear out value to let callback know we are done */
-	if(handle->totaldlcb) {
-		handle->totaldlcb(0);
-	}
 	return 0;
 }
 
diff --git a/src/pacman/callback.c b/src/pacman/callback.c
index d3dc744..b1e5136 100644
--- a/src/pacman/callback.c
+++ b/src/pacman/callback.c
@@ -38,9 +38,6 @@
 /* download progress bar */
 static double rate_last;
 static off_t xfered_last;
-static off_t list_xfered = 0.0;
-static off_t list_total = 0.0;
-static struct timeval initial_time;
 
 /* transaction progress bar */
 static int prevpercent = 0; /* for less progressbar output */
@@ -469,38 +466,25 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,
 	}
 }
 
-/* callback to handle receipt of total download value */
-void cb_dl_total(off_t total)
-{
-	list_total = total;
-	/* if we get a 0 value, it means this list has finished downloading,
-	 * so clear out our list_xfered as well */
-	if(total == 0) {
-		list_xfered = 0;
-	}
-}
-
 /* callback to handle display of download progress */
-void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
+void cb_dl_progress(const pm_download_status_t *status)
 {
 	int infolen;
 	int filenamelen;
-	char *fname, *p;
 	/* used for wide character width determination and printing */
 	int len, wclen, wcwid, padwid;
 	wchar_t *wcfname;
 
-	int totaldownload = 0;
-	off_t xfered, total;
 	double rate = 0.0, timediff = 0.0;
 	unsigned int eta_h = 0, eta_m = 0, eta_s = 0;
 	double rate_human, xfered_human;
 	const char *rate_label, *xfered_label;
 	int file_percent = 0, total_percent = 0;
+	const int totaldownload = config->totaldownload;
 
-	if(config->noprogressbar || file_total == -1) {
-		if(file_xfered == 0) {
-			printf(_("downloading %s...\n"), filename);
+	if(config->noprogressbar || status->file_total <= 0) {
+		if(status->file_xfered == 0) {
+			printf(_("downloading %s...\n"), status->url);
 			fflush(stdout);
 		}
 		return;
@@ -513,52 +497,26 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
 	/* explanation of magic 28 number at the end */
 	filenamelen = infolen - 28;
 
-	/* only use TotalDownload if enabled and we have a callback value */
-	if(config->totaldownload && list_total) {
-		/* sanity check */
-		if(list_xfered + file_total <= list_total) {
-			totaldownload = 1;
-		} else {
-			/* bogus values : don't enable totaldownload and reset */
-			list_xfered = 0;
-			list_total = 0;
-		}
-	}
-
-	if(totaldownload) {
-		xfered = list_xfered + file_xfered;
-		total = list_total;
-	} else {
-		xfered = file_xfered;
-		total = file_total;
-	}
-
-	/* bogus values : stop here */
-	if(xfered > total) {
-		return;
-	}
-
 	/* this is basically a switch on xfered: 0, total, and
 	 * anything else */
-	if(file_xfered == 0) {
+	if(status->file_xfered == 0) {
 		/* set default starting values, ensure we only call this once
 		 * if TotalDownload is enabled */
-		if(!totaldownload || (totaldownload && list_xfered == 0)) {
-			gettimeofday(&initial_time, NULL);
+		if(!totaldownload || (totaldownload && status->total_xfered == 0)) {
 			xfered_last = (off_t)0;
 			rate_last = 0.0;
 			get_update_timediff(1);
 		}
-	} else if(file_xfered == file_total) {
+	} else if(status->file_xfered == status->file_total) {
 		/* compute final values */
 		struct timeval current_time;
 		double diff_sec, diff_usec;
 
 		gettimeofday(&current_time, NULL);
-		diff_sec = current_time.tv_sec - initial_time.tv_sec;
-		diff_usec = current_time.tv_usec - initial_time.tv_usec;
+		diff_sec = current_time.tv_sec - status->file_started.tv_sec;
+		diff_usec = current_time.tv_usec - status->file_started.tv_usec;
 		timediff = diff_sec + (diff_usec / 1000000.0);
-		rate = xfered / timediff;
+		rate = status->file_xfered / timediff;
 
 		/* round elapsed time to the nearest second */
 		eta_s = (int)(timediff + 0.5);
@@ -570,25 +528,16 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
 			/* return if the calling interval was too short */
 			return;
 		}
-		rate = (xfered - xfered_last) / timediff;
+		rate = (status->file_xfered - xfered_last) / timediff;
 		/* average rate to reduce jumpiness */
 		rate = (rate + 2 * rate_last) / 3;
-		eta_s = (total - xfered) / rate;
+		eta_s = (status->file_total - status->file_xfered) / rate;
 		rate_last = rate;
-		xfered_last = xfered;
+		xfered_last = status->file_xfered;
 	}
 
-	file_percent = (file_xfered * 100) / file_total;
-
-	if(totaldownload) {
-		total_percent = ((list_xfered + file_xfered) * 100) /
-			list_total;
-
-		/* if we are at the end, add the completed file to list_xfered */
-		if(file_xfered == file_total) {
-			list_xfered += file_total;
-		}
-	}
+	file_percent = (status->file_xfered * 100) / status->file_total;
+	total_percent = (status->total_xfered * 100) / status->total_total;
 
 	/* fix up time for display */
 	eta_h = eta_s / 3600;
@@ -596,20 +545,15 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
 	eta_m = eta_s / 60;
 	eta_s -= eta_m * 60;
 
-	fname = strdup(filename);
-	/* strip package or DB extension for cleaner look */
-	if((p = strstr(fname, ".pkg")) || (p = strstr(fname, ".db"))) {
-			*p = '\0';
-	}
 	/* In order to deal with characters from all locales, we have to worry
 	 * about wide characters and their column widths. A lot of stuff is
 	 * done here to figure out the actual number of screen columns used
 	 * by the output, and then pad it accordingly so we fill the terminal.
 	 */
 	/* len = filename len + null */
-	len = strlen(filename) + 1;
+	len = strlen(status->displayname) + 1;
 	wcfname = calloc(len, sizeof(wchar_t));
-	wclen = mbstowcs(wcfname, fname, len);
+	wclen = mbstowcs(wcfname, status->displayname, len);
 	wcwid = wcswidth(wcfname, wclen);
 	padwid = filenamelen - wcwid;
 	/* if padwid is < 0, we need to trim the string so padwid = 0 */
@@ -628,14 +572,13 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
 	}
 
 	rate_human = humanize_size((off_t)rate, '\0', 0, &rate_label);
-	xfered_human = humanize_size(xfered, '\0', 0, &xfered_label);
+	xfered_human = humanize_size(status->file_xfered, '\0', 0, &xfered_label);
 
 	/* 1 space + filenamelen + 1 space + 7 for size + 1 + 7 for rate + 2 for /s + 1 space + 8 for eta */
 	printf(" %ls%-*s %6.1f%s %#6.1f%s/s %02u:%02u:%02u", wcfname,
 			padwid, "", xfered_human, xfered_label, rate_human, rate_label,
 			eta_h, eta_m, eta_s);
 
-	free(fname);
 	free(wcfname);
 
 	if(totaldownload) {
diff --git a/src/pacman/callback.h b/src/pacman/callback.h
index 1109a3b..8cc1454 100644
--- a/src/pacman/callback.h
+++ b/src/pacman/callback.h
@@ -35,10 +35,8 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2,
 void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,
                    size_t howmany, size_t remain);
 
-/* callback to handle receipt of total download value */
-void cb_dl_total(off_t total);
 /* callback to handle display of download progress */
-void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total);
+void cb_dl_progress(const pm_download_status_t *status);
 
 /* callback to handle messages/notifications from pacman library */
 void cb_log(pmloglevel_t level, const char *fmt, va_list args);
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index a4cfe75..47ba7e1 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -1458,11 +1458,6 @@ int main(int argc, char *argv[])
 		cleanup(ret);
 	}
 
-	/* set TotalDownload callback if option enabled */
-	if(config->totaldownload) {
-		alpm_option_set_totaldlcb(cb_dl_total);
-	}
-
 	/* noask is meant to be non-interactive */
 	if(config->noask) {
 		config->noconfirm = 1;
