summaryrefslogtreecommitdiffstats
path: root/src/pacman/sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman/sync.c')
-rw-r--r--src/pacman/sync.c218
1 files changed, 127 insertions, 91 deletions
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index e3e87703..c074746f 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -29,9 +29,6 @@
#include <alpm.h>
#include <alpm_list.h>
-#include <download.h> /* downloadLastErrString */
-/* TODO remove above download.h inclusion once we abstract more, and also
- * remove it from Makefile.am on the pacman side */
/* pacman */
#include "pacman.h"
@@ -89,7 +86,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) {
/* We have a directory that doesn't match any syncdb.
* Ask the user if he wants to remove it. */
if(!found) {
- if(!yesno(_("Do you want to remove %s? [Y/n] "), path)) {
+ if(!yesno(1, _("Do you want to remove %s?"), path)) {
continue;
}
@@ -108,7 +105,7 @@ static int sync_cleandb_all(void) {
char newdbpath[PATH_MAX];
printf(_("Database directory: %s\n"), dbpath);
- if(!yesno(_("Do you want to remove unused repositories? [Y/n] "))) {
+ if(!yesno(1, _("Do you want to remove unused repositories?"))) {
return(0);
}
/* The sync dbs were previously put in dbpath/, but are now in dbpath/sync/,
@@ -133,13 +130,23 @@ static int sync_cleancache(int level)
/* incomplete cleanup */
DIR *dir;
struct dirent *ent;
- /* Let's vastly improve the way this is done. Before, we went by package
- * name. Instead, let's only keep packages we have installed. Open up each
- * package and see if it has an entry in the local DB; if not, delete it.
- */
+ /* Open up each package and see if it should be deleted,
+ * depending on the clean method used */
printf(_("Cache directory: %s\n"), cachedir);
- if(!yesno(_("Do you want to remove uninstalled packages from cache? [Y/n] "))) {
- return(0);
+ switch(config->cleanmethod) {
+ case PM_CLEAN_KEEPINST:
+ if(!yesno(1, _("Do you want to remove uninstalled packages from cache?"))) {
+ return(0);
+ }
+ break;
+ case PM_CLEAN_KEEPCUR:
+ if(!yesno(1, _("Do you want to remove outdated packages from cache?"))) {
+ return(0);
+ }
+ break;
+ default:
+ /* this should not happen : the config parsing doesn't set any other value */
+ return(1);
}
printf(_("removing old packages from cache... "));
@@ -153,13 +160,16 @@ static int sync_cleancache(int level)
/* step through the directory one file at a time */
while((ent = readdir(dir)) != NULL) {
char path[PATH_MAX];
- pmpkg_t *localpkg = NULL, *dbpkg = NULL;
+ int delete = 1;
+ pmpkg_t *localpkg = NULL, *pkg = NULL;
+ alpm_list_t *sync_dbs = alpm_option_get_syncdbs();
+ alpm_list_t *j;
if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
continue;
}
/* build the full filepath */
- snprintf(path, PATH_MAX, "%s/%s", cachedir, ent->d_name);
+ snprintf(path, PATH_MAX, "%s%s", cachedir, ent->d_name);
/* attempt to load the package, skip file on failures as we may have
* files here that aren't valid packages. we also don't need a full
@@ -167,25 +177,45 @@ static int sync_cleancache(int level)
if(alpm_pkg_load(path, 0, &localpkg) != 0 || localpkg == NULL) {
continue;
}
- /* check if this package is in the local DB */
- dbpkg = alpm_db_get_pkg(db_local, alpm_pkg_get_name(localpkg));
- if(dbpkg == NULL) {
- /* delete package, not present in local DB */
- unlink(path);
- } else if(alpm_pkg_vercmp(alpm_pkg_get_version(localpkg),
- alpm_pkg_get_version(dbpkg)) != 0) {
- /* delete package, it was found but version differs */
- unlink(path);
+ switch(config->cleanmethod) {
+ case PM_CLEAN_KEEPINST:
+ /* check if this package is in the local DB */
+ pkg = alpm_db_get_pkg(db_local, alpm_pkg_get_name(localpkg));
+ if(pkg != NULL && alpm_pkg_vercmp(alpm_pkg_get_version(localpkg),
+ alpm_pkg_get_version(pkg)) == 0) {
+ /* package was found in local DB and version matches, keep it */
+ delete = 0;
+ }
+ break;
+ case PM_CLEAN_KEEPCUR:
+ /* check if this package is in a sync DB */
+ for(j = sync_dbs; j && delete; j = alpm_list_next(j)) {
+ pmdb_t *db = alpm_list_getdata(j);
+ pkg = alpm_db_get_pkg(db, alpm_pkg_get_name(localpkg));
+ if(pkg != NULL && alpm_pkg_vercmp(alpm_pkg_get_version(localpkg),
+ alpm_pkg_get_version(pkg)) == 0) {
+ /* package was found in a sync DB and version matches, keep it */
+ delete = 0;
+ }
+ }
+ break;
+ default:
+ /* this should not happen : the config parsing doesn't set any other value */
+ delete = 0;
+ break;
}
- /* else version was the same, so keep the package */
/* free the local file package */
alpm_pkg_free(localpkg);
+
+ if(delete) {
+ unlink(path);
+ }
}
printf(_("done.\n"));
} else {
/* full cleanup */
printf(_("Cache directory: %s\n"), cachedir);
- if(!yesno(_("Do you want to remove ALL packages from cache? [Y/n] "))) {
+ if(!yesno(0, _("Do you want to remove ALL packages from cache?"))) {
return(0);
}
printf(_("removing all packages from cache... "));
@@ -232,25 +262,17 @@ static int sync_synctree(int level, alpm_list_t *syncs)
alpm_list_t *i;
int success = 0, ret;
+ if(sync_trans_init(0) == -1) {
+ return(0);
+ }
+
for(i = syncs; i; i = alpm_list_next(i)) {
pmdb_t *db = alpm_list_getdata(i);
ret = alpm_db_update((level < 2 ? 0 : 1), db);
if(ret < 0) {
- if(pm_errno == PM_ERR_DB_SYNC) {
- /* use libdownload error */
- /* TODO breaking abstraction barrier here?
- * pacman -> libalpm -> libdownload
- *
- * Yes. This will be here until we add a nice pacman "pm_errstr" or
- * something, OR add all libdownload error codes into the pm_error enum
- */
- fprintf(stderr, _("error: failed to synchronize %s: %s\n"),
- alpm_db_get_name(db), downloadLastErrString);
- } else {
- fprintf(stderr, _("error: failed to update %s (%s)\n"),
- alpm_db_get_name(db), alpm_strerrorlast());
- }
+ fprintf(stderr, _("error: failed to update %s (%s)\n"),
+ alpm_db_get_name(db), alpm_strerrorlast());
} else if(ret == 1) {
printf(_(" %s is up to date\n"), alpm_db_get_name(db));
success++;
@@ -259,10 +281,16 @@ static int sync_synctree(int level, alpm_list_t *syncs)
}
}
+ if(sync_trans_release() == -1) {
+ return(0);
+ }
/* We should always succeed if at least one DB was upgraded - we may possibly
* fail later with unresolved deps, but that should be rare, and would be
* expected
*/
+ if(!success) {
+ fprintf(stderr, _("error: failed to synchronize any databases\n"));
+ }
return(success > 0);
}
@@ -289,8 +317,6 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
found = 1;
}
for(j = ret; j; j = alpm_list_next(j)) {
- /* print repo/name (group) info about each package in our list */
- char *group = NULL;
alpm_list_t *grp;
pmpkg_t *pkg = alpm_list_getdata(j);
@@ -311,8 +337,17 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
if (!config->quiet) {
if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
- group = alpm_list_getdata(grp);
- printf(" (%s)", (char *)alpm_list_getdata(grp));
+ alpm_list_t *k;
+ printf(" (");
+ for(k = grp; k; k = alpm_list_next(k)) {
+ const char *group = alpm_list_getdata(k);
+ printf("%s", group);
+ if(alpm_list_next(k)) {
+ /* only print a spacer if there are more groups */
+ printf(" ");
+ }
+ }
+ printf(")");
}
/* we need a newline and initial indent first */
@@ -332,7 +367,8 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
{
- alpm_list_t *i, *j;
+ alpm_list_t *i, *j, *k;
+ alpm_list_t *pkgnames = NULL;
if(targets) {
for(i = targets; i; i = alpm_list_next(i)) {
@@ -342,9 +378,14 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
pmgrp_t *grp = alpm_db_readgrp(db, grpname);
if(grp) {
- /* TODO this should be a lot cleaner, why two outputs? */
printf("%s\n", (char *)alpm_grp_get_name(grp));
- list_display(" ", alpm_grp_get_pkgs(grp));
+ /* get names of packages in group */
+ for(k = alpm_grp_get_pkgs(grp); k; k = alpm_list_next(k)) {
+ pkgnames = alpm_list_add(pkgnames,
+ (char*)alpm_pkg_get_name(k->data));
+ }
+ list_display(" ", pkgnames);
+ alpm_list_free(pkgnames);
}
}
}
@@ -357,7 +398,12 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
printf("%s\n", (char *)alpm_grp_get_name(grp));
if(grp && level > 1) {
- list_display(" ", alpm_grp_get_pkgs(grp));
+ for(k = alpm_grp_get_pkgs(grp); k; k = alpm_list_next(k)) {
+ pkgnames = alpm_list_add(pkgnames,
+ (char*)alpm_pkg_get_name(k->data));
+ }
+ list_display(" ", pkgnames);
+ alpm_list_free(pkgnames);
}
}
}
@@ -499,7 +545,7 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
return(0);
}
-static int sync_trans(alpm_list_t *targets, int sync_only)
+static int sync_trans(alpm_list_t *targets)
{
int retval = 0;
alpm_list_t *data = NULL;
@@ -510,23 +556,8 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
return(1);
}
- if(config->op_s_sync) {
- /* grab a fresh package list */
- printf(_(":: Synchronizing package databases...\n"));
- alpm_logaction("synchronizing package lists\n");
- if(!sync_synctree(config->op_s_sync, sync_dbs)) {
- fprintf(stderr, _("error: failed to synchronize any databases\n"));
- retval = 1;
- goto cleanup;
- }
- if(sync_only) {
- goto cleanup;
- }
- }
-
if(config->op_s_upgrade) {
alpm_list_t *pkgs, *i;
-
printf(_(":: Starting full system upgrade...\n"));
alpm_logaction("starting full system upgrade\n");
if(alpm_trans_sysupgrade() == -1) {
@@ -550,8 +581,8 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
if(strcmp("pacman", alpm_pkg_get_name(spkg)) == 0) {
printf("\n");
printf(_(":: pacman has detected a newer version of itself.\n"));
- if(yesno(_(":: Do you want to cancel the current operation\n"
- ":: and install the new pacman version now? [Y/n] "))) {
+ if(yesno(1, _(":: Do you want to cancel the current operation\n"
+ ":: and install the new pacman version now?"))) {
if(sync_trans_release() == -1) {
return(1);
}
@@ -594,26 +625,31 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
pmdb_t *db = alpm_list_getdata(j);
grp = alpm_db_readgrp(db, targ);
if(grp) {
- alpm_list_t *k;
+ alpm_list_t *k, *pkgnames = NULL;
found++;
printf(_(":: group %s (including ignored packages):\n"), targ);
/* remove dupe entries in case a package exists in multiple repos */
- const alpm_list_t *grppkgs = alpm_grp_get_pkgs(grp);
+ alpm_list_t *grppkgs = alpm_grp_get_pkgs(grp);
alpm_list_t *pkgs = alpm_list_remove_dupes(grppkgs);
- list_display(" ", pkgs);
- if(yesno(_(":: Install whole content? [Y/n] "))) {
- for(k = pkgs; k; k = alpm_list_next(k)) {
+ for(k = pkgs; k; k = alpm_list_next(k)) {
+ pkgnames = alpm_list_add(pkgnames,
+ (char*)alpm_pkg_get_name(k->data));
+ }
+ list_display(" ", pkgnames);
+ if(yesno(1, _(":: Install whole content?"))) {
+ for(k = pkgnames; k; k = alpm_list_next(k)) {
targets = alpm_list_add(targets, strdup(alpm_list_getdata(k)));
}
} else {
- for(k = pkgs; k; k = alpm_list_next(k)) {
+ for(k = pkgnames; k; k = alpm_list_next(k)) {
char *pkgname = alpm_list_getdata(k);
- if(yesno(_(":: Install %s from group %s? [Y/n] "), pkgname, targ)) {
+ if(yesno(1, _(":: Install %s from group %s?"), pkgname, targ)) {
targets = alpm_list_add(targets, strdup(pkgname));
}
}
}
+ alpm_list_free(pkgnames);
alpm_list_free(pkgs);
}
}
@@ -698,19 +734,9 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
printf("\n");
if(config->op_s_downloadonly) {
- if(config->noconfirm) {
- printf(_("Beginning download...\n"));
- confirm = 1;
- } else {
- confirm = yesno(_("Proceed with download? [Y/n] "));
- }
+ confirm = yesno(1, _("Proceed with download?"));
} else {
- if(config->noconfirm) {
- printf(_("Beginning upgrade process...\n"));
- confirm = 1;
- } else {
- confirm = yesno(_("Proceed with installation? [Y/n] "));
- }
+ confirm = yesno(1, _("Proceed with installation?"));
}
if(!confirm) {
goto cleanup;
@@ -741,9 +767,11 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
}
}
break;
- case PM_ERR_PKG_CORRUPTED:
+ case PM_ERR_PKG_INVALID:
+ case PM_ERR_DLT_INVALID:
for(i = data; i; i = alpm_list_next(i)) {
- printf("%s", (char*)alpm_list_getdata(i));
+ char *filename = alpm_list_getdata(i);
+ printf(_("%s is invalid or corrupted\n"), filename);
}
break;
default:
@@ -770,7 +798,6 @@ cleanup:
int pacman_sync(alpm_list_t *targets)
{
alpm_list_t *sync_dbs = NULL;
- int sync_only = 0;
/* clean the cache */
if(config->op_s_clean) {
@@ -797,18 +824,27 @@ int pacman_sync(alpm_list_t *targets)
return(1);
}
- if(config->op_s_search || config->group
- || config->op_s_info || config->op_q_list) {
- sync_only = 1;
- } else if(targets == NULL && !(config->op_s_sync || config->op_s_upgrade)) {
+ if(targets == NULL && !(config->op_s_sync || config->op_s_upgrade
+ || config->op_s_search || config->group
+ || config->op_s_info || config->op_q_list)) {
/* don't proceed here unless we have an operation that doesn't require
* a target list */
pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
return(1);
}
+ if(config->op_s_sync) {
+ /* grab a fresh package list */
+ printf(_(":: Synchronizing package databases...\n"));
+ alpm_logaction("synchronizing package lists\n");
+ if(!sync_synctree(config->op_s_sync, sync_dbs)) {
+ return(1);
+ }
+ config->op_s_sync = 0;
+ }
+
if(needs_transaction()) {
- if(sync_trans(targets, sync_only) == 1) {
+ if(sync_trans(targets) == 1) {
return(1);
}
}