index : pacman | |
Archlinux32 fork of pacman | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | lib/libalpm/sync.c | 173 |
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) { |