diff options
Diffstat (limited to 'lib/libalpm/trans.c')
-rw-r--r-- | lib/libalpm/trans.c | 175 |
1 files changed, 71 insertions, 104 deletions
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index 82f11f3d..9eb27c30 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -33,9 +33,6 @@ #include <sys/statvfs.h> #include <unistd.h> #include <errno.h> -#ifndef __sun__ -#include <mntent.h> -#endif /* libalpm */ #include "trans.h" @@ -165,15 +162,31 @@ int SYMEXPORT alpm_trans_commit(alpm_list_t **data) ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(handle->trans->state == STATE_PREPARED, RET_ERR(PM_ERR_TRANS_NOT_PREPARED, -1)); - /* Check for database R/W permission */ - if(!(handle->trans->flags & PM_TRANS_FLAG_PRINTURIS)) { - /* The print-uris operation is a bit odd. So we explicitly check for it */ - ASSERT(handle->access == PM_ACCESS_RW, RET_ERR(PM_ERR_BADPERMS, -1)); - } - return(_alpm_trans_commit(handle->trans, data)); } +/** Interrupt a transaction. + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_trans_interrupt() +{ + pmtrans_t *trans; + + ALPM_LOG_FUNC; + + /* Sanity checks */ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + + trans = handle->trans; + ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); + ASSERT(trans->state == STATE_COMMITING || trans->state == STATE_INTERRUPTED, + RET_ERR(PM_ERR_TRANS_TYPE, -1)); + + trans->state = STATE_INTERRUPTED; + + return(0); +} + /** Release a transaction. * @return 0 on success, -1 on error (pm_errno is set accordingly) */ @@ -190,15 +203,6 @@ int SYMEXPORT alpm_trans_release() ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(trans->state != STATE_IDLE, RET_ERR(PM_ERR_TRANS_NULL, -1)); - /* during a commit do not interrupt immediately, just after a target */ - if(trans->state == STATE_COMMITING || trans->state == STATE_INTERRUPTED) { - if(trans->state == STATE_COMMITING) { - trans->state = STATE_INTERRUPTED; - } - pm_errno = PM_ERR_TRANS_COMMITING; - return(-1); - } - _alpm_trans_free(trans); handle->trans = NULL; @@ -208,7 +212,7 @@ int SYMEXPORT alpm_trans_release() handle->lckfd = -1; } if(_alpm_lckrm()) { - _alpm_log(PM_LOG_WARNING, _("could not remove lock file %s"), + _alpm_log(PM_LOG_WARNING, _("could not remove lock file %s\n"), alpm_option_get_lockfile()); alpm_logaction("warning: could not remove lock file %s", alpm_option_get_lockfile()); @@ -226,7 +230,7 @@ pmtrans_t *_alpm_trans_new() ALPM_LOG_FUNC; if((trans = malloc(sizeof(pmtrans_t))) == NULL) { - _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(pmtrans_t)); + _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes\n"), sizeof(pmtrans_t)); return(NULL); } @@ -304,6 +308,11 @@ int _alpm_trans_sysupgrade(pmtrans_t *trans) return(_alpm_sync_sysupgrade(trans, handle->db_local, handle->dbs_sync)); } +/** Add a target to the transaction. + * @param trans the current transaction + * @param target the name of the target to add + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ int _alpm_trans_addtarget(pmtrans_t *trans, char *target) { ALPM_LOG_FUNC; @@ -326,14 +335,15 @@ int _alpm_trans_addtarget(pmtrans_t *trans, char *target) } break; case PM_TRANS_TYPE_REMOVE: + case PM_TRANS_TYPE_REMOVEUPGRADE: if(_alpm_remove_loadtarget(trans, handle->db_local, target) == -1) { - /* pm_errno is set by remove_loadtarget() */ + /* pm_errno is set by _alpm_remove_loadtarget() */ return(-1); } break; case PM_TRANS_TYPE_SYNC: if(_alpm_sync_addtarget(trans, handle->db_local, handle->dbs_sync, target) == -1) { - /* pm_errno is set by sync_loadtarget() */ + /* pm_errno is set by _alpm_sync_loadtarget() */ return(-1); } break; @@ -367,6 +377,7 @@ int _alpm_trans_prepare(pmtrans_t *trans, alpm_list_t **data) } break; case PM_TRANS_TYPE_REMOVE: + case PM_TRANS_TYPE_REMOVEUPGRADE: if(_alpm_remove_prepare(trans, handle->db_local, data) == -1) { /* pm_errno is set by _alpm_remove_prepare() */ return(-1); @@ -406,13 +417,14 @@ int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data) case PM_TRANS_TYPE_ADD: case PM_TRANS_TYPE_UPGRADE: if(_alpm_add_commit(trans, handle->db_local) == -1) { - /* pm_errno is set by _alpm_add_prepare() */ + /* pm_errno is set by _alpm_add_commit() */ return(-1); } break; case PM_TRANS_TYPE_REMOVE: + case PM_TRANS_TYPE_REMOVEUPGRADE: if(_alpm_remove_commit(trans, handle->db_local) == -1) { - /* pm_errno is set by _alpm_remove_prepare() */ + /* pm_errno is set by _alpm_remove_commit() */ return(-1); } break; @@ -429,6 +441,8 @@ int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data) return(0); } +/* A depends on B through n depends <=> A listed in B's requiredby n times + * n == 0 or 1 in almost all cases */ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg) { alpm_list_t *i, *j; @@ -437,7 +451,7 @@ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg) pmdb_t *localdb; ALPM_LOG_FUNC; - + /* Sanity checks */ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(pkg != NULL, RET_ERR(PM_ERR_PKG_INVALID, -1)); @@ -446,95 +460,48 @@ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg) depends = alpm_pkg_get_depends(pkg); if(depends) { - _alpm_log(PM_LOG_DEBUG, _("updating dependency packages 'requiredby' fields for %s-%s"), + _alpm_log(PM_LOG_DEBUG, "updating dependency packages 'requiredby' fields for %s-%s\n", pkgname, pkg->version); } else { - _alpm_log(PM_LOG_DEBUG, _("package has no dependencies, no other packages to update")); + _alpm_log(PM_LOG_DEBUG, "package has no dependencies, no other packages to update\n"); } localdb = alpm_option_get_localdb(); for(i = depends; i; i = i->next) { + if(!i->data) { + continue; + } pmdepend_t* dep = alpm_splitdep(i->data); if(dep == NULL) { continue; } - - if(trans->packages && trans->type == PM_TRANS_TYPE_REMOVE) { - if(_alpm_pkg_find(dep->name, handle->trans->packages)) { - continue; - } - } - - pmpkg_t *deppkg = _alpm_db_get_pkgfromcache(localdb, dep->name); - if(!deppkg) { - int found_provides = 0; - /* look for a provides package */ - alpm_list_t *provides = _alpm_db_whatprovides(localdb, dep->name); - for(j = provides; j; j = j->next) { - if(!j->data) { - continue; - } - pmpkg_t *provpkg = j->data; - deppkg = _alpm_db_get_pkgfromcache(localdb, alpm_pkg_get_name(provpkg)); - - if(!deppkg) { - continue; - } - - found_provides = 1; - + for(j = _alpm_db_get_pkgcache(localdb); j; j = j->next) { + pmpkg_t *deppkg = j->data; + if(deppkg && alpm_depcmp(deppkg, dep)) { /* this is cheating... we call this function to populate the package */ alpm_list_t *rqdby = alpm_pkg_get_requiredby(deppkg); - _alpm_log(PM_LOG_DEBUG, _("updating 'requiredby' field for package '%s'"), + _alpm_log(PM_LOG_DEBUG, "updating 'requiredby' field for package '%s'\n", alpm_pkg_get_name(deppkg)); - if(trans->type == PM_TRANS_TYPE_REMOVE) { + + if(trans->type == PM_TRANS_TYPE_REMOVE + || trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) { void *data = NULL; rqdby = alpm_list_remove(rqdby, pkgname, _alpm_str_cmp, &data); FREE(data); deppkg->requiredby = rqdby; } else { - if(!alpm_list_find_str(rqdby, pkgname)) { - rqdby = alpm_list_add(rqdby, strdup(pkgname)); - deppkg->requiredby = rqdby; - } + rqdby = alpm_list_add(rqdby, strdup(pkgname)); + deppkg->requiredby = rqdby; } if(_alpm_db_write(localdb, deppkg, INFRQ_DEPENDS)) { - _alpm_log(PM_LOG_ERROR, _("could not update 'requiredby' database entry %s-%s"), + _alpm_log(PM_LOG_ERROR, _("could not update 'requiredby' database entry %s-%s\n"), alpm_pkg_get_name(deppkg), alpm_pkg_get_version(deppkg)); } } - alpm_list_free(provides); - - if(!found_provides) { - _alpm_log(PM_LOG_DEBUG, _("could not find dependency '%s'"), dep->name); - continue; - } - } - - /* this is cheating... we call this function to populate the package */ - alpm_list_t *rqdby = alpm_pkg_get_requiredby(deppkg); - - _alpm_log(PM_LOG_DEBUG, _("updating 'requiredby' field for package '%s'"), - alpm_pkg_get_name(deppkg)); - if(trans->type == PM_TRANS_TYPE_REMOVE) { - void *data = NULL; - rqdby = alpm_list_remove(rqdby, pkgname, _alpm_str_cmp, &data); - FREE(data); - deppkg->requiredby = rqdby; - } else { - if(!alpm_list_find_str(rqdby, pkgname)) { - rqdby = alpm_list_add(rqdby, strdup(pkgname)); - deppkg->requiredby = rqdby; - } - } - - if(_alpm_db_write(localdb, deppkg, INFRQ_DEPENDS)) { - _alpm_log(PM_LOG_ERROR, _("could not update 'requiredby' database entry %s-%s"), - alpm_pkg_get_name(deppkg), alpm_pkg_get_version(deppkg)); } - free(dep); + FREE(dep); } return(0); } @@ -566,7 +533,7 @@ static int grep(const char *fn, const char *needle) int _alpm_runscriptlet(const char *root, const char *installfn, const char *script, const char *ver, - const char *oldver, pmtrans_t *trans) + const char *oldver) { char scriptfn[PATH_MAX]; char cmdline[PATH_MAX]; @@ -581,7 +548,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn, if(stat(installfn, &buf)) { /* not found */ - _alpm_log(PM_LOG_DEBUG, "scriptlet '%s' not found", installfn); + _alpm_log(PM_LOG_DEBUG, "scriptlet '%s' not found\n", installfn); return(0); } @@ -592,7 +559,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn, } snprintf(tmpdir, PATH_MAX, "%stmp/alpm_XXXXXX", root); if(mkdtemp(tmpdir) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not create temp directory")); + _alpm_log(PM_LOG_ERROR, _("could not create temp directory\n")); return(1); } _alpm_unpack(installfn, tmpdir, ".INSTALL"); @@ -612,18 +579,18 @@ int _alpm_runscriptlet(const char *root, const char *installfn, /* save the cwd so we can restore it later */ if(getcwd(cwd, PATH_MAX) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not get current working directory")); + _alpm_log(PM_LOG_ERROR, _("could not get current working directory\n")); /* in case of error, cwd content is undefined: so we set it to something */ cwd[0] = 0; } /* just in case our cwd was removed in the upgrade operation */ if(chdir(root) != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)"), root, strerror(errno)); + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), root, strerror(errno)); goto cleanup; } - _alpm_log(PM_LOG_DEBUG, _("executing %s script..."), script); + _alpm_log(PM_LOG_DEBUG, "executing %s script...\n", script); if(oldver) { snprintf(cmdline, PATH_MAX, "source %s %s %s %s", @@ -632,32 +599,32 @@ int _alpm_runscriptlet(const char *root, const char *installfn, snprintf(cmdline, PATH_MAX, "source %s %s %s", scriptpath, script, ver); } - _alpm_log(PM_LOG_DEBUG, "%s", cmdline); + _alpm_log(PM_LOG_DEBUG, "%s\n", cmdline); pid = fork(); if(pid == -1) { - _alpm_log(PM_LOG_ERROR, _("could not fork a new process (%s)"), strerror(errno)); + _alpm_log(PM_LOG_ERROR, _("could not fork a new process (%s)\n"), strerror(errno)); retval = 1; goto cleanup; } if(pid == 0) { - _alpm_log(PM_LOG_DEBUG, _("chrooting in %s"), root); + _alpm_log(PM_LOG_DEBUG, "chrooting in %s\n", root); if(chroot(root) != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change the root directory (%s)"), strerror(errno)); - return(1); + _alpm_log(PM_LOG_ERROR, _("could not change the root directory (%s)\n"), strerror(errno)); + exit(1); } if(chdir("/") != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change directory to / (%s)"), strerror(errno)); - return(1); + _alpm_log(PM_LOG_ERROR, _("could not change directory to / (%s)\n"), strerror(errno)); + exit(1); } umask(0022); - _alpm_log(PM_LOG_DEBUG, _("executing \"%s\""), cmdline); + _alpm_log(PM_LOG_DEBUG, "executing \"%s\"\n", cmdline); execl("/bin/sh", "sh", "-c", cmdline, (char *)NULL); exit(0); } else { if(waitpid(pid, 0, 0) == -1) { - _alpm_log(PM_LOG_ERROR, _("call to waitpid failed (%s)"), + _alpm_log(PM_LOG_ERROR, _("call to waitpid failed (%s)\n"), strerror(errno)); retval = 1; goto cleanup; @@ -666,7 +633,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn, cleanup: if(strlen(tmpdir) && _alpm_rmrf(tmpdir)) { - _alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s"), tmpdir); + _alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s\n"), tmpdir); } if(strlen(cwd)) { chdir(cwd); |