diff options
Diffstat (limited to 'src/pacman')
| -rw-r--r-- | src/pacman/Makefile.am | 2 | ||||
| -rw-r--r-- | src/pacman/callback.c | 124 | ||||
| -rw-r--r-- | src/pacman/callback.h | 3 | ||||
| -rw-r--r-- | src/pacman/conf.h | 16 | ||||
| -rw-r--r-- | src/pacman/deptest.c | 46 | ||||
| -rw-r--r-- | src/pacman/pacman.c | 101 | ||||
| -rw-r--r-- | src/pacman/pacman.h | 9 | ||||
| -rw-r--r-- | src/pacman/query.c | 47 | ||||
| -rw-r--r-- | src/pacman/remove.c | 41 | ||||
| -rw-r--r-- | src/pacman/sync.c | 253 | ||||
| -rw-r--r-- | src/pacman/upgrade.c (renamed from src/pacman/add.c) | 58 | ||||
| -rw-r--r-- | src/pacman/util.c | 92 | ||||
| -rw-r--r-- | src/pacman/util.h | 4 | 
13 files changed, 360 insertions, 436 deletions
| diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am index 5e287404..5d6fef3c 100644 --- a/src/pacman/Makefile.am +++ b/src/pacman/Makefile.am @@ -22,7 +22,6 @@ INCLUDES = -I$(top_srcdir)/lib/libalpm  AM_CFLAGS = -pedantic -D_GNU_SOURCE  pacman_SOURCES = \ -	add.c \  	conf.h conf.c \  	deptest.c \  	package.h package.c \ @@ -31,6 +30,7 @@ pacman_SOURCES = \  	remove.c \  	sync.c \  	callback.h callback.c \ +	upgrade.c \  	util.h util.c  LDADD = $(LTLIBINTL) $(top_builddir)/lib/libalpm/.libs/libalpm.la diff --git a/src/pacman/callback.c b/src/pacman/callback.c index a7686483..8a7af5c5 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -34,9 +34,6 @@  #include "util.h"  #include "conf.h" -/* TODO this should not have to be defined twice- trans.c & log.c */ -#define LOG_STR_LEN 256 -  /* download progress bar */  static float rate_last;  static int xfered_last; @@ -86,17 +83,14 @@ static float get_update_timediff(int first_call)  }  /* refactored from cb_trans_progress */ -static void fill_progress(const int graph_percent, const int display_percent, -		const int proglen) +static void fill_progress(const int percent, const int proglen)  {  	const unsigned int hashlen = proglen - 8; -	const unsigned int hash = graph_percent * hashlen / 100; +	const unsigned int hash = percent * hashlen / 100;  	static unsigned int lasthash = 0, mouth = 0;  	unsigned int i; -	/* printf("\ndebug: proglen: %i\n", proglen); DEBUG*/ - -	if(graph_percent == 0) { +	if(percent == 0) {  		lasthash = 0;  		mouth = 0;  	} @@ -141,10 +135,10 @@ static void fill_progress(const int graph_percent, const int display_percent,  	}  	/* print percent after progress bar */  	if(proglen > 5) { -		printf(" %3d%%", display_percent); +		printf(" %3d%%", percent);  	} -	if(graph_percent == 100) { +	if(percent == 100) {  		printf("\n");  	} else {  		printf("\r"); @@ -157,8 +151,6 @@ static void fill_progress(const int graph_percent, const int display_percent,  /* callback to handle messages/notifications from libalpm transactions */  void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)  { -	char str[LOG_STR_LEN] = ""; -  	switch(event) {  		case PM_TRANS_EVT_CHECKDEPS_START:  		  printf(_("checking dependencies...\n")); @@ -180,10 +172,9 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)  			}  			break;  		case PM_TRANS_EVT_ADD_DONE: -			snprintf(str, LOG_STR_LEN, "installed %s (%s)\n", +			alpm_logaction("installed %s (%s)\n",  			         alpm_pkg_get_name(data1),  			         alpm_pkg_get_version(data1)); -			alpm_logaction(str);  			break;  		case PM_TRANS_EVT_REMOVE_START:  			if(config->noprogressbar) { @@ -191,10 +182,9 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)  			}  			break;  		case PM_TRANS_EVT_REMOVE_DONE: -			snprintf(str, LOG_STR_LEN, "removed %s (%s)\n", +			alpm_logaction("removed %s (%s)\n",  			         alpm_pkg_get_name(data1),  			         alpm_pkg_get_version(data1)); -			alpm_logaction(str);  			break;  		case PM_TRANS_EVT_UPGRADE_START:  			if(config->noprogressbar) { @@ -202,11 +192,10 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)  			}  			break;  		case PM_TRANS_EVT_UPGRADE_DONE: -			snprintf(str, LOG_STR_LEN, "upgraded %s (%s -> %s)\n", +			alpm_logaction("upgraded %s (%s -> %s)\n",  			         (char *)alpm_pkg_get_name(data1),  			         (char *)alpm_pkg_get_version(data2),  			         (char *)alpm_pkg_get_version(data1)); -			alpm_logaction(str);  			break;  		case PM_TRANS_EVT_INTEGRITY_START:  			printf(_("checking package integrity...\n")); @@ -255,67 +244,46 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)  void cb_trans_conv(pmtransconv_t event, void *data1, void *data2,                     void *data3, int *response)  { -	char str[LOG_STR_LEN] = ""; -  	switch(event) {  		case PM_TRANS_CONV_INSTALL_IGNOREPKG:  			if(data2) {  				/* TODO we take this route based on data2 being not null? WTF */ -				snprintf(str, LOG_STR_LEN, _(":: %s requires installing %s from IgnorePkg/IgnoreGroup. Install anyway? [Y/n] "), +				*response = yesno(1, _(":: %s requires installing %s from IgnorePkg/IgnoreGroup. Install anyway?"),  						alpm_pkg_get_name(data1),  						alpm_pkg_get_name(data2)); -				*response = yesno(str);  			} else { -				snprintf(str, LOG_STR_LEN, _(":: %s is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n] "), +				*response = yesno(1, _(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"),  						alpm_pkg_get_name(data1)); -				*response = yesno(str);  			}  			break;  		case PM_TRANS_CONV_REMOVE_HOLDPKG: -			snprintf(str, LOG_STR_LEN, _(":: %s is designated as a HoldPkg. Remove anyway? [Y/n] "), +			*response = yesno(1, _(":: %s is designated as a HoldPkg. Remove anyway?"),  					alpm_pkg_get_name(data1)); -			*response = yesno(str);  			break;  		case PM_TRANS_CONV_REPLACE_PKG: -			if(!config->noconfirm) { -				snprintf(str, LOG_STR_LEN, _(":: Replace %s with %s/%s? [Y/n] "), -						alpm_pkg_get_name(data1), -						(char *)data3, -						alpm_pkg_get_name(data2)); -				*response = yesno(str); -			} else { -				printf(_("Replacing %s with %s/%s\n"), -						alpm_pkg_get_name(data1), -						(char *)data3, -						alpm_pkg_get_name(data2)); -				*response = 1; -			} +			*response = yesno(1, _(":: Replace %s with %s/%s?"), +					alpm_pkg_get_name(data1), +					(char *)data3, +					alpm_pkg_get_name(data2));  			break;  		case PM_TRANS_CONV_CONFLICT_PKG: -			snprintf(str, LOG_STR_LEN, _(":: %s conflicts with %s. Remove %s? [Y/n] "), +			*response = yesno(1, _(":: %s conflicts with %s. Remove %s?"),  					(char *)data1,  					(char *)data2,  					(char *)data2); -			*response = yesno(str);  			break;  		case PM_TRANS_CONV_LOCAL_NEWER:  			if(!config->op_s_downloadonly) { -				snprintf(str, LOG_STR_LEN, _(":: %s-%s: local version is newer. Upgrade anyway? [Y/n] "), +				*response = yesno(1, _(":: %s-%s: local version is newer. Upgrade anyway?"),  						alpm_pkg_get_name(data1),  						alpm_pkg_get_version(data1)); -				*response = yesno(str);  			} else {  				*response = 1;  			}  			break;  		case PM_TRANS_CONV_CORRUPTED_PKG: -			if(!config->noconfirm) { -				snprintf(str, LOG_STR_LEN, _(":: File %s is corrupted. Do you want to delete it? [Y/n] "), -						(char *)data1); -				*response = yesno(str); -			} else { -				*response = 1; -			} +			*response = yesno(1, _(":: File %s is corrupted. Do you want to delete it?"), +					(char *)data1);  			break;  	}  } @@ -427,7 +395,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,  	free(wcstr);  	/* call refactored fill progress function */ -	fill_progress(percent, percent, getcols() - infolen); +	fill_progress(percent, getcols() - infolen);  	if(percent == 100) {  		alpm_list_t *i = NULL; @@ -443,8 +411,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,  }  /* callback to handle display of download progress */ -void cb_dl_progress(const char *filename, int file_xfered, int file_total, -		int list_xfered, int list_total) +void cb_dl_progress(const char *filename, int xfered, int total)  {  	const int infolen = 50;  	const int filenamelen = infolen - 27; @@ -455,43 +422,22 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total,  	float rate = 0.0, timediff = 0.0, f_xfered = 0.0;  	unsigned int eta_h = 0, eta_m = 0, eta_s = 0; -	int graph_percent = 0, display_percent = 0; +	int percent;  	char rate_size = 'K', xfered_size = 'K'; -	int xfered = 0, total = 0; - -	/* Need this variable when TotalDownload is set to know if we should -	 * reset xfered_last and rate_last. */ -	static int has_init = 0;  	if(config->noprogressbar) {  		return;  	} -	/* Choose how to display the amount downloaded, rate, ETA, and -	 * percentage depending on the TotalDownload option. */ -	if (config->totaldownload && list_total > 0) { -		xfered = list_xfered; -		total = list_total; -	} else { -		xfered = file_xfered; -		total = file_total; -	} -  	/* this is basically a switch on file_xferred: 0, file_total, and  	 * anything else */ -	if(file_xfered == 0) { -		/* set default starting values, but only once for TotalDownload */ -		if (!(config->totaldownload && list_total > 0) || -				(config->totaldownload && list_total > 0 && !has_init)) { -			gettimeofday(&initial_time, NULL); -			timediff = get_update_timediff(1); -			xfered_last = 0; -			rate_last = 0.0; -			has_init = 1; -		} -		rate = 0.0; -		eta_s = 0; -	} else if(file_xfered == file_total) { +	if(xfered == 0) { +		/* set default starting values */ +		gettimeofday(&initial_time, NULL); +		xfered_last = 0; +		rate_last = 0.0; +		timediff = get_update_timediff(1); +	} else if(xfered == total) {  		/* compute final values */  		struct timeval current_time;  		float diff_sec, diff_usec; @@ -500,7 +446,7 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total,  		diff_sec = current_time.tv_sec - initial_time.tv_sec;  		diff_usec = current_time.tv_usec - initial_time.tv_usec;  		timediff = diff_sec + (diff_usec / 1000000.0); -		rate = xfered / (timediff * 1024.0); +		rate = total / (timediff * 1024.0);  		/* round elapsed time to the nearest second */  		eta_s = (int)(timediff + 0.5); @@ -514,12 +460,14 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total,  		}  		rate = (xfered - xfered_last) / (timediff * 1024.0);  		/* average rate to reduce jumpiness */ -		rate = (rate + 2*rate_last) / 3; +		rate = (rate + 2 * rate_last) / 3;  		eta_s = (total - xfered) / (rate * 1024.0);  		rate_last = rate;  		xfered_last = xfered;  	} +	percent = (int)((float)xfered) / ((float)total) * 100; +  	/* fix up time for display */  	eta_h = eta_s / 3600;  	eta_s -= eta_h * 3600; @@ -591,11 +539,7 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total,  	free(fname);  	free(wcfname); -	/* The progress bar is based on the file percent regardless of the -	 * TotalDownload option. */ -	graph_percent = (int)((float)file_xfered) / ((float)file_total) * 100; -	display_percent = (int)((float)xfered) / ((float)total) * 100; -	fill_progress(graph_percent, display_percent, getcols() - infolen); +	fill_progress(percent, getcols() - infolen);  	return;  } diff --git a/src/pacman/callback.h b/src/pacman/callback.h index aa8d9370..39d59d8b 100644 --- a/src/pacman/callback.h +++ b/src/pacman/callback.h @@ -33,8 +33,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,                     int howmany, int remain);  /* callback to handle display of download progress */ -void cb_dl_progress(const char *filename, int file_xfered, int file_total, -		int list_xfered, int list_total); +void cb_dl_progress(const char *filename, int file_xfered, int file_total);  /* callback to handle messages/notifications from pacman library */  void cb_log(pmloglevel_t level, char *fmt, va_list args); diff --git a/src/pacman/conf.h b/src/pacman/conf.h index f804f560..28ac4b96 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -27,7 +27,6 @@ typedef struct __config_t {  	unsigned short verbose;  	unsigned short version;  	unsigned short help; -	unsigned short upgrade;  	unsigned short noconfirm;  	unsigned short noprogressbar;  	unsigned short logmask; @@ -53,7 +52,6 @@ typedef struct __config_t {  	unsigned short op_q_upgrade;  	unsigned short op_s_clean; -	unsigned short op_s_dependsonly;  	unsigned short op_s_downloadonly;  	unsigned short op_s_info;  	unsigned short op_s_sync; @@ -67,15 +65,15 @@ typedef struct __config_t {  	unsigned short chomp; /* I Love Candy! */  	unsigned short usecolor; /* enable colorful output */  	unsigned short showsize; /* show individual package sizes */ -	unsigned short totaldownload; /* When downloading, display the amount -	                                 downloaded, rate, ETA, and percent -	                                 downloaded of the total download list */ +	/* When downloading, display the amount downloaded, rate, ETA, and percent +	 * downloaded of the total download list */ +	unsigned short totaldownload; +	unsigned short cleanmethod; /* select -Sc behavior */  } config_t;  /* Operations */  enum {  	PM_OP_MAIN = 1, -	PM_OP_ADD,  	PM_OP_REMOVE,  	PM_OP_UPGRADE,  	PM_OP_QUERY, @@ -83,6 +81,12 @@ enum {  	PM_OP_DEPTEST  }; +/* clean method */ +enum { +	PM_CLEAN_KEEPINST = 0, /* default */ +	PM_CLEAN_KEEPCUR +}; +  /* global config variable */  extern config_t *config; diff --git a/src/pacman/deptest.c b/src/pacman/deptest.c index 2481c0b6..2feca5c4 100644 --- a/src/pacman/deptest.c +++ b/src/pacman/deptest.c @@ -31,53 +31,23 @@  #include "util.h"  #include "conf.h" -/* TODO: This should use _alpm_checkdeps() */  int pacman_deptest(alpm_list_t *targets)  { -	int retval = 0;  	alpm_list_t *i; -	if(targets == NULL) { +	alpm_list_t *deps = alpm_deptest(alpm_option_get_localdb(), targets); +	if(deps == NULL) {  		return(0);  	} -	for(i = targets; i; i = alpm_list_next(i)) { -		int found = 0; -		pmpkg_t *pkg; -		pmdepend_t *dep; -		const char *target; -		alpm_list_t *j, *provides; +	for(i = deps; i; i = alpm_list_next(i)) { +		const char *dep; -		target = alpm_list_getdata(i); -		dep = alpm_splitdep(target); - -		pkg = alpm_db_get_pkg(alpm_option_get_localdb(), -				alpm_dep_get_name(dep)); -		if(pkg && alpm_depcmp(pkg, dep)) { -			found = 1; -		} else { -			/* not found, can we find anything that provides this in the local DB? */ -			provides = alpm_db_whatprovides(alpm_option_get_localdb(), -					alpm_dep_get_name(dep)); -			for(j = provides; j; j = alpm_list_next(j)) { -				pmpkg_t *pkg; -				pkg = alpm_list_getdata(j); - -				if(pkg && alpm_depcmp(pkg, dep)) { -					found = 1; -					break; -				} -			} -			alpm_list_free(provides); -		} - -		if(!found) { -			printf("%s\n", target); -			retval = 127; -		} -		free(dep); +		dep = alpm_list_getdata(i); +		printf("%s\n", dep);  	} -	return(retval); +	alpm_list_free(deps); +	return(127);  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index c2b61fcd..9468d51c 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -68,31 +68,27 @@ static void usage(int op, const char * const myname)  		printf("%s:\n", str_opt);  		printf("    %s {-h --help}\n", myname);  		printf("    %s {-V --version}\n", myname); -		printf("    %s {-A --add}     [%s] <%s>\n", myname, str_opt, str_file);  		printf("    %s {-Q --query}   [%s] [%s]\n", myname, str_opt, str_pkg);  		printf("    %s {-R --remove}  [%s] <%s>\n", myname, str_opt, str_pkg);  		printf("    %s {-S --sync}    [%s] [%s]\n", myname, str_opt, str_pkg);  		printf("    %s {-U --upgrade} [%s] <%s>\n", myname, str_opt, str_file);  		printf(_("\nuse '%s --help' with other options for more syntax\n"), myname);  	} else { -		if(op == PM_OP_ADD) { -			printf("%s:  %s {-A --add} [%s] <%s>\n", str_usg, myname, str_opt, str_file); -			printf("%s:\n", str_opt); -			printf(_("      --asdeps         install packages as non-explicitly installed\n")); -			printf(_("  -d, --nodeps         skip dependency checks\n")); -			printf(_("  -f, --force          force install, overwrite conflicting files\n")); -		} else if(op == PM_OP_REMOVE) { +		if(op == PM_OP_REMOVE) {  			printf("%s:  %s {-R --remove} [%s] <%s>\n", str_usg, myname, str_opt, str_pkg);  			printf("%s:\n", str_opt);  			printf(_("  -c, --cascade        remove packages and all packages that depend on them\n"));  			printf(_("  -d, --nodeps         skip dependency checks\n"));  			printf(_("  -k, --dbonly         only remove database entry, do not remove files\n"));  			printf(_("  -n, --nosave         remove configuration files as well\n")); -			printf(_("  -s, --recursive      remove dependencies also (that won't break packages)\n")); +			printf(_("  -s, --recursive      remove dependencies also (that won't break packages)\n" +				 "                       (-ss includes explicitly installed dependencies too)\n")); +			printf(_("  -u, --unneeded       remove unneeded packages (that won't break packages)\n"));  		} else if(op == PM_OP_UPGRADE) {  			printf("%s:  %s {-U --upgrade} [%s] <%s>\n", str_usg, myname, str_opt, str_file);  			printf("%s:\n", str_opt);  			printf(_("      --asdeps         install packages as non-explicitly installed\n")); +			printf(_("      --asexplicit     install packages as explicitly installed\n"));  			printf(_("  -d, --nodeps         skip dependency checks\n"));  			printf(_("  -f, --force          force install, overwrite conflicting files\n"));  		} else if(op == PM_OP_QUERY) { @@ -115,9 +111,9 @@ static void usage(int op, const char * const myname)  			printf("%s:  %s {-S --sync} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);  			printf("%s:\n", str_opt);  			printf(_("      --asdeps         install packages as non-explicitly installed\n")); +			printf(_("      --asexplicit     install packages as explicitly installed\n"));  			printf(_("  -c, --clean          remove old packages from cache directory (-cc for all)\n"));  			printf(_("  -d, --nodeps         skip dependency checks\n")); -			printf(_("  -e, --dependsonly    install dependencies only\n"));  			printf(_("  -f, --force          force install, overwrite conflicting files\n"));  			printf(_("  -g, --groups         view all members of a package group\n"));  			printf(_("  -i, --info           view package information\n")); @@ -212,7 +208,7 @@ static void cleanup(int ret) {   * in a consistant state.   * @param signum the thrown signal   */ -static void handler(int signum) +static RETSIGTYPE handler(int signum)  {  	if(signum==SIGSEGV)  	{ @@ -305,7 +301,6 @@ static int parseargs(int argc, char *argv[])  	int option_index = 0;  	static struct option opts[] =  	{ -		{"add",        no_argument,       0, 'A'},  		{"query",      no_argument,       0, 'Q'},  		{"remove",     no_argument,       0, 'R'},  		{"sync",       no_argument,       0, 'S'}, @@ -318,7 +313,6 @@ static int parseargs(int argc, char *argv[])  		{"clean",      no_argument,       0, 'c'},  		{"nodeps",     no_argument,       0, 'd'},  		{"deps",       no_argument,       0, 'd'}, -		{"dependsonly",no_argument,       0, 'e'},  		{"explicit",   no_argument,       0, 'e'},  		{"force",      no_argument,       0, 'f'},  		{"groups",     no_argument,       0, 'g'}, @@ -338,6 +332,7 @@ static int parseargs(int argc, char *argv[])  		{"unrequired", no_argument,       0, 't'},  		{"upgrades",   no_argument,       0, 'u'},  		{"sysupgrade", no_argument,       0, 'u'}, +		{"unneeded",   no_argument,       0, 'u'},  		{"verbose",    no_argument,       0, 'v'},  		{"downloadonly", no_argument,     0, 'w'},  		{"refresh",    no_argument,       0, 'y'}, @@ -352,10 +347,11 @@ static int parseargs(int argc, char *argv[])  		{"logfile",    required_argument, 0, 1009},  		{"ignoregroup", required_argument, 0, 1010},  		{"needed",     no_argument,       0, 1011}, +		{"asexplicit",     no_argument,   0, 1012},  		{0, 0, 0, 0}  	}; -	while((opt = getopt_long(argc, argv, "ARUFQSTr:b:vkhscVfmnoldepqituwygz", opts, &option_index))) { +	while((opt = getopt_long(argc, argv, "RUFQSTr:b:vkhscVfmnoldepqituwygz", opts, &option_index))) {  		alpm_list_t *list = NULL, *item = NULL; /* lists for splitting strings */  		if(opt < 0) { @@ -423,7 +419,9 @@ static int parseargs(int argc, char *argv[])  				FREELIST(list);  				break;  			case 1011: config->flags |= PM_TRANS_FLAG_NEEDED; break; -			case 'A': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_ADD); break; +			case 1012: +				config->flags |= PM_TRANS_FLAG_ALLEXPLICIT; +				break;  			case 'Q': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break;  			case 'R': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break;  			case 'S': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break; @@ -444,7 +442,6 @@ static int parseargs(int argc, char *argv[])  				break;  			case 'e':  				config->op_q_explicit = 1; -				config->flags |= PM_TRANS_FLAG_DEPENDSONLY;  				break;  			case 'f': config->flags |= PM_TRANS_FLAG_FORCE; break;  			case 'g': (config->group)++; break; @@ -468,7 +465,11 @@ static int parseargs(int argc, char *argv[])  			case 's':  				config->op_s_search = 1;  				config->op_q_search = 1; -				config->flags |= PM_TRANS_FLAG_RECURSE; +				if(config->flags & PM_TRANS_FLAG_RECURSE) { +					config->flags |= PM_TRANS_FLAG_RECURSEALL; +				} else { +					config->flags |= PM_TRANS_FLAG_RECURSE; +				}  				break;  			case 't':  				config->op_q_unrequired = 1; @@ -476,6 +477,7 @@ static int parseargs(int argc, char *argv[])  			case 'u':  				config->op_s_upgrade = 1;  				config->op_q_upgrade = 1; +				config->flags |= PM_TRANS_FLAG_UNNEEDED;  				break;  			case 'v': (config->verbose)++; break;  			case 'w': @@ -599,7 +601,7 @@ static int _parseconfig(const char *file, const char *givensection,  			}  		} else {  			/* directive */ -			char *key, *upperkey; +			char *key;  			/* strsep modifies the 'line' string: 'key \0 ptr' */  			key = line;  			ptr = line; @@ -612,11 +614,7 @@ static int _parseconfig(const char *file, const char *givensection,  						file, linenum);  				return(1);  			} -			/* For each directive, compare to the uppercase and camelcase string. -			 * This prevents issues with certain locales where characters don't -			 * follow the toupper() rules we may expect, e.g. tr_TR where i != I. -			 */ -			upperkey = strtoupper(strdup(key)); +			/* For each directive, compare to the camelcase string. */  			if(section == NULL) {  				pm_printf(PM_LOG_ERROR, _("config file %s, line %d: All directives must belong to a section.\n"),  						file, linenum); @@ -624,25 +622,25 @@ static int _parseconfig(const char *file, const char *givensection,  			}  			if(ptr == NULL && strcmp(section, "options") == 0) {  				/* directives without settings, all in [options] */ -				if(strcmp(key, "NoPassiveFTP") == 0 || strcmp(upperkey, "NOPASSIVEFTP") == 0) { +				if(strcmp(key, "NoPassiveFTP") == 0) {  					alpm_option_set_nopassiveftp(1);  					pm_printf(PM_LOG_DEBUG, "config: nopassiveftp\n"); -				} else if(strcmp(key, "UseSyslog") == 0 || strcmp(upperkey, "USESYSLOG") == 0) { +				} else if(strcmp(key, "UseSyslog") == 0) {  					alpm_option_set_usesyslog(1);  					pm_printf(PM_LOG_DEBUG, "config: usesyslog\n"); -				} else if(strcmp(key, "ILoveCandy") == 0 || strcmp(upperkey, "ILOVECANDY") == 0) { +				} else if(strcmp(key, "ILoveCandy") == 0) {  					config->chomp = 1;  					pm_printf(PM_LOG_DEBUG, "config: chomp\n"); -				} else if(strcmp(key, "UseColor") == 0 || strcmp(upperkey, "USECOLOR") == 0) { +				} else if(strcmp(key, "UseColor") == 0) {  					config->usecolor = 1;  					pm_printf(PM_LOG_DEBUG, "config: usecolor\n"); -				} else if(strcmp(key, "ShowSize") == 0 || strcmp(upperkey, "SHOWSIZE") == 0) { +				} else if(strcmp(key, "ShowSize") == 0) {  					config->showsize = 1;  					pm_printf(PM_LOG_DEBUG, "config: showsize\n"); -				} else if(strcmp(key, "UseDelta") == 0 || strcmp(upperkey, "USEDELTA") == 0) { +				} else if(strcmp(key, "UseDelta") == 0) {  					alpm_option_set_usedelta(1);  					pm_printf(PM_LOG_DEBUG, "config: usedelta\n"); -				} else if(strcmp(key, "TotalDownload") == 0 || strcmp(upperkey, "TOTALDOWNLOAD") == 0) { +				} else if(strcmp(key, "TotalDownload") == 0) {  					config->totaldownload = 1;  					pm_printf(PM_LOG_DEBUG, "config: totaldownload\n");  				} else { @@ -652,59 +650,64 @@ static int _parseconfig(const char *file, const char *givensection,  				}  			} else {  				/* directives with settings */ -				if(strcmp(key, "Include") == 0 || strcmp(upperkey, "INCLUDE") == 0) { +				if(strcmp(key, "Include") == 0) {  					pm_printf(PM_LOG_DEBUG, "config: including %s\n", ptr);  					_parseconfig(ptr, section, db);  					/* Ignore include failures... assume non-critical */  				} else if(strcmp(section, "options") == 0) { -					if(strcmp(key, "NoUpgrade") == 0 -							|| strcmp(upperkey, "NOUPGRADE") == 0) { +					if(strcmp(key, "NoUpgrade") == 0) {  						setrepeatingoption(ptr, "NoUpgrade", alpm_option_add_noupgrade); -					} else if(strcmp(key, "NoExtract") == 0 -							|| strcmp(upperkey, "NOEXTRACT") == 0) { +					} else if(strcmp(key, "NoExtract") == 0) {  						setrepeatingoption(ptr, "NoExtract", alpm_option_add_noextract); -					} else if(strcmp(key, "IgnorePkg") == 0 -							|| strcmp(upperkey, "IGNOREPKG") == 0) { +					} else if(strcmp(key, "IgnorePkg") == 0) {  						setrepeatingoption(ptr, "IgnorePkg", alpm_option_add_ignorepkg); -					} else if(strcmp(key, "IgnoreGroup") == 0 -							|| strcmp(upperkey, "IGNOREGROUP") == 0) { +					} else if(strcmp(key, "IgnoreGroup") == 0) {  						setrepeatingoption(ptr, "IgnoreGroup", alpm_option_add_ignoregrp); -					} else if(strcmp(key, "HoldPkg") == 0 -							|| strcmp(upperkey, "HOLDPKG") == 0) { +					} else if(strcmp(key, "HoldPkg") == 0) {  						setrepeatingoption(ptr, "HoldPkg", alpm_option_add_holdpkg); -					} else if(strcmp(key, "DBPath") == 0 || strcmp(upperkey, "DBPATH") == 0) { +					} else if(strcmp(key, "DBPath") == 0) {  						/* don't overwrite a path specified on the command line */  						if(!config->dbpath) {  							config->dbpath = strdup(ptr);  							pm_printf(PM_LOG_DEBUG, "config: dbpath: %s\n", ptr);  						} -					} else if(strcmp(key, "CacheDir") == 0 || strcmp(upperkey, "CACHEDIR") == 0) { +					} else if(strcmp(key, "CacheDir") == 0) {  						if(alpm_option_add_cachedir(ptr) != 0) {  							pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"),  									ptr, alpm_strerrorlast());  							return(1);  						}  						pm_printf(PM_LOG_DEBUG, "config: cachedir: %s\n", ptr); -					} else if(strcmp(key, "RootDir") == 0 || strcmp(upperkey, "ROOTDIR") == 0) { +					} else if(strcmp(key, "RootDir") == 0) {  						/* don't overwrite a path specified on the command line */  						if(!config->rootdir) {  							config->rootdir = strdup(ptr);  							pm_printf(PM_LOG_DEBUG, "config: rootdir: %s\n", ptr);  						} -					} else if (strcmp(key, "LogFile") == 0 || strcmp(upperkey, "LOGFILE") == 0) { +					} else if (strcmp(key, "LogFile") == 0) {  						if(!config->logfile) {  							config->logfile = strdup(ptr);  							pm_printf(PM_LOG_DEBUG, "config: logfile: %s\n", ptr);  						} -					} else if (strcmp(key, "XferCommand") == 0 || strcmp(upperkey, "XFERCOMMAND") == 0) { +					} else if (strcmp(key, "XferCommand") == 0) {  						alpm_option_set_xfercommand(ptr);  						pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", ptr); +					} else if (strcmp(key, "CleanMethod") == 0) { +						if (strcmp(ptr, "KeepInstalled") == 0) { +							config->cleanmethod = PM_CLEAN_KEEPINST; +						} else if (strcmp(ptr, "KeepCurrent") == 0) { +							config->cleanmethod = PM_CLEAN_KEEPCUR; +						} else { +							pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"), ptr); +							return(1); +						} +						pm_printf(PM_LOG_DEBUG, "config: cleanmethod: %s\n", ptr);  					} else {  						pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' not recognized.\n"),  								file, linenum, key);  						return(1);  					} -				} else if(strcmp(key, "Server") == 0 || strcmp(upperkey, "SERVER") == 0) { +				} else if(strcmp(key, "Server") == 0) {  					/* let's attempt a replacement for the current repo */  					char *server = strreplace(ptr, "$repo", section); @@ -720,7 +723,6 @@ static int _parseconfig(const char *file, const char *givensection,  					return(1);  				}  			} -			free(upperkey);  		}  	}  	fclose(fp); @@ -867,9 +869,6 @@ int main(int argc, char *argv[])  	/* start the requested operation */  	switch(config->op) { -		case PM_OP_ADD: -			ret = pacman_add(pm_targets); -			break;  		case PM_OP_REMOVE:  			ret = pacman_remove(pm_targets);  			break; diff --git a/src/pacman/pacman.h b/src/pacman/pacman.h index 9d23a89c..97d0301e 100644 --- a/src/pacman/pacman.h +++ b/src/pacman/pacman.h @@ -21,15 +21,14 @@  #include <alpm_list.h> -/* add.c, this should merge with upgrade.c */ -int pacman_add(alpm_list_t *targets); -int pacman_upgrade(alpm_list_t *targets); -/* sync.c */ -int pacman_sync(alpm_list_t *targets);  /* query.c */  int pacman_query(alpm_list_t *targets);  /* remove.c */  int pacman_remove(alpm_list_t *targets); +/* sync.c */ +int pacman_sync(alpm_list_t *targets); +/* upgrade.c */ +int pacman_upgrade(alpm_list_t *targets);  /* deptest.c */  int pacman_deptest(alpm_list_t *targets); diff --git a/src/pacman/query.c b/src/pacman/query.c index e999a328..b40359ed 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -1,7 +1,7 @@  /*   *  query.c   * - *  Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org> + *  Copyright (c) 2002-2008 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 @@ -119,8 +119,13 @@ static int query_fileowner(alpm_list_t *targets)  				free(pdname);  				if(ppath && strcmp(ppath, rpath) == 0) { -					printf(_("%s is owned by %s %s\n"), filename, -					       alpm_pkg_get_name(info), alpm_pkg_get_version(info)); +					if (!config->quiet) { +						printf(_("%s is owned by %s %s\n"), filename, +								alpm_pkg_get_name(info), alpm_pkg_get_version(info)); +					} else { +						printf("%s %s\n", alpm_pkg_get_name(info), +								alpm_pkg_get_version(info)); +					}  					found = 1;  				}  				free(ppath); @@ -155,7 +160,6 @@ static int query_search(alpm_list_t *targets)  	}  	for(i = searchlist; i; i = alpm_list_next(i)) { -		char *group = NULL;  		alpm_list_t *grp;  		pmpkg_t *pkg = alpm_list_getdata(i); @@ -176,8 +180,17 @@ static int query_search(alpm_list_t *targets)  		if (!config->quiet) {  			if((grp = alpm_pkg_get_groups(pkg)) != NULL) { -				group = alpm_list_getdata(grp); -				printf(" (%s)", (char *)alpm_list_getdata(grp)); +				alpm_list_t *k; +				printf(" ("); +				for(k = grp; k; k = alpm_list_next(k)) { +					const char *group = alpm_list_getdata(k); +					printf("%s", group); +					if(alpm_list_next(k)) { +						/* only print a spacer if there are more groups */ +						printf(" "); +					} +				} +				printf(")");  			}  			/* we need a newline and initial indent first */ @@ -197,33 +210,33 @@ static int query_search(alpm_list_t *targets)  static int query_group(alpm_list_t *targets)  {  	alpm_list_t *i, *j; -	char *package = NULL; +	char *grpname = NULL;  	int ret = 0;  	if(targets == NULL) {  		for(j = alpm_db_getgrpcache(db_local); j; j = alpm_list_next(j)) {  			pmgrp_t *grp = alpm_list_getdata(j); -			const alpm_list_t *p, *pkgnames; +			const alpm_list_t *p, *packages;  			const char *grpname;  			grpname = alpm_grp_get_name(grp); -			pkgnames = alpm_grp_get_pkgs(grp); +			packages = alpm_grp_get_pkgs(grp); -			for(p = pkgnames; p; p = alpm_list_next(p)) { -				printf("%s %s\n", grpname, (char *)alpm_list_getdata(p)); +			for(p = packages; p; p = alpm_list_next(p)) { +				printf("%s %s\n", grpname, alpm_pkg_get_name(alpm_list_getdata(p)));  			}  		}  	} else {  		for(i = targets; i; i = alpm_list_next(i)) {  			pmgrp_t *grp; -			package = alpm_list_getdata(i); -			grp = alpm_db_readgrp(db_local, package); +			grpname = alpm_list_getdata(i); +			grp = alpm_db_readgrp(db_local, grpname);  			if(grp) { -				const alpm_list_t *p, *pkgnames = alpm_grp_get_pkgs(grp); -				for(p = pkgnames; p; p = alpm_list_next(p)) { -					printf("%s %s\n", package, (char *)alpm_list_getdata(p)); +				const alpm_list_t *p, *packages = alpm_grp_get_pkgs(grp); +				for(p = packages; p; p = alpm_list_next(p)) { +					printf("%s %s\n", grpname, alpm_pkg_get_name(alpm_list_getdata(p)));  				}  			} else { -				fprintf(stderr, _("error: group \"%s\" was not found\n"), package); +				fprintf(stderr, _("error: group \"%s\" was not found\n"), grpname);  				ret++;  			}  		} diff --git a/src/pacman/remove.c b/src/pacman/remove.c index e3750e4c..a2209ac6 100644 --- a/src/pacman/remove.c +++ b/src/pacman/remove.c @@ -29,24 +29,10 @@  /* pacman */  #include "pacman.h"  #include "util.h" -#include "callback.h"  #include "conf.h"  extern pmdb_t *db_local; -/* Free the current transaction and print an error if unsuccessful */ -static int remove_cleanup(void) -{ -	int ret = alpm_trans_release(); -	if(ret != 0) { -		pm_printf(PM_LOG_ERROR, _("failed to release transaction (%s)\n"), -		        alpm_strerrorlast()); -		ret = 1; -	} - -	return(ret); -} -  /**   * @brief Remove a specified list of packages.   * @@ -75,11 +61,11 @@ int pacman_remove(alpm_list_t *targets)  			printf(_(":: group %s:\n"), alpm_grp_get_name(grp));  			list_display("   ", pkgnames); -			all = yesno(_("    Remove whole content? [Y/n] ")); +			all = yesno(1, _("    Remove whole content?"));  			for(p = pkgnames; p; p = alpm_list_next(p)) {  				char *pkg = alpm_list_getdata(p); -				if(all || yesno(_(":: Remove %s from group %s? [Y/n] "), pkg, (char *)alpm_list_getdata(i))) { +				if(all || yesno(1, _(":: Remove %s from group %s?"), pkg, (char *)alpm_list_getdata(i))) {  					finaltargs = alpm_list_add(finaltargs, strdup(pkg));  				}  			} @@ -90,14 +76,7 @@ int pacman_remove(alpm_list_t *targets)  	}  	/* Step 1: create a new transaction */ -	if(alpm_trans_init(PM_TRANS_TYPE_REMOVE, config->flags, -	   cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) { -		fprintf(stderr, _("error: failed to init transaction (%s)\n"), -		        alpm_strerrorlast()); -		if(pm_errno == PM_ERR_HANDLE_LOCK) { -			printf(_("  if you're sure a package manager is not already\n" -			         "  running, you can remove %s.\n"), alpm_option_get_lockfile()); -		} +	if(trans_init(PM_TRANS_TYPE_REMOVE, config->flags) == -1) {  		FREELIST(finaltargs);  		return(1);  	} @@ -109,7 +88,7 @@ int pacman_remove(alpm_list_t *targets)  		if(alpm_trans_addtarget(targ) == -1) {  			fprintf(stderr, _("error: '%s': %s\n"),  					targ, alpm_strerrorlast()); -			remove_cleanup(); +			trans_release();  			FREELIST(finaltargs);  			return(1);  		} @@ -134,7 +113,7 @@ int pacman_remove(alpm_list_t *targets)  			default:  				break;  		} -		remove_cleanup(); +		trans_release();  		FREELIST(finaltargs);  		return(1);  	} @@ -153,8 +132,8 @@ int pacman_remove(alpm_list_t *targets)  		list_display(_("Targets:"), lst);  		FREELIST(lst);  		/* get confirmation */ -		if(yesno(_("\nDo you want to remove these packages? [Y/n] ")) == 0) { -			remove_cleanup(); +		if(yesno(1, _("\nDo you want to remove these packages?")) == 0) { +			trans_release();  			FREELIST(finaltargs);  			return(1);  		} @@ -165,13 +144,15 @@ int pacman_remove(alpm_list_t *targets)  	if(alpm_trans_commit(NULL) == -1) {  		fprintf(stderr, _("error: failed to commit transaction (%s)\n"),  		        alpm_strerrorlast()); -		remove_cleanup(); +		trans_release();  		FREELIST(finaltargs);  		return(1);  	}  	/* Step 4: release transaction resources */ -	retval = remove_cleanup(); +	if(trans_release() == -1) { +		retval = 1; +	}  	FREELIST(finaltargs);  	return(retval);  } diff --git a/src/pacman/sync.c b/src/pacman/sync.c index e3e87703..77b66da5 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -29,15 +29,11 @@  #include <alpm.h>  #include <alpm_list.h> -#include <download.h> /* downloadLastErrString */ -/* TODO remove above download.h inclusion once we abstract more, and also - * remove it from Makefile.am on the pacman side */  /* pacman */  #include "pacman.h"  #include "util.h"  #include "package.h" -#include "callback.h"  #include "conf.h"  extern pmdb_t *db_local; @@ -89,7 +85,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) {  		/* We have a directory that doesn't match any syncdb.  		 * Ask the user if he wants to remove it. */  		if(!found) { -			if(!yesno(_("Do you want to remove %s? [Y/n] "), path)) { +			if(!yesno(1, _("Do you want to remove %s?"), path)) {  				continue;  			} @@ -108,7 +104,7 @@ static int sync_cleandb_all(void) {  	char newdbpath[PATH_MAX];  	printf(_("Database directory: %s\n"), dbpath); -	if(!yesno(_("Do you want to remove unused repositories? [Y/n] "))) { +	if(!yesno(1, _("Do you want to remove unused repositories?"))) {  		return(0);  	}  	/* The sync dbs were previously put in dbpath/, but are now in dbpath/sync/, @@ -133,13 +129,23 @@ static int sync_cleancache(int level)  		/* incomplete cleanup */  		DIR *dir;  		struct dirent *ent; -		/* Let's vastly improve the way this is done. Before, we went by package -		 * name. Instead, let's only keep packages we have installed. Open up each -		 * package and see if it has an entry in the local DB; if not, delete it. -		 */ +		/* Open up each package and see if it should be deleted, +		 * depending on the clean method used */  		printf(_("Cache directory: %s\n"), cachedir); -		if(!yesno(_("Do you want to remove uninstalled packages from cache? [Y/n] "))) { -			return(0); +		switch(config->cleanmethod) { +			case PM_CLEAN_KEEPINST: +				if(!yesno(1, _("Do you want to remove uninstalled packages from cache?"))) { +					return(0); +				} +				break; +			case PM_CLEAN_KEEPCUR: +				if(!yesno(1, _("Do you want to remove outdated packages from cache?"))) { +					return(0); +				} +				break; +			default: +				/* this should not happen : the config parsing doesn't set any other value */ +				return(1);  		}  		printf(_("removing old packages from cache... ")); @@ -153,13 +159,16 @@ static int sync_cleancache(int level)  		/* step through the directory one file at a time */  		while((ent = readdir(dir)) != NULL) {  			char path[PATH_MAX]; -			pmpkg_t *localpkg = NULL, *dbpkg = NULL; +			int delete = 1; +			pmpkg_t *localpkg = NULL, *pkg = NULL; +			alpm_list_t *sync_dbs = alpm_option_get_syncdbs(); +			alpm_list_t *j;  			if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {  				continue;  			}  			/* build the full filepath */ -			snprintf(path, PATH_MAX, "%s/%s", cachedir, ent->d_name); +			snprintf(path, PATH_MAX, "%s%s", cachedir, ent->d_name);  			/* attempt to load the package, skip file on failures as we may have  			 * files here that aren't valid packages. we also don't need a full @@ -167,25 +176,45 @@ static int sync_cleancache(int level)  			if(alpm_pkg_load(path, 0, &localpkg) != 0 || localpkg == NULL) {  				continue;  			} -			/* check if this package is in the local DB */ -			dbpkg = alpm_db_get_pkg(db_local, alpm_pkg_get_name(localpkg)); -			if(dbpkg == NULL) { -				/* delete package, not present in local DB */ -				unlink(path); -			} else if(alpm_pkg_vercmp(alpm_pkg_get_version(localpkg), -							alpm_pkg_get_version(dbpkg)) != 0) { -				/* delete package, it was found but version differs */ -				unlink(path); +			switch(config->cleanmethod) { +				case PM_CLEAN_KEEPINST: +					/* check if this package is in the local DB */ +					pkg = alpm_db_get_pkg(db_local, alpm_pkg_get_name(localpkg)); +					if(pkg != NULL && alpm_pkg_vercmp(alpm_pkg_get_version(localpkg), +								alpm_pkg_get_version(pkg)) == 0) { +						/* package was found in local DB and version matches, keep it */ +						delete = 0; +					} +					break; +				case PM_CLEAN_KEEPCUR: +					/* check if this package is in a sync DB */ +					for(j = sync_dbs; j && delete; j = alpm_list_next(j)) { +						pmdb_t *db = alpm_list_getdata(j); +						pkg = alpm_db_get_pkg(db, alpm_pkg_get_name(localpkg)); +						if(pkg != NULL && alpm_pkg_vercmp(alpm_pkg_get_version(localpkg), +									alpm_pkg_get_version(pkg)) == 0) { +							/* package was found in a sync DB and version matches, keep it */ +							delete = 0; +						} +					} +					break; +				default: +					/* this should not happen : the config parsing doesn't set any other value */ +					delete = 0; +					break;  			} -			/* else version was the same, so keep the package */  			/* free the local file package */  			alpm_pkg_free(localpkg); + +			if(delete) { +				unlink(path); +			}  		}  		printf(_("done.\n"));  	} else {  		/* full cleanup */  		printf(_("Cache directory: %s\n"), cachedir); -		if(!yesno(_("Do you want to remove ALL packages from cache? [Y/n] "))) { +		if(!yesno(0, _("Do you want to remove ALL packages from cache?"))) {  			return(0);  		}  		printf(_("removing all packages from cache... ")); @@ -205,52 +234,22 @@ static int sync_cleancache(int level)  	return(0);  } -static int sync_trans_init(pmtransflag_t flags) { -	if(alpm_trans_init(PM_TRANS_TYPE_SYNC, flags, cb_trans_evt, -				cb_trans_conv, cb_trans_progress) == -1) { -		fprintf(stderr, _("error: failed to init transaction (%s)\n"), -				alpm_strerrorlast()); -		if(pm_errno == PM_ERR_HANDLE_LOCK) { -			printf(_("  if you're sure a package manager is not already\n" -						"  running, you can remove %s.\n"), alpm_option_get_lockfile()); -		} -		return(-1); -	} -	return(0); -} - -static int sync_trans_release() { -	if(alpm_trans_release() == -1) { -		fprintf(stderr, _("error: failed to release transaction (%s)\n"), -				alpm_strerrorlast()); -		return(-1); -	} -	return(0); -}  static int sync_synctree(int level, alpm_list_t *syncs)  {  	alpm_list_t *i;  	int success = 0, ret; +	if(trans_init(PM_TRANS_TYPE_SYNC, 0) == -1) { +		return(0); +	} +  	for(i = syncs; i; i = alpm_list_next(i)) {  		pmdb_t *db = alpm_list_getdata(i);  		ret = alpm_db_update((level < 2 ? 0 : 1), db);  		if(ret < 0) { -			if(pm_errno == PM_ERR_DB_SYNC) { -				/* use libdownload error */ -				/* TODO breaking abstraction barrier here? -				 *			pacman -> libalpm -> libdownload -				 * -				 * Yes.  This will be here until we add a nice pacman "pm_errstr" or -				 * something, OR add all libdownload error codes into the pm_error enum -				 */ -				fprintf(stderr, _("error: failed to synchronize %s: %s\n"), -				        alpm_db_get_name(db), downloadLastErrString); -			} else { -				fprintf(stderr, _("error: failed to update %s (%s)\n"), -				        alpm_db_get_name(db), alpm_strerrorlast()); -			} +			fprintf(stderr, _("error: failed to update %s (%s)\n"), +					alpm_db_get_name(db), alpm_strerrorlast());  		} else if(ret == 1) {  			printf(_(" %s is up to date\n"), alpm_db_get_name(db));  			success++; @@ -259,10 +258,16 @@ static int sync_synctree(int level, alpm_list_t *syncs)  		}  	} +	if(trans_release() == -1) { +		return(0); +	}  	/* We should always succeed if at least one DB was upgraded - we may possibly  	 * fail later with unresolved deps, but that should be rare, and would be  	 * expected  	 */ +	if(!success) { +		fprintf(stderr, _("error: failed to synchronize any databases\n")); +	}  	return(success > 0);  } @@ -289,8 +294,6 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)  			found = 1;  		}  		for(j = ret; j; j = alpm_list_next(j)) { -			/* print repo/name (group) info about each package in our list */ -			char *group = NULL;  			alpm_list_t *grp;  			pmpkg_t *pkg = alpm_list_getdata(j); @@ -311,8 +314,17 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)  			if (!config->quiet) {  				if((grp = alpm_pkg_get_groups(pkg)) != NULL) { -					group = alpm_list_getdata(grp); -					printf(" (%s)", (char *)alpm_list_getdata(grp)); +					alpm_list_t *k; +					printf(" ("); +					for(k = grp; k; k = alpm_list_next(k)) { +						const char *group = alpm_list_getdata(k); +						printf("%s", group); +						if(alpm_list_next(k)) { +							/* only print a spacer if there are more groups */ +							printf(" "); +						} +					} +					printf(")");  				}  				/* we need a newline and initial indent first */ @@ -332,7 +344,8 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)  static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)  { -	alpm_list_t *i, *j; +	alpm_list_t *i, *j, *k; +	alpm_list_t *pkgnames = NULL;  	if(targets) {  		for(i = targets; i; i = alpm_list_next(i)) { @@ -342,9 +355,14 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)  				pmgrp_t *grp = alpm_db_readgrp(db, grpname);  				if(grp) { -					/* TODO this should be a lot cleaner, why two outputs? */  					printf("%s\n", (char *)alpm_grp_get_name(grp)); -					list_display("   ", alpm_grp_get_pkgs(grp)); +					/* get names of packages in group */ +					for(k = alpm_grp_get_pkgs(grp); k; k = alpm_list_next(k)) { +						pkgnames = alpm_list_add(pkgnames, +								(char*)alpm_pkg_get_name(k->data)); +					} +					list_display("   ", pkgnames); +					alpm_list_free(pkgnames);  				}  			}  		} @@ -357,7 +375,12 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)  				printf("%s\n", (char *)alpm_grp_get_name(grp));  				if(grp && level > 1) { -					list_display("   ", alpm_grp_get_pkgs(grp)); +					for(k = alpm_grp_get_pkgs(grp); k; k = alpm_list_next(k)) { +						pkgnames = alpm_list_add(pkgnames, +								(char*)alpm_pkg_get_name(k->data)); +					} +					list_display("   ", pkgnames); +					alpm_list_free(pkgnames);  				}  			}  		} @@ -499,34 +522,19 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)  	return(0);  } -static int sync_trans(alpm_list_t *targets, int sync_only) +static int sync_trans(alpm_list_t *targets)  {  	int retval = 0;  	alpm_list_t *data = NULL;  	alpm_list_t *sync_dbs = alpm_option_get_syncdbs();  	/* Step 1: create a new transaction... */ -	if(sync_trans_init(config->flags) == -1) { +	if(trans_init(PM_TRANS_TYPE_SYNC, config->flags) == -1) {  		return(1);  	} -	if(config->op_s_sync) { -		/* grab a fresh package list */ -		printf(_(":: Synchronizing package databases...\n")); -		alpm_logaction("synchronizing package lists\n"); -		if(!sync_synctree(config->op_s_sync, sync_dbs)) { -			fprintf(stderr, _("error: failed to synchronize any databases\n")); -			retval = 1; -			goto cleanup; -		} -		if(sync_only) { -			goto cleanup; -		} -	} -  	if(config->op_s_upgrade) {  		alpm_list_t *pkgs, *i; -  		printf(_(":: Starting full system upgrade...\n"));  		alpm_logaction("starting full system upgrade\n");  		if(alpm_trans_sysupgrade() == -1) { @@ -550,12 +558,12 @@ static int sync_trans(alpm_list_t *targets, int sync_only)  				if(strcmp("pacman", alpm_pkg_get_name(spkg)) == 0) {  					printf("\n");  					printf(_(":: pacman has detected a newer version of itself.\n")); -					if(yesno(_(":: Do you want to cancel the current operation\n" -					           ":: and install the new pacman version now? [Y/n] "))) { -						if(sync_trans_release() == -1) { +					if(yesno(1, _(":: Do you want to cancel the current operation\n" +					           ":: and install the new pacman version now?"))) { +						if(trans_release() == -1) {  							return(1);  						} -						if(sync_trans_init(0) == -1) { +						if(trans_init(PM_TRANS_TYPE_SYNC, 0) == -1) {  							return(1);  						}  						if(alpm_trans_addtarget("pacman") == -1) { @@ -594,26 +602,31 @@ static int sync_trans(alpm_list_t *targets, int sync_only)  					pmdb_t *db = alpm_list_getdata(j);  					grp = alpm_db_readgrp(db, targ);  					if(grp) { -						alpm_list_t *k; +						alpm_list_t *k, *pkgnames = NULL;  						found++;  						printf(_(":: group %s (including ignored packages):\n"), targ);  						/* remove dupe entries in case a package exists in multiple repos */ -						const alpm_list_t *grppkgs = alpm_grp_get_pkgs(grp); +						alpm_list_t *grppkgs = alpm_grp_get_pkgs(grp);  						alpm_list_t *pkgs = alpm_list_remove_dupes(grppkgs); -						list_display("   ", pkgs); -						if(yesno(_(":: Install whole content? [Y/n] "))) { -							for(k = pkgs; k; k = alpm_list_next(k)) { +						for(k = pkgs; k; k = alpm_list_next(k)) { +							pkgnames = alpm_list_add(pkgnames, +									(char*)alpm_pkg_get_name(k->data)); +						} +						list_display("   ", pkgnames); +						if(yesno(1, _(":: Install whole content?"))) { +							for(k = pkgnames; k; k = alpm_list_next(k)) {  								targets = alpm_list_add(targets, strdup(alpm_list_getdata(k)));  							}  						} else { -							for(k = pkgs; k; k = alpm_list_next(k)) { +							for(k = pkgnames; k; k = alpm_list_next(k)) {  								char *pkgname = alpm_list_getdata(k); -								if(yesno(_(":: Install %s from group %s? [Y/n] "), pkgname, targ)) { +								if(yesno(1, _(":: Install %s from group %s?"), pkgname, targ)) {  									targets = alpm_list_add(targets, strdup(pkgname));  								}  							}  						} +						alpm_list_free(pkgnames);  						alpm_list_free(pkgs);  					}  				} @@ -698,19 +711,9 @@ static int sync_trans(alpm_list_t *targets, int sync_only)  		printf("\n");  		if(config->op_s_downloadonly) { -			if(config->noconfirm) { -				printf(_("Beginning download...\n")); -				confirm = 1; -			} else { -				confirm = yesno(_("Proceed with download? [Y/n] ")); -			} +			confirm = yesno(1, _("Proceed with download?"));  		} else { -			if(config->noconfirm) { -				printf(_("Beginning upgrade process...\n")); -				confirm = 1; -			} else { -				confirm = yesno(_("Proceed with installation? [Y/n] ")); -			} +			confirm = yesno(1, _("Proceed with installation?"));  		}  		if(!confirm) {  			goto cleanup; @@ -741,9 +744,11 @@ static int sync_trans(alpm_list_t *targets, int sync_only)  					}  				}  				break; -			case PM_ERR_PKG_CORRUPTED: +			case PM_ERR_PKG_INVALID: +			case PM_ERR_DLT_INVALID:  				for(i = data; i; i = alpm_list_next(i)) { -					printf("%s", (char*)alpm_list_getdata(i)); +					char *filename = alpm_list_getdata(i); +					printf(_("%s is invalid or corrupted\n"), filename);  				}  				break;  			default: @@ -760,7 +765,7 @@ cleanup:  	if(data) {  		FREELIST(data);  	} -	if(sync_trans_release() == -1) { +	if(trans_release() == -1) {  		retval = 1;  	} @@ -770,20 +775,19 @@ cleanup:  int pacman_sync(alpm_list_t *targets)  {  	alpm_list_t *sync_dbs = NULL; -	int sync_only = 0;  	/* clean the cache */  	if(config->op_s_clean) {  		int ret = 0; -		if(sync_trans_init(0) == -1) { +		if(trans_init(PM_TRANS_TYPE_SYNC, 0) == -1) {  			return(1);  		}  		ret += sync_cleancache(config->op_s_clean);  		ret += sync_cleandb_all(); -		if(sync_trans_release() == -1) { +		if(trans_release() == -1) {  			ret++;  		} @@ -797,18 +801,27 @@ int pacman_sync(alpm_list_t *targets)  		return(1);  	} -	if(config->op_s_search || config->group -			|| config->op_s_info || config->op_q_list) { -		sync_only = 1; -	} else if(targets == NULL && !(config->op_s_sync || config->op_s_upgrade)) { +	if(targets == NULL && !(config->op_s_sync || config->op_s_upgrade +				|| config->op_s_search || config->group +				|| config->op_s_info || config->op_q_list)) {  		/* don't proceed here unless we have an operation that doesn't require  		 * a target list */  		pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));  		return(1);  	} +	if(config->op_s_sync) { +		/* grab a fresh package list */ +		printf(_(":: Synchronizing package databases...\n")); +		alpm_logaction("synchronizing package lists\n"); +		if(!sync_synctree(config->op_s_sync, sync_dbs)) { +			return(1); +		} +		config->op_s_sync = 0; +	} +  	if(needs_transaction()) { -		if(sync_trans(targets, sync_only) == 1) { +		if(sync_trans(targets) == 1) {  			return(1);  		}  	} diff --git a/src/pacman/add.c b/src/pacman/upgrade.c index fd40f005..589970ed 100644 --- a/src/pacman/add.c +++ b/src/pacman/upgrade.c @@ -1,5 +1,5 @@  /* - *  add.c + *  upgrade.c   *   *  Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>   * @@ -28,23 +28,9 @@  /* pacman */  #include "pacman.h" -#include "callback.h"  #include "conf.h"  #include "util.h" -/* Free the current transaction and print an error if unsuccessful */ -static int add_cleanup(void) -{ -	int ret = alpm_trans_release(); -	if(ret != 0) { -		pm_printf(PM_LOG_ERROR, _("failed to release transaction (%s)\n"), -		        alpm_strerrorlast()); -		ret = 1; -	} - -	return(ret); -} -  /**   * @brief Upgrade a specified list of packages.   * @@ -54,23 +40,8 @@ static int add_cleanup(void)   */  int pacman_upgrade(alpm_list_t *targets)  { -	/* this is basically just a remove-then-add process. pacman_add() will */ -	/* handle it */ -	config->upgrade = 1; -	return(pacman_add(targets)); -} - -/** - * @brief Add a specified list of packages which cannot already be installed. - * - * @param targets a list of packages (as strings) to add - * - * @return 0 on success, 1 on failure - */ -int pacman_add(alpm_list_t *targets) -{  	alpm_list_t *i, *data = NULL; -	pmtranstype_t transtype = PM_TRANS_TYPE_ADD; +	pmtranstype_t transtype = PM_TRANS_TYPE_UPGRADE;  	int retval = 0;  	if(targets == NULL) { @@ -93,20 +64,7 @@ int pacman_add(alpm_list_t *targets)  	}  	/* Step 1: create a new transaction */ -	if(config->upgrade == 1) { -		/* if upgrade flag was set, change this to an upgrade transaction */ -		transtype = PM_TRANS_TYPE_UPGRADE; -	} - -	if(alpm_trans_init(transtype, config->flags, cb_trans_evt, -	   cb_trans_conv, cb_trans_progress) == -1) { -		/* TODO: error messages should be in the front end, not the back */ -		fprintf(stderr, _("error: %s\n"), alpm_strerrorlast()); -		if(pm_errno == PM_ERR_HANDLE_LOCK) { -			/* TODO this and the 2 other places should probably be on stderr */ -			printf(_("  if you're sure a package manager is not already\n" -			         "  running, you can remove %s.\n"), alpm_option_get_lockfile()); -		} +	if(trans_init(transtype, config->flags) == -1) {  		return(1);  	} @@ -117,7 +75,7 @@ int pacman_add(alpm_list_t *targets)  		if(alpm_trans_addtarget(targ) == -1) {  			fprintf(stderr, _("error: '%s': %s\n"),  					targ, alpm_strerrorlast()); -			add_cleanup(); +			trans_release();  			return(1);  		}  	} @@ -171,7 +129,7 @@ int pacman_add(alpm_list_t *targets)  			default:  				break;  		} -		add_cleanup(); +		trans_release();  		FREELIST(data);  		return(1);  	} @@ -180,11 +138,13 @@ int pacman_add(alpm_list_t *targets)  	/* Step 3: perform the installation */  	if(alpm_trans_commit(NULL) == -1) {  		fprintf(stderr, _("error: failed to commit transaction (%s)\n"), alpm_strerrorlast()); -		add_cleanup(); +		trans_release();  		return(1);  	} -	retval = add_cleanup(); +	if(trans_release() == -1) { +		retval = 1; +	}  	return(retval);  } diff --git a/src/pacman/util.c b/src/pacman/util.c index 0facfdd1..9617e6f2 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -42,6 +42,33 @@  /* pacman */  #include "util.h"  #include "conf.h" +#include "callback.h" + + +int trans_init(pmtranstype_t type, pmtransflag_t flags) +{ +	if(alpm_trans_init(type, flags, cb_trans_evt, +				cb_trans_conv, cb_trans_progress) == -1) { +		fprintf(stderr, _("error: failed to init transaction (%s)\n"), +				alpm_strerrorlast()); +		if(pm_errno == PM_ERR_HANDLE_LOCK) { +			fprintf(stderr, _("  if you're sure a package manager is not already\n" +						"  running, you can remove %s\n"), alpm_option_get_lockfile()); +		} +		return(-1); +	} +	return(0); +} + +int trans_release() +{ +	if(alpm_trans_release() == -1) { +		fprintf(stderr, _("error: failed to release transaction (%s)\n"), +				alpm_strerrorlast()); +		return(-1); +	} +	return(0); +}  int needs_transaction()  { @@ -234,6 +261,10 @@ void indentprint(const char *str, int indent)  	p = wcstr;  	cidx = indent; +	if(!p) { +		return; +	} +  	while(*p) {  		if(*p == L' ') {  			const wchar_t *q, *next; @@ -464,25 +495,22 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local)  		pmsyncpkg_t *sync = alpm_list_getdata(i);  		pmpkg_t *pkg = alpm_sync_get_pkg(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); +		/* The removes member contains a list of packages to be removed +		 * due to the package that is being installed. */ +		alpm_list_t *to_replace = alpm_sync_get_removes(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); +		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)) { -					rsize += alpm_pkg_get_isize(rp); -					to_remove = alpm_list_add(to_remove, strdup(name)); -				} +			if(!alpm_list_find_str(to_remove, name)) { +				rsize += alpm_pkg_get_isize(rp); +				to_remove = alpm_list_add(to_remove, strdup(name));  			}  		}  		dispsize = alpm_pkg_get_size(pkg); -		dlsize += alpm_pkg_download_size(pkg, db_local); +		dlsize += alpm_pkg_download_size(pkg);  		isize += alpm_pkg_get_isize(pkg);  		/* print the package size with the output if ShowSize option set */ @@ -520,38 +548,50 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local)  	printf("\n");  	printf(_("Total Download Size:    %.2f MB\n"), mbdlsize); - -	/* TODO because all pkgs don't include isize, this is a crude hack */ -	if(mbisize > mbdlsize) { -		printf(_("Total Installed Size:   %.2f MB\n"), mbisize); -	} +	printf(_("Total Installed Size:   %.2f MB\n"), mbisize);  	FREELIST(targets);  }  /* presents a prompt and gets a Y/N answer */ -/* TODO there must be a better way */ -int yesno(char *fmt, ...) +int yesno(short preset, char *fmt, ...)  {  	char response[32];  	va_list args; +	FILE *stream;  	if(config->noconfirm) { -		return(1); +		stream = stdout; +	} else { +		/* Use stderr so questions are always displayed when redirecting output */ +		stream = stderr;  	}  	va_start(args, fmt); -	/* Use stderr so questions are always displayed when redirecting output */ -	vfprintf(stderr, fmt, args); +	vfprintf(stream, fmt, args);  	va_end(args); +	if(preset) { +		fprintf(stream, " %s ", _("[Y/n]")); +	} else { +		fprintf(stream, " %s ", _("[y/N]")); +	} + +	if(config->noconfirm) { +		fprintf(stream, "\n"); +		return(preset); +	} +  	if(fgets(response, 32, stdin)) { -		if(strlen(response) != 0) { -			strtrim(response); +		strtrim(response); +		if(strlen(response) == 0) { +			return(preset);  		} -		if(!strcasecmp(response, _("Y")) || !strcasecmp(response, _("YES")) || strlen(response) == 0) { +		if(!strcasecmp(response, _("Y")) || !strcasecmp(response, _("YES"))) {  			return(1); +		} else if (!strcasecmp(response, _("N")) || !strcasecmp(response, _("NO"))) { +			return(0);  		}  	}  	return(0); diff --git a/src/pacman/util.h b/src/pacman/util.h index 0273512e..722e4ab6 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -36,6 +36,8 @@  /* update speed for the fill_progress based functions */  #define UPDATE_SPEED_SEC 0.2f +int trans_init(pmtranstype_t type, pmtransflag_t flags); +int trans_release();  int needs_transaction();  int getcols();  int makepath(const char *path); @@ -50,7 +52,7 @@ alpm_list_t *strsplit(const char *str, const char splitchar);  void string_display(const char *title, const char *string);  void list_display(const char *title, const alpm_list_t *list);  void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local); -int yesno(char *fmt, ...); +int yesno(short preset, char *fmt, ...);  int pm_printf(pmloglevel_t level, const char *format, ...) __attribute__((format(printf,2,3)));  int pm_fprintf(FILE *stream, pmloglevel_t level, const char *format, ...) __attribute__((format(printf,3,4)));  int pm_vfprintf(FILE *stream, pmloglevel_t level, const char *format, va_list args) __attribute__((format(printf,3,0))); | 
