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.c686
1 files changed, 362 insertions, 324 deletions
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index ca95fe63..77939623 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -1,8 +1,8 @@
/*
* sync.c
- *
- * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
- *
+ *
+ * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
@@ -24,16 +24,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
-#if defined(__APPLE__) || defined(__OpenBSD__)
-#include <sys/syslimits.h>
-#endif
+#include <limits.h>
#include <unistd.h>
#include <dirent.h>
-#include <libintl.h>
-#ifdef CYGWIN
-#include <limits.h> /* PATH_MAX */
-#endif
#include <alpm.h>
#include <alpm_list.h>
@@ -42,158 +35,163 @@
* remove it from Makefile.am on the pacman side */
/* pacman */
-#include "sync.h"
+#include "pacman.h"
#include "util.h"
-#include "log.h"
-#include "downloadprog.h"
#include "package.h"
-#include "trans.h"
+#include "callback.h"
#include "conf.h"
-extern config_t *config;
+extern pmdb_t *db_local;
-/* splits package name into its respective parts */
-static int split_pkgname(char *target, char *name, char *version)
-{
- char tmp[512];
- char *p, *q;
+static int sync_cleandb(const char *dbpath) {
+ DIR *dir;
+ struct dirent *ent;
- if(target == NULL) {
- return(-1);
+ dir = opendir(dbpath);
+ if(dir == NULL) {
+ fprintf(stderr, _("error: could not access database directory\n"));
+ return(1);
}
- /* trim path name (if any) */
- if((p = strrchr(target, '/')) == NULL) {
- p = target;
- } else {
- p++;
- }
- strncpy(tmp, p, 512);
- /* trim file extension (if any) */
- if((p = strstr(tmp, PM_EXT_PKG))) {
- *p = '\0';
- }
- /* trim architecture */
- if((p = alpm_pkg_name_hasarch(tmp))) {
- *p = '\0';
- }
+ rewinddir(dir);
+ /* step through the directory one file at a time */
+ while((ent = readdir(dir)) != NULL) {
+ char path[PATH_MAX];
+ alpm_list_t *syncdbs = NULL, *i;
+ int found = 0;
+ char *dname = ent->d_name;
+
+ if(!strcmp(dname, ".") || !strcmp(dname, "..")) {
+ continue;
+ }
+ /* skip the local and sync directories */
+ if(!strcmp(dname, "sync") || !strcmp(dname, "local")) {
+ continue;
+ }
+ syncdbs = alpm_option_get_syncdbs();
+ for(i = syncdbs; i && !found; i = alpm_list_next(i)) {
+ pmdb_t *db = alpm_list_getdata(i);
+ found = !strcmp(dname, alpm_db_get_name(db));
+ }
+
+ /* We have a directory that doesn't match any syncdb.
+ * Ask the user if he wants to remove it. */
+ if(!found) {
+ /* build the full path */
+ snprintf(path, PATH_MAX, "%s%s", dbpath, ent->d_name);
+
+ if(!yesno(_("Do you want to remove %s? [Y/n] "), path)) {
+ continue;
+ }
- p = tmp + strlen(tmp);
+ if(rmrf(path)) {
+ fprintf(stderr, _("error: could not remove repository directory\n"));
+ return(1);
+ }
+ }
- for(q = --p; *q && *q != '-'; q--);
- if(*q != '-' || q == tmp) {
- return(-1);
}
- for(p = --q; *p && *p != '-'; p--);
- if(*p != '-' || p == tmp) {
- return(-1);
+ return(0);
+}
+
+static int sync_cleandb_all(void) {
+ const char *dbpath = alpm_option_get_dbpath();
+ char newdbpath[PATH_MAX];
+
+ printf(_("Database directory: %s\n"), dbpath);
+ if(!yesno(_("Do you want to remove unused repositories? [Y/n] "))) {
+ return(0);
}
- strncpy(version, p+1, 64);
- *p = '\0';
+ /* The sync dbs were previously put in dbpath, but are now in dbpath/sync,
+ * so we will clean both directories */
+ sync_cleandb(dbpath);
- strncpy(name, tmp, 256);
+ sprintf(newdbpath, "%s%s", dbpath, "sync/");
+ sync_cleandb(newdbpath);
+ printf(_("Database directory cleaned up\n"));
return(0);
}
static int sync_cleancache(int level)
{
- const char *root, *cachedir;
- char dirpath[PATH_MAX];
-
- root = alpm_option_get_root();
- cachedir = alpm_option_get_cachedir();
-
- snprintf(dirpath, PATH_MAX, "%s%s", root, cachedir);
+ /* TODO for now, just mess with the first cache directory */
+ alpm_list_t* cachedirs = alpm_option_get_cachedirs();
+ const char *cachedir = alpm_list_getdata(cachedirs);
if(level == 1) {
- /* incomplete cleanup: we keep latest packages and partial downloads */
+ /* incomplete cleanup */
DIR *dir;
struct dirent *ent;
- alpm_list_t *cache = NULL, *clean = NULL, *i, *j;
-
- if(!yesno(_("Do you want to remove old packages from cache? [Y/n] ")))
+ /* 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.
+ */
+ printf(_("Cache directory: %s\n"), cachedir);
+ if(!yesno(_("Do you want to remove uninstalled packages from cache? [Y/n] "))) {
return(0);
- MSG(NL, _("removing old packages from cache... "));
- dir = opendir(dirpath);
+ }
+ printf(_("removing old packages from cache... "));
+
+ dir = opendir(cachedir);
if(dir == NULL) {
- ERR(NL, _("could not access cache directory\n"));
+ fprintf(stderr, _("error: could not access cache directory\n"));
return(1);
}
+
rewinddir(dir);
+ /* step through the directory one file at a time */
while((ent = readdir(dir)) != NULL) {
+ char path[PATH_MAX];
+ pmpkg_t *localpkg = NULL, *dbpkg = NULL;
+
if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
continue;
}
- cache = alpm_list_add(cache, strdup(ent->d_name));
- }
- closedir(dir);
-
- for(i = cache; i; i = alpm_list_next(i)) {
- char *str = alpm_list_getdata(i);
- char name[256], version[64];
+ /* build the full filepath */
+ snprintf(path, PATH_MAX, "%s/%s", cachedir, ent->d_name);
- if(strstr(str, PM_EXT_PKG) == NULL) {
- clean = alpm_list_add(clean, strdup(str));
- continue;
- }
- /* we keep partially downloaded files */
- if(strstr(str, PM_EXT_PKG ".part")) {
- continue;
- }
- if(split_pkgname(str, name, version) != 0) {
- clean = alpm_list_add(clean, strdup(str));
+ /* 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
+ * load of the package, just the metadata. */
+ if(alpm_pkg_load(path, 0, &localpkg) != 0 || localpkg == NULL) {
continue;
}
- for(j = alpm_list_next(i); j; j = alpm_list_next(j)) {
- char *s = alpm_list_getdata(j);
- char n[256], v[64];
-
- if(strstr(s, PM_EXT_PKG) == NULL) {
- continue;
- }
- if(strstr(s, PM_EXT_PKG ".part")) {
- continue;
- }
- if(split_pkgname(s, n, v) != 0) {
- continue;
- }
- /* TODO Do not remove the currently installed version EITHER */
- if(!strcmp(name, n)) {
- char *ptr = (alpm_pkg_vercmp(version, v) < 0) ? str : s;
- if(!alpm_list_find_str(clean, ptr)) {
- clean = alpm_list_add(clean, strdup(ptr));
- }
- }
+ /* 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);
}
+ /* else version was the same, so keep the package */
+ /* free the local file package */
+ alpm_pkg_free(localpkg);
}
- FREELIST(cache);
-
- for(i = clean; i; i = alpm_list_next(i)) {
- char path[PATH_MAX];
-
- snprintf(path, PATH_MAX, "%s/%s", dirpath, (char *)alpm_list_getdata(i));
- unlink(path);
- }
- FREELIST(clean);
+ printf(_("done.\n"));
} else {
/* full cleanup */
- if(!yesno(_("Do you want to remove all packages from cache? [Y/n] ")))
+ printf(_("Cache directory: %s\n"), cachedir);
+ if(!yesno(_("Do you want to remove ALL packages from cache? [Y/n] "))) {
return(0);
- MSG(NL, _("removing all packages from cache... "));
+ }
+ printf(_("removing all packages from cache... "));
- if(rmrf(dirpath)) {
- ERR(NL, _("could not remove cache directory\n"));
+ if(rmrf(cachedir)) {
+ fprintf(stderr, _("error: could not remove cache directory\n"));
return(1);
}
- if(makepath(dirpath)) {
- ERR(NL, _("could not create new cache directory\n"));
+ if(makepath(cachedir)) {
+ fprintf(stderr, _("error: could not create new cache directory\n"));
return(1);
}
+ printf(_("done.\n"));
}
- MSG(CL, _("done.\n"));
return(0);
}
@@ -215,12 +213,14 @@ static int sync_synctree(int level, alpm_list_t *syncs)
* 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
*/
- ERR(NL, _("failed to synchronize %s: %s\n"), alpm_db_get_name(db), downloadLastErrString);
+ fprintf(stderr, _("error: failed to synchronize %s: %s\n"),
+ alpm_db_get_name(db), downloadLastErrString);
} else {
- ERR(NL, _("failed to update %s (%s)\n"), alpm_db_get_name(db), alpm_strerror(pm_errno));
+ fprintf(stderr, _("error: failed to update %s (%s)\n"),
+ alpm_db_get_name(db), alpm_strerrorlast());
}
} else if(ret == 1) {
- MSG(NL, _(" %s is up to date\n"), alpm_db_get_name(db));
+ printf(_(" %s is up to date\n"), alpm_db_get_name(db));
success++;
} else {
success++;
@@ -234,48 +234,68 @@ static int sync_synctree(int level, alpm_list_t *syncs)
return(success > 0);
}
+/* search the sync dbs for a matching package */
static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
{
alpm_list_t *i, *j, *ret;
+ int freelist;
+ int found = 0;
for(i = syncs; i; i = alpm_list_next(i)) {
- pmdb_t *db = (pmdb_t *)alpm_list_getdata(i);
+ pmdb_t *db = alpm_list_getdata(i);
+ /* if we have a targets list, search for packages matching it */
if(targets) {
ret = alpm_db_search(db, targets);
- if(ret == NULL) {
- continue;
- }
- for(j = ret; j; j = alpm_list_next(j)) {
- char *group = NULL;
- alpm_list_t *grp;
- pmpkg_t *pkg = alpm_list_getdata(j);
+ freelist = 1;
+ } else {
+ ret = alpm_db_getpkgcache(db);
+ freelist = 0;
+ }
+ if(ret == NULL) {
+ continue;
+ } else {
+ 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);
+ if (!config->quiet) {
printf("%s/%s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
- alpm_pkg_get_version(pkg));
+ alpm_pkg_get_version(pkg));
+ } else {
+ printf("%s", alpm_pkg_get_name(pkg));
+ }
+
+ /* print the package size with the output if ShowSize option set */
+ if(config->showsize) {
+ /* Convert byte size to MB */
+ double mbsize = alpm_pkg_get_size(pkg) / (1024.0 * 1024.0);
+
+ printf(" [%.2f MB]", mbsize);
+ }
+ if (!config->quiet) {
if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
- group = alpm_list_getdata(grp);
- printf(" (%s)\n ", (char *)alpm_list_getdata(grp));
- } else {
- printf("\n ");
+ group = alpm_list_getdata(grp);
+ printf(" (%s)", (char *)alpm_list_getdata(grp));
}
-
- indentprint(alpm_pkg_get_desc(pkg), 4);
- printf("\n");
- }
- alpm_list_free(ret);
- } else {
- for(j = alpm_db_getpkgcache(db); j; j = alpm_list_next(j)) {
- pmpkg_t *pkg = alpm_list_getdata(j);
- MSG(NL, "%s/%s %s\n ", alpm_db_get_name(db), alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
+ /* we need a newline and initial indent first */
+ printf("\n ");
indentprint(alpm_pkg_get_desc(pkg), 4);
- MSG(NL, "\n");
}
+ printf("\n");
+ }
+ /* we only want to free if the list was a search list */
+ if(freelist) {
+ alpm_list_free(ret);
}
}
- return(0);
+ return(!found);
}
static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
@@ -291,7 +311,7 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
if(grp) {
/* TODO this should be a lot cleaner, why two outputs? */
- MSG(NL, "%s\n", (char *)alpm_grp_get_name(grp));
+ printf("%s\n", (char *)alpm_grp_get_name(grp));
list_display(" ", alpm_grp_get_pkgs(grp));
}
}
@@ -303,7 +323,7 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
for(j = alpm_db_getgrpcache(db); j; j = alpm_list_next(j)) {
pmgrp_t *grp = alpm_list_getdata(j);
- MSG(NL, "%s\n", (char *)alpm_grp_get_name(grp));
+ printf("%s\n", (char *)alpm_grp_get_name(grp));
if(grp && level > 1) {
list_display(" ", alpm_grp_get_pkgs(grp));
}
@@ -317,6 +337,7 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
{
alpm_list_t *i, *j, *k;
+ int ret = 0;
if(targets) {
for(i = targets; i; i = alpm_list_next(i)) {
@@ -340,29 +361,29 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
}
db = NULL;
}
-
+
if(!db) {
- ERR(NL, _("repository '%s' does not exist\n"), repo);
+ fprintf(stderr, _("error: repository '%s' does not exist\n"), repo);
return(1);
}
-
+
for(k = alpm_db_getpkgcache(db); k; k = alpm_list_next(k)) {
pmpkg_t *pkg = alpm_list_getdata(k);
if(strcmp(alpm_pkg_get_name(pkg), pkgstr) == 0) {
dump_pkg_sync(pkg, alpm_db_get_name(db));
- MSG(NL, "\n");
foundpkg = 1;
break;
}
}
-
+
if(!foundpkg) {
- ERR(NL, _("package '%s' was not found in repository '%s'\n"), pkgstr, repo);
+ fprintf(stderr, _("error: package '%s' was not found in repository '%s'\n"), pkgstr, repo);
+ ret++;
}
} else {
pkgstr = target;
-
+
for(j = syncs; j; j = alpm_list_next(j)) {
pmdb_t *db = alpm_list_getdata(j);
@@ -371,29 +392,28 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
if(strcmp(alpm_pkg_get_name(pkg), pkgstr) == 0) {
dump_pkg_sync(pkg, alpm_db_get_name(db));
- MSG(NL, "\n");
foundpkg = 1;
break;
}
}
}
if(!foundpkg) {
- ERR(NL, _("package '%s' was not found\n"), pkgstr);
+ fprintf(stderr, _("error: package '%s' was not found\n"), pkgstr);
+ ret++;
}
}
}
} else {
for(i = syncs; i; i = alpm_list_next(i)) {
pmdb_t *db = alpm_list_getdata(i);
-
+
for(j = alpm_db_getpkgcache(db); j; j = alpm_list_next(j)) {
dump_pkg_sync(alpm_list_getdata(j), alpm_db_get_name(db));
- MSG(NL, "\n");
}
}
}
- return(0);
+ return(ret);
}
static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
@@ -415,7 +435,7 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
}
if(db == NULL) {
- ERR(NL, _("repository \"%s\" was not found.\n"),repo);
+ fprintf(stderr, _("error: repository \"%s\" was not found.\n"),repo);
alpm_list_free(ls);
return(1);
}
@@ -431,7 +451,12 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
for(j = alpm_db_getpkgcache(db); j; j = alpm_list_next(j)) {
pmpkg_t *pkg = alpm_list_getdata(j);
- MSG(NL, "%s %s %s\n", alpm_db_get_name(db), alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
+ if (!config->quiet) {
+ printf("%s %s %s\n", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
+ alpm_pkg_get_version(pkg));
+ } else {
+ printf("%s\n", alpm_pkg_get_name(pkg));
+ }
}
}
@@ -442,99 +467,82 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
return(0);
}
-int pacman_sync(alpm_list_t *targets)
+int sync_trans(alpm_list_t *targets, int sync_only)
{
- int confirm = 0;
int retval = 0;
- alpm_list_t *packages, *data = NULL, *i, *j, *k, *sync_dbs;
-
- sync_dbs = alpm_option_get_syncdbs();
- if(sync_dbs == NULL || alpm_list_count(sync_dbs) == 0) {
- ERR(NL, _("no usable package repositories configured.\n"));
- return(1);
- }
-
- if(config->op_s_clean) {
- return(sync_cleancache(config->op_s_clean));
- }
-
- if(config->op_s_search) {
- return(sync_search(sync_dbs, targets));
- }
-
- if(config->group) {
- return(sync_group(config->group, sync_dbs, targets));
- }
-
- if(config->op_s_info) {
- return(sync_info(sync_dbs, targets));
- }
-
- if(config->op_q_list) {
- return(sync_list(sync_dbs, targets));
- }
-
- /* Step 1: create a new transaction...
- */
- if(alpm_trans_init(PM_TRANS_TYPE_SYNC, config->flags, cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) {
- ERR(NL, _("failed to init transaction (%s)\n"), alpm_strerror(pm_errno));
+ alpm_list_t *data = NULL;
+ alpm_list_t *sync_dbs = alpm_option_get_syncdbs();
+
+ /* Step 1: create a new transaction... */
+ if(alpm_trans_init(PM_TRANS_TYPE_SYNC, config->flags, cb_trans_evt,
+ cb_trans_conv, cb_trans_progress) == -1) {
+ fprintf(stderr, _("error: failed to init transaction (%s)\n"),
+ alpm_strerrorlast());
if(pm_errno == PM_ERR_HANDLE_LOCK) {
- MSG(NL, _(" if you're sure a package manager is not already running,\n"
- " you can remove %s%s\n"), alpm_option_get_root(), PM_LOCK);
+ printf(_(" if you're sure a package manager is not already\n"
+ " running, you can remove %s.\n"), alpm_option_get_lockfile());
}
return(1);
}
if(config->op_s_sync) {
/* grab a fresh package list */
- MSG(NL, _(":: Synchronizing package databases...\n"));
- alpm_logaction(_("synchronizing package lists"));
+ printf(_(":: Synchronizing package databases...\n"));
+ alpm_logaction("synchronizing package lists\n");
if(!sync_synctree(config->op_s_sync, sync_dbs)) {
- ERR(NL, _("failed to synchronize any databases"));
- return(1);
+ fprintf(stderr, _("error: failed to synchronize any databases\n"));
+ retval = 1;
+ goto cleanup;
+ }
+ if(sync_only) {
+ goto cleanup;
}
}
if(config->op_s_upgrade) {
- MSG(NL, _(":: Starting full system upgrade...\n"));
- alpm_logaction(_("starting full system upgrade"));
+ alpm_list_t *pkgs, *i;
+
+ printf(_(":: Starting full system upgrade...\n"));
+ alpm_logaction("starting full system upgrade\n");
if(alpm_trans_sysupgrade() == -1) {
- ERR(NL, "%s\n", alpm_strerror(pm_errno));
+ fprintf(stderr, _("error: %s\n"), alpm_strerrorlast());
retval = 1;
goto cleanup;
}
- /* check if pacman itself is one of the packages to upgrade. If so, we
- * we should upgrade ourselves first and then re-exec as the new version.
- *
+ /* check if pacman itself is one of the packages to upgrade.
* this can prevent some of the "syntax error" problems users can have
* when sysupgrade'ing with an older version of pacman.
*/
- data = alpm_trans_get_pkgs();
- for(i = data; i; i = alpm_list_next(i)) {
+ pkgs = alpm_trans_get_pkgs();
+ for(i = pkgs; i; i = alpm_list_next(i)) {
pmsyncpkg_t *sync = alpm_list_getdata(i);
pmpkg_t *spkg = alpm_sync_get_pkg(sync);
- if(strcmp("pacman", alpm_pkg_get_name(spkg)) == 0 && alpm_list_count(data) > 1) {
- MSG(NL, _("\n:: pacman has detected a newer version of the \"pacman\" package.\n"));
- MSG(NL, _(":: It is recommended that you allow pacman to upgrade itself\n"));
- MSG(NL, _(":: first, then you can re-run the operation with the newer version.\n"));
- MSG(NL, "::\n");
- if(yesno(_(":: Upgrade pacman first? [Y/n] "))) {
+ /* TODO pacman name should probably not be hardcoded. In addition, we
+ * have problems on an -Syu if pacman has to pull in deps, so recommend
+ * an '-S pacman' operation */
+ if(strcmp("pacman", alpm_pkg_get_name(spkg)) == 0) {
+ printf("\n");
+ printf(_(":: pacman has detected a newer version of itself.\n"
+ ":: It is recommended that you upgrade pacman by itself\n"
+ ":: using 'pacman -S pacman', and then rerun the current\n"
+ ":: operation. If you wish to continue the operation and\n"
+ ":: not upgrade pacman separately, answer no.\n"));
+ if(yesno(_(":: Cancel current operation? [Y/n] "))) {
if(alpm_trans_release() == -1) {
- ERR(NL, _("failed to release transaction (%s)\n"), alpm_strerror(pm_errno));
+ fprintf(stderr, _("error: failed to release transaction (%s)\n"),
+ alpm_strerrorlast());
retval = 1;
goto cleanup;
}
- if(alpm_trans_init(PM_TRANS_TYPE_SYNC, config->flags, cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) {
- ERR(NL, _("failed to init transaction (%s)\n"), alpm_strerror(pm_errno));
- if(pm_errno == PM_ERR_HANDLE_LOCK) {
- MSG(NL, _(" if you're sure a package manager is not already running,\n"
- " you can remove %s%s\n"), alpm_option_get_root(), PM_LOCK);
- }
+ if(alpm_trans_init(PM_TRANS_TYPE_SYNC, config->flags,
+ cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) {
+ fprintf(stderr, _("error: failed to init transaction (%s)\n"),
+ alpm_strerrorlast());
return(1);
}
if(alpm_trans_addtarget("pacman") == -1) {
- ERR(NL, _("pacman: %s\n"), alpm_strerror(pm_errno));
+ fprintf(stderr, _("error: pacman: %s\n"), alpm_strerrorlast());
retval = 1;
goto cleanup;
}
@@ -543,31 +551,39 @@ int pacman_sync(alpm_list_t *targets)
}
}
} else {
+ alpm_list_t *i;
+
/* process targets */
for(i = targets; i; i = alpm_list_next(i)) {
char *targ = alpm_list_getdata(i);
if(alpm_trans_addtarget(targ) == -1) {
pmgrp_t *grp = NULL;
int found=0;
+ alpm_list_t *j;
+
if(pm_errno == PM_ERR_TRANS_DUP_TARGET) {
/* just ignore duplicate targets */
continue;
}
if(pm_errno != PM_ERR_PKG_NOT_FOUND) {
- ERR(NL, "'%s': %s\n", (char *)i->data, alpm_strerror(pm_errno));
+ fprintf(stderr, _("error: '%s': %s\n"),
+ (char *)i->data, alpm_strerrorlast());
retval = 1;
goto cleanup;
}
/* target not found: check if it's a group */
-
- for(j = alpm_option_get_syncdbs(); j; j = alpm_list_next(j)) {
+
+ for(j = sync_dbs; j; j = alpm_list_next(j)) {
pmdb_t *db = alpm_list_getdata(j);
grp = alpm_db_readgrp(db, targ);
if(grp) {
+ alpm_list_t *k;
+
found++;
- MSG(NL, _(":: group %s:\n"), targ);
+ printf(_(":: group %s:\n"), targ);
/* remove dupe entries in case a package exists in multiple repos */
- alpm_list_t *pkgs = alpm_list_remove_dupes(alpm_grp_get_pkgs(grp));
+ const 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)) {
@@ -585,108 +601,70 @@ int pacman_sync(alpm_list_t *targets)
}
}
if(!found) {
- /* targ not found in sync db, searching for providers... */
- const char *pname = NULL;
- for(j = alpm_option_get_syncdbs(); j; j = alpm_list_next(j)) {
- pmdb_t *db = alpm_list_getdata(j);
- alpm_list_t *prov = alpm_db_whatprovides(db, targ);
- if(prov) {
- pmpkg_t *pkg = alpm_list_getdata(prov);
- pname = alpm_pkg_get_name(pkg);
- break;
- }
- }
- if(pname != NULL) {
- /* targ is provided by pname */
- targets = alpm_list_add(targets, strdup(pname));
- } else {
- ERR(NL, _("'%s': not found in sync db\n"), targ);
- retval = 1;
- goto cleanup;
- }
+ fprintf(stderr, _("error: '%s': not found in sync db\n"), targ);
+ retval = 1;
+ goto cleanup;
}
}
}
}
- /* Step 2: "compute" the transaction based on targets and flags
- */
+ /* Step 2: "compute" the transaction based on targets and flags */
if(alpm_trans_prepare(&data) == -1) {
- long long *pkgsize, *freespace;
- ERR(NL, _("failed to prepare transaction (%s)\n"), alpm_strerror(pm_errno));
+ fprintf(stderr, _("error: failed to prepare transaction (%s)\n"),
+ alpm_strerrorlast());
switch(pm_errno) {
+ alpm_list_t *i;
case PM_ERR_UNSATISFIED_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
pmdepmissing_t *miss = alpm_list_getdata(i);
- MSG(NL, ":: %s %s %s", alpm_dep_get_target(miss), _("requires"),
- alpm_dep_get_name(miss));
- switch(alpm_dep_get_mod(miss)) {
- case PM_DEP_MOD_ANY:
- break;
- case PM_DEP_MOD_EQ:
- MSG(CL, "=%s", alpm_dep_get_version(miss));
- break;
- case PM_DEP_MOD_GE:
- MSG(CL, ">=%s", alpm_dep_get_version(miss));
- break;
- case PM_DEP_MOD_LE:
- MSG(CL, "<=%s", alpm_dep_get_version(miss));
- break;
- }
- MSG(CL, "\n");
+ pmdepend_t *dep = alpm_miss_get_dep(miss);
+ char *depstring = alpm_dep_get_string(dep);
+ printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss),
+ depstring);
+ free(depstring);
}
- break;
+ break;
case PM_ERR_CONFLICTING_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
- pmdepmissing_t *miss = alpm_list_getdata(i);
-
- MSG(NL, _(":: %s: conflicts with %s"),
- alpm_dep_get_target(miss), alpm_dep_get_name(miss));
+ pmconflict_t *conflict = alpm_list_getdata(i);
+ printf(_(":: %s: conflicts with %s\n"),
+ alpm_conflict_get_package1(conflict), alpm_conflict_get_package2(conflict));
}
- break;
- case PM_ERR_DISK_FULL:
- pkgsize = alpm_list_getdata(data);
- freespace = alpm_list_getdata(alpm_list_next(data));
- MSG(NL, _(":: %.1f MB required, have %.1f MB"),
- (double)(*pkgsize / 1048576.0), (double)(*freespace / 1048576.0));
- break;
+ break;
default:
- break;
+ break;
}
retval = 1;
goto cleanup;
}
- packages = alpm_trans_get_pkgs();
+ alpm_list_t *packages = alpm_trans_get_pkgs();
if(packages == NULL) {
/* nothing to do: just exit without complaining */
- MSG(NL, _(" local database is up to date\n"));
+ printf(_(" local database is up to date\n"));
goto cleanup;
}
if(!(alpm_trans_get_flags() & PM_TRANS_FLAG_PRINTURIS)) {
- display_targets(packages);
+ int confirm;
+
+ display_targets(packages, db_local);
+ printf("\n");
if(config->op_s_downloadonly) {
if(config->noconfirm) {
- MSG(NL, _("\nBeginning download...\n"));
+ printf(_("Beginning download...\n"));
confirm = 1;
} else {
- MSG(NL, "\n");
confirm = yesno(_("Proceed with download? [Y/n] "));
}
} else {
- /* don't get any confirmation if we're called from makepkg */
- if(config->op_d_resolve) {
+ if(config->noconfirm) {
+ printf(_("Beginning upgrade process...\n"));
confirm = 1;
} else {
- if(config->noconfirm) {
- MSG(NL, _("\nBeginning upgrade process...\n"));
- confirm = 1;
- } else {
- MSG(NL, "\n");
- confirm = yesno(_("Proceed with installation? [Y/n] "));
- }
+ confirm = yesno(_("Proceed with installation? [Y/n] "));
}
}
if(!confirm) {
@@ -694,55 +672,115 @@ int pacman_sync(alpm_list_t *targets)
}
}/* else 'print uris' requested. We're done at this point */
- /* Step 3: actually perform the installation
- */
+ /* Step 3: actually perform the installation */
if(alpm_trans_commit(&data) == -1) {
- ERR(NL, _("failed to commit transaction (%s)\n"), alpm_strerror(pm_errno));
+ fprintf(stderr, _("error: failed to commit transaction (%s)\n"),
+ alpm_strerrorlast());
switch(pm_errno) {
- case PM_ERR_FILE_CONFLICTS:
- for(i = data; i; i = alpm_list_next(i)) {
- pmconflict_t *conflict = alpm_list_getdata(i);
- switch(alpm_conflict_get_type(conflict)) {
- case PM_CONFLICT_TYPE_TARGET:
- MSG(NL, _("%s exists in both '%s' and '%s'\n"),
- alpm_conflict_get_file(conflict),
- alpm_conflict_get_target(conflict),
- alpm_conflict_get_ctarget(conflict));
- break;
- case PM_CONFLICT_TYPE_FILE:
- MSG(NL, _("%s: %s exists in filesystem\n"),
- alpm_conflict_get_target(conflict),
- alpm_conflict_get_file(conflict));
- break;
+ alpm_list_t *i;
+ case PM_ERR_FILE_CONFLICTS:
+ for(i = data; i; i = alpm_list_next(i)) {
+ pmfileconflict_t *conflict = alpm_list_getdata(i);
+ switch(alpm_fileconflict_get_type(conflict)) {
+ case PM_FILECONFLICT_TARGET:
+ printf(_("%s exists in both '%s' and '%s'\n"),
+ alpm_fileconflict_get_file(conflict),
+ alpm_fileconflict_get_target(conflict),
+ alpm_fileconflict_get_ctarget(conflict));
+ break;
+ case PM_FILECONFLICT_FILESYSTEM:
+ printf(_("%s: %s exists in filesystem\n"),
+ alpm_fileconflict_get_target(conflict),
+ alpm_fileconflict_get_file(conflict));
+ break;
+ }
}
- }
- MSG(NL, _("\nerrors occurred, no packages were upgraded.\n"));
- break;
- case PM_ERR_PKG_CORRUPTED:
- for(i = data; i; i = alpm_list_next(i)) {
- MSG(NL, "%s", (char*)alpm_list_getdata(i));
- }
- MSG(NL, _("\nerrors occurred, no packages were upgraded.\n"));
- break;
- default:
- break;
+ break;
+ case PM_ERR_PKG_CORRUPTED:
+ for(i = data; i; i = alpm_list_next(i)) {
+ printf("%s", (char*)alpm_list_getdata(i));
+ }
+ break;
+ default:
+ break;
}
+ /* TODO: stderr? */
+ printf(_("Errors occurred, no packages were upgraded.\n"));
retval = 1;
goto cleanup;
}
- /* Step 4: release transaction resources
- */
+ /* Step 4: release transaction resources */
cleanup:
if(data) {
+ alpm_list_free_inner(data, free);
alpm_list_free(data);
}
if(alpm_trans_release() == -1) {
- ERR(NL, _("failed to release transaction (%s)\n"), alpm_strerror(pm_errno));
+ fprintf(stderr, _("error: failed to release transaction (%s)\n"),
+ alpm_strerrorlast());
retval = 1;
}
return(retval);
}
+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) {
+ int ret = sync_cleancache(config->op_s_clean);
+ ret += sync_cleandb_all();
+ return(ret);
+ }
+
+ /* ensure we have at least one valid sync db set up */
+ sync_dbs = alpm_option_get_syncdbs();
+ if(sync_dbs == NULL || alpm_list_count(sync_dbs) == 0) {
+ pm_printf(PM_LOG_ERROR, _("no usable package repositories configured.\n"));
+ 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)) {
+ /* 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(needs_transaction()) {
+ if(sync_trans(targets, sync_only) == 1) {
+ return(1);
+ }
+ }
+
+ /* search for a package */
+ if(config->op_s_search) {
+ return(sync_search(sync_dbs, targets));
+ }
+
+ /* look for groups */
+ if(config->group) {
+ return(sync_group(config->group, sync_dbs, targets));
+ }
+
+ /* get package info */
+ if(config->op_s_info) {
+ return(sync_info(sync_dbs, targets));
+ }
+
+ /* get a listing of files in sync DBs */
+ if(config->op_q_list) {
+ return(sync_list(sync_dbs, targets));
+ }
+
+ return(0);
+}
+
/* vim: set ts=2 sw=2 noet: */