diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/pacman/downloadprog.c | 89 | ||||
| -rw-r--r-- | src/pacman/pacman.c | 6 | ||||
| -rw-r--r-- | src/pacman/sync.c | 54 | ||||
| -rw-r--r-- | src/pacman/trans.c | 82 | ||||
| -rw-r--r-- | src/pacman/util.c | 162 | ||||
| -rw-r--r-- | src/pacman/util.h | 6 | 
6 files changed, 218 insertions, 181 deletions
| diff --git a/src/pacman/downloadprog.c b/src/pacman/downloadprog.c index 4ea40535..35bbab72 100644 --- a/src/pacman/downloadprog.c +++ b/src/pacman/downloadprog.c @@ -40,58 +40,57 @@  /* progress bar */  static float rate_last;  static int xfered_last; -static struct timeval last_time;  static struct timeval initial_time;  /* pacman options */  extern config_t *config; -#define FILENAME_TRIM_LEN 21 -#define UPDATE_SPEED_SEC 0.1 +#define FILENAME_TRIM_LEN 23  void log_progress(const char *filename, int xfered, int total)  { -	static unsigned int lasthash = 0, mouth = 0; -	unsigned int i, hash; -	/* a little hard to conceal easter eggs in open-source software, -	 * but they're still fun. ;) */ -	const unsigned short chomp = alpm_option_get_chomp(); +	const int infolen = 50;  	char *fname, *p;  -	unsigned int maxcols = getcols(); -	unsigned int progresslen = maxcols - 57; -	int percent = (int)((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(config->noprogressbar) { +		return; +	} + +	int percent = (int)((float)xfered) / ((float)total) * 100; +    if(xfered == 0) {  		set_output_padding(1); /* we need padding from pm_fprintf output */  		gettimeofday(&initial_time, NULL); -		gettimeofday(&last_time, NULL);  		xfered_last = 0;  		rate_last = 0.0; +		timediff = get_update_timediff(1); +	} else { +		timediff = get_update_timediff(0);  	} -	if(config->noprogressbar) { +	if(percent > 0 && percent < 100 && !timediff) { +		/* only update the progress bar when +		 * a) we first start +		 * b) we end the progress +		 * c) it has been long enough since the last call +		 */  		return;  	}  	gettimeofday(¤t_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 = (float)total / (total_timediff * 1024);  		eta_s = (unsigned int)total_timediff;  		set_output_padding(0); /* shut off padding */ -	} 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 = (float)(xfered - xfered_last) / (timediff * 1024);  		rate = (float)(rate + 2*rate_last) / 3; @@ -99,7 +98,6 @@ void log_progress(const char *filename, int xfered, int total)  	}  	rate_last = rate; -	last_time = current_time;  	xfered_last = xfered;  	/* fix up time for display */ @@ -116,61 +114,18 @@ void log_progress(const char *filename, int xfered, int total)  		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 -	 */ +	/* 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 %02u:%02u:%02u [", FILENAME_TRIM_LEN, fname,  +	printf(" %-*s %6dK %#6.1fK/s %02u:%02u:%02u", FILENAME_TRIM_LEN, fname,   				 xfered/1024, rate, eta_h, eta_m, eta_s);  	free(fname); -	hash = (unsigned int)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); +	fill_progress(percent, getcols() - infolen);  	return;  } diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 7f6f4192..c473227c 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -130,6 +130,7 @@ static void usage(int op, char *myname)  			printf(_("  -o, --owns <file>   query the package that owns <file>\n"));  			printf(_("  -p, --file          query the package file [package] instead of the database\n"));  			printf(_("  -s, --search        search locally-installed packages for matching strings\n")); +			printf(_("  -u, --upgrades      list all packages that can be upgraded\n"));  		} else if(op == PM_OP_SYNC) {  			printf(_("usage:  %s {-S --sync} [options] [package]\n"), myname);  			printf(_("options:\n")); @@ -369,7 +370,10 @@ static int parseargs(int argc, char *argv[])  				config->op_q_search = 1;  				config->flags |= PM_TRANS_FLAG_RECURSE;  				break; -			case 'u': config->op_s_upgrade = 1; break; +			case 'u': +				config->op_s_upgrade = 1; +				/* TODO config->op_q_upgrade = 1; */ +				break;  			case 'v': (config->verbose)++; break;  			case 'w':  				config->op_s_downloadonly = 1; diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 09f4587d..0a5ef72b 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -626,60 +626,8 @@ int pacman_sync(alpm_list_t *targets)  		goto cleanup;  	} -	/* list targets and get confirmation */  	if(!(alpm_trans_get_flags() & PM_TRANS_FLAG_PRINTURIS)) { -		alpm_list_t *list_install = NULL, *list_remove = NULL; - -		char *str; -		unsigned long totalsize = 0; -		unsigned long totalisize = 0; -		double mb, umb; - -		for(i = packages; i; i = alpm_list_next(i)) { -			pmsyncpkg_t *sync = alpm_list_getdata(i); -			pmpkg_t *pkg = alpm_sync_get_package(sync); -			const char *pkgname, *pkgver; - -			if(alpm_sync_get_type(sync) == PM_SYNC_TYPE_REPLACE) { -				alpm_list_t *data = alpm_sync_get_data(sync); -				for(j = data; j; j = alpm_list_next(j)) { -					pmpkg_t *p = alpm_list_getdata(j); -					const char *pkgname = alpm_pkg_get_name(p); -					if(!alpm_list_find_str(list_remove, pkgname)) { -						list_remove = alpm_list_add(list_remove, strdup(pkgname)); -					} -				} -			} - -			pkgname = alpm_pkg_get_name(pkg); -			pkgver = alpm_pkg_get_version(pkg); -			totalsize += alpm_pkg_get_size(pkg); -			totalisize += alpm_pkg_get_isize(pkg); - -			asprintf(&str, "%s-%s", pkgname, pkgver); -			list_install = alpm_list_add(list_install, str); -		} -		if(list_remove) { -			MSG(NL, "\n"); /* TODO ugly hack. printing a single NL should be easy */ -			list_display(_("Remove:"), list_remove); -			FREELIST(list_remove); -		} -		mb = (double)(totalsize / 1048576.0); -		umb = (double)(totalisize / 1048576.0); -		/* round up to 0.1 */ -		if(mb < 0.1) { -			mb = 0.1; -		} -		if(umb > 0 && umb < 0.1) { -			umb = 0.1; -		} -		MSG(NL, "\n"); -		list_display(_("Targets:"), list_install); -		MSG(NL, _("\nTotal Package Size:   %.1f MB\n"), mb); -		if(umb > 0) { -		  MSG(NL, _("Total Installed Size:   %.1f MB\n"), umb); -		} -		FREELIST(list_install); +		display_targets(packages);  		if(config->op_s_downloadonly) {  			if(config->noconfirm) { diff --git a/src/pacman/trans.c b/src/pacman/trans.c index f2f7113c..e2dcf645 100644 --- a/src/pacman/trans.c +++ b/src/pacman/trans.c @@ -57,58 +57,6 @@ static void retrieve_local(void *data1, void *data2)  	fputs(_("] 100%    LOCAL "), stdout);  } -/* refactored from cb_trans_progress */ -/* TODO with a little more work, we may be able to incorporate this - * into the download progress bar as well. */ -static void fill_progress(const int percent, const int proglen) -{ -	const unsigned short chomp = alpm_option_get_chomp(); -	const unsigned int hashlen = proglen - 8; -	const unsigned int hash = percent * hashlen / 100; -	unsigned int lasthash = 0, mouth = 0; -	unsigned int i; - -	printf(" ["); -	for(i = hashlen; i > 1; --i) { -		/* if special progress bar enabled */ -		if(chomp) { -			if(i > hashlen - hash) { -				printf("-"); -			} else if(i == hashlen - 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 regular progress bar */ -		else if(i > hashlen - hash) { -			printf("#"); -		} else { -			printf("-"); -		} -	} -	printf("] %3d%%\r", percent); - -	if(percent == 100) { -		printf("\n"); -	} -} -  /* Callback to handle transaction events   */  void cb_trans_evt(pmtransevt_t event, void *data1, void *data2) @@ -347,9 +295,11 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2,  void cb_trans_progress(pmtransprog_t event, char *pkgname, const int percent,                         const int howmany, const int remain)  { +	float timediff; +  	/* size of line to allocate for text printing (e.g. not progressbar) */  	const int infolen = 50; -	int i, digits, textlen, pkglen, proglen; +	int i, digits, textlen, pkglen;  	char *ptr = NULL;  	if(config->noprogressbar) { @@ -358,12 +308,22 @@ void cb_trans_progress(pmtransprog_t event, char *pkgname, const int percent,  	if(percent == 0) {  		set_output_padding(1); /* turn on output padding with ' ' */ -	} else if(percent == 100) { -		set_output_padding(0); /* shut it off again */ +		timediff = get_update_timediff(1); +	} else { +		timediff = get_update_timediff(0); +	} + +	if(percent > 0 && percent < 100 && !timediff) { +		/* only update the progress bar when +		 * a) we first start +		 * b) we end the progress +		 * c) it has been long enough since the last call +		 */ +		return;  	}  	/* if no pkgname, percent is too high or unchanged, then return */ -	if (!pkgname || percent > 100 || percent == prevpercent) { +	if(!pkgname || percent == prevpercent) {  		return;  	} @@ -403,17 +363,19 @@ void cb_trans_progress(pmtransprog_t event, char *pkgname, const int percent,  			printf("(%*d/%*d) %s %-*.*s", digits, remain, digits, howmany,  			       ptr, pkglen, pkglen, pkgname);  			break; -  		case PM_TRANS_PROGRESS_CONFLICTS_START:  			printf("(%*d/%*d) %-*s", digits, remain, digits, howmany,  			       textlen, ptr);  			break; -  	}  	/* call refactored fill progress function */ -	proglen = getcols() - infolen; -	fill_progress(percent, proglen); +	fill_progress(percent, getcols() - infolen); + +	if(percent >= 100) { +		set_output_padding(0); /* restore padding */ +	} +  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/util.c b/src/pacman/util.c index 7cff41b7..a30ae617 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -26,6 +26,7 @@  #include <sys/types.h>  #include <sys/ioctl.h> +#include <sys/time.h>  #include "config.h"  #include <stdio.h> @@ -258,4 +259,165 @@ void list_display(const char *title, alpm_list_t *list)  	}  } +/* Display a list of transaction targets. + * `pkgs` should be a list of pmsyncpkg_t's, + * retrieved from a transaction object + */ +void display_targets(alpm_list_t *pkgs) +{ +	char *str; +	alpm_list_t *i, *j; +	alpm_list_t *targets = NULL, *to_remove = NULL; +	unsigned long totalsize = 0, totalisize = 0, totalrsize = 0; + +	for(i = pkgs; i; i = alpm_list_next(i)) { +		pmsyncpkg_t *sync = alpm_list_getdata(i); +		pmpkg_t *pkg = alpm_sync_get_package(sync); + +		/* If this sync record is a replacement, the data member contains +		 * a list of packages to be removed due to the package that is being +		 * installed. */ +		if(alpm_sync_get_type(sync) == PM_SYNC_TYPE_REPLACE) { +			alpm_list_t *to_replace = alpm_sync_get_data(sync); +			 +			for(j = to_replace; j; j = alpm_list_next(j)) { +				pmpkg_t *rp = alpm_list_getdata(j); +				const char *name = alpm_pkg_get_name(rp); + +				if(!alpm_list_find_str(to_remove, name)) { +					totalrsize += alpm_pkg_get_isize(rp); +					to_remove = alpm_list_add(to_remove, strdup(name)); +				} +			} +		} + +		totalsize += alpm_pkg_get_size(pkg); +		totalisize += alpm_pkg_get_isize(pkg); + +		asprintf(&str, "%s-%s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); +		targets = alpm_list_add(targets, str); +	} + +	if(to_remove) { +		MSG(NL, "\n"); /* TODO ugly hack. printing a single NL should be easy */ +		list_display(_("Remove:"), to_remove); +		FREELIST(to_remove); +	 +		double rmb = (double)(totalrsize) / (1024.0 * 1024.0); +		if(rmb > 0) { +			if(rmb < 0.1) { +				rmb = 0.1; +			} +			MSG(NL, _("\nTotal Removed Size:   %.2f MB\n"), rmb); +		} +	} + +	MSG(NL, "\n"); /* TODO ugly hack. printing a single NL should be easy */  +	list_display(_("Targets:"), targets); + +	double mb = (double)(totalsize) / (1024.0 * 1024.0); +	if(mb < 0.1) { +		mb = 0.1; +	} +	MSG(NL, _("\nTotal Package Size:   %.2f MB\n"), mb); +	 +	double umb = (double)(totalisize) / (1024.0 * 1024.0); +	if(umb > 0) { +		if(umb < 0.1) { +			umb = 0.1; +		} +		MSG(NL, _("Total Installed Size:   %.2f MB\n"), umb); +	} + +	FREELIST(targets); +} + +/* Silly little helper function, determines if the caller needs a visual update + * since the last time this function was called. + * This is made for the two progress bar functions, to prevent flicker + * + * first_call indicates if this is the first time it is called, for + * initialization purposes */ +float get_update_timediff(int first_call) +{ +	float retval = 0.0; +	static struct timeval last_time = {0}; +	struct timeval this_time; + +	if(first_call) { +		/* always update on the first call */ +		retval = 1.0; +	} else { +		gettimeofday(&this_time, NULL); + +		float diff_sec = this_time.tv_sec - last_time.tv_sec; +		float diff_usec = this_time.tv_usec - last_time.tv_usec; + +		retval = diff_sec + (diff_usec / 1000000.0f); +		/*printf("update time: %fs %fus = %f\n", diff_sec, diff_usec, retval);*/ + +		if(retval < UPDATE_SPEED_SEC) { +			/* maintain the last_time value for the next call */ +			return(0.0); +		} +	} + +	/* set the time for the next call */ +	gettimeofday(&last_time, NULL); + +	return(retval); +} + +/* refactored from cb_trans_progress */ +void fill_progress(const int percent, const int proglen) +{ +	const unsigned short chomp = alpm_option_get_chomp(); +	const unsigned int hashlen = proglen - 8; +	const unsigned int hash = percent * hashlen / 100; +	unsigned int lasthash = 0, mouth = 0; +	unsigned int i; + +	printf(" ["); +	for(i = hashlen; i > 1; --i) { +		/* if special progress bar enabled */ +		if(chomp) { +			if(i > hashlen - hash) { +				printf("-"); +			} else if(i == hashlen - 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 regular progress bar */ +		else if(i > hashlen - hash) { +			printf("#"); +		} else { +			printf("-"); +		} +	} +	printf("] %3d%%\r", percent); + +	if(percent == 100) { +		printf("\n"); +	} +	fflush(stdout); +} + +  /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/util.h b/src/pacman/util.h index 37509788..61bf09ee 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -47,6 +47,9 @@  	s1[(len)-1] = 0; \  } while(0) +/* update speed for the fill_progress based functions */ +#define UPDATE_SPEED_SEC 0.2f +  #define _(str) gettext(str)  unsigned int getcols();  int makepath(char *path); @@ -56,6 +59,9 @@ char *strtoupper(char *str);  char *strtrim(char *str);  int reg_match(char *string, char *pattern);  void list_display(const char *title, alpm_list_t *list); +void display_targets(alpm_list_t *pkgs); +float get_update_timediff(int first_call); +void fill_progress(const int percent, const int proglen);  #endif /* _PM_UTIL_H */ | 
