From a36ded25eb9bdea5b73c33f993820b657f9e6623 Mon Sep 17 00:00:00 2001 From: Judd Vinet Date: Sun, 9 Oct 2005 06:09:57 +0000 Subject: added conversation callback support for transactions --- lib/libalpm/alpm.c | 4 +-- lib/libalpm/alpm.h | 18 ++++++++--- lib/libalpm/deps.c | 10 +++--- lib/libalpm/deps.h | 2 +- lib/libalpm/package.c | 21 ++++++++++++ lib/libalpm/package.h | 1 + lib/libalpm/sync.c | 89 ++++++++++++++++++++++++++++----------------------- lib/libalpm/trans.c | 4 ++- lib/libalpm/trans.h | 11 +++++-- lib/libalpm/util.c | 10 +++--- 10 files changed, 109 insertions(+), 61 deletions(-) (limited to 'lib') diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index d0e31e52..2b6c2f5f 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -545,7 +545,7 @@ void *alpm_trans_getinfo(unsigned char parm) return(data); } -int alpm_trans_init(unsigned char type, unsigned char flags, alpm_trans_cb_event event) +int alpm_trans_init(unsigned char type, unsigned char flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv) { /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); @@ -557,7 +557,7 @@ int alpm_trans_init(unsigned char type, unsigned char flags, alpm_trans_cb_event RET_ERR(PM_ERR_MEMORY, -1); } - return(trans_init(handle->trans, type, flags, event)); + return(trans_init(handle->trans, type, flags, event, conv)); } int alpm_trans_sysupgrade() diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 68e8b7b0..3ab747e3 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -211,7 +211,7 @@ enum { #define PM_TRANS_FLAG_RECURSE 0x20 #define PM_TRANS_FLAG_DBONLY 0x40 -/* Events */ +/* Transaction Events */ enum { PM_TRANS_EVT_CHECKDEPS_START = 1, PM_TRANS_EVT_CHECKDEPS_DONE, @@ -229,11 +229,19 @@ enum { PM_TRANS_EVT_UPGRADE_DONE }; -/* Event callback */ +/* Transaction Conversations (ie, questions) */ +enum { + PM_TRANS_CONV_INSTALL_IGNOREPKG, + PM_TRANS_CONV_REPLACE_PKG, + PM_TRANS_CONV_LOCAL_NEWER, + PM_TRANS_CONV_LOCAL_UPTODATE +}; + +/* Transaction Event callback */ typedef void (*alpm_trans_cb_event)(unsigned char, void *, void *); -/* Conversation callback */ -typedef void (*alpm_trans_cb_conv)(unsigned char, void *, void *); +/* Transaction Conversation callback */ +typedef void (*alpm_trans_cb_conv)(unsigned char, void *, void *, void *, int *); /* Info parameters */ enum { @@ -244,7 +252,7 @@ enum { }; void *alpm_trans_getinfo(unsigned char parm); -int alpm_trans_init(unsigned char type, unsigned char flags, alpm_trans_cb_event cb_event); +int alpm_trans_init(unsigned char type, unsigned char flags, alpm_trans_cb_event cb_event, alpm_trans_cb_conv conv); int alpm_trans_sysupgrade(); int alpm_trans_addtarget(char *target); int alpm_trans_prepare(PM_LIST **data); diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 9a35e665..b92d2a45 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -543,7 +543,7 @@ PMList* removedeps(pmdb_t *db, PMList *targs) * * make sure *list and *trail are already initialized */ -int resolvedeps(pmdb_t *local, PMList *dbs_sync, pmpkg_t *syncpkg, PMList *list, PMList *trail) +int resolvedeps(pmdb_t *local, PMList *dbs_sync, pmpkg_t *syncpkg, PMList *list, PMList *trail, pmtrans_t *trans) { PMList *i, *j; PMList *targ; @@ -632,13 +632,13 @@ int resolvedeps(pmdb_t *local, PMList *dbs_sync, pmpkg_t *syncpkg, PMList *list, } } if(found) { - /* ORE - usedep = yesno("%s requires %s, but it is in IgnorePkg. Install anyway? [Y/n] ", - miss->target, sync->pkg->name);*/ + pmpkg_t *dummypkg = pkg_dummy(miss->target, NULL); + QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, dummypkg, sync, NULL, &usedep); + FREEPKG(dummypkg); } if(usedep) { trail = pm_list_add(trail, sync); - if(resolvedeps(local, dbs_sync, sync, list, trail)) { + if(resolvedeps(local, dbs_sync, sync, list, trail, trans)) { goto error; } _alpm_log(PM_LOG_FLOW2, "adding dependency %s-%s", sync->name, sync->version); diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h index cc0d891b..44718808 100644 --- a/lib/libalpm/deps.h +++ b/lib/libalpm/deps.h @@ -40,7 +40,7 @@ PMList *sortbydeps(PMList *targets, int mode); PMList *checkdeps(pmdb_t *db, unsigned char op, PMList *packages); int splitdep(char *depstr, pmdepend_t *depend); PMList *removedeps(pmdb_t *db, PMList *targs); -int resolvedeps(pmdb_t *local, PMList *dbs_sync, pmpkg_t *syncpkg, PMList *list, PMList *trail); +int resolvedeps(pmdb_t *local, PMList *dbs_sync, pmpkg_t *syncpkg, PMList *list, PMList *trail, pmtrans_t *trans); #endif /* _ALPM_DEPS_H */ diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 3b0669fc..93f234e7 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -132,6 +132,27 @@ void pkg_free(pmpkg_t *pkg) return; } +/* Create a dummy package struct that only contains the package + * name and version. This is useful when we're only passing + * name/version data, but it needs to be wrapped in a pmpkg_t + */ +pmpkg_t* pkg_dummy(const char *name, const char *version) +{ + pmpkg_t *pkg = pkg_new(); + if(pkg == NULL) { + return(NULL); + } + + if(name) { + STRNCPY(pkg->name, name, PKG_NAME_LEN-1); + } + if(version) { + STRNCPY(pkg->version, version, PKG_VERSION_LEN-1); + } + + return(pkg); +} + /* Parses the package description file for the current package * * Returns: 0 on success, 1 on error diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index a6b8b224..41566143 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -89,6 +89,7 @@ do { \ pmpkg_t* pkg_new(); pmpkg_t *pkg_dup(pmpkg_t *pkg); void pkg_free(pmpkg_t *pkg); +pmpkg_t* pkg_dummy(const char *name, const char *version); pmpkg_t *pkg_load(char *pkgfile); int pkg_isin(pmpkg_t *needle, PMList *haystack); int pkg_splitname(char *target, char *name, char *version); diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 27c4dac5..3fa33452 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -154,37 +154,43 @@ int sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync) if(pm_list_is_strin(lpkg->name, handle->ignorepkg)) { _alpm_log(PM_LOG_WARNING, "%s-%s: ignoring package upgrade (to be replaced by %s-%s)", lpkg->name, lpkg->version, spkg->name, spkg->version); - } else /* ORE if(yesno(":: Replace %s with %s from \"%s\"? [Y/n] ", lpkg->name, spkg->name, ((pmdb_t *)i->data)->treename)) */ { - /* if confirmed, add this to the 'final' list, designating 'lpkg' as - * the package to replace. - */ - pmsyncpkg_t *sync; - pmpkg_t *dummy = pkg_new(); - if(dummy == NULL) { - pm_errno = PM_ERR_MEMORY; - goto error; - } - STRNCPY(dummy->name, lpkg->name, PKG_NAME_LEN); - dummy->requiredby = _alpm_list_strdup(lpkg->requiredby); - /* check if spkg->name is already in the packages list. */ - sync = find_pkginsync(spkg->name, trans->packages); - if(sync) { - /* found it -- just append to the replaces list */ - sync->data = pm_list_add(sync->data, dummy); - } else { - /* none found -- enter pkg into the final sync list */ - sync = sync_new(PM_SYNC_TYPE_REPLACE, spkg, NULL); - if(sync == NULL) { - FREEPKG(dummy); + } else { + /* get confirmation for the replacement */ + int doreplace = 0; + QUESTION(trans, PM_TRANS_CONV_REPLACE_PKG, lpkg, spkg, ((pmdb_t *)i->data)->treename, &doreplace); + + if(doreplace) { + /* if confirmed, add this to the 'final' list, designating 'lpkg' as + * the package to replace. + */ + pmsyncpkg_t *sync; + pmpkg_t *dummy = pkg_dummy(lpkg->name, NULL); + if(dummy == NULL) { pm_errno = PM_ERR_MEMORY; goto error; } - sync->data = pm_list_add(sync->data, dummy); - trans->packages = pm_list_add(trans->packages, sync); + dummy->requiredby = _alpm_list_strdup(lpkg->requiredby); + /* check if spkg->name is already in the packages list. */ + sync = find_pkginsync(spkg->name, trans->packages); + if(sync) { + /* found it -- just append to the replaces list */ + sync->data = pm_list_add(sync->data, dummy); + } else { + /* none found -- enter pkg into the final sync list */ + sync = sync_new(PM_SYNC_TYPE_REPLACE, spkg, NULL); + if(sync == NULL) { + FREEPKG(dummy); + pm_errno = PM_ERR_MEMORY; + goto error; + } + sync->data = pm_list_add(sync->data, dummy); + trans->packages = pm_list_add(trans->packages, sync); + } + _alpm_log(PM_LOG_DEBUG, "%s-%s elected for upgrade (to be replaced by %s-%s)", + lpkg->name, lpkg->version, spkg->name, spkg->version); } - _alpm_log(PM_LOG_DEBUG, "%s-%s elected for upgrade (to be replaced by %s-%s)", - lpkg->name, lpkg->version, spkg->name, spkg->version); } + break; } } } @@ -288,19 +294,21 @@ int sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, char *n if(local) { cmp = alpm_pkg_vercmp(local->version, spkg->version); if(cmp > 0) { - /* local version is newer - get confirmation first */ - /* ORE - if(!yesno(":: %s-%s: local version is newer. Upgrade anyway? [Y/n] ", lpkgname, lpkgver)) { - }*/ - _alpm_log(PM_LOG_WARNING, "%s-%s: local version is newer -- skipping", local->name, local->version); - return(0); + /* local version is newer -- get confirmation before adding */ + int resp = 0; + QUESTION(trans, PM_TRANS_CONV_LOCAL_NEWER, local, NULL, NULL, &resp); + if(!resp) { + _alpm_log(PM_LOG_WARNING, "%s-%s: local version is newer -- skipping", local->name, local->version); + return(0); + } } else if(cmp == 0) { - /* versions are identical */ - /* ORE - if(!yesno(":: %s-%s: is up to date. Upgrade anyway? [Y/n] ", lpkgname, lpkgver)) { - }*/ - _alpm_log(PM_LOG_WARNING, "%s-%s is up to date -- skipping", local->name, local->version); - return(0); + /* versions are identical -- get confirmation before adding */ + int resp = 0; + QUESTION(trans, PM_TRANS_CONV_LOCAL_UPTODATE, local, NULL, NULL, &resp); + if(!resp) { + _alpm_log(PM_LOG_WARNING, "%s-%s is up to date -- skipping", local->name, local->version); + return(0); + } } } @@ -353,7 +361,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList ** pmsyncpkg_t *sync = i->data; pmpkg_t *spkg = sync->pkg; _alpm_log(PM_LOG_FLOW1, "resolving dependencies for package %s", spkg->name); - if(resolvedeps(db_local, dbs_sync, spkg, list, trail) == -1) { + if(resolvedeps(db_local, dbs_sync, spkg, list, trail, trans) == -1) { /* pm_errno is set by resolvedeps */ goto error; } @@ -523,6 +531,7 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local) } FREETRANS(tr); + fprintf(stderr, "HERE\n"); fflush(stdout); /* install targets */ _alpm_log(PM_LOG_FLOW1, "installing packages"); tr = trans_new(); @@ -531,7 +540,7 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local) pm_errno = PM_ERR_XXX; goto error; } - if(trans_init(tr, PM_TRANS_TYPE_UPGRADE, trans->flags | PM_TRANS_FLAG_NODEPS, NULL) == -1) { + if(trans_init(tr, PM_TRANS_TYPE_UPGRADE, trans->flags | PM_TRANS_FLAG_NODEPS, NULL, NULL) == -1) { _alpm_log(PM_LOG_ERROR, "could not initialize transaction"); pm_errno = PM_ERR_XXX; goto error; diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index 43f134e0..12d35806 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -50,6 +50,7 @@ pmtrans_t *trans_new() trans->type = 0; trans->flags = 0; trans->cb_event = NULL; + trans->cb_conv = NULL; trans->state = STATE_IDLE; return(trans); @@ -77,7 +78,7 @@ void trans_free(pmtrans_t *trans) free(trans); } -int trans_init(pmtrans_t *trans, unsigned char type, unsigned char flags, alpm_trans_cb_event event) +int trans_init(pmtrans_t *trans, unsigned char type, unsigned char flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv) { /* Sanity checks */ if(trans == NULL) { @@ -91,6 +92,7 @@ int trans_init(pmtrans_t *trans, unsigned char type, unsigned char flags, alpm_t trans->type = type; trans->flags = flags; trans->cb_event = event; + trans->cb_conv = conv; trans->state = STATE_INITIALIZED; return(0); diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h index 8518e5aa..b9ca04a8 100644 --- a/lib/libalpm/trans.h +++ b/lib/libalpm/trans.h @@ -38,6 +38,7 @@ typedef struct __pmtrans_t { PMList *packages; /* PMList of (pmpkg_t *) or (pmsyncpkg_t *) */ PMList *skiplist; /* PMList of (char *) */ alpm_trans_cb_event cb_event; + alpm_trans_cb_conv cb_conv; } pmtrans_t; #define FREETRANS(p) \ @@ -49,14 +50,20 @@ do { \ } while (0) #define EVENT(t, e, d1, d2) \ do { \ - if((t) && (t)->cb_event) { \ + if((t) && (t)->cb_conv) { \ (t)->cb_event(e, d1, d2); \ } \ } while(0) +#define QUESTION(t, e, d1, d2, d3, r) \ +do { \ + if((t) && (t)->cb_event) { \ + (t)->cb_conv(e, d1, d2, d3, r); \ + } \ +} while(0) pmtrans_t *trans_new(); void trans_free(pmtrans_t *trans); -int trans_init(pmtrans_t *trans, unsigned char type, unsigned char flags, alpm_trans_cb_event event); +int trans_init(pmtrans_t *trans, unsigned char type, unsigned char flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv); int trans_sysupgrade(pmtrans_t *trans); int trans_addtarget(pmtrans_t *trans, char *target); int trans_prepare(pmtrans_t *trans, PMList **data); diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 6b2b60a6..680c4095 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -376,7 +376,7 @@ int _alpm_runscriptlet(char *root, char *installfn, char *script, char *ver, cha snprintf(cpath, PATH_MAX, "%s/chroot", dirs[i]); if(!stat(cpath, &buf)) { chrootbin = strdup(cpath); - _alpm_log(PM_LOG_DEBUG, "found chroot binary: %s", chrootbin); + _alpm_log(PM_LOG_FLOW2, "found chroot binary: %s", chrootbin); } } if(chrootbin == NULL) { @@ -421,11 +421,11 @@ int _alpm_runscriptlet(char *root, char *installfn, char *script, char *ver, cha _alpm_log(PM_LOG_FLOW2, "executing %s script...", script); if(oldver) { - snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | chroot %s /bin/sh", - scriptpath, script, ver, oldver, root); + snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | %s %s /bin/sh", + scriptpath, script, ver, oldver, chrootbin, root); } else { - snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | chroot %s /bin/sh", - scriptpath, script, ver, root); + snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | %s %s /bin/sh", + scriptpath, script, ver, chrootbin, root); } _alpm_log(PM_LOG_DEBUG, "%s", cmdline); system(cmdline); -- cgit v1.2.3-70-g09d2