summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/sync.c')
-rw-r--r--lib/libalpm/sync.c173
1 files changed, 87 insertions, 86 deletions
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 4a705b57..fca96d8f 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -77,17 +77,12 @@ void _alpm_sync_free(pmsyncpkg_t *sync)
/* Find recommended replacements for packages during a sync.
*/
-static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
- alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
+static int find_replacements(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync)
{
alpm_list_t *i, *j, *k; /* wow */
ALPM_LOG_FUNC;
- if(syncpkgs == NULL) {
- return(-1);
- }
-
/* check for "recommended" package replacements */
_alpm_log(PM_LOG_DEBUG, "checking for package replacements\n");
for(i = dbs_sync; i; i = i->next) {
@@ -113,13 +108,10 @@ static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
alpm_pkg_get_name(lpkg), alpm_pkg_get_version(lpkg),
alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
} else {
- /* get confirmation for the replacement */
- if(trans) {
- int doreplace = 0;
- QUESTION(trans, PM_TRANS_CONV_REPLACE_PKG, lpkg, spkg, db->treename, &doreplace);
- if(!doreplace) {
- continue;
- }
+ int doreplace = 0;
+ QUESTION(trans, PM_TRANS_CONV_REPLACE_PKG, lpkg, spkg, db->treename, &doreplace);
+ if(!doreplace) {
+ continue;
}
/* if confirmed, add this to the 'final' list, designating 'lpkg' as
@@ -129,7 +121,7 @@ static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
/* check if spkg->name is already in the packages list. */
/* TODO: same package name doesn't mean same package */
- sync = _alpm_sync_find(*syncpkgs, alpm_pkg_get_name(spkg));
+ sync = _alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg));
if(sync) {
/* found it -- just append to the removes list */
sync->removes = alpm_list_add(sync->removes, lpkg);
@@ -143,15 +135,12 @@ static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
sync = _alpm_sync_new(alpm_pkg_get_reason(lpkg), spkg, NULL);
if(sync == NULL) {
pm_errno = PM_ERR_MEMORY;
- alpm_list_free_inner(*syncpkgs, (alpm_list_fn_free)_alpm_sync_free);
- alpm_list_free(*syncpkgs);
- *syncpkgs = NULL;
return(-1);
}
sync->removes = alpm_list_add(NULL, lpkg);
_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
- *syncpkgs = alpm_list_add(*syncpkgs, sync);
+ trans->packages = alpm_list_add(trans->packages, sync);
}
_alpm_log(PM_LOG_DEBUG, "%s-%s elected for removal (to be replaced by %s-%s)\n",
alpm_pkg_get_name(lpkg), alpm_pkg_get_version(lpkg),
@@ -199,33 +188,19 @@ pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync)
return(NULL);
}
-/** Get a list of upgradable packages on the current system
- * Adds out of date packages to *list.
- * @arg list pointer to a list of pmsyncpkg_t.
- */
-int SYMEXPORT alpm_sync_sysupgrade(pmdb_t *db_local,
- alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
-{
- return(_alpm_sync_sysupgrade(NULL, db_local, dbs_sync, syncpkgs));
-}
-
-int _alpm_sync_sysupgrade(pmtrans_t *trans,
- pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
+int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync)
{
alpm_list_t *i, *j, *replaced = NULL;
ALPM_LOG_FUNC;
- if(syncpkgs == NULL) {
- return(-1);
- }
/* check for "recommended" package replacements */
- if(find_replacements(trans, db_local, dbs_sync, syncpkgs)) {
+ if(find_replacements(trans, db_local, dbs_sync)) {
return(-1);
}
/* compute the to-be-replaced packages for efficiency */
- for(i = *syncpkgs; i; i = i->next) {
+ for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;
for(j = sync->removes; j; j = j->next) {
replaced = alpm_list_add(replaced, j->data);
@@ -255,22 +230,19 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans,
}
/* add the upgrade package to our pmsyncpkg_t list */
- if(_alpm_sync_find(*syncpkgs, alpm_pkg_get_name(spkg))) {
+ if(_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
/* avoid duplicated targets */
continue;
}
/* we can set any reason here, it will be overridden by add_commit */
pmsyncpkg_t *sync = _alpm_sync_new(PM_PKG_REASON_EXPLICIT, spkg, NULL);
if(sync == NULL) {
- alpm_list_free_inner(*syncpkgs, (alpm_list_fn_free)_alpm_sync_free);
- alpm_list_free(*syncpkgs);
- *syncpkgs = NULL;
alpm_list_free(replaced);
return(-1);
}
_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
- *syncpkgs = alpm_list_add(*syncpkgs, sync);
+ trans->packages = alpm_list_add(trans->packages, sync);
}
}
@@ -313,12 +285,12 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
RET_ERR(PM_ERR_PKG_REPO_NOT_FOUND, -1);
}
dep = _alpm_splitdep(targ);
- spkg = _alpm_resolvedep(dep, dbs, NULL, NULL);
+ spkg = _alpm_resolvedep(dep, dbs, NULL, 1);
_alpm_dep_free(dep);
alpm_list_free(dbs);
} else {
dep = _alpm_splitdep(targline);
- spkg = _alpm_resolvedep(dep, dbs_sync, NULL, NULL);
+ spkg = _alpm_resolvedep(dep, dbs_sync, NULL, 1);
_alpm_dep_free(dep);
}
FREE(targline);
@@ -400,7 +372,6 @@ static int compute_download_size(pmpkg_t *newpkg)
dltsize = _alpm_shortest_delta_path(
alpm_pkg_get_deltas(newpkg),
alpm_pkg_get_filename(newpkg),
- alpm_pkg_get_md5sum(newpkg),
&newpkg->delta_path);
if(newpkg->delta_path && (dltsize < pkgsize * MAX_DELTA_RATIO)) {
@@ -427,6 +398,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
{
alpm_list_t *deps = NULL;
alpm_list_t *list = NULL, *remove = NULL; /* allow checkdeps usage with trans->packages */
+ alpm_list_t *unresolvable = NULL;
alpm_list_t *i, *j;
int ret = 0;
@@ -439,15 +411,13 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
*data = NULL;
}
- for(i = trans->packages; i; i = i->next) {
- pmsyncpkg_t *sync = i->data;
- list = alpm_list_add(list, sync->pkg);
- }
-
- if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
- /* store a pointer to the last original target so we can tell what was
- * pulled by resolvedeps */
- alpm_list_t *pulled = alpm_list_last(list);
+ if(trans->flags & PM_TRANS_FLAG_NODEPS) {
+ for(i = trans->packages; i; i = i->next) {
+ pmsyncpkg_t *sync = i->data;
+ list = alpm_list_add(list, sync->pkg);
+ }
+ } else {
+ /* Build up list by repeatedly resolving each transaction package */
/* Resolve targets dependencies */
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n");
@@ -460,14 +430,53 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
}
}
- if(_alpm_resolvedeps(db_local, dbs_sync, list, remove, data) == -1) {
- /* pm_errno is set by resolvedeps */
- ret = -1;
- goto cleanup;
+ /* Resolve packages in the transaction one at a time, in addtion
+ building up a list of packages which could not be resolved. */
+ for(i = trans->packages; i; i = i->next) {
+ pmpkg_t *pkg = ((pmsyncpkg_t *) i->data)->pkg;
+ if(_alpm_resolvedeps(db_local, dbs_sync, pkg, &list, remove, data) == -1) {
+ unresolvable = alpm_list_add(unresolvable, pkg);
+ }
+ /* Else, [list] now additionally contains [pkg] and all of its
+ dependencies not already on the list */
}
- for(i = pulled->next; i; i = i->next) {
+ /* 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->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable,
+ NULL, NULL, &remove_unresolvable);
+ if (remove_unresolvable) {
+ /* User wants to remove the unresolvable packages from the
+ transaction, so simply drop the unresolvable list. The
+ packages will be removed from the actual transaction when
+ the transaction packages are replaced with a
+ dependency-reordered list below */
+ alpm_list_free(unresolvable);
+ unresolvable = NULL;
+ }
+ else {
+ /* pm_errno is set by resolvedeps */
+ ret = -1;
+ goto cleanup;
+ }
+ }
+
+ /* Add all packages which were "pulled" (i.e. weren't already in the
+ transaction) to the transaction in pmsyncpkg_t structures */
+ for(i = list; i; i = i->next) {
pmpkg_t *spkg = i->data;
+ for(j = trans->packages; j; j = j->next) {
+ if(_alpm_pkg_cmp(spkg, ((pmsyncpkg_t *) j->data)->pkg) == 0) {
+ spkg = NULL;
+ break;
+ }
+ }
+ if (spkg == NULL) {
+ continue;
+ }
+
pmsyncpkg_t *sync = _alpm_sync_new(PM_PKG_REASON_DEPEND, spkg, NULL);
if(sync == NULL) {
ret = -1;
@@ -497,8 +506,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL);
}
- /* We don't care about conflicts if we're just printing uris */
- if(!(trans->flags & (PM_TRANS_FLAG_NOCONFLICTS | PM_TRANS_FLAG_PRINTURIS))) {
+ if(!(trans->flags & PM_TRANS_FLAG_NOCONFLICTS)) {
/* check for inter-conflicts and whatnot */
EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL);
@@ -631,7 +639,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
}
_alpm_log(PM_LOG_DEBUG, "checking dependencies\n");
- deps = alpm_checkdeps(db_local, 1, remove, list);
+ deps = alpm_checkdeps(_alpm_db_get_pkgcache(db_local), 1, remove, list);
if(deps) {
pm_errno = PM_ERR_UNSATISFIED_DEPS;
ret = -1;
@@ -656,6 +664,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
cleanup:
alpm_list_free(list);
alpm_list_free(remove);
+ alpm_list_free(unresolvable);
return(ret);
}
@@ -838,32 +847,27 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
fname = alpm_pkg_get_filename(spkg);
ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1));
- if(trans->flags & PM_TRANS_FLAG_PRINTURIS) {
- EVENT(trans, PM_TRANS_EVT_PRINTURI, (char *)alpm_db_get_url(current),
- (char *)fname);
- } else {
- if(spkg->download_size != 0) {
- alpm_list_t *delta_path = spkg->delta_path;
- if(delta_path) {
- alpm_list_t *dlts = NULL;
-
- for(dlts = delta_path; dlts; dlts = dlts->next) {
- pmdelta_t *d = dlts->data;
-
- if(d->download_size != 0) {
- /* add the delta filename to the download list if
- * it's not in the cache */
- files = alpm_list_add(files, strdup(d->delta));
- }
-
- /* keep a list of the delta files for md5sums */
- deltas = alpm_list_add(deltas, d);
+ if(spkg->download_size != 0) {
+ alpm_list_t *delta_path = spkg->delta_path;
+ if(delta_path) {
+ alpm_list_t *dlts = NULL;
+
+ for(dlts = delta_path; dlts; dlts = dlts->next) {
+ pmdelta_t *d = dlts->data;
+
+ if(d->download_size != 0) {
+ /* add the delta filename to the download list if
+ * it's not in the cache */
+ files = alpm_list_add(files, strdup(d->delta));
}
- } else {
- /* not using deltas, so add the file to the download list */
- files = alpm_list_add(files, strdup(fname));
+ /* keep a list of the delta files for md5sums */
+ deltas = alpm_list_add(deltas, d);
}
+
+ } else {
+ /* not using deltas, so add the file to the download list */
+ files = alpm_list_add(files, strdup(fname));
}
}
}
@@ -880,9 +884,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
FREELIST(files);
}
}
- if(trans->flags & PM_TRANS_FLAG_PRINTURIS) {
- return(0);
- }
/* clear out value to let callback know we are done */
if(handle->totaldlcb) {