diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libalpm/alpm.h | 104 | ||||
| -rw-r--r-- | lib/libalpm/deps.c | 38 | ||||
| -rw-r--r-- | lib/libalpm/handle.h | 4 | ||||
| -rw-r--r-- | lib/libalpm/signing.c | 12 | ||||
| -rw-r--r-- | lib/libalpm/sync.c | 60 | 
5 files changed, 173 insertions, 45 deletions
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 66bb5f98..c81b1f2d 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -567,23 +567,119 @@ typedef struct _alpm_event_pacorig_created_t {  typedef void (*alpm_cb_event)(alpm_event_t *);  /** - * Questions. + * Type of questions.   * Unlike the events or progress enumerations, this enum has bitmask values   * so a frontend can use a bitmask map to supply preselected answers to the   * different types of questions.   */ -typedef enum _alpm_question_t { -	ALPM_QUESTION_INSTALL_IGNOREPKG = 1, +typedef enum _alpm_question_type_t { +	ALPM_QUESTION_INSTALL_IGNOREPKG = (1 << 0),  	ALPM_QUESTION_REPLACE_PKG = (1 << 1),  	ALPM_QUESTION_CONFLICT_PKG = (1 << 2),  	ALPM_QUESTION_CORRUPTED_PKG = (1 << 3),  	ALPM_QUESTION_REMOVE_PKGS = (1 << 4),  	ALPM_QUESTION_SELECT_PROVIDER = (1 << 5),  	ALPM_QUESTION_IMPORT_KEY = (1 << 6) +} alpm_question_type_t; + +typedef struct _alpm_question_any_t { +	/** Type of question. */ +	alpm_question_type_t type; +	/** Answer. */ +	int answer; +} alpm_question_any_t; + +typedef struct _alpm_question_install_ignorepkg_t { +	/** Type of question. */ +	alpm_question_type_t type; +	/** Answer: whether or not to install pkg anyway. */ +	int install; +	/* Package in IgnorePkg/IgnoreGroup. */ +	alpm_pkg_t *pkg; +} alpm_question_install_ignorepkg_t; + +typedef struct _alpm_question_replace_t { +	/** Type of question. */ +	alpm_question_type_t type; +	/** Answer: whether or not to replace oldpkg with newpkg. */ +	int replace; +	/* Package to be replaced. */ +	alpm_pkg_t *oldpkg; +	/* Package to replace with. */ +	alpm_pkg_t *newpkg; +	/* DB of newpkg */ +	alpm_db_t *newdb; +} alpm_question_replace_t; + +typedef struct _alpm_question_conflict_t { +	/** Type of question. */ +	alpm_question_type_t type; +	/** Answer: whether or not to remove conflict->package2. */ +	int remove; +	/** Conflict info. */ +	alpm_conflict_t *conflict; +} alpm_question_conflict_t; + +typedef struct _alpm_question_corrupted_t { +	/** Type of question. */ +	alpm_question_type_t type; +	/** Answer: whether or not to remove filepath. */ +	int remove; +	/** Filename to remove */ +	const char *filepath; +	/** Error code indicating the reason for package invalidity */ +	alpm_errno_t reason; +} alpm_question_corrupted_t; + +typedef struct _alpm_question_remove_pkgs_t { +	/** Type of question. */ +	alpm_question_type_t type; +	/** Answer: whether or not to skip packages. */ +	int skip; +	/** List of alpm_pkg_t* with unresolved dependencies. */ +	alpm_list_t *packages; +} alpm_question_remove_pkgs_t; + +typedef struct _alpm_question_select_provider_t { +	/** Type of question. */ +	alpm_question_type_t type; +	/** Answer: which provider to use (index from providers). */ +	int use_index; +	/** List of alpm_pkg_t* as possible providers. */ +	alpm_list_t *providers; +	/** What providers provide for. */ +	alpm_depend_t *depend; +} alpm_question_select_provider_t; + +typedef struct _alpm_question_import_key_t { +	/** Type of question. */ +	alpm_question_type_t type; +	/** Answer: whether or not to import key. */ +	int import; +	/** The key to import. */ +	alpm_pgpkey_t *key; +} alpm_question_import_key_t; + +/** + * Questions. + * This is an union passed to the callback, that allows the frontend to know + * which type of question was triggered (via type). It is then possible to + * typecast the pointer to the right structure, or use the union field, in order + * to access question-specific data. */ +typedef union _alpm_question_t { +	alpm_question_type_t type; +	alpm_question_any_t any; +	alpm_question_install_ignorepkg_t install_ignorepkg; +	alpm_question_replace_t replace; +	alpm_question_conflict_t conflict; +	alpm_question_corrupted_t corrupted; +	alpm_question_remove_pkgs_t remove_pkgs; +	alpm_question_select_provider_t select_provider; +	alpm_question_import_key_t import_key;  } alpm_question_t;  /** Question callback */ -typedef void (*alpm_cb_question)(alpm_question_t, void *, void *, void *, int *); +typedef void (*alpm_cb_question)(alpm_question_t *);  /** Progress */  typedef enum _alpm_progress_t { diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index b3de1b00..1cbbc5f6 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -640,15 +640,18 @@ static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,  		if(pkg && _alpm_depcmp_literal(pkg, dep)  				&& !alpm_pkg_find(excluding, pkg->name)) {  			if(alpm_pkg_should_ignore(handle, pkg)) { -				int install = 0; +				alpm_question_install_ignorepkg_t question = { +					.type = ALPM_QUESTION_INSTALL_IGNOREPKG, +					.install = 0, +					.pkg = pkg +				};  				if(prompt) { -					QUESTION(handle, ALPM_QUESTION_INSTALL_IGNOREPKG, pkg, -							 NULL, NULL, &install); +					QUESTION(handle, &question);  				} else {  					_alpm_log(handle, ALPM_LOG_WARNING, _("ignoring package %s-%s\n"),  							pkg->name, pkg->version);  				} -				if(!install) { +				if(!question.install) {  					ignored = 1;  					continue;  				} @@ -669,15 +672,18 @@ static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,  			if(pkg->name_hash != dep->name_hash && _alpm_depcmp(pkg, dep)  					&& !alpm_pkg_find(excluding, pkg->name)) {  				if(alpm_pkg_should_ignore(handle, pkg)) { -					int install = 0; +					alpm_question_install_ignorepkg_t question = { +						.type = ALPM_QUESTION_INSTALL_IGNOREPKG, +						.install = 0, +						.pkg = pkg +					};  					if(prompt) { -						QUESTION(handle, ALPM_QUESTION_INSTALL_IGNOREPKG, -									pkg, NULL, NULL, &install); +						QUESTION(handle, &question);  					} else {  						_alpm_log(handle, ALPM_LOG_WARNING, _("ignoring package %s-%s\n"),  								pkg->name, pkg->version);  					} -					if(!install) { +					if(!question.install) {  						ignored = 1;  						continue;  					} @@ -700,15 +706,19 @@ static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,  	}  	count = alpm_list_count(providers);  	if(count >= 1) { -		/* default to first provider if there is no QUESTION callback */ -		int idx = 0; +		alpm_question_select_provider_t question = { +			.type = ALPM_QUESTION_SELECT_PROVIDER, +			/* default to first provider if there is no QUESTION callback */ +			.use_index = 0, +			.providers = providers, +			.depend = dep +		};  		if(count > 1) {  			/* if there is more than one provider, we ask the user */ -			QUESTION(handle, ALPM_QUESTION_SELECT_PROVIDER, -					providers, dep, NULL, &idx); +			QUESTION(handle, &question);  		} -		if(idx >= 0 && idx < count) { -			alpm_list_t *nth = alpm_list_nth(providers, idx); +		if(question.use_index >= 0 && question.use_index < count) { +			alpm_list_t *nth = alpm_list_nth(providers, question.use_index);  			alpm_pkg_t *pkg = nth->data;  			alpm_list_free(providers);  			return pkg; diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 27241ea0..85c64f6f 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -37,10 +37,10 @@ do { \  		(h)->eventcb((alpm_event_t *) (e)); \  	} \  } while(0) -#define QUESTION(h, q, d1, d2, d3, r) \ +#define QUESTION(h, q) \  do { \  	if((h)->questioncb) { \ -		(h)->questioncb(q, d1, d2, d3, r); \ +		(h)->questioncb((alpm_question_t *) (q)); \  	} \  } while(0)  #define PROGRESS(h, e, p, per, n, r) \ diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c index 8fb909d9..c6b748e3 100644 --- a/lib/libalpm/signing.c +++ b/lib/libalpm/signing.c @@ -417,7 +417,7 @@ gpg_error:   */  int _alpm_key_import(alpm_handle_t *handle, const char *fpr)  { -	int answer = 0, ret = -1; +	int ret = -1;  	alpm_pgpkey_t fetch_key;  	memset(&fetch_key, 0, sizeof(fetch_key)); @@ -425,9 +425,13 @@ int _alpm_key_import(alpm_handle_t *handle, const char *fpr)  		_alpm_log(handle, ALPM_LOG_DEBUG,  				"unknown key, found %s on keyserver\n", fetch_key.uid);  		if(!_alpm_access(handle, handle->gpgdir, "pubring.gpg", W_OK)) { -			QUESTION(handle, ALPM_QUESTION_IMPORT_KEY, -					&fetch_key, NULL, NULL, &answer); -			if(answer) { +			alpm_question_import_key_t question = { +				.type = ALPM_QUESTION_IMPORT_KEY, +				.import = 0, +				.key = &fetch_key +			}; +			QUESTION(handle, &question); +			if(question.import) {  				if(key_import(handle, &fetch_key) == 0) {  					ret = 0;  				} else { diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index a025b68a..38e8f9e8 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -145,7 +145,13 @@ static alpm_list_t *check_replacers(alpm_handle_t *handle, alpm_pkg_t *lpkg,  			}  		}  		if(found) { -			int doreplace = 0; +			alpm_question_replace_t question = { +				.type = ALPM_QUESTION_REPLACE_PKG, +				.replace = 0, +				.oldpkg = lpkg, +				.newpkg = spkg, +				.newdb = sdb +			};  			alpm_pkg_t *tpkg;  			/* check IgnorePkg/IgnoreGroup */  			if(alpm_pkg_should_ignore(handle, spkg) @@ -156,9 +162,8 @@ static alpm_list_t *check_replacers(alpm_handle_t *handle, alpm_pkg_t *lpkg,  				continue;  			} -			QUESTION(handle, ALPM_QUESTION_REPLACE_PKG, lpkg, spkg, -					sdb->treename, &doreplace); -			if(!doreplace) { +			QUESTION(handle, &question); +			if(!question.replace) {  				continue;  			} @@ -276,11 +281,14 @@ alpm_list_t SYMEXPORT *alpm_find_group_pkgs(alpm_list_t *dbs,  				continue;  			}  			if(alpm_pkg_should_ignore(db->handle, pkg)) { +				alpm_question_install_ignorepkg_t question = { +					.type = ALPM_QUESTION_INSTALL_IGNOREPKG, +					.install = 0, +					.pkg = pkg +				};  				ignorelist = alpm_list_add(ignorelist, pkg); -				int install = 0; -				QUESTION(db->handle, ALPM_QUESTION_INSTALL_IGNOREPKG, pkg, -						NULL, NULL, &install); -				if(!install) +				QUESTION(db->handle, &question); +				if(!question.install)  					continue;  			}  			if(!alpm_pkg_find(pkgs, pkg->name)) { @@ -443,10 +451,13 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)  		/* If there were unresolvable top-level packages, prompt the user to  		   see if they'd like to ignore them rather than failing the sync */  		if(unresolvable != NULL) { -			int remove_unresolvable = 0; -			QUESTION(handle, ALPM_QUESTION_REMOVE_PKGS, unresolvable, -					NULL, NULL, &remove_unresolvable); -			if(remove_unresolvable) { +			alpm_question_remove_pkgs_t question = { +				.type = ALPM_QUESTION_REMOVE_PKGS, +				.skip = 0, +				.packages = unresolvable +			}; +			QUESTION(handle, &question); +			if(question.skip) {  				/* User wants to remove the unresolvable packages from the  				   transaction. The packages will be removed from the actual  				   transaction when the transaction packages are replaced with a @@ -560,8 +571,12 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)  		deps = _alpm_outerconflicts(handle->db_local, trans->add);  		for(i = deps; i; i = i->next) { +			alpm_question_conflict_t question = { +				.type = ALPM_QUESTION_CONFLICT_PKG, +				.remove = 0, +				.conflict = i->data +			};  			alpm_conflict_t *conflict = i->data; -			int doremove = 0;  			int found = 0;  			/* if conflict->package2 (the local package) is not elected for removal, @@ -582,9 +597,8 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)  			_alpm_log(handle, ALPM_LOG_DEBUG, "package '%s' conflicts with '%s'\n",  					conflict->package1, conflict->package2); -			QUESTION(handle, ALPM_QUESTION_CONFLICT_PKG, conflict->package1, -							conflict->package2, conflict->reason->name, &doremove); -			if(doremove) { +			QUESTION(handle, &question); +			if(question.remove) {  				/* append to the removes list */  				alpm_pkg_t *sync = alpm_pkg_find(trans->add, conflict->package1);  				alpm_pkg_t *local = _alpm_db_get_pkgfromcache(handle->db_local, conflict->package2); @@ -793,13 +807,17 @@ static int apply_deltas(alpm_handle_t *handle)  static int prompt_to_delete(alpm_handle_t *handle, const char *filepath,  		alpm_errno_t reason)  { -	int doremove = 0; -	QUESTION(handle, ALPM_QUESTION_CORRUPTED_PKG, (char *)filepath, -			&reason, NULL, &doremove); -	if(doremove) { +	alpm_question_corrupted_t question = { +		.type = ALPM_QUESTION_CORRUPTED_PKG, +		.remove = 0, +		.filepath = filepath, +		.reason = reason +	}; +	QUESTION(handle, &question); +	if(question.remove) {  		unlink(filepath);  	} -	return doremove; +	return question.remove;  }  static int validate_deltas(alpm_handle_t *handle, alpm_list_t *deltas)  | 
