From f1fadecfb34555cfac1c47f217253a535d64a28b Mon Sep 17 00:00:00 2001 From: Olivier Brunel Date: Sun, 15 Jun 2014 19:42:40 +0200 Subject: Update the question callback Much like with events, instead of using a bunch of void* arguments for all questions, we now send one pointer to an alpm_question_t union. This contains the type of question that was triggered. With this information, a question-specific struct can be accessed in order to get additional arguments. Signed-off-by: Olivier Brunel Signed-off-by: Allan McRae --- lib/libalpm/alpm.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++-- lib/libalpm/deps.c | 38 +++++++++++------- lib/libalpm/handle.h | 4 +- lib/libalpm/signing.c | 12 ++++-- lib/libalpm/sync.c | 60 +++++++++++++++++++---------- 5 files changed, 173 insertions(+), 45 deletions(-) (limited to 'lib') 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) -- cgit v1.2.3-24-g4f1b