diff options
Diffstat (limited to 'lib/libalpm/add.c')
-rw-r--r-- | lib/libalpm/add.c | 229 |
1 files changed, 36 insertions, 193 deletions
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 1d143c6f..c6751a49 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -50,21 +50,30 @@ #include "remove.h" #include "handle.h" -int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name) +/** Add a file target to the transaction. + * @param target the name of the file target to add + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_add_target(char *target) { pmpkg_t *pkg = NULL; const char *pkgname, *pkgver; alpm_list_t *i; + pmtrans_t *trans; ALPM_LOG_FUNC; + /* Sanity checks */ + ASSERT(target != NULL && strlen(target) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1)); + 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_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - ASSERT(name != NULL && strlen(name) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1)); - _alpm_log(PM_LOG_DEBUG, "loading target '%s'\n", name); + _alpm_log(PM_LOG_DEBUG, "loading target '%s'\n", target); - if(alpm_pkg_load(name, 1, &pkg) != 0) { + if(alpm_pkg_load(target, 1, &pkg) != 0) { goto error; } pkgname = alpm_pkg_get_name(pkg); @@ -72,17 +81,19 @@ int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name) /* check if an older version of said package is already in transaction * packages. if so, replace it in the list */ - for(i = trans->packages; i; i = i->next) { + for(i = trans->add; i; i = i->next) { pmpkg_t *transpkg = i->data; if(strcmp(transpkg->name, pkgname) == 0) { if(alpm_pkg_vercmp(transpkg->version, pkgver) < 0) { - _alpm_log(PM_LOG_WARNING, _("replacing older version %s-%s by %s in target list\n"), - transpkg->name, transpkg->version, pkgver); + _alpm_log(PM_LOG_WARNING, + _("replacing older version %s-%s by %s in target list\n"), + transpkg->name, transpkg->version, pkgver); _alpm_pkg_free(i->data); i->data = pkg; } else { - _alpm_log(PM_LOG_WARNING, _("skipping %s-%s because newer version %s is in target list\n"), - pkgname, pkgver, transpkg->version); + _alpm_log(PM_LOG_WARNING, + _("skipping %s-%s because newer version %s is in target list\n"), + pkgname, pkgver, transpkg->version); _alpm_pkg_free(pkg); } return(0); @@ -90,7 +101,7 @@ int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name) } /* add the package to the transaction */ - trans->packages = alpm_list_add(trans->packages, pkg); + trans->add = alpm_list_add(trans->add, pkg); return(0); @@ -99,176 +110,6 @@ error: return(-1); } -int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) -{ - alpm_list_t *lp = NULL; - - ALPM_LOG_FUNC; - - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - - /* Check dependencies - */ - if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { - EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL); - - /* look for unsatisfied dependencies */ - _alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n"); - lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, NULL, trans->packages); - if(lp != NULL) { - if(data) { - *data = lp; - } else { - alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free); - alpm_list_free(lp); - } - RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1); - } - - /* no unsatisfied deps, so look for conflicts */ - _alpm_log(PM_LOG_DEBUG, "looking for conflicts\n"); - alpm_list_t *inner = _alpm_innerconflicts(trans->packages); - alpm_list_t *outer = _alpm_outerconflicts(db, trans->packages); - lp = alpm_list_join(inner, outer); - - /* TODO : factorize the conflict resolving code from sync.c to use it here (FS#3492) */ - - if(lp != NULL) { - if(data) { - *data = lp; - } else { - alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_conflict_free); - alpm_list_free(lp); - } - if(inner) { - _alpm_log(PM_LOG_ERROR, _("conflicting packages were found in target list\n")); - _alpm_log(PM_LOG_ERROR, _("you cannot install two conflicting packages at the same time\n")); - } - if(outer) { - _alpm_log(PM_LOG_ERROR, _("replacing packages with -U is not supported yet\n")); - _alpm_log(PM_LOG_ERROR, _("you can replace packages manually using -Rd and -U\n")); - } - RET_ERR(PM_ERR_CONFLICTING_DEPS, -1); - } - - /* re-order w.r.t. dependencies */ - _alpm_log(PM_LOG_DEBUG, "sorting by dependencies\n"); - lp = _alpm_sortbydeps(trans->packages, 0); - /* free the old alltargs */ - alpm_list_free(trans->packages); - trans->packages = lp; - - EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL); - } - - /* Check for file conflicts */ - if(!(trans->flags & PM_TRANS_FLAG_FORCE)) { - EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL); - - _alpm_log(PM_LOG_DEBUG, "looking for file conflicts\n"); - lp = _alpm_db_find_fileconflicts(db, trans, trans->packages, NULL); - if(lp != NULL) { - if(data) { - *data = lp; - } else { - alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_fileconflict_free); - alpm_list_free(lp); - } - RET_ERR(PM_ERR_FILE_CONFLICTS, -1); - } - - EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL); - } - - return(0); -} - -static int upgrade_remove(pmpkg_t *oldpkg, pmpkg_t *newpkg, pmtrans_t *trans, pmdb_t *db) { - /* this is kinda odd. If the old package exists, at this point we make a - * NEW transaction, unrelated to handle->trans, and instantiate a "remove" - * with the type PM_TRANS_TYPE_REMOVEUPGRADE. TODO: kill this weird - * behavior. */ - pmtrans_t *tr = _alpm_trans_new(); - - ALPM_LOG_FUNC; - - _alpm_log(PM_LOG_DEBUG, "removing old package first (%s-%s)\n", - oldpkg->name, oldpkg->version); - - if(!tr) { - RET_ERR(PM_ERR_TRANS_ABORT, -1); - } - - if(_alpm_trans_init(tr, PM_TRANS_TYPE_REMOVEUPGRADE, trans->flags, - NULL, NULL, NULL) == -1) { - _alpm_trans_free(tr); - tr = NULL; - RET_ERR(PM_ERR_TRANS_ABORT, -1); - } - - if(_alpm_remove_loadtarget(tr, db, newpkg->name) == -1) { - _alpm_trans_free(tr); - tr = NULL; - RET_ERR(PM_ERR_TRANS_ABORT, -1); - } - - /* copy the remove skiplist over */ - tr->skip_remove = alpm_list_strdup(trans->skip_remove); - const alpm_list_t *b; - - /* Add files in the NEW backup array to the NoUpgrade array - * so this removal operation doesn't kill them */ - alpm_list_t *old_noupgrade = alpm_list_strdup(handle->noupgrade); - /* old package backup list */ - alpm_list_t *filelist = alpm_pkg_get_files(newpkg); - for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) { - char *backup = _alpm_backup_file(b->data); - /* safety check (fix the upgrade026 pactest) */ - if(!alpm_list_find_str(filelist, backup)) { - FREE(backup); - continue; - } - _alpm_log(PM_LOG_DEBUG, "adding %s to the NoUpgrade array temporarily\n", - backup); - handle->noupgrade = alpm_list_add(handle->noupgrade, - backup); - } - - /* TODO: we could also add files in the OLD backup array, but this would - * change the backup handling behavior, and break several pactests, and we - * can't do this just before 3.1 release. - * The unlink_file function in remove.c would also need to be reviewed. */ -#if 0 - /* new package backup list */ - for(b = alpm_pkg_get_backup(oldpkg); b; b = b->next) { - char *backup = _alpm_backup_file(b->data); - /* make sure we don't add duplicate entries */ - if(!alpm_list_find_ptr(handle->noupgrade, backup)) { - _alpm_log(PM_LOG_DEBUG, "adding %s to the NoUpgrade array temporarily\n", - backup); - handle->noupgrade = alpm_list_add(handle->noupgrade, - backup); - } - } -#endif - - int ret = _alpm_remove_commit(tr, db); - - _alpm_trans_free(tr); - tr = NULL; - - /* restore our "NoUpgrade" list to previous state */ - FREELIST(handle->noupgrade); - handle->noupgrade = old_noupgrade; - - if(ret == -1) { - RET_ERR(PM_ERR_TRANS_ABORT, -1); - } - - return(0); -} - static int extract_single_file(struct archive *archive, struct archive_entry *entry, pmpkg_t *newpkg, pmpkg_t *oldpkg, pmtrans_t *trans, pmdb_t *db) @@ -291,13 +132,13 @@ static int extract_single_file(struct archive *archive, if(strcmp(entryname, ".INSTALL") == 0) { /* the install script goes inside the db */ - snprintf(filename, PATH_MAX, "%s%s-%s/install", db->path, - newpkg->name, newpkg->version); + snprintf(filename, PATH_MAX, "%s%s-%s/install", + _alpm_db_path(db), newpkg->name, newpkg->version); archive_entry_set_perm(entry, 0644); } else if(strcmp(entryname, ".CHANGELOG") == 0) { /* the changelog goes inside the db */ - snprintf(filename, PATH_MAX, "%s%s-%s/changelog", db->path, - newpkg->name, newpkg->version); + snprintf(filename, PATH_MAX, "%s%s-%s/changelog", + _alpm_db_path(db), newpkg->name, newpkg->version); archive_entry_set_perm(entry, 0644); } else if(*entryname == '.') { /* for now, ignore all files starting with '.' that haven't @@ -642,8 +483,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count, ALPM_LOG_FUNC; - snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", db->path, - alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg)); + snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", + _alpm_db_path(db), alpm_pkg_get_name(newpkg), + alpm_pkg_get_version(newpkg)); /* see if this is an upgrade. if so, remove the old package first */ pmpkg_t *local = _alpm_db_get_pkgfromcache(db, newpkg->name); @@ -691,8 +533,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count, if(oldpkg) { /* set up fake remove transaction */ - int ret = upgrade_remove(oldpkg, newpkg, trans, db); - if(ret != 0) { + if(_alpm_upgraderemove_package(oldpkg, newpkg, trans) == -1) { + pm_errno = PM_ERR_TRANS_ABORT; + ret = -1; goto cleanup; } } @@ -858,7 +701,7 @@ cleanup: return(ret); } -int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) +int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db) { int pkg_count, pkg_current; alpm_list_t *targ; @@ -868,15 +711,15 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - if(trans->packages == NULL) { + if(trans->add == NULL) { return(0); } - pkg_count = alpm_list_count(trans->packages); + pkg_count = alpm_list_count(trans->add); pkg_current = 1; /* loop through our package list adding/upgrading one at a time */ - for(targ = trans->packages; targ; targ = targ->next) { + for(targ = trans->add; targ; targ = targ->next) { if(handle->trans->state == STATE_INTERRUPTED) { return(0); } |