1
0
mirror of https://github.com/moparisthebest/pacman synced 2024-12-22 15:58:50 -05:00

added conversation callback support for transactions

This commit is contained in:
Judd Vinet 2005-10-09 06:09:57 +00:00
parent 9a4719d3c5
commit a36ded25eb
16 changed files with 151 additions and 67 deletions

View File

@ -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()

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -59,7 +59,7 @@ int pacman_add(list_t *targets)
/* Step 1: create a new transaction
*/
if(alpm_trans_init((pmo_upgrade == 0) ? PM_TRANS_TYPE_ADD : PM_TRANS_TYPE_UPGRADE,
pmo_flags, cb_trans) == -1) {
pmo_flags, cb_trans_evt, cb_trans_conv) == -1) {
ERR(NL, "%s\n", alpm_strerror(pm_errno));
return(1);
}

View File

@ -287,7 +287,7 @@ int pacman_deptest(list_t *targets)
/* we create a transaction to hold a dummy package to be able to use
* deps checkings from alpm_trans_prepare() */
if(alpm_trans_init(PM_TRANS_TYPE_ADD, 0, NULL) == -1) {
if(alpm_trans_init(PM_TRANS_TYPE_ADD, 0, NULL, NULL) == -1) {
ERR(NL, "%s", alpm_strerror(pm_errno));
return(1);
}

View File

@ -73,7 +73,7 @@ int pacman_remove(list_t *targets)
/* Step 1: create a new transaction
*/
if(alpm_trans_init(PM_TRANS_TYPE_REMOVE, pmo_flags, cb_trans) == -1) {
if(alpm_trans_init(PM_TRANS_TYPE_REMOVE, pmo_flags, cb_trans_evt, cb_trans_conv) == -1) {
ERR(NL, "failed to init transaction (%s)\n", alpm_strerror(pm_errno));
goto error;
}

View File

@ -424,7 +424,7 @@ int pacman_sync(list_t *targets)
/* Step 1: create a new transaction...
*/
if(alpm_trans_init(PM_TRANS_TYPE_SYNC, pmo_flags, cb_trans) == -1) {
if(alpm_trans_init(PM_TRANS_TYPE_SYNC, pmo_flags, cb_trans_evt, cb_trans_conv) == -1) {
ERR(NL, "failed to init transaction (%s)\n", alpm_strerror(pm_errno));
retval = 1;
goto cleanup;

View File

@ -36,7 +36,7 @@
/* Callback to handle transaction events
*/
void cb_trans(unsigned char event, void *data1, void *data2)
void cb_trans_evt(unsigned char event, void *data1, void *data2)
{
char str[LOG_STR_LEN] = "";
@ -93,4 +93,37 @@ void cb_trans(unsigned char event, void *data1, void *data2)
}
}
void cb_trans_conv(unsigned char event, void *data1, void *data2, void *data3, int *response)
{
char str[LOG_STR_LEN] = "";
switch(event) {
case PM_TRANS_CONV_INSTALL_IGNOREPKG:
snprintf(str, LOG_STR_LEN, ":: %s requires %s, but it is in IgnorePkg. Install anyway? [Y/n] ",
(char *)alpm_pkg_getinfo(data1, PM_PKG_NAME),
(char *)alpm_pkg_getinfo(data2, PM_PKG_NAME));
*response = yesno(str);
break;
case PM_TRANS_CONV_REPLACE_PKG:
snprintf(str, LOG_STR_LEN, ":: Replace %s with %s from \"%s\"? [Y/n] ",
(char *)alpm_pkg_getinfo(data1, PM_PKG_NAME),
(char *)alpm_pkg_getinfo(data2, PM_PKG_NAME),
(char *)data3);
*response = yesno(str);
break;
case PM_TRANS_CONV_LOCAL_NEWER:
snprintf(str, LOG_STR_LEN, ":: %s-%s: local version is newer. Upgrade anyway? [Y/n] ",
(char *)alpm_pkg_getinfo(data1, PM_PKG_NAME),
(char *)alpm_pkg_getinfo(data1, PM_PKG_VERSION));
*response = yesno(str);
break;
case PM_TRANS_CONV_LOCAL_UPTODATE:
snprintf(str, LOG_STR_LEN, ":: %s-%s: local version is up to date. Upgrade anyway? [Y/n] ",
(char *)alpm_pkg_getinfo(data1, PM_PKG_NAME),
(char *)alpm_pkg_getinfo(data1, PM_PKG_VERSION));
*response = yesno(str);
break;
}
}
/* vim: set ts=2 sw=2 noet: */

View File

@ -22,7 +22,10 @@
#define _PM_TRANS_H
/* callback to handle messages/notifications from pacman transactions */
void cb_trans(unsigned char event, void *data1, void *data2);
void cb_trans_evt(unsigned char event, void *data1, void *data2);
/* callback to handle questions from pacman transactions (yes/no) */
void cb_trans_conv(unsigned char event, void *data1, void *data2, void *data3, int *response);
#endif /* _PM_TRANS_H */