forked from mirrors/pacman
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			morganamil
			...
			morganamil
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					689223f40d | 
@@ -57,7 +57,7 @@ int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg)
 | 
			
		||||
	ASSERT(pkg->origin == ALPM_PKG_FROM_SYNCDB,
 | 
			
		||||
			RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1));
 | 
			
		||||
 | 
			
		||||
	fpath = _alpm_filecache_find(pkg->handle, pkg->filename);
 | 
			
		||||
	fpath = _alpm_cache_find_pkg(pkg, 0);
 | 
			
		||||
 | 
			
		||||
	retval = _alpm_test_checksum(fpath, pkg->md5sum, ALPM_PKG_VALIDATION_MD5SUM);
 | 
			
		||||
 | 
			
		||||
@@ -283,7 +283,7 @@ int SYMEXPORT alpm_pkg_get_sig(alpm_pkg_t *pkg, unsigned char **sig, size_t *sig
 | 
			
		||||
		alpm_errno_t err;
 | 
			
		||||
		int ret = -1;
 | 
			
		||||
 | 
			
		||||
		pkgpath = _alpm_filecache_find(pkg->handle, pkg->filename);
 | 
			
		||||
		pkgpath = _alpm_cache_find_pkg(pkg, 0);
 | 
			
		||||
		if(!pkgpath) {
 | 
			
		||||
			GOTO_ERR(pkg->handle, ALPM_ERR_PKG_NOT_FOUND, cleanup);
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -323,7 +323,7 @@ static int compute_download_size(alpm_pkg_t *newpkg)
 | 
			
		||||
 | 
			
		||||
	ASSERT(newpkg->filename != NULL, RET_ERR(handle, ALPM_ERR_PKG_INVALID_NAME, -1));
 | 
			
		||||
	fname = newpkg->filename;
 | 
			
		||||
	fpath = _alpm_filecache_find(handle, fname);
 | 
			
		||||
	fpath = _alpm_cache_find_pkg(newpkg, 0);
 | 
			
		||||
 | 
			
		||||
	/* downloaded file exists, so there's nothing to grab */
 | 
			
		||||
	if(fpath) {
 | 
			
		||||
@@ -333,7 +333,7 @@ static int compute_download_size(alpm_pkg_t *newpkg)
 | 
			
		||||
 | 
			
		||||
	CALLOC(fnamepart, strlen(fname) + 6, sizeof(char), return -1);
 | 
			
		||||
	sprintf(fnamepart, "%s.part", fname);
 | 
			
		||||
	fpath = _alpm_filecache_find(handle, fnamepart);
 | 
			
		||||
	fpath = _alpm_cache_find_pkg(newpkg, 1);
 | 
			
		||||
	if(fpath) {
 | 
			
		||||
		struct stat st;
 | 
			
		||||
		if(stat(fpath, &st) == 0) {
 | 
			
		||||
@@ -737,21 +737,13 @@ static int find_dl_candidates(alpm_handle_t *handle, alpm_list_t **files)
 | 
			
		||||
 | 
			
		||||
			ASSERT(spkg->filename != NULL, RET_ERR(handle, ALPM_ERR_PKG_INVALID_NAME, -1));
 | 
			
		||||
 | 
			
		||||
			need_download = spkg->download_size != 0 || !_alpm_filecache_exists(handle, spkg->filename);
 | 
			
		||||
			need_download = spkg->download_size != 0 || !_alpm_cache_pkg_exists(spkg, 0);
 | 
			
		||||
			/* even if the package file in the cache we need to check for
 | 
			
		||||
			 * accompanion *.sig file as well.
 | 
			
		||||
			 * If *.sig is not cached then force download the package + its signature file.
 | 
			
		||||
			 */
 | 
			
		||||
			if(!need_download && (siglevel & ALPM_SIG_PACKAGE)) {
 | 
			
		||||
				char *sig_filename = NULL;
 | 
			
		||||
				int len = strlen(spkg->filename) + 5;
 | 
			
		||||
 | 
			
		||||
				MALLOC(sig_filename, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
 | 
			
		||||
				snprintf(sig_filename, len, "%s.sig", spkg->filename);
 | 
			
		||||
 | 
			
		||||
				need_download = !_alpm_filecache_exists(handle, sig_filename);
 | 
			
		||||
 | 
			
		||||
				FREE(sig_filename);
 | 
			
		||||
				need_download = !_alpm_cache_pkg_exists(spkg, 1);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(need_download) {
 | 
			
		||||
@@ -990,7 +982,7 @@ static int check_validity(alpm_handle_t *handle,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		current_bytes += v.pkg->size;
 | 
			
		||||
		v.path = _alpm_filecache_find(handle, v.pkg->filename);
 | 
			
		||||
		v.path = _alpm_cache_find_pkg(v.pkg, 0);
 | 
			
		||||
		v.siglevel = alpm_db_get_siglevel(alpm_pkg_get_db(v.pkg));
 | 
			
		||||
 | 
			
		||||
		if(_alpm_pkg_validate_internal(handle, v.path, v.pkg,
 | 
			
		||||
@@ -1080,7 +1072,8 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		current_bytes += spkg->size;
 | 
			
		||||
		filepath = _alpm_filecache_find(handle, spkg->filename);
 | 
			
		||||
 | 
			
		||||
		filepath = _alpm_cache_find_pkg(spkg, 0);
 | 
			
		||||
 | 
			
		||||
		/* load the package file and replace pkgcache entry with it in the target list */
 | 
			
		||||
		/* TODO: alpm_pkg_get_db() will not work on this target anymore */
 | 
			
		||||
 
 | 
			
		||||
@@ -815,6 +815,37 @@ int _alpm_str_cmp(const void *s1, const void *s2)
 | 
			
		||||
	return strcmp(s1, s2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *_alpm_cache_find_pkg(alpm_pkg_t *pkg, int sig) {
 | 
			
		||||
	alpm_handle_t *handle = pkg->handle;
 | 
			
		||||
	struct stat buf;
 | 
			
		||||
	alpm_list_t *servers = pkg->origin_data.db->servers;
 | 
			
		||||
	char *retpath;
 | 
			
		||||
	char filepath[PATH_MAX];
 | 
			
		||||
 | 
			
		||||
	for(alpm_list_t *j = servers; j; j = j->next) {
 | 
			
		||||
		char *server = j->data;
 | 
			
		||||
 | 
			
		||||
		if(strncmp("file://", server, strlen("file://")) == 0) {
 | 
			
		||||
			int len = strlen(server) - strlen("file://") + 1 + strlen(pkg->filename) + 1;
 | 
			
		||||
 | 
			
		||||
			if(sig) {
 | 
			
		||||
				len += strlen(".sig");
 | 
			
		||||
				snprintf(filepath, len, "%s/%s", server + strlen("file://"), pkg->filename);
 | 
			
		||||
			} else {
 | 
			
		||||
				snprintf(filepath, len, "%s/%s.sig", server + strlen("file://"), pkg->filename);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(stat(filepath, &buf) == 0 && S_ISREG(buf.st_mode)) {
 | 
			
		||||
				STRDUP(retpath, filepath, RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
 | 
			
		||||
				_alpm_log(handle, ALPM_LOG_DEBUG, "found pkg in repo cache: %s\n", retpath);
 | 
			
		||||
				return retpath;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return _alpm_filecache_find(handle, pkg->filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Find a filename in a registered alpm cachedir.
 | 
			
		||||
 * @param handle the context handle
 | 
			
		||||
 * @param filename name of file to find
 | 
			
		||||
@@ -846,10 +877,10 @@ char *_alpm_filecache_find(alpm_handle_t *handle, const char *filename)
 | 
			
		||||
 * @param filename name of file to find
 | 
			
		||||
 * @return 0 if the filename was not found, 1 otherwise
 | 
			
		||||
 */
 | 
			
		||||
int _alpm_filecache_exists(alpm_handle_t *handle, const char *filename)
 | 
			
		||||
int _alpm_cache_pkg_exists(alpm_pkg_t *pkg, int sig)
 | 
			
		||||
{
 | 
			
		||||
	int res;
 | 
			
		||||
	char *fpath = _alpm_filecache_find(handle, filename);
 | 
			
		||||
	char *fpath = _alpm_cache_find_pkg(pkg, sig);
 | 
			
		||||
	res = (fpath != NULL);
 | 
			
		||||
	FREE(fpath);
 | 
			
		||||
	return res;
 | 
			
		||||
 
 | 
			
		||||
@@ -133,9 +133,10 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[],
 | 
			
		||||
		_alpm_cb_io in_cb, void *in_ctx);
 | 
			
		||||
int _alpm_ldconfig(alpm_handle_t *handle);
 | 
			
		||||
int _alpm_str_cmp(const void *s1, const void *s2);
 | 
			
		||||
char *_alpm_cache_find_pkg(alpm_pkg_t *pkg, int sig);
 | 
			
		||||
char *_alpm_filecache_find(alpm_handle_t *handle, const char *filename);
 | 
			
		||||
/* Checks whether a file exists in cache */
 | 
			
		||||
int _alpm_filecache_exists(alpm_handle_t *handle, const char *filename);
 | 
			
		||||
int _alpm_cache_pkg_exists(alpm_pkg_t *pkg, int sig);
 | 
			
		||||
const char *_alpm_filecache_setup(alpm_handle_t *handle);
 | 
			
		||||
/* Unlike many uses of alpm_pkgvalidation_t, _alpm_test_checksum expects
 | 
			
		||||
 * an enum value rather than a bitfield. */
 | 
			
		||||
 
 | 
			
		||||
@@ -105,8 +105,7 @@ config_t *config_new(void)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	/* defaults which may get overridden later */
 | 
			
		||||
	newconfig->op = 0;
 | 
			
		||||
	newconfig->curr_op = 0;
 | 
			
		||||
	newconfig->op = PM_OP_MAIN;
 | 
			
		||||
	newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING;
 | 
			
		||||
	newconfig->configfile = strdup(CONFFILE);
 | 
			
		||||
	if(alpm_capabilities() & ALPM_CAPABILITY_SIGNATURES) {
 | 
			
		||||
@@ -132,13 +131,6 @@ config_t *config_new(void)
 | 
			
		||||
	return newconfig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void targets_free(targets_t *targets) {
 | 
			
		||||
	FREELIST(targets->targets);
 | 
			
		||||
	FREELIST(targets->sync);
 | 
			
		||||
	FREELIST(targets->upgrade);
 | 
			
		||||
	FREELIST(targets->remove);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int config_free(config_t *oldconfig)
 | 
			
		||||
{
 | 
			
		||||
	if(oldconfig == NULL) {
 | 
			
		||||
 
 | 
			
		||||
@@ -43,17 +43,8 @@ typedef struct __config_repo_t {
 | 
			
		||||
	int siglevel_mask;
 | 
			
		||||
} config_repo_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct __targets_t {
 | 
			
		||||
	alpm_list_t *targets;
 | 
			
		||||
	alpm_list_t *sync;
 | 
			
		||||
	alpm_list_t *upgrade;
 | 
			
		||||
	alpm_list_t *remove;
 | 
			
		||||
} targets_t;
 | 
			
		||||
 | 
			
		||||
typedef struct __config_t {
 | 
			
		||||
	unsigned short op;
 | 
			
		||||
	unsigned short curr_op;
 | 
			
		||||
	unsigned short quiet;
 | 
			
		||||
	unsigned short verbose;
 | 
			
		||||
	unsigned short version;
 | 
			
		||||
@@ -151,15 +142,14 @@ typedef struct __config_t {
 | 
			
		||||
 | 
			
		||||
/* Operations */
 | 
			
		||||
enum {
 | 
			
		||||
	PM_OP_INVALID = 1 << 0,
 | 
			
		||||
	PM_OP_REMOVE = 1 << 1,
 | 
			
		||||
	PM_OP_UPGRADE = 1 << 2,
 | 
			
		||||
	PM_OP_QUERY = 1 << 3,
 | 
			
		||||
	PM_OP_SYNC = 1 << 4,
 | 
			
		||||
	PM_OP_DEPTEST = 1 << 5,
 | 
			
		||||
	PM_OP_DATABASE = 1 << 6,
 | 
			
		||||
	PM_OP_FILES = 1 << 7,
 | 
			
		||||
	PM_OP_TRANS = PM_OP_SYNC | PM_OP_UPGRADE | PM_OP_REMOVE
 | 
			
		||||
	PM_OP_MAIN = 1,
 | 
			
		||||
	PM_OP_REMOVE,
 | 
			
		||||
	PM_OP_UPGRADE,
 | 
			
		||||
	PM_OP_QUERY,
 | 
			
		||||
	PM_OP_SYNC,
 | 
			
		||||
	PM_OP_DEPTEST,
 | 
			
		||||
	PM_OP_DATABASE,
 | 
			
		||||
	PM_OP_FILES
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Long Operations */
 | 
			
		||||
@@ -245,9 +235,6 @@ enum {
 | 
			
		||||
/* global config variable */
 | 
			
		||||
extern config_t *config;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void targets_free(targets_t *targets);
 | 
			
		||||
 | 
			
		||||
void enable_colors(int colors);
 | 
			
		||||
config_t *config_new(void);
 | 
			
		||||
int config_free(config_t *oldconfig);
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@ pacman_sources = files('''
 | 
			
		||||
  remove.c
 | 
			
		||||
  sighandler.h sighandler.c
 | 
			
		||||
  sync.c
 | 
			
		||||
  trans.c
 | 
			
		||||
  callback.h callback.c
 | 
			
		||||
  upgrade.c
 | 
			
		||||
  util.h util.c
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@
 | 
			
		||||
#include "sighandler.h"
 | 
			
		||||
 | 
			
		||||
/* list of targets specified on command line */
 | 
			
		||||
static targets_t pm_targets;
 | 
			
		||||
static alpm_list_t *pm_targets;
 | 
			
		||||
 | 
			
		||||
/* Used to sort the options in --help */
 | 
			
		||||
static int options_cmp(const void *p1, const void *p2)
 | 
			
		||||
@@ -104,7 +104,7 @@ static void usage(int op, const char * const myname)
 | 
			
		||||
	char const *const str_opr  = _("operation");
 | 
			
		||||
 | 
			
		||||
	/* please limit your strings to 80 characters in width */
 | 
			
		||||
	if(!op) {
 | 
			
		||||
	if(op == PM_OP_MAIN) {
 | 
			
		||||
		printf("%s:  %s <%s> [...]\n", str_usg, myname, str_opr);
 | 
			
		||||
		printf(_("operations:\n"));
 | 
			
		||||
		printf("    %s {-h --help}\n", myname);
 | 
			
		||||
@@ -126,9 +126,10 @@ static void usage(int op, const char * const myname)
 | 
			
		||||
			addlist(_("  -n, --nosave         remove configuration files\n"));
 | 
			
		||||
			addlist(_("  -s, --recursive      remove unnecessary dependencies\n"
 | 
			
		||||
			          "                       (-ss includes explicitly installed dependencies)\n"));
 | 
			
		||||
			addlist(_("      --unneeded       remove unneeded packages\n"));
 | 
			
		||||
			addlist(_("  -u, --unneeded       remove unneeded packages\n"));
 | 
			
		||||
		} else if(op == PM_OP_UPGRADE) {
 | 
			
		||||
			printf("%s:  %s {-U --upgrade} [%s] <%s>\n", str_usg, myname, str_opt, str_file);
 | 
			
		||||
			addlist(_("      --needed         do not reinstall up to date packages\n"));
 | 
			
		||||
			printf("%s:\n", str_opt);
 | 
			
		||||
		} else if(op == PM_OP_QUERY) {
 | 
			
		||||
			printf("%s:  %s {-Q --query} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);
 | 
			
		||||
@@ -162,6 +163,7 @@ static void usage(int op, const char * const myname)
 | 
			
		||||
			addlist(_("  -u, --sysupgrade     upgrade installed packages (-uu enables downgrades)\n"));
 | 
			
		||||
			addlist(_("  -y, --refresh        download fresh package databases from the server\n"
 | 
			
		||||
			          "                       (-yy to force a refresh even if up to date)\n"));
 | 
			
		||||
			addlist(_("      --needed         do not reinstall up to date packages\n"));
 | 
			
		||||
		} else if(op == PM_OP_DATABASE) {
 | 
			
		||||
			printf("%s:  %s {-D --database} <%s> <%s>\n", str_usg, myname, str_opt, str_pkg);
 | 
			
		||||
			printf("%s:\n", str_opt);
 | 
			
		||||
@@ -183,8 +185,9 @@ static void usage(int op, const char * const myname)
 | 
			
		||||
			addlist(_("      --machinereadable\n"
 | 
			
		||||
			          "                       produce machine-readable output\n"));
 | 
			
		||||
		}
 | 
			
		||||
		if(op & (PM_OP_UPGRADE | PM_OP_SYNC)) {
 | 
			
		||||
			addlist(_("      --needed         do not reinstall up to date packages\n"));
 | 
			
		||||
		switch(op) {
 | 
			
		||||
			case PM_OP_SYNC:
 | 
			
		||||
			case PM_OP_UPGRADE:
 | 
			
		||||
				addlist(_("  -w, --downloadonly   download packages but do not install/upgrade anything\n"));
 | 
			
		||||
				addlist(_("      --overwrite <glob>\n"
 | 
			
		||||
				          "                       overwrite conflicting files (can be used more than once)\n"));
 | 
			
		||||
@@ -193,8 +196,8 @@ static void usage(int op, const char * const myname)
 | 
			
		||||
				addlist(_("      --ignore <pkg>   ignore a package upgrade (can be used more than once)\n"));
 | 
			
		||||
				addlist(_("      --ignoregroup <grp>\n"
 | 
			
		||||
				          "                       ignore a group upgrade (can be used more than once)\n"));
 | 
			
		||||
		}
 | 
			
		||||
		if(op & PM_OP_TRANS) {
 | 
			
		||||
				__attribute__((fallthrough));
 | 
			
		||||
			case PM_OP_REMOVE:
 | 
			
		||||
				addlist(_("  -d, --nodeps         skip dependency version checks (-dd to skip all checks)\n"));
 | 
			
		||||
				addlist(_("      --assume-installed <package=version>\n"
 | 
			
		||||
				          "                       add a virtual package to satisfy dependencies\n"));
 | 
			
		||||
@@ -204,6 +207,7 @@ static void usage(int op, const char * const myname)
 | 
			
		||||
				addlist(_("  -p, --print          print the targets instead of performing the operation\n"));
 | 
			
		||||
				addlist(_("      --print-format <string>\n"
 | 
			
		||||
				          "                       specify how the targets should be printed\n"));
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		addlist(_("  -b, --dbpath <path>  set an alternate database location\n"));
 | 
			
		||||
@@ -297,7 +301,7 @@ static void cleanup(int ret)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* free memory */
 | 
			
		||||
	targets_free(&pm_targets);
 | 
			
		||||
	FREELIST(pm_targets);
 | 
			
		||||
	console_cursor_show();
 | 
			
		||||
	exit(ret);
 | 
			
		||||
}
 | 
			
		||||
@@ -323,24 +327,6 @@ static int parsearg_util_addlist(alpm_list_t **list)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_op(int opt)
 | 
			
		||||
{
 | 
			
		||||
	int trans = (config->op & PM_OP_TRANS) != 0;
 | 
			
		||||
	int setting_trans = (opt & PM_OP_TRANS) != 0;
 | 
			
		||||
 | 
			
		||||
	/* we allow -SS so allow -QQ for sake of consistency */
 | 
			
		||||
	if(config->op == opt) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(!config->op || (trans && setting_trans)) {
 | 
			
		||||
		config->op |= opt;
 | 
			
		||||
		config->curr_op = opt;
 | 
			
		||||
	} else {
 | 
			
		||||
		config->op |= PM_OP_INVALID;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Helper function for parsing operation from command-line arguments.
 | 
			
		||||
 * @param opt Keycode returned by getopt_long
 | 
			
		||||
 * @param dryrun If nonzero, application state is NOT changed
 | 
			
		||||
@@ -352,25 +338,25 @@ static int parsearg_op(int opt, int dryrun)
 | 
			
		||||
		/* operations */
 | 
			
		||||
		case 'D':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_DATABASE); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_DATABASE); break;
 | 
			
		||||
		case 'F':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_FILES); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_FILES); break;
 | 
			
		||||
		case 'Q':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_QUERY); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break;
 | 
			
		||||
		case 'R':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_REMOVE); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break;
 | 
			
		||||
		case 'S':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_SYNC); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break;
 | 
			
		||||
		case 'T':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_DEPTEST); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_DEPTEST); break;
 | 
			
		||||
		case 'U':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			set_op(PM_OP_UPGRADE); break;
 | 
			
		||||
			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_UPGRADE); break;
 | 
			
		||||
		case 'V':
 | 
			
		||||
			if(dryrun) break;
 | 
			
		||||
			config->version = 1; break;
 | 
			
		||||
@@ -383,7 +369,6 @@ static int parsearg_op(int opt, int dryrun)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** Helper functions for parsing command-line arguments.
 | 
			
		||||
 * @param opt Keycode returned by getopt_long
 | 
			
		||||
 * @return 0 on success, 1 on failure
 | 
			
		||||
@@ -634,8 +619,62 @@ static void checkargs_query(void)
 | 
			
		||||
			"--native", "--foreign");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* options common to -S -R -U */
 | 
			
		||||
static int parsearg_trans(int opt)
 | 
			
		||||
{
 | 
			
		||||
	switch(opt) {
 | 
			
		||||
		case OP_NODEPS:
 | 
			
		||||
		case 'd':
 | 
			
		||||
			if(config->flags & ALPM_TRANS_FLAG_NODEPVERSION) {
 | 
			
		||||
				config->flags |= ALPM_TRANS_FLAG_NODEPS;
 | 
			
		||||
			} else {
 | 
			
		||||
				config->flags |= ALPM_TRANS_FLAG_NODEPVERSION;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_DBONLY:
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_DBONLY;
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_NOSCRIPTLET;
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_NOHOOKS;
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_NOPROGRESSBAR:
 | 
			
		||||
			config->noprogressbar = 1;
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_NOSCRIPTLET:
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_NOSCRIPTLET;
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_PRINT:
 | 
			
		||||
		case 'p':
 | 
			
		||||
			config->print = 1;
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_PRINTFORMAT:
 | 
			
		||||
			config->print = 1;
 | 
			
		||||
			free(config->print_format);
 | 
			
		||||
			config->print_format = strdup(optarg);
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_ASSUMEINSTALLED:
 | 
			
		||||
			parsearg_util_addlist(&(config->assumeinstalled));
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			return 1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void checkargs_trans(void)
 | 
			
		||||
{
 | 
			
		||||
	if(config->print) {
 | 
			
		||||
		invalid_opt(config->flags & ALPM_TRANS_FLAG_DBONLY,
 | 
			
		||||
				"--print", "--dbonly");
 | 
			
		||||
		invalid_opt(config->flags & ALPM_TRANS_FLAG_NOSCRIPTLET,
 | 
			
		||||
				"--print", "--noscriptlet");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int parsearg_remove(int opt)
 | 
			
		||||
{
 | 
			
		||||
	if(parsearg_trans(opt) == 0) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	switch(opt) {
 | 
			
		||||
		case OP_CASCADE:
 | 
			
		||||
		case 'c':
 | 
			
		||||
@@ -654,6 +693,7 @@ static int parsearg_remove(int opt)
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_UNNEEDED:
 | 
			
		||||
		case 'u':
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_UNNEEDED;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
@@ -664,6 +704,7 @@ static int parsearg_remove(int opt)
 | 
			
		||||
 | 
			
		||||
static void checkargs_remove(void)
 | 
			
		||||
{
 | 
			
		||||
	checkargs_trans();
 | 
			
		||||
	if(config->flags & ALPM_TRANS_FLAG_NOSAVE) {
 | 
			
		||||
		invalid_opt(config->print, "--nosave", "--print");
 | 
			
		||||
		invalid_opt(config->flags & ALPM_TRANS_FLAG_DBONLY,
 | 
			
		||||
@@ -674,6 +715,9 @@ static void checkargs_remove(void)
 | 
			
		||||
/* options common to -S -U */
 | 
			
		||||
static int parsearg_upgrade(int opt)
 | 
			
		||||
{
 | 
			
		||||
	if(parsearg_trans(opt) == 0) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	switch(opt) {
 | 
			
		||||
		case OP_OVERWRITE_FILES:
 | 
			
		||||
			parsearg_util_addlist(&(config->overwrite_files));
 | 
			
		||||
@@ -698,7 +742,6 @@ static int parsearg_upgrade(int opt)
 | 
			
		||||
			config->op_s_downloadonly = 1;
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_DOWNLOADONLY;
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_NOCONFLICTS;
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_NOLOCK;
 | 
			
		||||
			break;
 | 
			
		||||
		default: return 1;
 | 
			
		||||
	}
 | 
			
		||||
@@ -707,6 +750,7 @@ static int parsearg_upgrade(int opt)
 | 
			
		||||
 | 
			
		||||
static void checkargs_upgrade(void)
 | 
			
		||||
{
 | 
			
		||||
	checkargs_trans();
 | 
			
		||||
	invalid_opt(config->flags & ALPM_TRANS_FLAG_ALLDEPS
 | 
			
		||||
			&& config->flags & ALPM_TRANS_FLAG_ALLEXPLICIT,
 | 
			
		||||
			"--asdeps", "--asexplicit");
 | 
			
		||||
@@ -714,6 +758,9 @@ static void checkargs_upgrade(void)
 | 
			
		||||
 | 
			
		||||
static int parsearg_files(int opt)
 | 
			
		||||
{
 | 
			
		||||
	if(parsearg_trans(opt) == 0) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	switch(opt) {
 | 
			
		||||
		case OP_LIST:
 | 
			
		||||
		case 'l':
 | 
			
		||||
@@ -752,26 +799,6 @@ static int parsearg_sync(int opt)
 | 
			
		||||
	if(parsearg_upgrade(opt) == 0) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	switch(opt) {
 | 
			
		||||
		case OP_SYSUPGRADE:
 | 
			
		||||
		case 'u':
 | 
			
		||||
			(config->op_s_upgrade)++;
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_REFRESH:
 | 
			
		||||
		case 'y':
 | 
			
		||||
			(config->op_s_sync)++;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			return 1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int parsearg_sync_only(int opt)
 | 
			
		||||
{
 | 
			
		||||
	if(parsearg_sync(opt) == 0) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	switch(opt) {
 | 
			
		||||
		case OP_CLEAN:
 | 
			
		||||
		case 'c':
 | 
			
		||||
@@ -813,12 +840,7 @@ static int parsearg_sync_only(int opt)
 | 
			
		||||
 | 
			
		||||
static void checkargs_sync(void)
 | 
			
		||||
{
 | 
			
		||||
	/* no conflicts currently */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void checkargs_sync_only(void)
 | 
			
		||||
{
 | 
			
		||||
	checkargs_sync();
 | 
			
		||||
	checkargs_upgrade();
 | 
			
		||||
	if(config->op_s_clean) {
 | 
			
		||||
		invalid_opt(config->group, "--clean", "--groups");
 | 
			
		||||
		invalid_opt(config->op_s_info, "--clean", "--info");
 | 
			
		||||
@@ -848,89 +870,6 @@ static void checkargs_sync_only(void)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* options common to -S -R -U */
 | 
			
		||||
static int parsearg_trans(int opt)
 | 
			
		||||
{
 | 
			
		||||
	if(config->op & (PM_OP_SYNC | PM_OP_UPGRADE) && parsearg_upgrade(opt) == 0) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if(config->op & PM_OP_SYNC && parsearg_sync(opt) == 0) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if(config->op & PM_OP_REMOVE && parsearg_remove(opt) == 0) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	switch(opt) {
 | 
			
		||||
		case OP_NODEPS:
 | 
			
		||||
		case 'd':
 | 
			
		||||
			if(config->flags & ALPM_TRANS_FLAG_NODEPVERSION) {
 | 
			
		||||
				config->flags |= ALPM_TRANS_FLAG_NODEPS;
 | 
			
		||||
			} else {
 | 
			
		||||
				config->flags |= ALPM_TRANS_FLAG_NODEPVERSION;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_DBONLY:
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_DBONLY;
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_NOSCRIPTLET;
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_NOHOOKS;
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_NOPROGRESSBAR:
 | 
			
		||||
			config->noprogressbar = 1;
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_NOSCRIPTLET:
 | 
			
		||||
			config->flags |= ALPM_TRANS_FLAG_NOSCRIPTLET;
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_PRINT:
 | 
			
		||||
		case 'p':
 | 
			
		||||
			config->print = 1;
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_PRINTFORMAT:
 | 
			
		||||
			config->print = 1;
 | 
			
		||||
			free(config->print_format);
 | 
			
		||||
			config->print_format = strdup(optarg);
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_ASSUMEINSTALLED:
 | 
			
		||||
			parsearg_util_addlist(&(config->assumeinstalled));
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			return 1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void checkargs_trans(void)
 | 
			
		||||
{
 | 
			
		||||
	if(config->op & (PM_OP_SYNC | PM_OP_UPGRADE)) {
 | 
			
		||||
		checkargs_upgrade();
 | 
			
		||||
	}
 | 
			
		||||
	if(config->op & PM_OP_SYNC) {
 | 
			
		||||
		checkargs_sync();
 | 
			
		||||
	}
 | 
			
		||||
	if(config->op & PM_OP_REMOVE) {
 | 
			
		||||
		checkargs_remove();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->print) {
 | 
			
		||||
		invalid_opt(config->flags & ALPM_TRANS_FLAG_DBONLY,
 | 
			
		||||
				"--print", "--dbonly");
 | 
			
		||||
		invalid_opt(config->flags & ALPM_TRANS_FLAG_NOSCRIPTLET,
 | 
			
		||||
				"--print", "--noscriptlet");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void add_target(char *targ)
 | 
			
		||||
{
 | 
			
		||||
	if(config->curr_op & PM_OP_SYNC) {
 | 
			
		||||
		pm_targets.sync = alpm_list_add(pm_targets.sync, targ);
 | 
			
		||||
	} else if(config->curr_op & PM_OP_REMOVE) {
 | 
			
		||||
		pm_targets.remove = alpm_list_add(pm_targets.remove, targ);
 | 
			
		||||
	} else if(config->curr_op & PM_OP_UPGRADE) {
 | 
			
		||||
		pm_targets.upgrade = alpm_list_add(pm_targets.upgrade, targ);
 | 
			
		||||
	} else {
 | 
			
		||||
		pm_targets.targets = alpm_list_add(pm_targets.targets, targ);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Parse command-line arguments for each operation.
 | 
			
		||||
 * @param argc argc
 | 
			
		||||
 * @param argv argv
 | 
			
		||||
@@ -941,7 +880,7 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
	int opt;
 | 
			
		||||
	int option_index = 0;
 | 
			
		||||
	int result;
 | 
			
		||||
	const char *optstring = "-DFQRSTUVb:cdefghiklmnopqr:stuvwxy";
 | 
			
		||||
	const char *optstring = "DFQRSTUVb:cdefghiklmnopqr:stuvwxy";
 | 
			
		||||
	static const struct option opts[] =
 | 
			
		||||
	{
 | 
			
		||||
		{"database",   no_argument,       0, 'D'},
 | 
			
		||||
@@ -1016,11 +955,6 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
	while((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) {
 | 
			
		||||
		if(opt == 0) {
 | 
			
		||||
			continue;
 | 
			
		||||
		} else if(opt == 1) {
 | 
			
		||||
			char *targ = strdup(optarg);
 | 
			
		||||
			/* add the target to our target array */
 | 
			
		||||
			add_target(targ);
 | 
			
		||||
			continue;
 | 
			
		||||
		} else if(opt == '?') {
 | 
			
		||||
			/* unknown option, getopt printed an error */
 | 
			
		||||
			return 1;
 | 
			
		||||
@@ -1028,8 +962,8 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
		parsearg_op(opt, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->op & PM_OP_INVALID) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("these operations can not be used together\n"));
 | 
			
		||||
	if(config->op == 0) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("only one operation may be used at a time\n"));
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	if(config->help) {
 | 
			
		||||
@@ -1044,7 +978,7 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
	/* parse all other options */
 | 
			
		||||
	optind = 1;
 | 
			
		||||
	while((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) {
 | 
			
		||||
		if(opt == 0 || opt == 1) {
 | 
			
		||||
		if(opt == 0) {
 | 
			
		||||
			continue;
 | 
			
		||||
		} else if(opt == '?') {
 | 
			
		||||
			/* this should have failed during first pass already */
 | 
			
		||||
@@ -1061,9 +995,14 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
			case PM_OP_QUERY:
 | 
			
		||||
				result = parsearg_query(opt);
 | 
			
		||||
				break;
 | 
			
		||||
			case PM_OP_REMOVE:
 | 
			
		||||
				result = parsearg_remove(opt);
 | 
			
		||||
				break;
 | 
			
		||||
			case PM_OP_SYNC:
 | 
			
		||||
				/* handle -Si -Sg etc if -S is the only trans op */
 | 
			
		||||
				result = parsearg_sync_only(opt);
 | 
			
		||||
				result = parsearg_sync(opt);
 | 
			
		||||
				break;
 | 
			
		||||
			case PM_OP_UPGRADE:
 | 
			
		||||
				result = parsearg_upgrade(opt);
 | 
			
		||||
				break;
 | 
			
		||||
			case PM_OP_FILES:
 | 
			
		||||
				result = parsearg_files(opt);
 | 
			
		||||
@@ -1077,13 +1016,6 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(config->op & PM_OP_TRANS) {
 | 
			
		||||
			result = parsearg_trans(opt);
 | 
			
		||||
		}
 | 
			
		||||
		if(result == 0) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* fall back to global options */
 | 
			
		||||
		result = parsearg_global(opt);
 | 
			
		||||
		if(result != 0) {
 | 
			
		||||
@@ -1100,7 +1032,7 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
	while(optind < argc) {
 | 
			
		||||
		/* add the target to our target array */
 | 
			
		||||
		add_target(strdup(argv[optind]));
 | 
			
		||||
		pm_targets = alpm_list_add(pm_targets, strdup(argv[optind]));
 | 
			
		||||
		optind++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1112,7 +1044,7 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
			/* no conflicting options */
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_SYNC:
 | 
			
		||||
			checkargs_sync_only();
 | 
			
		||||
			checkargs_sync();
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_QUERY:
 | 
			
		||||
			checkargs_query();
 | 
			
		||||
@@ -1129,83 +1061,10 @@ static int parseargs(int argc, char *argv[])
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	if(config->op & PM_OP_TRANS) {
 | 
			
		||||
		checkargs_trans();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void parse_stdin(alpm_list_t **targets)
 | 
			
		||||
{
 | 
			
		||||
	if(!isatty(fileno(stdin))) {
 | 
			
		||||
		int target_found = 0;
 | 
			
		||||
		char *vdata, *line = NULL;
 | 
			
		||||
		size_t line_size = 0;
 | 
			
		||||
		ssize_t nread;
 | 
			
		||||
 | 
			
		||||
		/* remove the '-' from the list */
 | 
			
		||||
		*targets = alpm_list_remove_str(*targets, "-", &vdata);
 | 
			
		||||
		free(vdata);
 | 
			
		||||
 | 
			
		||||
		while((nread = getline(&line, &line_size, stdin)) != -1) {
 | 
			
		||||
			if(line[nread - 1] == '\n') {
 | 
			
		||||
				/* remove trailing newline */
 | 
			
		||||
				line[nread - 1] = '\0';
 | 
			
		||||
			}
 | 
			
		||||
			if(line[0] == '\0') {
 | 
			
		||||
				/* skip empty lines */
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if(!alpm_list_append_strdup(targets, line)) {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			target_found = 1;
 | 
			
		||||
		}
 | 
			
		||||
		free(line);
 | 
			
		||||
 | 
			
		||||
		if(ferror(stdin)) {
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR,
 | 
			
		||||
					_("failed to read arguments from stdin: (%s)\n"), strerror(errno));
 | 
			
		||||
			cleanup(EXIT_FAILURE);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(!freopen(ctermid(NULL), "r", stdin)) {
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"),
 | 
			
		||||
					strerror(errno));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(!target_found) {
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, _("argument '-' specified with empty stdin\n"));
 | 
			
		||||
			cleanup(1);
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		/* do not read stdin from terminal */
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("argument '-' specified without input on stdin\n"));
 | 
			
		||||
		cleanup(1);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void parse_stdins(void)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t **lists[4] = {&pm_targets.targets, &pm_targets.sync, &pm_targets.upgrade, &pm_targets.remove};
 | 
			
		||||
	int replaced = 0;
 | 
			
		||||
 | 
			
		||||
	for(int i = 0; i < 4; i++) {
 | 
			
		||||
		alpm_list_t **list = lists[i];
 | 
			
		||||
		if(alpm_list_find_str(*list, "-")) {
 | 
			
		||||
			if(replaced) {
 | 
			
		||||
				pm_printf(ALPM_LOG_ERROR, _("argument '-' can not be specified multiple times\n"));
 | 
			
		||||
				cleanup(1);
 | 
			
		||||
			}
 | 
			
		||||
			parse_stdin(list);
 | 
			
		||||
			replaced++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** Print command line to logfile.
 | 
			
		||||
 * @param argc
 | 
			
		||||
 * @param argv
 | 
			
		||||
@@ -1279,7 +1138,54 @@ int main(int argc, char *argv[])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* we support reading targets from stdin if a cmdline parameter is '-' */
 | 
			
		||||
	parse_stdins();
 | 
			
		||||
	if(alpm_list_find_str(pm_targets, "-")) {
 | 
			
		||||
		if(!isatty(fileno(stdin))) {
 | 
			
		||||
			int target_found = 0;
 | 
			
		||||
			char *vdata, *line = NULL;
 | 
			
		||||
			size_t line_size = 0;
 | 
			
		||||
			ssize_t nread;
 | 
			
		||||
 | 
			
		||||
			/* remove the '-' from the list */
 | 
			
		||||
			pm_targets = alpm_list_remove_str(pm_targets, "-", &vdata);
 | 
			
		||||
			free(vdata);
 | 
			
		||||
 | 
			
		||||
			while((nread = getline(&line, &line_size, stdin)) != -1) {
 | 
			
		||||
				if(line[nread - 1] == '\n') {
 | 
			
		||||
					/* remove trailing newline */
 | 
			
		||||
					line[nread - 1] = '\0';
 | 
			
		||||
				}
 | 
			
		||||
				if(line[0] == '\0') {
 | 
			
		||||
					/* skip empty lines */
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				if(!alpm_list_append_strdup(&pm_targets, line)) {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				target_found = 1;
 | 
			
		||||
			}
 | 
			
		||||
			free(line);
 | 
			
		||||
 | 
			
		||||
			if(ferror(stdin)) {
 | 
			
		||||
				pm_printf(ALPM_LOG_ERROR,
 | 
			
		||||
						_("failed to read arguments from stdin: (%s)\n"), strerror(errno));
 | 
			
		||||
				cleanup(EXIT_FAILURE);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(!freopen(ctermid(NULL), "r", stdin)) {
 | 
			
		||||
				pm_printf(ALPM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"),
 | 
			
		||||
						strerror(errno));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(!target_found) {
 | 
			
		||||
				pm_printf(ALPM_LOG_ERROR, _("argument '-' specified with empty stdin\n"));
 | 
			
		||||
				cleanup(1);
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			/* do not read stdin from terminal */
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, _("argument '-' specified without input on stdin\n"));
 | 
			
		||||
			cleanup(1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->sysroot && (chroot(config->sysroot) != 0 || chdir("/") != 0)) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR,
 | 
			
		||||
@@ -1327,10 +1233,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
		printf("Lock File : %s\n", alpm_option_get_lockfile(config->handle));
 | 
			
		||||
		printf("Log File  : %s\n", alpm_option_get_logfile(config->handle));
 | 
			
		||||
		printf("GPG Dir   : %s\n", alpm_option_get_gpgdir(config->handle));
 | 
			
		||||
		list_display("Targets   :", pm_targets.targets, 0);
 | 
			
		||||
		list_display("Sync      :", pm_targets.sync, 0);
 | 
			
		||||
		list_display("Upgrade   :", pm_targets.upgrade, 0);
 | 
			
		||||
		list_display("Remove    :", pm_targets.remove, 0);
 | 
			
		||||
		list_display("Targets   :", pm_targets, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Log command line */
 | 
			
		||||
@@ -1339,27 +1242,32 @@ int main(int argc, char *argv[])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* start the requested operation */
 | 
			
		||||
	if(config->op & PM_OP_TRANS) {
 | 
			
		||||
		ret = do_transaction(&pm_targets);
 | 
			
		||||
	} else {
 | 
			
		||||
	switch(config->op) {
 | 
			
		||||
		case PM_OP_DATABASE:
 | 
			
		||||
				ret = pacman_database(pm_targets.targets);
 | 
			
		||||
			ret = pacman_database(pm_targets);
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_REMOVE:
 | 
			
		||||
			ret = pacman_remove(pm_targets);
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_UPGRADE:
 | 
			
		||||
			ret = pacman_upgrade(pm_targets);
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_QUERY:
 | 
			
		||||
				ret = pacman_query(pm_targets.targets);
 | 
			
		||||
			ret = pacman_query(pm_targets);
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_SYNC:
 | 
			
		||||
			ret = pacman_sync(pm_targets);
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_DEPTEST:
 | 
			
		||||
				ret = pacman_deptest(pm_targets.targets);
 | 
			
		||||
			ret = pacman_deptest(pm_targets);
 | 
			
		||||
			break;
 | 
			
		||||
		case PM_OP_FILES:
 | 
			
		||||
				ret = pacman_files(pm_targets.targets);
 | 
			
		||||
			ret = pacman_files(pm_targets);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, _("no operation specified (use -h for help)\n"));
 | 
			
		||||
			ret = EXIT_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cleanup(ret);
 | 
			
		||||
	/* not reached */
 | 
			
		||||
 
 | 
			
		||||
@@ -22,8 +22,6 @@
 | 
			
		||||
 | 
			
		||||
#include <alpm_list.h>
 | 
			
		||||
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
 | 
			
		||||
#define PACMAN_CALLER_PREFIX "PACMAN"
 | 
			
		||||
 | 
			
		||||
/* database.c */
 | 
			
		||||
@@ -34,14 +32,12 @@ int pacman_deptest(alpm_list_t *targets);
 | 
			
		||||
int pacman_files(alpm_list_t *files);
 | 
			
		||||
/* 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);
 | 
			
		||||
/* remove.c */
 | 
			
		||||
int load_remove(alpm_list_t *targets);
 | 
			
		||||
int sync_prepare_execute(void);
 | 
			
		||||
/* upgrade.c */
 | 
			
		||||
int load_upgrade(alpm_list_t *targets);
 | 
			
		||||
/* trans.c */
 | 
			
		||||
int do_transaction(targets_t *targets);
 | 
			
		||||
 | 
			
		||||
int pacman_upgrade(alpm_list_t *targets);
 | 
			
		||||
 | 
			
		||||
#endif /* PM_PACMAN_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@
 | 
			
		||||
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <fnmatch.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
@@ -29,6 +30,11 @@
 | 
			
		||||
#include "util.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
 | 
			
		||||
static int fnmatch_cmp(const void *pattern, const void *string)
 | 
			
		||||
{
 | 
			
		||||
	return fnmatch(pattern, string, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int remove_target(const char *target)
 | 
			
		||||
{
 | 
			
		||||
	alpm_pkg_t *pkg;
 | 
			
		||||
@@ -63,16 +69,28 @@ static int remove_target(const char *target)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int load_remove(alpm_list_t *targets)
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Remove a specified list of packages.
 | 
			
		||||
 *
 | 
			
		||||
 * @param targets a list of packages (as strings) to remove from the system
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, 1 on failure
 | 
			
		||||
 */
 | 
			
		||||
int pacman_remove(alpm_list_t *targets)
 | 
			
		||||
{
 | 
			
		||||
	int retval = 0;
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	alpm_list_t *i, *data = NULL;
 | 
			
		||||
 | 
			
		||||
	if(targets == NULL) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 0: create a new transaction */
 | 
			
		||||
	if(trans_init(config->flags, 0) == -1) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 1: add targets to the created transaction */
 | 
			
		||||
	for(i = targets; i; i = alpm_list_next(i)) {
 | 
			
		||||
		char *target = i->data;
 | 
			
		||||
@@ -84,6 +102,81 @@ int load_remove(alpm_list_t *targets)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(retval == 1) {
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 2: prepare the transaction based on its type, targets and flags */
 | 
			
		||||
	if(alpm_trans_prepare(config->handle, &data) == -1) {
 | 
			
		||||
		alpm_errno_t err = alpm_errno(config->handle);
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
 | 
			
		||||
		        alpm_strerror(err));
 | 
			
		||||
		switch(err) {
 | 
			
		||||
			case ALPM_ERR_UNSATISFIED_DEPS:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					alpm_depmissing_t *miss = i->data;
 | 
			
		||||
					char *depstring = alpm_dep_compute_string(miss->depend);
 | 
			
		||||
					colon_printf(_("removing %s breaks dependency '%s' required by %s\n"),
 | 
			
		||||
							miss->causingpkg, depstring, miss->target);
 | 
			
		||||
					free(depstring);
 | 
			
		||||
					alpm_depmissing_free(miss);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		alpm_list_free(data);
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Search for holdpkg in target list */
 | 
			
		||||
	int holdpkg = 0;
 | 
			
		||||
	for(i = alpm_trans_get_remove(config->handle); i; i = alpm_list_next(i)) {
 | 
			
		||||
		alpm_pkg_t *pkg = i->data;
 | 
			
		||||
		if(alpm_list_find(config->holdpkg, alpm_pkg_get_name(pkg), fnmatch_cmp)) {
 | 
			
		||||
			pm_printf(ALPM_LOG_WARNING, _("%s is designated as a HoldPkg.\n"),
 | 
			
		||||
							alpm_pkg_get_name(pkg));
 | 
			
		||||
			holdpkg = 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if(holdpkg && (noyes(_("HoldPkg was found in target list. Do you want to continue?")) == 0)) {
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 3: actually perform the removal */
 | 
			
		||||
	alpm_list_t *pkglist = alpm_trans_get_remove(config->handle);
 | 
			
		||||
	if(pkglist == NULL) {
 | 
			
		||||
		printf(_(" there is nothing to do\n"));
 | 
			
		||||
		goto cleanup; /* we are done */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->print) {
 | 
			
		||||
		print_packages(pkglist);
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* print targets and ask user confirmation */
 | 
			
		||||
	display_targets();
 | 
			
		||||
	printf("\n");
 | 
			
		||||
	if(yesno(_("Do you want to remove these packages?")) == 0) {
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(alpm_trans_commit(config->handle, &data) == -1) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
 | 
			
		||||
		        alpm_strerror(alpm_errno(config->handle)));
 | 
			
		||||
		retval = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	FREELIST(data);
 | 
			
		||||
 | 
			
		||||
	/* Step 4: release transaction resources */
 | 
			
		||||
cleanup:
 | 
			
		||||
	if(trans_release() == -1) {
 | 
			
		||||
		retval = 1;
 | 
			
		||||
	}
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@
 | 
			
		||||
#include "pacman.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
#include "package.h"
 | 
			
		||||
#include "callback.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
 | 
			
		||||
static int unlink_verbose(const char *pathname, int ignore_missing)
 | 
			
		||||
@@ -509,6 +510,376 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static alpm_db_t *get_db(const char *dbname)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	for(i = alpm_get_syncdbs(config->handle); i; i = i->next) {
 | 
			
		||||
		alpm_db_t *db = i->data;
 | 
			
		||||
		if(strcmp(alpm_db_get_name(db), dbname) == 0) {
 | 
			
		||||
			return db;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int process_pkg(alpm_pkg_t *pkg)
 | 
			
		||||
{
 | 
			
		||||
	int ret = alpm_add_pkg(config->handle, pkg);
 | 
			
		||||
 | 
			
		||||
	if(ret == -1) {
 | 
			
		||||
		alpm_errno_t err = alpm_errno(config->handle);
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg), alpm_strerror(err));
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int group_exists(alpm_list_t *dbs, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	for(i = dbs; i; i = i->next) {
 | 
			
		||||
		alpm_db_t *db = i->data;
 | 
			
		||||
 | 
			
		||||
		if(alpm_db_get_group(db, name)) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int process_group(alpm_list_t *dbs, const char *group, int error)
 | 
			
		||||
{
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	alpm_list_t *pkgs = alpm_find_group_pkgs(dbs, group);
 | 
			
		||||
	int count = alpm_list_count(pkgs);
 | 
			
		||||
 | 
			
		||||
	if(!count) {
 | 
			
		||||
		if(group_exists(dbs, group)) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("target not found: %s\n"), group);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(error) {
 | 
			
		||||
		/* we already know another target errored. there is no reason to prompt the
 | 
			
		||||
		 * user here; we already validated the group name so just move on since we
 | 
			
		||||
		 * won't actually be installing anything anyway. */
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->print == 0) {
 | 
			
		||||
		char *array = malloc(count);
 | 
			
		||||
		int n = 0;
 | 
			
		||||
		const colstr_t *colstr = &config->colstr;
 | 
			
		||||
		colon_printf(_n("There is %d member in group %s%s%s:\n",
 | 
			
		||||
				"There are %d members in group %s%s%s:\n", count),
 | 
			
		||||
				count, colstr->groups, group, colstr->title);
 | 
			
		||||
		select_display(pkgs);
 | 
			
		||||
		if(!array) {
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			goto cleanup;
 | 
			
		||||
		}
 | 
			
		||||
		if(multiselect_question(array, count)) {
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			free(array);
 | 
			
		||||
			goto cleanup;
 | 
			
		||||
		}
 | 
			
		||||
		for(i = pkgs, n = 0; i; i = alpm_list_next(i)) {
 | 
			
		||||
			alpm_pkg_t *pkg = i->data;
 | 
			
		||||
 | 
			
		||||
			if(array[n++] == 0) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(process_pkg(pkg) == 1) {
 | 
			
		||||
				ret = 1;
 | 
			
		||||
				free(array);
 | 
			
		||||
				goto cleanup;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		free(array);
 | 
			
		||||
	} else {
 | 
			
		||||
		for(i = pkgs; i; i = alpm_list_next(i)) {
 | 
			
		||||
			alpm_pkg_t *pkg = i->data;
 | 
			
		||||
 | 
			
		||||
			if(process_pkg(pkg) == 1) {
 | 
			
		||||
				ret = 1;
 | 
			
		||||
				goto cleanup;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
	alpm_list_free(pkgs);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int process_targname(alpm_list_t *dblist, const char *targname,
 | 
			
		||||
		int error)
 | 
			
		||||
{
 | 
			
		||||
	alpm_pkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, targname);
 | 
			
		||||
 | 
			
		||||
	/* skip ignored packages when user says no */
 | 
			
		||||
	if(alpm_errno(config->handle) == ALPM_ERR_PKG_IGNORED) {
 | 
			
		||||
			pm_printf(ALPM_LOG_WARNING, _("skipping target: %s\n"), targname);
 | 
			
		||||
			return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(pkg) {
 | 
			
		||||
		return process_pkg(pkg);
 | 
			
		||||
	}
 | 
			
		||||
	/* fallback on group */
 | 
			
		||||
	return process_group(dblist, targname, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int process_target(const char *target, int error)
 | 
			
		||||
{
 | 
			
		||||
	/* process targets */
 | 
			
		||||
	char *targstring = strdup(target);
 | 
			
		||||
	char *targname = strchr(targstring, '/');
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	alpm_list_t *dblist;
 | 
			
		||||
 | 
			
		||||
	if(targname && targname != targstring) {
 | 
			
		||||
		alpm_db_t *db;
 | 
			
		||||
		const char *dbname;
 | 
			
		||||
		int usage;
 | 
			
		||||
 | 
			
		||||
		*targname = '\0';
 | 
			
		||||
		targname++;
 | 
			
		||||
		dbname = targstring;
 | 
			
		||||
		db = get_db(dbname);
 | 
			
		||||
		if(!db) {
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, _("database not found: %s\n"),
 | 
			
		||||
					dbname);
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			goto cleanup;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* explicitly mark this repo as valid for installs since
 | 
			
		||||
		 * a repo name was given with the target */
 | 
			
		||||
		alpm_db_get_usage(db, &usage);
 | 
			
		||||
		alpm_db_set_usage(db, usage|ALPM_DB_USAGE_INSTALL);
 | 
			
		||||
 | 
			
		||||
		dblist = alpm_list_add(NULL, db);
 | 
			
		||||
		ret = process_targname(dblist, targname, error);
 | 
			
		||||
		alpm_list_free(dblist);
 | 
			
		||||
 | 
			
		||||
		/* restore old usage so we don't possibly disturb later
 | 
			
		||||
		 * targets */
 | 
			
		||||
		alpm_db_set_usage(db, usage);
 | 
			
		||||
	} else {
 | 
			
		||||
		targname = targstring;
 | 
			
		||||
		dblist = alpm_get_syncdbs(config->handle);
 | 
			
		||||
		ret = process_targname(dblist, targname, error);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
	free(targstring);
 | 
			
		||||
	if(ret && access(target, R_OK) == 0) {
 | 
			
		||||
		pm_printf(ALPM_LOG_WARNING,
 | 
			
		||||
				_("'%s' is a file, did you mean %s instead of %s?\n"),
 | 
			
		||||
				target, "-U/--upgrade", "-S/--sync");
 | 
			
		||||
	}
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sync_trans(alpm_list_t *targets)
 | 
			
		||||
{
 | 
			
		||||
	int retval = 0;
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
 | 
			
		||||
	/* Step 1: create a new transaction... */
 | 
			
		||||
	if(trans_init(config->flags, 1) == -1) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* process targets */
 | 
			
		||||
	for(i = targets; i; i = alpm_list_next(i)) {
 | 
			
		||||
		const char *targ = i->data;
 | 
			
		||||
		if(process_target(targ, retval) == 1) {
 | 
			
		||||
			retval = 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(retval) {
 | 
			
		||||
		trans_release();
 | 
			
		||||
		return retval;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->op_s_upgrade) {
 | 
			
		||||
		if(!config->print) {
 | 
			
		||||
			colon_printf(_("Starting full system upgrade...\n"));
 | 
			
		||||
			alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
 | 
			
		||||
					"starting full system upgrade\n");
 | 
			
		||||
		}
 | 
			
		||||
		if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) {
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle)));
 | 
			
		||||
			trans_release();
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sync_prepare_execute();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void print_broken_dep(alpm_depmissing_t *miss)
 | 
			
		||||
{
 | 
			
		||||
	char *depstring = alpm_dep_compute_string(miss->depend);
 | 
			
		||||
	alpm_list_t *trans_add = alpm_trans_get_add(config->handle);
 | 
			
		||||
	alpm_pkg_t *pkg;
 | 
			
		||||
	if(miss->causingpkg == NULL) {
 | 
			
		||||
		/* package being installed/upgraded has unresolved dependency */
 | 
			
		||||
		colon_printf(_("unable to satisfy dependency '%s' required by %s\n"),
 | 
			
		||||
				depstring, miss->target);
 | 
			
		||||
	} else if((pkg = alpm_pkg_find(trans_add, miss->causingpkg))) {
 | 
			
		||||
		/* upgrading a package breaks a local dependency */
 | 
			
		||||
		colon_printf(_("installing %s (%s) breaks dependency '%s' required by %s\n"),
 | 
			
		||||
				miss->causingpkg, alpm_pkg_get_version(pkg), depstring, miss->target);
 | 
			
		||||
	} else {
 | 
			
		||||
		/* removing a package breaks a local dependency */
 | 
			
		||||
		colon_printf(_("removing %s breaks dependency '%s' required by %s\n"),
 | 
			
		||||
				miss->causingpkg, depstring, miss->target);
 | 
			
		||||
	}
 | 
			
		||||
	free(depstring);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sync_prepare_execute(void)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *i, *packages, *data = NULL;
 | 
			
		||||
	int retval = 0;
 | 
			
		||||
 | 
			
		||||
	/* Step 2: "compute" the transaction based on targets and flags */
 | 
			
		||||
	if(alpm_trans_prepare(config->handle, &data) == -1) {
 | 
			
		||||
		alpm_errno_t err = alpm_errno(config->handle);
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
 | 
			
		||||
		        alpm_strerror(err));
 | 
			
		||||
		switch(err) {
 | 
			
		||||
			case ALPM_ERR_PKG_INVALID_ARCH:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					char *pkg = i->data;
 | 
			
		||||
					colon_printf(_("package %s does not have a valid architecture\n"), pkg);
 | 
			
		||||
					free(pkg);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case ALPM_ERR_UNSATISFIED_DEPS:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					print_broken_dep(i->data);
 | 
			
		||||
					alpm_depmissing_free(i->data);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case ALPM_ERR_CONFLICTING_DEPS:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					alpm_conflict_t *conflict = i->data;
 | 
			
		||||
					/* only print reason if it contains new information */
 | 
			
		||||
					if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
 | 
			
		||||
						colon_printf(_("%s and %s are in conflict\n"),
 | 
			
		||||
								conflict->package1, conflict->package2);
 | 
			
		||||
					} else {
 | 
			
		||||
						char *reason = alpm_dep_compute_string(conflict->reason);
 | 
			
		||||
						colon_printf(_("%s and %s are in conflict (%s)\n"),
 | 
			
		||||
								conflict->package1, conflict->package2, reason);
 | 
			
		||||
						free(reason);
 | 
			
		||||
					}
 | 
			
		||||
					alpm_conflict_free(conflict);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	packages = alpm_trans_get_add(config->handle);
 | 
			
		||||
	if(packages == NULL) {
 | 
			
		||||
		/* nothing to do: just exit without complaining */
 | 
			
		||||
		if(!config->print) {
 | 
			
		||||
			printf(_(" there is nothing to do\n"));
 | 
			
		||||
		}
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 3: actually perform the operation */
 | 
			
		||||
	if(config->print) {
 | 
			
		||||
		print_packages(packages);
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	display_targets();
 | 
			
		||||
	printf("\n");
 | 
			
		||||
 | 
			
		||||
	int confirm;
 | 
			
		||||
	if(config->op_s_downloadonly) {
 | 
			
		||||
		confirm = yesno(_("Proceed with download?"));
 | 
			
		||||
	} else {
 | 
			
		||||
		confirm = yesno(_("Proceed with installation?"));
 | 
			
		||||
	}
 | 
			
		||||
	if(!confirm) {
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	multibar_move_completed_up(true);
 | 
			
		||||
	if(alpm_trans_commit(config->handle, &data) == -1) {
 | 
			
		||||
		alpm_errno_t err = alpm_errno(config->handle);
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
 | 
			
		||||
		        alpm_strerror(err));
 | 
			
		||||
		switch(err) {
 | 
			
		||||
			case ALPM_ERR_FILE_CONFLICTS:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					alpm_fileconflict_t *conflict = i->data;
 | 
			
		||||
					switch(conflict->type) {
 | 
			
		||||
						case ALPM_FILECONFLICT_TARGET:
 | 
			
		||||
							printf(_("%s exists in both '%s' and '%s'\n"),
 | 
			
		||||
									conflict->file, conflict->target, conflict->ctarget);
 | 
			
		||||
							break;
 | 
			
		||||
						case ALPM_FILECONFLICT_FILESYSTEM:
 | 
			
		||||
							if(conflict->ctarget[0]) {
 | 
			
		||||
								printf(_("%s: %s exists in filesystem (owned by %s)\n"),
 | 
			
		||||
										conflict->target, conflict->file, conflict->ctarget);
 | 
			
		||||
							} else {
 | 
			
		||||
								printf(_("%s: %s exists in filesystem\n"),
 | 
			
		||||
										conflict->target, conflict->file);
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
					alpm_fileconflict_free(conflict);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case ALPM_ERR_PKG_INVALID:
 | 
			
		||||
			case ALPM_ERR_PKG_INVALID_CHECKSUM:
 | 
			
		||||
			case ALPM_ERR_PKG_INVALID_SIG:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					char *filename = i->data;
 | 
			
		||||
					printf(_("%s is invalid or corrupted\n"), filename);
 | 
			
		||||
					free(filename);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		/* TODO: stderr? */
 | 
			
		||||
		printf(_("Errors occurred, no packages were upgraded.\n"));
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 4: release transaction resources */
 | 
			
		||||
cleanup:
 | 
			
		||||
	alpm_list_free(data);
 | 
			
		||||
	if(trans_release() == -1) {
 | 
			
		||||
		retval = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pacman_sync(alpm_list_t *targets)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *sync_dbs = NULL;
 | 
			
		||||
@@ -531,8 +902,26 @@ int pacman_sync(alpm_list_t *targets)
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(check_syncdbs(1, 0)) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sync_dbs = alpm_get_syncdbs(config->handle);
 | 
			
		||||
 | 
			
		||||
	if(config->op_s_sync) {
 | 
			
		||||
		/* grab a fresh package list */
 | 
			
		||||
		colon_printf(_("Synchronizing package databases...\n"));
 | 
			
		||||
		alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
 | 
			
		||||
				"synchronizing package lists\n");
 | 
			
		||||
		if(!sync_syncdbs(config->op_s_sync, sync_dbs)) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(check_syncdbs(1, 1)) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* search for a package */
 | 
			
		||||
	if(config->op_s_search) {
 | 
			
		||||
		return sync_search(sync_dbs, targets);
 | 
			
		||||
@@ -554,9 +943,17 @@ int pacman_sync(alpm_list_t *targets)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(targets == NULL) {
 | 
			
		||||
		if(config->op_s_upgrade) {
 | 
			
		||||
			/* proceed */
 | 
			
		||||
		} else if(config->op_s_sync) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		} else {
 | 
			
		||||
			/* don't proceed here unless we have an operation that doesn't require a
 | 
			
		||||
			 * target list */
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return sync_trans(targets);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,478 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  upgrade.c
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) 2006-2021 Pacman Development Team <pacman-dev@archlinux.org>
 | 
			
		||||
 *  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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <fnmatch.h>
 | 
			
		||||
 | 
			
		||||
#include <alpm.h>
 | 
			
		||||
#include <alpm_list.h>
 | 
			
		||||
 | 
			
		||||
/* pacman */
 | 
			
		||||
#include "pacman.h"
 | 
			
		||||
#include "callback.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
static int fnmatch_cmp(const void *pattern, const void *string)
 | 
			
		||||
{
 | 
			
		||||
	return fnmatch(pattern, string, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void print_broken_dep(alpm_depmissing_t *miss)
 | 
			
		||||
{
 | 
			
		||||
	char *depstring = alpm_dep_compute_string(miss->depend);
 | 
			
		||||
	alpm_list_t *trans_add = alpm_trans_get_add(config->handle);
 | 
			
		||||
	alpm_pkg_t *pkg;
 | 
			
		||||
	if(miss->causingpkg == NULL) {
 | 
			
		||||
		/* package being installed/upgraded has unresolved dependency */
 | 
			
		||||
		colon_printf(_("unable to satisfy dependency '%s' required by %s\n"),
 | 
			
		||||
				depstring, miss->target);
 | 
			
		||||
	} else if((pkg = alpm_pkg_find(trans_add, miss->causingpkg))) {
 | 
			
		||||
		/* upgrading a package breaks a local dependency */
 | 
			
		||||
		colon_printf(_("installing %s (%s) breaks dependency '%s' required by %s\n"),
 | 
			
		||||
				miss->causingpkg, alpm_pkg_get_version(pkg), depstring, miss->target);
 | 
			
		||||
	} else {
 | 
			
		||||
		/* removing a package breaks a local dependency */
 | 
			
		||||
		colon_printf(_("removing %s breaks dependency '%s' required by %s\n"),
 | 
			
		||||
				miss->causingpkg, depstring, miss->target);
 | 
			
		||||
	}
 | 
			
		||||
	free(depstring);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sync_prepare_execute(void)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *i, *packages, *remove_packages, *data = NULL;
 | 
			
		||||
	int retval = 0;
 | 
			
		||||
 | 
			
		||||
	/* Step 2: "compute" the transaction based on targets and flags */
 | 
			
		||||
	if(alpm_trans_prepare(config->handle, &data) == -1) {
 | 
			
		||||
		alpm_errno_t err = alpm_errno(config->handle);
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
 | 
			
		||||
		        alpm_strerror(err));
 | 
			
		||||
		switch(err) {
 | 
			
		||||
			case ALPM_ERR_PKG_INVALID_ARCH:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					char *pkg = i->data;
 | 
			
		||||
					colon_printf(_("package %s does not have a valid architecture\n"), pkg);
 | 
			
		||||
					free(pkg);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case ALPM_ERR_UNSATISFIED_DEPS:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					print_broken_dep(i->data);
 | 
			
		||||
					alpm_depmissing_free(i->data);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case ALPM_ERR_CONFLICTING_DEPS:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					alpm_conflict_t *conflict = i->data;
 | 
			
		||||
					/* only print reason if it contains new information */
 | 
			
		||||
					if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
 | 
			
		||||
						colon_printf(_("%s and %s are in conflict\n"),
 | 
			
		||||
								conflict->package1, conflict->package2);
 | 
			
		||||
					} else {
 | 
			
		||||
						char *reason = alpm_dep_compute_string(conflict->reason);
 | 
			
		||||
						colon_printf(_("%s and %s are in conflict (%s)\n"),
 | 
			
		||||
								conflict->package1, conflict->package2, reason);
 | 
			
		||||
						free(reason);
 | 
			
		||||
					}
 | 
			
		||||
					alpm_conflict_free(conflict);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	packages = alpm_trans_get_add(config->handle);
 | 
			
		||||
	remove_packages = alpm_trans_get_remove(config->handle);
 | 
			
		||||
 | 
			
		||||
	if(packages == NULL && remove_packages == NULL) {
 | 
			
		||||
		/* nothing to do: just exit without complaining */
 | 
			
		||||
		if(!config->print) {
 | 
			
		||||
			printf(_(" there is nothing to do\n"));
 | 
			
		||||
		}
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* Search for holdpkg in target list */
 | 
			
		||||
	int holdpkg = 0;
 | 
			
		||||
	for(i = remove_packages; i; i = alpm_list_next(i)) {
 | 
			
		||||
		alpm_pkg_t *pkg = i->data;
 | 
			
		||||
		if(alpm_list_find(config->holdpkg, alpm_pkg_get_name(pkg), fnmatch_cmp)) {
 | 
			
		||||
			pm_printf(ALPM_LOG_WARNING, _("%s is designated as a HoldPkg.\n"),
 | 
			
		||||
							alpm_pkg_get_name(pkg));
 | 
			
		||||
			holdpkg = 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if(holdpkg && (noyes(_("HoldPkg was found in target list. Do you want to continue?")) == 0)) {
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 3: actually perform the operation */
 | 
			
		||||
	if(config->print) {
 | 
			
		||||
		print_packages(packages);
 | 
			
		||||
		print_packages(remove_packages);
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	display_targets();
 | 
			
		||||
	printf("\n");
 | 
			
		||||
 | 
			
		||||
	int confirm;
 | 
			
		||||
	if(config->op_s_downloadonly) {
 | 
			
		||||
		confirm = yesno(_("Proceed with download?"));
 | 
			
		||||
	} else {
 | 
			
		||||
		confirm = yesno(_("Proceed with installation?"));
 | 
			
		||||
	}
 | 
			
		||||
	if(!confirm) {
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	multibar_move_completed_up(true);
 | 
			
		||||
	if(alpm_trans_commit(config->handle, &data) == -1) {
 | 
			
		||||
		alpm_errno_t err = alpm_errno(config->handle);
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
 | 
			
		||||
		        alpm_strerror(err));
 | 
			
		||||
		switch(err) {
 | 
			
		||||
			case ALPM_ERR_FILE_CONFLICTS:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					alpm_fileconflict_t *conflict = i->data;
 | 
			
		||||
					switch(conflict->type) {
 | 
			
		||||
						case ALPM_FILECONFLICT_TARGET:
 | 
			
		||||
							printf(_("%s exists in both '%s' and '%s'\n"),
 | 
			
		||||
									conflict->file, conflict->target, conflict->ctarget);
 | 
			
		||||
							break;
 | 
			
		||||
						case ALPM_FILECONFLICT_FILESYSTEM:
 | 
			
		||||
							if(conflict->ctarget[0]) {
 | 
			
		||||
								printf(_("%s: %s exists in filesystem (owned by %s)\n"),
 | 
			
		||||
										conflict->target, conflict->file, conflict->ctarget);
 | 
			
		||||
							} else {
 | 
			
		||||
								printf(_("%s: %s exists in filesystem\n"),
 | 
			
		||||
										conflict->target, conflict->file);
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
					alpm_fileconflict_free(conflict);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case ALPM_ERR_PKG_INVALID:
 | 
			
		||||
			case ALPM_ERR_PKG_INVALID_CHECKSUM:
 | 
			
		||||
			case ALPM_ERR_PKG_INVALID_SIG:
 | 
			
		||||
				for(i = data; i; i = alpm_list_next(i)) {
 | 
			
		||||
					char *filename = i->data;
 | 
			
		||||
					printf(_("%s is invalid or corrupted\n"), filename);
 | 
			
		||||
					free(filename);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		/* TODO: stderr? */
 | 
			
		||||
		printf(_("Errors occurred, no packages were upgraded.\n"));
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 4: release transaction resources */
 | 
			
		||||
cleanup:
 | 
			
		||||
	alpm_list_free(data);
 | 
			
		||||
	if(trans_release() == -1) {
 | 
			
		||||
		retval = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int group_exists(alpm_list_t *dbs, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	for(i = dbs; i; i = i->next) {
 | 
			
		||||
		alpm_db_t *db = i->data;
 | 
			
		||||
 | 
			
		||||
		if(alpm_db_get_group(db, name)) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static alpm_db_t *get_db(const char *dbname)
 | 
			
		||||
{
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	for(i = alpm_get_syncdbs(config->handle); i; i = i->next) {
 | 
			
		||||
		alpm_db_t *db = i->data;
 | 
			
		||||
		if(strcmp(alpm_db_get_name(db), dbname) == 0) {
 | 
			
		||||
			return db;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int process_pkg(alpm_pkg_t *pkg)
 | 
			
		||||
{
 | 
			
		||||
	int ret = alpm_add_pkg(config->handle, pkg);
 | 
			
		||||
 | 
			
		||||
	if(ret == -1) {
 | 
			
		||||
		alpm_errno_t err = alpm_errno(config->handle);
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg), alpm_strerror(err));
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int process_group(alpm_list_t *dbs, const char *group, int error)
 | 
			
		||||
{
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
	alpm_list_t *pkgs = alpm_find_group_pkgs(dbs, group);
 | 
			
		||||
	int count = alpm_list_count(pkgs);
 | 
			
		||||
 | 
			
		||||
	if(!count) {
 | 
			
		||||
		if(group_exists(dbs, group)) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("target not found: %s\n"), group);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(error) {
 | 
			
		||||
		/* we already know another target errored. there is no reason to prompt the
 | 
			
		||||
		 * user here; we already validated the group name so just move on since we
 | 
			
		||||
		 * won't actually be installing anything anyway. */
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->print == 0) {
 | 
			
		||||
		char *array = malloc(count);
 | 
			
		||||
		int n = 0;
 | 
			
		||||
		const colstr_t *colstr = &config->colstr;
 | 
			
		||||
		colon_printf(_n("There is %d member in group %s%s%s:\n",
 | 
			
		||||
				"There are %d members in group %s%s%s:\n", count),
 | 
			
		||||
				count, colstr->groups, group, colstr->title);
 | 
			
		||||
		select_display(pkgs);
 | 
			
		||||
		if(!array) {
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			goto cleanup;
 | 
			
		||||
		}
 | 
			
		||||
		if(multiselect_question(array, count)) {
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			free(array);
 | 
			
		||||
			goto cleanup;
 | 
			
		||||
		}
 | 
			
		||||
		for(i = pkgs, n = 0; i; i = alpm_list_next(i)) {
 | 
			
		||||
			alpm_pkg_t *pkg = i->data;
 | 
			
		||||
 | 
			
		||||
			if(array[n++] == 0) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(process_pkg(pkg) == 1) {
 | 
			
		||||
				ret = 1;
 | 
			
		||||
				free(array);
 | 
			
		||||
				goto cleanup;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		free(array);
 | 
			
		||||
	} else {
 | 
			
		||||
		for(i = pkgs; i; i = alpm_list_next(i)) {
 | 
			
		||||
			alpm_pkg_t *pkg = i->data;
 | 
			
		||||
 | 
			
		||||
			if(process_pkg(pkg) == 1) {
 | 
			
		||||
				ret = 1;
 | 
			
		||||
				goto cleanup;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
	alpm_list_free(pkgs);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int process_targname(alpm_list_t *dblist, const char *targname,
 | 
			
		||||
		int error)
 | 
			
		||||
{
 | 
			
		||||
	alpm_pkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, targname);
 | 
			
		||||
 | 
			
		||||
	/* skip ignored packages when user says no */
 | 
			
		||||
	if(alpm_errno(config->handle) == ALPM_ERR_PKG_IGNORED) {
 | 
			
		||||
			pm_printf(ALPM_LOG_WARNING, _("skipping target: %s\n"), targname);
 | 
			
		||||
			return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(pkg) {
 | 
			
		||||
		return process_pkg(pkg);
 | 
			
		||||
	}
 | 
			
		||||
	/* fallback on group */
 | 
			
		||||
	return process_group(dblist, targname, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int process_target(const char *target, int error)
 | 
			
		||||
{
 | 
			
		||||
	/* process targets */
 | 
			
		||||
	char *targstring = strdup(target);
 | 
			
		||||
	char *targname = strchr(targstring, '/');
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	alpm_list_t *dblist;
 | 
			
		||||
 | 
			
		||||
	if(targname && targname != targstring) {
 | 
			
		||||
		alpm_db_t *db;
 | 
			
		||||
		const char *dbname;
 | 
			
		||||
		int usage;
 | 
			
		||||
 | 
			
		||||
		*targname = '\0';
 | 
			
		||||
		targname++;
 | 
			
		||||
		dbname = targstring;
 | 
			
		||||
		db = get_db(dbname);
 | 
			
		||||
		if(!db) {
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, _("database not found: %s\n"),
 | 
			
		||||
					dbname);
 | 
			
		||||
			ret = 1;
 | 
			
		||||
			goto cleanup;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* explicitly mark this repo as valid for installs since
 | 
			
		||||
		 * a repo name was given with the target */
 | 
			
		||||
		alpm_db_get_usage(db, &usage);
 | 
			
		||||
		alpm_db_set_usage(db, usage|ALPM_DB_USAGE_INSTALL);
 | 
			
		||||
 | 
			
		||||
		dblist = alpm_list_add(NULL, db);
 | 
			
		||||
		ret = process_targname(dblist, targname, error);
 | 
			
		||||
		alpm_list_free(dblist);
 | 
			
		||||
 | 
			
		||||
		/* restore old usage so we don't possibly disturb later
 | 
			
		||||
		 * targets */
 | 
			
		||||
		alpm_db_set_usage(db, usage);
 | 
			
		||||
	} else {
 | 
			
		||||
		targname = targstring;
 | 
			
		||||
		dblist = alpm_get_syncdbs(config->handle);
 | 
			
		||||
		ret = process_targname(dblist, targname, error);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
	free(targstring);
 | 
			
		||||
	if(ret && access(target, R_OK) == 0) {
 | 
			
		||||
		pm_printf(ALPM_LOG_WARNING,
 | 
			
		||||
				_("'%s' is a file, did you mean %s instead of %s?\n"),
 | 
			
		||||
				target, "-U/--upgrade", "-S/--sync");
 | 
			
		||||
	}
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int load_sync(alpm_list_t *targets)
 | 
			
		||||
{
 | 
			
		||||
	int retval = 0;
 | 
			
		||||
	alpm_list_t *i;
 | 
			
		||||
 | 
			
		||||
	if(targets == NULL && !config->op_s_upgrade && !config->op_s_sync) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* process targets */
 | 
			
		||||
	for(i = targets; i; i = alpm_list_next(i)) {
 | 
			
		||||
		const char *targ = i->data;
 | 
			
		||||
		if(process_target(targ, retval) == 1) {
 | 
			
		||||
			retval = 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int do_transaction(targets_t *targets) {
 | 
			
		||||
	int need_repos = (config->op & PM_OP_SYNC);
 | 
			
		||||
	alpm_list_t *sync_dbs;
 | 
			
		||||
 | 
			
		||||
	if(targets->targets != NULL) {
 | 
			
		||||
		pm_printf(ALPM_LOG_ERROR, _("targets must come after operation\n"));
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(check_syncdbs(need_repos, 0)) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sync_dbs = alpm_get_syncdbs(config->handle);
 | 
			
		||||
 | 
			
		||||
	if(config->op_s_sync) {
 | 
			
		||||
		/* grab a fresh package list */
 | 
			
		||||
		colon_printf(_("Synchronizing package databases...\n"));
 | 
			
		||||
		alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
 | 
			
		||||
				"synchronizing package lists\n");
 | 
			
		||||
		if(!sync_syncdbs(config->op_s_sync, sync_dbs)) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(check_syncdbs(need_repos, 1)) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->op_s_clean || config->op_s_search || config->op_s_info
 | 
			
		||||
			|| config->op_q_list || config->group) {
 | 
			
		||||
		return pacman_sync(targets->sync);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 1: create a new transaction... */
 | 
			
		||||
	if(trans_init(config->flags, 1) == -1) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->op & PM_OP_SYNC && load_sync(targets->sync)) {
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
	if(config->op & PM_OP_REMOVE && load_remove(targets->remove)) {
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
	if(config->op & PM_OP_UPGRADE && load_upgrade(targets->upgrade)) {
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(config->op_s_upgrade) {
 | 
			
		||||
		if(!config->print) {
 | 
			
		||||
			colon_printf(_("Starting full system upgrade...\n"));
 | 
			
		||||
			alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
 | 
			
		||||
					"starting full system upgrade\n");
 | 
			
		||||
		}
 | 
			
		||||
		if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) {
 | 
			
		||||
			pm_printf(ALPM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle)));
 | 
			
		||||
			trans_release();
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sync_prepare_execute();
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
	trans_release();
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -65,7 +65,7 @@ static int load_packages(alpm_list_t *targets, int siglevel)
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, 1 on failure
 | 
			
		||||
 */
 | 
			
		||||
int load_upgrade(alpm_list_t *targets)
 | 
			
		||||
int pacman_upgrade(alpm_list_t *targets)
 | 
			
		||||
{
 | 
			
		||||
	int retval = 0;
 | 
			
		||||
	alpm_list_t *remote_targets = NULL, *fetched_files = NULL;
 | 
			
		||||
@@ -88,16 +88,38 @@ int load_upgrade(alpm_list_t *targets)
 | 
			
		||||
 | 
			
		||||
	if(remote_targets) {
 | 
			
		||||
		retval = alpm_fetch_pkgurl(config->handle, remote_targets, &fetched_files);
 | 
			
		||||
		if(retval) {
 | 
			
		||||
			goto fail_free;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Step 1: create a new transaction */
 | 
			
		||||
	if(trans_init(config->flags, 1) == -1) {
 | 
			
		||||
		retval = 1;
 | 
			
		||||
		goto fail_free;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printf(_("loading packages...\n"));
 | 
			
		||||
	retval |= load_packages(local_targets, alpm_option_get_local_file_siglevel(config->handle));
 | 
			
		||||
	retval |= load_packages(fetched_files, alpm_option_get_remote_file_siglevel(config->handle));
 | 
			
		||||
 | 
			
		||||
	if(retval) {
 | 
			
		||||
		goto fail_release;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	alpm_list_free(remote_targets);
 | 
			
		||||
	alpm_list_free(local_targets);
 | 
			
		||||
	FREELIST(fetched_files);
 | 
			
		||||
 | 
			
		||||
	/* now that targets are resolved, we can hand it all off to the sync code */
 | 
			
		||||
	return sync_prepare_execute();
 | 
			
		||||
 | 
			
		||||
fail_release:
 | 
			
		||||
	trans_release();
 | 
			
		||||
fail_free:
 | 
			
		||||
	alpm_list_free(remote_targets);
 | 
			
		||||
	alpm_list_free(local_targets);
 | 
			
		||||
	FREELIST(fetched_files);
 | 
			
		||||
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -106,17 +106,16 @@ int needs_root(void)
 | 
			
		||||
	if(config->sysroot) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	if(config->op & PM_OP_SYNC) {
 | 
			
		||||
		return (config->op_s_clean || config->op_s_sync ||
 | 
			
		||||
				(!config->group && !config->op_s_info && !config->op_q_list &&
 | 
			
		||||
				 !config->op_s_search && !config->print));
 | 
			
		||||
	}
 | 
			
		||||
	if(config->op & PM_OP_TRANS) {
 | 
			
		||||
		return !config->print;
 | 
			
		||||
	}
 | 
			
		||||
	switch(config->op) {
 | 
			
		||||
		case PM_OP_DATABASE:
 | 
			
		||||
			return !config->op_q_check;
 | 
			
		||||
		case PM_OP_UPGRADE:
 | 
			
		||||
		case PM_OP_REMOVE:
 | 
			
		||||
			return !config->print;
 | 
			
		||||
		case PM_OP_SYNC:
 | 
			
		||||
			return (config->op_s_clean || config->op_s_sync ||
 | 
			
		||||
					(!config->group && !config->op_s_info && !config->op_q_list &&
 | 
			
		||||
					 !config->op_s_search && !config->print));
 | 
			
		||||
		case PM_OP_FILES:
 | 
			
		||||
			return config->op_s_sync;
 | 
			
		||||
		default:
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ lp3 = pmpkg("pkg3")
 | 
			
		||||
lp3.depends = [ "pkg1" ]
 | 
			
		||||
self.addpkg2db("local", lp3)
 | 
			
		||||
 | 
			
		||||
self.args = "-R --unneeded pkg1 pkg2"
 | 
			
		||||
self.args = "-Ru pkg1 pkg2"
 | 
			
		||||
 | 
			
		||||
self.addrule("PACMAN_RETCODE=0")
 | 
			
		||||
self.addrule("PKG_EXIST=pkg1")
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user