2005-03-14 20:51:43 -05:00
|
|
|
/*
|
|
|
|
* sync.c
|
2007-06-02 12:34:01 -04:00
|
|
|
*
|
2015-01-21 01:31:20 -05:00
|
|
|
* Copyright (c) 2006-2015 Pacman Development Team <pacman-dev@archlinux.org>
|
2009-07-01 03:08:33 -04:00
|
|
|
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
2007-06-02 12:34:01 -04:00
|
|
|
*
|
2005-03-14 20:51:43 -05:00
|
|
|
* 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
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2007-12-10 23:55:22 -05:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2005-03-14 20:51:43 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2007-10-23 00:33:47 -04:00
|
|
|
#include <limits.h>
|
2005-03-14 20:51:43 -05:00
|
|
|
#include <unistd.h>
|
2012-02-29 16:51:54 -05:00
|
|
|
#include <errno.h>
|
2005-03-14 20:51:43 -05:00
|
|
|
#include <dirent.h>
|
2008-02-19 09:47:05 -05:00
|
|
|
#include <sys/stat.h>
|
2012-03-09 08:16:40 -05:00
|
|
|
#include <fnmatch.h>
|
2005-03-14 20:51:43 -05:00
|
|
|
|
|
|
|
#include <alpm.h>
|
2007-01-19 04:28:44 -05:00
|
|
|
#include <alpm_list.h>
|
2007-03-05 17:13:33 -05:00
|
|
|
|
2005-03-14 20:51:43 -05:00
|
|
|
/* pacman */
|
2007-04-25 02:21:12 -04:00
|
|
|
#include "pacman.h"
|
2005-03-14 20:51:43 -05:00
|
|
|
#include "util.h"
|
|
|
|
#include "package.h"
|
2005-10-28 08:20:40 -04:00
|
|
|
#include "conf.h"
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2012-02-29 16:51:54 -05:00
|
|
|
static int unlink_verbose(const char *pathname, int ignore_missing)
|
|
|
|
{
|
|
|
|
int ret = unlink(pathname);
|
|
|
|
if(ret) {
|
|
|
|
if(ignore_missing && errno == ENOENT) {
|
|
|
|
ret = 0;
|
|
|
|
} else {
|
|
|
|
pm_printf(ALPM_LOG_ERROR, _("could not remove %s: %s\n"),
|
|
|
|
pathname, strerror(errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-17 08:17:55 -04:00
|
|
|
static int sync_cleandb(const char *dbpath)
|
2011-05-10 18:39:22 -04:00
|
|
|
{
|
2007-11-17 16:52:03 -05:00
|
|
|
DIR *dir;
|
|
|
|
struct dirent *ent;
|
2011-01-29 12:30:01 -05:00
|
|
|
alpm_list_t *syncdbs;
|
2012-02-29 16:51:54 -05:00
|
|
|
int ret = 0;
|
2007-11-17 16:52:03 -05:00
|
|
|
|
|
|
|
dir = opendir(dbpath);
|
|
|
|
if(dir == NULL) {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR, _("could not access database directory\n"));
|
2011-03-20 20:45:57 -04:00
|
|
|
return 1;
|
2007-11-17 16:52:03 -05:00
|
|
|
}
|
|
|
|
|
2012-02-02 00:45:52 -05:00
|
|
|
syncdbs = alpm_get_syncdbs(config->handle);
|
2011-01-29 12:30:01 -05:00
|
|
|
|
2007-11-17 16:52:03 -05:00
|
|
|
rewinddir(dir);
|
|
|
|
/* step through the directory one file at a time */
|
|
|
|
while((ent = readdir(dir)) != NULL) {
|
|
|
|
char path[PATH_MAX];
|
2008-02-19 09:47:05 -05:00
|
|
|
struct stat buf;
|
2007-11-17 16:52:03 -05:00
|
|
|
int found = 0;
|
2008-05-04 20:15:49 -04:00
|
|
|
const char *dname = ent->d_name;
|
2012-02-29 16:51:54 -05:00
|
|
|
char *dbname;
|
2010-07-09 10:52:50 -04:00
|
|
|
size_t len;
|
2015-06-17 08:17:55 -04:00
|
|
|
alpm_list_t *i;
|
2007-11-17 16:52:03 -05:00
|
|
|
|
2010-06-19 04:55:08 -04:00
|
|
|
if(strcmp(dname, ".") == 0 || strcmp(dname, "..") == 0) {
|
2007-11-17 16:52:03 -05:00
|
|
|
continue;
|
|
|
|
}
|
2008-02-19 09:47:05 -05:00
|
|
|
|
|
|
|
/* build the full path */
|
2008-05-04 20:15:49 -04:00
|
|
|
snprintf(path, PATH_MAX, "%s%s", dbpath, dname);
|
2010-07-09 10:52:50 -04:00
|
|
|
|
|
|
|
/* remove all non-skipped directories and non-database files */
|
2015-02-24 10:05:20 -05:00
|
|
|
if(stat(path, &buf) == -1) {
|
|
|
|
pm_printf(ALPM_LOG_ERROR, _("could not remove %s: %s\n"),
|
|
|
|
path, strerror(errno));
|
|
|
|
}
|
2012-02-29 16:51:54 -05:00
|
|
|
if(S_ISDIR(buf.st_mode)) {
|
2010-07-09 10:52:50 -04:00
|
|
|
if(rmrf(path)) {
|
2012-02-29 16:51:54 -05:00
|
|
|
pm_printf(ALPM_LOG_ERROR, _("could not remove %s: %s\n"),
|
|
|
|
path, strerror(errno));
|
2010-07-09 10:52:50 -04:00
|
|
|
}
|
2008-02-19 09:47:05 -05:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-02-29 16:51:54 -05:00
|
|
|
len = strlen(dname);
|
|
|
|
if(len > 3 && strcmp(dname + len - 3, ".db") == 0) {
|
|
|
|
dbname = strndup(dname, len - 3);
|
|
|
|
} else if(len > 7 && strcmp(dname + len - 7, ".db.sig") == 0) {
|
|
|
|
dbname = strndup(dname, len - 7);
|
2015-06-17 08:27:50 -04:00
|
|
|
} else if(len > 6 && strcmp(dname + len - 6, ".files") == 0) {
|
|
|
|
dbname = strndup(dname, len - 6);
|
|
|
|
} else if(len > 6 && strcmp(dname + len - 6, ".files.sig") == 0) {
|
|
|
|
dbname = strndup(dname, len - 10);
|
2012-02-29 16:51:54 -05:00
|
|
|
} else {
|
|
|
|
ret += unlink_verbose(path, 0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-06-17 08:17:55 -04:00
|
|
|
for(i = syncdbs; i && !found; i = alpm_list_next(i)) {
|
|
|
|
alpm_db_t *db = i->data;
|
|
|
|
found = !strcmp(dbname, alpm_db_get_name(db));
|
2007-11-17 16:52:03 -05:00
|
|
|
}
|
|
|
|
|
2015-06-17 08:17:55 -04:00
|
|
|
/* We have a file that doesn't match any syncdb. */
|
2012-02-29 16:51:54 -05:00
|
|
|
if(!found) {
|
2015-06-17 08:17:55 -04:00
|
|
|
ret += unlink_verbose(path, 0);
|
2007-11-17 16:52:03 -05:00
|
|
|
}
|
2015-06-17 08:17:55 -04:00
|
|
|
|
2012-02-29 16:51:54 -05:00
|
|
|
free(dbname);
|
2007-11-17 16:52:03 -05:00
|
|
|
}
|
2009-09-21 09:03:07 -04:00
|
|
|
closedir(dir);
|
2012-02-29 16:51:54 -05:00
|
|
|
return ret;
|
2007-11-17 16:52:03 -05:00
|
|
|
}
|
|
|
|
|
2011-05-10 18:39:22 -04:00
|
|
|
static int sync_cleandb_all(void)
|
|
|
|
{
|
2009-09-21 09:09:00 -04:00
|
|
|
const char *dbpath;
|
2015-06-17 08:17:55 -04:00
|
|
|
char *syncdbpath;
|
2009-09-21 09:09:00 -04:00
|
|
|
int ret = 0;
|
2007-11-17 16:52:03 -05:00
|
|
|
|
2011-06-07 14:15:43 -04:00
|
|
|
dbpath = alpm_option_get_dbpath(config->handle);
|
2007-11-17 16:52:03 -05:00
|
|
|
printf(_("Database directory: %s\n"), dbpath);
|
2008-08-20 16:08:11 -04:00
|
|
|
if(!yesno(_("Do you want to remove unused repositories?"))) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return 0;
|
2007-11-17 16:52:03 -05:00
|
|
|
}
|
2012-02-29 16:51:54 -05:00
|
|
|
printf(_("removing unused sync repositories...\n"));
|
2007-11-17 16:52:03 -05:00
|
|
|
|
2015-06-17 08:17:55 -04:00
|
|
|
if(asprintf(&syncdbpath, "%s%s", dbpath, "sync/") < 0) {
|
2011-09-19 20:57:29 -04:00
|
|
|
ret += 1;
|
|
|
|
return ret;
|
|
|
|
}
|
2015-06-17 08:17:55 -04:00
|
|
|
ret += sync_cleandb(syncdbpath);
|
|
|
|
free(syncdbpath);
|
2007-11-17 16:52:03 -05:00
|
|
|
|
2011-03-20 20:45:57 -04:00
|
|
|
return ret;
|
2007-11-17 16:52:03 -05:00
|
|
|
}
|
|
|
|
|
2005-03-14 20:51:43 -05:00
|
|
|
static int sync_cleancache(int level)
|
|
|
|
{
|
2009-09-21 09:12:10 -04:00
|
|
|
alpm_list_t *i;
|
2012-02-02 00:45:52 -05:00
|
|
|
alpm_list_t *sync_dbs = alpm_get_syncdbs(config->handle);
|
|
|
|
alpm_db_t *db_local = alpm_get_localdb(config->handle);
|
2011-06-07 14:15:43 -04:00
|
|
|
alpm_list_t *cachedirs = alpm_option_get_cachedirs(config->handle);
|
2009-09-21 09:12:10 -04:00
|
|
|
int ret = 0;
|
|
|
|
|
2011-01-29 13:10:05 -05:00
|
|
|
if(!config->cleanmethod) {
|
|
|
|
/* default to KeepInstalled if user did not specify */
|
|
|
|
config->cleanmethod = PM_CLEAN_KEEPINST;
|
|
|
|
}
|
|
|
|
|
2005-05-09 05:14:10 -04:00
|
|
|
if(level == 1) {
|
2011-01-29 13:10:05 -05:00
|
|
|
printf(_("Packages to keep:\n"));
|
|
|
|
if(config->cleanmethod & PM_CLEAN_KEEPINST) {
|
|
|
|
printf(_(" All locally installed packages\n"));
|
|
|
|
}
|
|
|
|
if(config->cleanmethod & PM_CLEAN_KEEPCUR) {
|
|
|
|
printf(_(" All current sync database packages\n"));
|
|
|
|
}
|
2009-09-21 09:12:10 -04:00
|
|
|
}
|
2012-06-15 19:12:22 -04:00
|
|
|
printf("\n");
|
2009-09-21 09:12:10 -04:00
|
|
|
|
2011-06-07 14:15:43 -04:00
|
|
|
for(i = cachedirs; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
const char *cachedir = i->data;
|
2012-06-15 19:12:22 -04:00
|
|
|
DIR *dir;
|
2009-09-21 09:12:10 -04:00
|
|
|
struct dirent *ent;
|
2007-09-25 23:07:36 -04:00
|
|
|
|
2012-06-15 19:12:22 -04:00
|
|
|
printf(_("Cache directory: %s\n"), (const char *)i->data);
|
|
|
|
|
|
|
|
if(level == 1) {
|
|
|
|
if(!yesno(_("Do you want to remove all other packages from cache?"))) {
|
|
|
|
printf("\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
printf(_("removing old packages from cache...\n"));
|
|
|
|
} else {
|
|
|
|
if(!noyes(_("Do you want to remove ALL files from cache?"))) {
|
|
|
|
printf("\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
printf(_("removing all files from cache...\n"));
|
|
|
|
}
|
|
|
|
|
|
|
|
dir = opendir(cachedir);
|
2007-09-25 23:07:36 -04:00
|
|
|
if(dir == NULL) {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR,
|
2009-09-21 09:12:10 -04:00
|
|
|
_("could not access cache directory %s\n"), cachedir);
|
|
|
|
ret++;
|
|
|
|
continue;
|
2007-09-25 23:07:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
rewinddir(dir);
|
|
|
|
/* step through the directory one file at a time */
|
|
|
|
while((ent = readdir(dir)) != NULL) {
|
|
|
|
char path[PATH_MAX];
|
2008-02-16 10:01:13 -05:00
|
|
|
int delete = 1;
|
2011-06-28 09:26:39 -04:00
|
|
|
alpm_pkg_t *localpkg = NULL, *pkg = NULL;
|
2011-01-29 13:10:05 -05:00
|
|
|
const char *local_name, *local_version;
|
2007-09-25 23:07:36 -04:00
|
|
|
|
2010-06-19 04:55:08 -04:00
|
|
|
if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
|
2007-09-25 23:07:36 -04:00
|
|
|
continue;
|
|
|
|
}
|
2012-03-09 08:16:40 -05:00
|
|
|
|
2013-01-03 16:48:53 -05:00
|
|
|
if(level <= 1) {
|
2014-12-14 21:01:22 -05:00
|
|
|
static const char *const glob_skips[] = {
|
2012-07-12 15:00:44 -04:00
|
|
|
/* skip signature files - they are removed with their package file */
|
|
|
|
"*.sig",
|
2015-06-17 08:27:50 -04:00
|
|
|
/* skip package databases within the cache directory */
|
|
|
|
"*.db*", "*.files*",
|
2012-07-12 15:00:44 -04:00
|
|
|
/* skip source packages within the cache directory */
|
|
|
|
"*.src.tar.*",
|
|
|
|
/* skip package deltas, we aren't smart enough to clean these yet */
|
2013-05-18 10:20:01 -04:00
|
|
|
"*.delta"
|
2012-07-12 15:00:44 -04:00
|
|
|
};
|
|
|
|
size_t j;
|
|
|
|
|
|
|
|
for(j = 0; j < sizeof(glob_skips) / sizeof(glob_skips[0]); j++) {
|
|
|
|
if(fnmatch(glob_skips[j], ent->d_name, 0) == 0) {
|
|
|
|
delete = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(delete == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
2012-07-11 00:14:40 -04:00
|
|
|
}
|
|
|
|
|
2007-09-25 23:07:36 -04:00
|
|
|
/* build the full filepath */
|
2008-02-16 10:01:13 -05:00
|
|
|
snprintf(path, PATH_MAX, "%s%s", cachedir, ent->d_name);
|
2007-09-25 23:07:36 -04:00
|
|
|
|
2012-01-18 13:12:39 -05:00
|
|
|
/* short circuit for removing all files from cache */
|
2009-09-21 09:12:10 -04:00
|
|
|
if(level > 1) {
|
2012-02-29 16:51:54 -05:00
|
|
|
ret += unlink_verbose(path, 0);
|
2009-09-21 09:12:10 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-01-18 13:12:39 -05:00
|
|
|
/* attempt to load the file as a package. if we cannot load the file,
|
|
|
|
* simply skip it and move on. we don't need a full load of the package,
|
|
|
|
* just the metadata. */
|
|
|
|
if(alpm_pkg_load(config->handle, path, 0, 0, &localpkg) != 0) {
|
|
|
|
pm_printf(ALPM_LOG_DEBUG, "skipping %s, could not load as package\n",
|
|
|
|
path);
|
2007-09-25 23:07:36 -04:00
|
|
|
continue;
|
|
|
|
}
|
2011-01-29 13:10:05 -05:00
|
|
|
local_name = alpm_pkg_get_name(localpkg);
|
|
|
|
local_version = alpm_pkg_get_version(localpkg);
|
|
|
|
|
|
|
|
if(config->cleanmethod & PM_CLEAN_KEEPINST) {
|
|
|
|
/* check if this package is in the local DB */
|
|
|
|
pkg = alpm_db_get_pkg(db_local, local_name);
|
|
|
|
if(pkg != NULL && alpm_pkg_vercmp(local_version,
|
|
|
|
alpm_pkg_get_version(pkg)) == 0) {
|
|
|
|
/* package was found in local DB and version matches, keep it */
|
2012-01-18 13:12:39 -05:00
|
|
|
pm_printf(ALPM_LOG_DEBUG, "package %s-%s found in local db\n",
|
2011-01-29 13:10:05 -05:00
|
|
|
local_name, local_version);
|
|
|
|
delete = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(config->cleanmethod & PM_CLEAN_KEEPCUR) {
|
2011-05-10 18:39:22 -04:00
|
|
|
alpm_list_t *j;
|
2011-01-29 13:10:05 -05:00
|
|
|
/* check if this package is in a sync DB */
|
|
|
|
for(j = sync_dbs; j && delete; j = alpm_list_next(j)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_db_t *db = j->data;
|
2011-01-29 13:10:05 -05:00
|
|
|
pkg = alpm_db_get_pkg(db, local_name);
|
|
|
|
if(pkg != NULL && alpm_pkg_vercmp(local_version,
|
2008-02-16 10:01:13 -05:00
|
|
|
alpm_pkg_get_version(pkg)) == 0) {
|
2011-01-29 13:10:05 -05:00
|
|
|
/* package was found in a sync DB and version matches, keep it */
|
2012-01-18 13:12:39 -05:00
|
|
|
pm_printf(ALPM_LOG_DEBUG, "package %s-%s found in sync db\n",
|
2011-01-29 13:10:05 -05:00
|
|
|
local_name, local_version);
|
2008-02-16 10:01:13 -05:00
|
|
|
delete = 0;
|
|
|
|
}
|
2011-01-29 13:10:05 -05:00
|
|
|
}
|
2007-09-25 23:07:36 -04:00
|
|
|
}
|
|
|
|
/* free the local file package */
|
|
|
|
alpm_pkg_free(localpkg);
|
2008-02-16 10:01:13 -05:00
|
|
|
|
|
|
|
if(delete) {
|
2012-01-18 13:12:39 -05:00
|
|
|
size_t pathlen = strlen(path);
|
2012-02-29 16:51:54 -05:00
|
|
|
ret += unlink_verbose(path, 0);
|
2011-05-10 18:39:22 -04:00
|
|
|
/* unlink a signature file if present too */
|
|
|
|
if(PATH_MAX - 5 >= pathlen) {
|
|
|
|
strcpy(path + pathlen, ".sig");
|
2012-02-29 16:51:54 -05:00
|
|
|
ret += unlink_verbose(path, 1);
|
2011-05-10 18:39:22 -04:00
|
|
|
}
|
2008-02-16 10:01:13 -05:00
|
|
|
}
|
2007-09-25 23:07:36 -04:00
|
|
|
}
|
2009-09-21 09:03:07 -04:00
|
|
|
closedir(dir);
|
2012-06-15 19:12:22 -04:00
|
|
|
printf("\n");
|
2005-05-09 05:14:10 -04:00
|
|
|
}
|
|
|
|
|
2011-03-20 20:45:57 -04:00
|
|
|
return ret;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2007-06-02 12:34:01 -04:00
|
|
|
/* search the sync dbs for a matching package */
|
2007-01-19 04:28:44 -05:00
|
|
|
static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
|
2005-03-14 20:51:43 -05:00
|
|
|
{
|
2013-02-28 13:56:28 -05:00
|
|
|
alpm_list_t *i;
|
2007-08-09 03:36:20 -04:00
|
|
|
int found = 0;
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2007-01-19 04:28:44 -05:00
|
|
|
for(i = syncs; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_db_t *db = i->data;
|
2013-02-28 13:56:28 -05:00
|
|
|
found += !dump_pkg_search(db, targets, 1);
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2013-02-28 13:56:28 -05:00
|
|
|
return (found == 0);
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2007-01-19 04:28:44 -05:00
|
|
|
static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
|
2005-03-14 20:51:43 -05:00
|
|
|
{
|
2012-04-01 22:16:28 -04:00
|
|
|
alpm_list_t *i, *j, *k, *s = NULL;
|
2013-07-16 05:18:32 -04:00
|
|
|
int ret = 0;
|
2006-10-15 15:34:52 -04:00
|
|
|
|
2005-03-14 20:51:43 -05:00
|
|
|
if(targets) {
|
2014-02-22 20:41:40 -05:00
|
|
|
size_t found;
|
2007-01-19 04:28:44 -05:00
|
|
|
for(i = targets; i; i = alpm_list_next(i)) {
|
2013-07-16 05:18:32 -04:00
|
|
|
found = 0;
|
2011-10-06 01:55:47 -04:00
|
|
|
const char *grpname = i->data;
|
2007-01-19 04:28:44 -05:00
|
|
|
for(j = syncs; j; j = alpm_list_next(j)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_db_t *db = j->data;
|
2012-02-02 00:45:52 -05:00
|
|
|
alpm_group_t *grp = alpm_db_get_group(db, grpname);
|
2005-03-14 20:51:43 -05:00
|
|
|
|
|
|
|
if(grp) {
|
2013-07-16 05:18:32 -04:00
|
|
|
found++;
|
2008-01-12 02:13:52 -05:00
|
|
|
/* get names of packages in group */
|
2011-06-16 12:55:26 -04:00
|
|
|
for(k = grp->packages; k; k = alpm_list_next(k)) {
|
2008-07-16 08:42:25 -04:00
|
|
|
if(!config->quiet) {
|
|
|
|
printf("%s %s\n", grpname,
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_pkg_get_name(k->data));
|
2008-07-16 08:42:25 -04:00
|
|
|
} else {
|
2011-10-06 01:55:47 -04:00
|
|
|
printf("%s\n", alpm_pkg_get_name(k->data));
|
2008-07-16 08:42:25 -04:00
|
|
|
}
|
2008-01-12 02:13:52 -05:00
|
|
|
}
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
}
|
2013-10-31 17:31:32 -04:00
|
|
|
if(!found) {
|
2013-07-16 05:18:32 -04:00
|
|
|
ret = 1;
|
|
|
|
}
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
} else {
|
2013-07-16 05:18:32 -04:00
|
|
|
ret = 1;
|
2007-01-19 04:28:44 -05:00
|
|
|
for(i = syncs; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_db_t *db = i->data;
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2011-06-29 01:46:49 -04:00
|
|
|
for(j = alpm_db_get_groupcache(db); j; j = alpm_list_next(j)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_group_t *grp = j->data;
|
2013-07-16 05:18:32 -04:00
|
|
|
ret = 0;
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2008-06-05 15:32:19 -04:00
|
|
|
if(level > 1) {
|
2011-06-16 12:55:26 -04:00
|
|
|
for(k = grp->packages; k; k = alpm_list_next(k)) {
|
|
|
|
printf("%s %s\n", grp->name,
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_pkg_get_name(k->data));
|
2008-01-12 02:13:52 -05:00
|
|
|
}
|
2008-06-05 15:32:19 -04:00
|
|
|
} else {
|
|
|
|
/* print grp names only, no package names */
|
2012-04-01 22:16:28 -04:00
|
|
|
if(!alpm_list_find_str (s, grp->name)) {
|
|
|
|
s = alpm_list_add (s, grp->name);
|
|
|
|
printf("%s\n", grp->name);
|
|
|
|
}
|
2005-12-31 12:59:28 -05:00
|
|
|
}
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
}
|
2012-04-01 22:16:28 -04:00
|
|
|
alpm_list_free(s);
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2013-07-16 05:18:32 -04:00
|
|
|
return ret;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2007-01-19 04:28:44 -05:00
|
|
|
static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
|
2005-03-14 20:51:43 -05:00
|
|
|
{
|
2007-01-19 04:28:44 -05:00
|
|
|
alpm_list_t *i, *j, *k;
|
2007-05-31 01:12:17 -04:00
|
|
|
int ret = 0;
|
2005-03-14 20:51:43 -05:00
|
|
|
|
|
|
|
if(targets) {
|
2007-01-19 04:28:44 -05:00
|
|
|
for(i = targets; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
const char *target = i->data;
|
2011-07-05 15:18:16 -04:00
|
|
|
char *name = strdup(target);
|
|
|
|
char *repo, *pkgstr;
|
|
|
|
int foundpkg = 0, founddb = 0;
|
2007-02-15 20:58:51 -05:00
|
|
|
|
2011-07-05 15:18:16 -04:00
|
|
|
pkgstr = strchr(name, '/');
|
2007-02-15 20:58:51 -05:00
|
|
|
if(pkgstr) {
|
2011-07-05 15:18:16 -04:00
|
|
|
repo = name;
|
2007-02-15 20:58:51 -05:00
|
|
|
*pkgstr = '\0';
|
|
|
|
++pkgstr;
|
2011-07-05 15:18:16 -04:00
|
|
|
} else {
|
|
|
|
repo = NULL;
|
|
|
|
pkgstr = name;
|
|
|
|
}
|
2007-02-15 20:58:51 -05:00
|
|
|
|
2011-07-05 15:18:16 -04:00
|
|
|
for(j = syncs; j; j = alpm_list_next(j)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_db_t *db = j->data;
|
2011-07-05 15:18:16 -04:00
|
|
|
if(repo && strcmp(repo, alpm_db_get_name(db)) != 0) {
|
|
|
|
continue;
|
2007-02-15 20:58:51 -05:00
|
|
|
}
|
2011-07-05 15:18:16 -04:00
|
|
|
founddb = 1;
|
2007-06-02 12:34:01 -04:00
|
|
|
|
2011-02-25 09:22:09 -05:00
|
|
|
for(k = alpm_db_get_pkgcache(db); k; k = alpm_list_next(k)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_pkg_t *pkg = k->data;
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2007-02-15 20:58:51 -05:00
|
|
|
if(strcmp(alpm_pkg_get_name(pkg), pkgstr) == 0) {
|
2011-08-29 00:41:17 -04:00
|
|
|
dump_pkg_full(pkg, config->op_s_info > 1);
|
2007-02-15 20:58:51 -05:00
|
|
|
foundpkg = 1;
|
|
|
|
break;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
}
|
2011-07-05 15:18:16 -04:00
|
|
|
}
|
2007-06-02 12:34:01 -04:00
|
|
|
|
2011-07-05 15:18:16 -04:00
|
|
|
if(!founddb) {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR,
|
2011-07-05 15:18:16 -04:00
|
|
|
_("repository '%s' does not exist\n"), repo);
|
|
|
|
ret++;
|
|
|
|
}
|
|
|
|
if(!foundpkg) {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR,
|
2011-07-05 15:18:16 -04:00
|
|
|
_("package '%s' was not found\n"), target);
|
|
|
|
ret++;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
2011-07-05 15:18:16 -04:00
|
|
|
free(name);
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
} else {
|
2007-01-19 04:28:44 -05:00
|
|
|
for(i = syncs; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_db_t *db = i->data;
|
2007-06-02 12:34:01 -04:00
|
|
|
|
2011-02-25 09:22:09 -05:00
|
|
|
for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_pkg_t *pkg = j->data;
|
2011-08-29 00:41:17 -04:00
|
|
|
dump_pkg_full(pkg, config->op_s_info > 1);
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-20 20:45:57 -04:00
|
|
|
return ret;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2007-01-19 04:28:44 -05:00
|
|
|
static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
|
2005-03-14 20:51:43 -05:00
|
|
|
{
|
2007-01-19 04:28:44 -05:00
|
|
|
alpm_list_t *i, *j, *ls = NULL;
|
2012-02-02 00:45:52 -05:00
|
|
|
alpm_db_t *db_local = alpm_get_localdb(config->handle);
|
2013-06-19 01:15:02 -04:00
|
|
|
int ret = 0;
|
2005-03-14 20:51:43 -05:00
|
|
|
|
|
|
|
if(targets) {
|
2007-01-19 04:28:44 -05:00
|
|
|
for(i = targets; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
const char *repo = i->data;
|
2011-06-28 00:11:43 -04:00
|
|
|
alpm_db_t *db = NULL;
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2007-01-19 04:28:44 -05:00
|
|
|
for(j = syncs; j; j = alpm_list_next(j)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_db_t *d = j->data;
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2007-01-19 04:28:44 -05:00
|
|
|
if(strcmp(repo, alpm_db_get_name(d)) == 0) {
|
|
|
|
db = d;
|
|
|
|
break;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-01-19 04:28:44 -05:00
|
|
|
if(db == NULL) {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR,
|
2013-01-03 16:48:51 -05:00
|
|
|
_("repository \"%s\" was not found.\n"), repo);
|
2013-06-19 01:15:02 -04:00
|
|
|
ret = 1;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2007-01-19 04:28:44 -05:00
|
|
|
ls = alpm_list_add(ls, db);
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
} else {
|
2005-05-09 05:14:10 -04:00
|
|
|
ls = syncs;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2007-01-19 04:28:44 -05:00
|
|
|
for(i = ls; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_db_t *db = i->data;
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2011-02-25 09:22:09 -05:00
|
|
|
for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_pkg_t *pkg = j->data;
|
2009-09-04 14:18:49 -04:00
|
|
|
|
2011-04-20 20:45:16 -04:00
|
|
|
if(!config->quiet) {
|
2013-03-01 15:33:46 -05:00
|
|
|
const colstr_t *colstr = &config->colstr;
|
|
|
|
printf("%s%s %s%s %s%s%s", colstr->repo, alpm_db_get_name(db),
|
|
|
|
colstr->title, alpm_pkg_get_name(pkg),
|
|
|
|
colstr->version, alpm_pkg_get_version(pkg), colstr->nocolor);
|
2011-01-28 18:41:15 -05:00
|
|
|
print_installed(db_local, pkg);
|
2009-09-04 14:18:49 -04:00
|
|
|
printf("\n");
|
2007-11-07 02:05:33 -05:00
|
|
|
} else {
|
|
|
|
printf("%s\n", alpm_pkg_get_name(pkg));
|
|
|
|
}
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(targets) {
|
2007-01-24 03:51:50 -05:00
|
|
|
alpm_list_free(ls);
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2013-06-19 01:15:02 -04:00
|
|
|
return ret;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2011-06-28 00:11:43 -04:00
|
|
|
static alpm_db_t *get_db(const char *dbname)
|
2010-10-16 19:08:34 -04:00
|
|
|
{
|
|
|
|
alpm_list_t *i;
|
2012-02-02 00:45:52 -05:00
|
|
|
for(i = alpm_get_syncdbs(config->handle); i; i = i->next) {
|
2011-06-28 00:11:43 -04:00
|
|
|
alpm_db_t *db = i->data;
|
2010-10-16 19:08:34 -04:00
|
|
|
if(strcmp(alpm_db_get_name(db), dbname) == 0) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return db;
|
2010-10-16 19:08:34 -04:00
|
|
|
}
|
|
|
|
}
|
2011-03-20 20:45:57 -04:00
|
|
|
return NULL;
|
2010-10-16 19:08:34 -04:00
|
|
|
}
|
|
|
|
|
2011-06-28 09:26:39 -04:00
|
|
|
static int process_pkg(alpm_pkg_t *pkg)
|
2010-10-16 19:08:34 -04:00
|
|
|
{
|
2011-06-09 17:00:55 -04:00
|
|
|
int ret = alpm_add_pkg(config->handle, pkg);
|
2010-10-16 19:08:34 -04:00
|
|
|
|
|
|
|
if(ret == -1) {
|
2011-10-28 22:03:24 -04:00
|
|
|
alpm_errno_t err = alpm_errno(config->handle);
|
2014-03-03 18:29:10 -05:00
|
|
|
if(err == ALPM_ERR_TRANS_DUP_TARGET) {
|
|
|
|
/* just skip duplicate targets */
|
2011-07-01 12:01:38 -04:00
|
|
|
pm_printf(ALPM_LOG_WARNING, _("skipping target: %s\n"), alpm_pkg_get_name(pkg));
|
2011-03-20 20:45:57 -04:00
|
|
|
return 0;
|
2010-10-16 19:08:34 -04:00
|
|
|
} else {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg),
|
2011-06-07 17:06:16 -04:00
|
|
|
alpm_strerror(err));
|
2011-03-20 20:45:57 -04:00
|
|
|
return 1;
|
2010-10-16 19:08:34 -04:00
|
|
|
}
|
|
|
|
}
|
2011-07-29 16:35:59 -04:00
|
|
|
config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
|
2011-03-20 20:45:57 -04:00
|
|
|
return 0;
|
2010-10-16 19:08:34 -04:00
|
|
|
}
|
|
|
|
|
2011-12-12 11:53:14 -05:00
|
|
|
static int process_group(alpm_list_t *dbs, const char *group, int error)
|
2010-10-16 19:08:34 -04:00
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
alpm_list_t *i;
|
2011-06-29 01:46:49 -04:00
|
|
|
alpm_list_t *pkgs = alpm_find_group_pkgs(dbs, group);
|
2010-10-16 19:08:34 -04:00
|
|
|
int count = alpm_list_count(pkgs);
|
|
|
|
|
|
|
|
if(!count) {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR, _("target not found: %s\n"), group);
|
2011-03-20 20:45:57 -04:00
|
|
|
return 1;
|
2010-10-16 19:08:34 -04:00
|
|
|
}
|
|
|
|
|
2011-12-12 11:53:14 -05:00
|
|
|
if(error) {
|
|
|
|
/* we already know another target errored. there is no reason to prompt the
|
|
|
|
* user here; we already validated the group name so just move on since we
|
|
|
|
* won't actually be installing anything anyway. */
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-10-16 19:08:34 -04:00
|
|
|
|
2011-03-20 23:29:37 -04:00
|
|
|
if(config->print == 0) {
|
2014-08-01 17:19:53 -04:00
|
|
|
char *array = malloc(count);
|
|
|
|
int n = 0;
|
2014-02-03 17:57:31 -05:00
|
|
|
colon_printf(_n("There is %d member in group %s:\n",
|
|
|
|
"There are %d members in group %s:\n", count),
|
|
|
|
count, group);
|
2011-03-20 23:29:37 -04:00
|
|
|
select_display(pkgs);
|
2011-07-25 11:05:36 -04:00
|
|
|
if(!array) {
|
|
|
|
ret = 1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if(multiselect_question(array, count)) {
|
|
|
|
ret = 1;
|
|
|
|
free(array);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2014-08-01 17:19:53 -04:00
|
|
|
for(i = pkgs, n = 0; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_pkg_t *pkg = i->data;
|
2011-03-20 23:29:37 -04:00
|
|
|
|
2014-08-01 17:19:53 -04:00
|
|
|
if(array[n++] == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-03-20 23:29:37 -04:00
|
|
|
if(process_pkg(pkg) == 1) {
|
|
|
|
ret = 1;
|
|
|
|
free(array);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2011-07-25 11:05:36 -04:00
|
|
|
free(array);
|
2011-03-20 23:29:37 -04:00
|
|
|
} else {
|
|
|
|
for(i = pkgs; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_pkg_t *pkg = i->data;
|
2011-03-20 23:29:37 -04:00
|
|
|
|
|
|
|
if(process_pkg(pkg) == 1) {
|
|
|
|
ret = 1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-10-16 19:08:34 -04:00
|
|
|
}
|
|
|
|
}
|
2011-12-12 11:53:14 -05:00
|
|
|
|
2010-10-16 19:08:34 -04:00
|
|
|
cleanup:
|
|
|
|
alpm_list_free(pkgs);
|
2011-03-20 20:45:57 -04:00
|
|
|
return ret;
|
2010-10-16 19:08:34 -04:00
|
|
|
}
|
|
|
|
|
2011-12-12 11:53:14 -05:00
|
|
|
static int process_targname(alpm_list_t *dblist, const char *targname,
|
|
|
|
int error)
|
2010-10-16 19:08:34 -04:00
|
|
|
{
|
2011-06-28 09:26:39 -04:00
|
|
|
alpm_pkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, targname);
|
2010-10-16 19:08:34 -04:00
|
|
|
|
2013-07-15 00:14:46 -04:00
|
|
|
/* skip ignored packages when user says no */
|
2011-07-01 12:01:39 -04:00
|
|
|
if(alpm_errno(config->handle) == ALPM_ERR_PKG_IGNORED) {
|
2011-07-01 12:01:38 -04:00
|
|
|
pm_printf(ALPM_LOG_WARNING, _("skipping target: %s\n"), targname);
|
2011-03-20 20:45:57 -04:00
|
|
|
return 0;
|
2011-03-19 04:09:27 -04:00
|
|
|
}
|
|
|
|
|
2010-10-16 19:08:34 -04:00
|
|
|
if(pkg) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return process_pkg(pkg);
|
2010-10-16 19:08:34 -04:00
|
|
|
}
|
|
|
|
/* fallback on group */
|
2011-12-12 11:53:14 -05:00
|
|
|
return process_group(dblist, targname, error);
|
2010-10-16 19:08:34 -04:00
|
|
|
}
|
|
|
|
|
2011-12-12 11:53:14 -05:00
|
|
|
static int process_target(const char *target, int error)
|
2009-09-07 14:58:49 -04:00
|
|
|
{
|
2009-07-16 08:55:45 -04:00
|
|
|
/* process targets */
|
2009-09-15 10:07:25 -04:00
|
|
|
char *targstring = strdup(target);
|
|
|
|
char *targname = strchr(targstring, '/');
|
|
|
|
int ret = 0;
|
2011-12-12 11:53:14 -05:00
|
|
|
alpm_list_t *dblist;
|
2010-10-16 19:08:34 -04:00
|
|
|
|
2011-08-25 19:37:23 -04:00
|
|
|
if(targname && targname != targstring) {
|
2011-12-12 11:53:14 -05:00
|
|
|
alpm_db_t *db;
|
|
|
|
const char *dbname;
|
2012-07-02 17:16:58 -04:00
|
|
|
alpm_db_usage_t usage;
|
2010-10-16 19:08:34 -04:00
|
|
|
|
2009-09-15 10:07:25 -04:00
|
|
|
*targname = '\0';
|
|
|
|
targname++;
|
|
|
|
dbname = targstring;
|
2010-10-16 19:08:34 -04:00
|
|
|
db = get_db(dbname);
|
|
|
|
if(!db) {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR, _("database not found: %s\n"),
|
2010-10-16 19:08:34 -04:00
|
|
|
dbname);
|
2009-09-15 10:07:25 -04:00
|
|
|
ret = 1;
|
2010-10-16 19:08:34 -04:00
|
|
|
goto cleanup;
|
2009-09-07 14:58:49 -04:00
|
|
|
}
|
2012-07-02 17:16:58 -04:00
|
|
|
|
|
|
|
/* explicitly mark this repo as valid for installs since
|
|
|
|
* a repo name was given with the target */
|
|
|
|
alpm_db_get_usage(db, &usage);
|
|
|
|
alpm_db_set_usage(db, usage|ALPM_DB_USAGE_INSTALL);
|
|
|
|
|
2011-12-12 11:53:14 -05:00
|
|
|
dblist = alpm_list_add(NULL, db);
|
|
|
|
ret = process_targname(dblist, targname, error);
|
2010-10-16 19:08:34 -04:00
|
|
|
alpm_list_free(dblist);
|
2012-07-02 17:16:58 -04:00
|
|
|
|
|
|
|
/* restore old usage so we don't possibly disturb later
|
|
|
|
* targets */
|
|
|
|
alpm_db_set_usage(db, usage);
|
2010-10-16 19:08:34 -04:00
|
|
|
} else {
|
|
|
|
targname = targstring;
|
2012-02-02 00:45:52 -05:00
|
|
|
dblist = alpm_get_syncdbs(config->handle);
|
2011-12-12 11:53:14 -05:00
|
|
|
ret = process_targname(dblist, targname, error);
|
2009-09-07 14:58:49 -04:00
|
|
|
}
|
2011-12-12 11:53:14 -05:00
|
|
|
|
2010-10-16 19:08:34 -04:00
|
|
|
cleanup:
|
2009-09-15 10:07:25 -04:00
|
|
|
free(targstring);
|
2011-08-25 19:37:23 -04:00
|
|
|
if(ret && access(target, R_OK) == 0) {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_WARNING,
|
2011-09-05 13:16:07 -04:00
|
|
|
_("'%s' is a file, did you mean %s instead of %s?\n"),
|
2011-08-25 19:37:23 -04:00
|
|
|
target, "-U/--upgrade", "-S/--sync");
|
|
|
|
}
|
2011-03-20 20:45:57 -04:00
|
|
|
return ret;
|
2009-09-07 14:58:49 -04:00
|
|
|
}
|
|
|
|
|
2008-01-28 13:49:27 -05:00
|
|
|
static int sync_trans(alpm_list_t *targets)
|
2005-03-14 20:51:43 -05:00
|
|
|
{
|
2011-12-12 11:53:14 -05:00
|
|
|
int retval = 0;
|
2009-09-07 14:58:49 -04:00
|
|
|
alpm_list_t *i;
|
2007-06-13 00:34:43 -04:00
|
|
|
|
2007-04-26 15:28:54 -04:00
|
|
|
/* Step 1: create a new transaction... */
|
2011-06-08 00:08:06 -04:00
|
|
|
if(trans_init(config->flags, 1) == -1) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return 1;
|
2005-03-30 17:32:43 -05:00
|
|
|
}
|
|
|
|
|
2009-09-07 14:58:49 -04:00
|
|
|
/* process targets */
|
|
|
|
for(i = targets; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
const char *targ = i->data;
|
2011-12-12 11:53:14 -05:00
|
|
|
if(process_target(targ, retval) == 1) {
|
|
|
|
retval = 1;
|
2009-09-07 14:58:49 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-12 11:53:14 -05:00
|
|
|
if(retval) {
|
|
|
|
trans_release();
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2005-10-28 08:20:40 -04:00
|
|
|
if(config->op_s_upgrade) {
|
2013-03-01 13:40:02 -05:00
|
|
|
colon_printf(_("Starting full system upgrade...\n"));
|
2013-01-18 20:42:21 -05:00
|
|
|
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
|
|
|
|
"starting full system upgrade\n");
|
2011-06-07 14:39:52 -04:00
|
|
|
if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) {
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle)));
|
2011-07-22 13:12:18 -04:00
|
|
|
trans_release();
|
|
|
|
return 1;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-22 13:12:18 -04:00
|
|
|
return sync_prepare_execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
int sync_prepare_execute(void)
|
|
|
|
{
|
|
|
|
alpm_list_t *i, *packages, *data = NULL;
|
|
|
|
int retval = 0;
|
|
|
|
|
2007-04-26 15:28:54 -04:00
|
|
|
/* Step 2: "compute" the transaction based on targets and flags */
|
2011-06-07 14:29:05 -04:00
|
|
|
if(alpm_trans_prepare(config->handle, &data) == -1) {
|
2011-10-28 22:03:24 -04:00
|
|
|
alpm_errno_t err = alpm_errno(config->handle);
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
|
2011-06-07 17:06:16 -04:00
|
|
|
alpm_strerror(err));
|
|
|
|
switch(err) {
|
2011-07-01 12:01:39 -04:00
|
|
|
case ALPM_ERR_PKG_INVALID_ARCH:
|
2009-08-19 11:58:03 -04:00
|
|
|
for(i = data; i; i = alpm_list_next(i)) {
|
2014-02-03 12:09:18 -05:00
|
|
|
char *pkg = i->data;
|
2013-03-01 13:40:02 -05:00
|
|
|
colon_printf(_("package %s does not have a valid architecture\n"), pkg);
|
2014-02-03 12:09:18 -05:00
|
|
|
free(pkg);
|
2009-08-19 11:58:03 -04:00
|
|
|
}
|
|
|
|
break;
|
2011-07-01 12:01:39 -04:00
|
|
|
case ALPM_ERR_UNSATISFIED_DEPS:
|
2007-01-19 04:28:44 -05:00
|
|
|
for(i = data; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_depmissing_t *miss = i->data;
|
2011-06-16 12:42:10 -04:00
|
|
|
char *depstring = alpm_dep_compute_string(miss->depend);
|
2013-03-01 13:40:02 -05:00
|
|
|
colon_printf(_("%s: requires %s\n"), miss->target, depstring);
|
2007-10-24 20:31:28 -04:00
|
|
|
free(depstring);
|
2014-02-03 12:09:18 -05:00
|
|
|
alpm_depmissing_free(miss);
|
2006-01-06 18:14:21 -05:00
|
|
|
}
|
2007-06-13 00:31:01 -04:00
|
|
|
break;
|
2011-07-01 12:01:39 -04:00
|
|
|
case ALPM_ERR_CONFLICTING_DEPS:
|
2009-08-31 10:20:18 -04:00
|
|
|
for(i = data; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_conflict_t *conflict = i->data;
|
2009-08-31 10:20:18 -04:00
|
|
|
/* only print reason if it contains new information */
|
2011-08-09 02:00:16 -04:00
|
|
|
if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
|
2013-03-01 13:40:02 -05:00
|
|
|
colon_printf(_("%s and %s are in conflict\n"),
|
2011-06-16 12:33:20 -04:00
|
|
|
conflict->package1, conflict->package2);
|
2009-08-31 10:20:18 -04:00
|
|
|
} else {
|
2011-08-09 02:00:16 -04:00
|
|
|
char *reason = alpm_dep_compute_string(conflict->reason);
|
2013-03-01 13:40:02 -05:00
|
|
|
colon_printf(_("%s and %s are in conflict (%s)\n"),
|
2011-08-09 02:00:16 -04:00
|
|
|
conflict->package1, conflict->package2, reason);
|
|
|
|
free(reason);
|
2009-08-31 10:20:18 -04:00
|
|
|
}
|
2014-02-03 12:09:18 -05:00
|
|
|
alpm_conflict_free(conflict);
|
2006-01-06 18:14:21 -05:00
|
|
|
}
|
2007-06-13 00:31:01 -04:00
|
|
|
break;
|
2006-01-06 18:14:21 -05:00
|
|
|
default:
|
2007-06-13 00:31:01 -04:00
|
|
|
break;
|
2006-01-06 18:14:21 -05:00
|
|
|
}
|
2005-04-06 17:03:09 -04:00
|
|
|
retval = 1;
|
|
|
|
goto cleanup;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2011-06-07 14:29:05 -04:00
|
|
|
packages = alpm_trans_get_add(config->handle);
|
2006-01-05 16:29:36 -05:00
|
|
|
if(packages == NULL) {
|
2006-01-06 09:00:03 -05:00
|
|
|
/* nothing to do: just exit without complaining */
|
2011-09-01 18:13:13 -04:00
|
|
|
if(!config->print) {
|
|
|
|
printf(_(" there is nothing to do\n"));
|
|
|
|
}
|
2006-01-05 16:29:36 -05:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2008-08-17 13:23:12 -04:00
|
|
|
/* Step 3: actually perform the operation */
|
2009-07-19 05:15:11 -04:00
|
|
|
if(config->print) {
|
|
|
|
print_packages(packages);
|
2008-08-17 13:23:12 -04:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2007-06-13 00:34:43 -04:00
|
|
|
|
2011-07-22 13:01:58 -04:00
|
|
|
display_targets();
|
2008-08-17 13:23:12 -04:00
|
|
|
printf("\n");
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2008-08-17 13:23:12 -04:00
|
|
|
int confirm;
|
|
|
|
if(config->op_s_downloadonly) {
|
|
|
|
confirm = yesno(_("Proceed with download?"));
|
|
|
|
} else {
|
|
|
|
confirm = yesno(_("Proceed with installation?"));
|
|
|
|
}
|
|
|
|
if(!confirm) {
|
2012-10-23 09:32:56 -04:00
|
|
|
retval = 1;
|
2008-08-17 13:23:12 -04:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2011-06-07 14:29:05 -04:00
|
|
|
if(alpm_trans_commit(config->handle, &data) == -1) {
|
2011-10-28 22:03:24 -04:00
|
|
|
alpm_errno_t err = alpm_errno(config->handle);
|
2011-10-21 11:44:19 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
|
2011-06-07 17:06:16 -04:00
|
|
|
alpm_strerror(err));
|
|
|
|
switch(err) {
|
2011-07-01 12:01:39 -04:00
|
|
|
case ALPM_ERR_FILE_CONFLICTS:
|
2013-02-12 07:00:53 -05:00
|
|
|
if(config->flags & ALPM_TRANS_FLAG_FORCE) {
|
|
|
|
printf(_("unable to %s directory-file conflicts\n"), "--force");
|
|
|
|
}
|
2007-04-26 15:28:54 -04:00
|
|
|
for(i = data; i; i = alpm_list_next(i)) {
|
2011-10-06 01:55:47 -04:00
|
|
|
alpm_fileconflict_t *conflict = i->data;
|
2011-06-16 12:27:44 -04:00
|
|
|
switch(conflict->type) {
|
2011-07-01 12:01:38 -04:00
|
|
|
case ALPM_FILECONFLICT_TARGET:
|
2007-04-26 15:28:54 -04:00
|
|
|
printf(_("%s exists in both '%s' and '%s'\n"),
|
2011-06-16 12:27:44 -04:00
|
|
|
conflict->file, conflict->target, conflict->ctarget);
|
2007-04-26 15:28:54 -04:00
|
|
|
break;
|
2011-07-01 12:01:38 -04:00
|
|
|
case ALPM_FILECONFLICT_FILESYSTEM:
|
2007-04-26 15:28:54 -04:00
|
|
|
printf(_("%s: %s exists in filesystem\n"),
|
2011-06-16 12:27:44 -04:00
|
|
|
conflict->target, conflict->file);
|
2007-04-26 15:28:54 -04:00
|
|
|
break;
|
|
|
|
}
|
2014-02-03 12:09:18 -05:00
|
|
|
alpm_fileconflict_free(conflict);
|
2006-10-15 15:34:52 -04:00
|
|
|
}
|
2007-04-26 15:28:54 -04:00
|
|
|
break;
|
2011-07-01 12:01:39 -04:00
|
|
|
case ALPM_ERR_PKG_INVALID:
|
2011-08-08 20:42:52 -04:00
|
|
|
case ALPM_ERR_PKG_INVALID_CHECKSUM:
|
|
|
|
case ALPM_ERR_PKG_INVALID_SIG:
|
2011-07-01 12:01:39 -04:00
|
|
|
case ALPM_ERR_DLT_INVALID:
|
2007-04-26 15:28:54 -04:00
|
|
|
for(i = data; i; i = alpm_list_next(i)) {
|
2014-02-03 12:09:18 -05:00
|
|
|
char *filename = i->data;
|
2008-02-26 18:50:17 -05:00
|
|
|
printf(_("%s is invalid or corrupted\n"), filename);
|
2014-02-03 12:09:18 -05:00
|
|
|
free(filename);
|
2007-04-26 15:28:54 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2006-01-07 13:42:44 -05:00
|
|
|
}
|
2007-04-26 15:28:54 -04:00
|
|
|
/* TODO: stderr? */
|
|
|
|
printf(_("Errors occurred, no packages were upgraded.\n"));
|
2007-01-03 03:05:13 -05:00
|
|
|
retval = 1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2005-03-14 20:51:43 -05:00
|
|
|
|
2007-04-26 15:28:54 -04:00
|
|
|
/* Step 4: release transaction resources */
|
2005-03-14 20:51:43 -05:00
|
|
|
cleanup:
|
2014-02-03 12:09:18 -05:00
|
|
|
alpm_list_free(data);
|
2008-04-26 05:30:49 -04:00
|
|
|
if(trans_release() == -1) {
|
2006-01-27 14:02:24 -05:00
|
|
|
retval = 1;
|
2006-01-26 15:46:48 -05:00
|
|
|
}
|
|
|
|
|
2011-03-20 20:45:57 -04:00
|
|
|
return retval;
|
2005-03-14 20:51:43 -05:00
|
|
|
}
|
|
|
|
|
2007-10-03 22:02:36 -04:00
|
|
|
int pacman_sync(alpm_list_t *targets)
|
|
|
|
{
|
|
|
|
alpm_list_t *sync_dbs = NULL;
|
|
|
|
|
|
|
|
/* clean the cache */
|
|
|
|
if(config->op_s_clean) {
|
2008-02-19 15:57:40 -05:00
|
|
|
int ret = 0;
|
|
|
|
|
2011-06-08 00:08:06 -04:00
|
|
|
if(trans_init(0, 0) == -1) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return 1;
|
2008-02-19 15:57:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
ret += sync_cleancache(config->op_s_clean);
|
2007-11-17 16:52:03 -05:00
|
|
|
ret += sync_cleandb_all();
|
2008-02-19 15:57:40 -05:00
|
|
|
|
2008-04-26 05:30:49 -04:00
|
|
|
if(trans_release() == -1) {
|
2008-02-19 15:57:40 -05:00
|
|
|
ret++;
|
|
|
|
}
|
|
|
|
|
2011-03-20 20:45:57 -04:00
|
|
|
return ret;
|
2007-10-03 22:02:36 -04:00
|
|
|
}
|
|
|
|
|
2011-06-08 00:08:06 -04:00
|
|
|
if(check_syncdbs(1, 0)) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return 1;
|
2007-10-03 22:02:36 -04:00
|
|
|
}
|
|
|
|
|
2012-02-02 00:45:52 -05:00
|
|
|
sync_dbs = alpm_get_syncdbs(config->handle);
|
2011-06-08 00:08:06 -04:00
|
|
|
|
2008-01-28 13:49:27 -05:00
|
|
|
if(config->op_s_sync) {
|
|
|
|
/* grab a fresh package list */
|
2013-03-01 13:40:02 -05:00
|
|
|
colon_printf(_("Synchronizing package databases...\n"));
|
2013-01-18 20:42:21 -05:00
|
|
|
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
|
|
|
|
"synchronizing package lists\n");
|
2015-06-17 10:12:14 -04:00
|
|
|
if(!sync_syncdbs(config->op_s_sync, sync_dbs)) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return 1;
|
2008-01-28 13:49:27 -05:00
|
|
|
}
|
2007-10-03 22:02:36 -04:00
|
|
|
}
|
|
|
|
|
2011-06-08 00:08:06 -04:00
|
|
|
if(check_syncdbs(1, 1)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-10-03 22:02:36 -04:00
|
|
|
/* search for a package */
|
|
|
|
if(config->op_s_search) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return sync_search(sync_dbs, targets);
|
2007-10-03 22:02:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* look for groups */
|
|
|
|
if(config->group) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return sync_group(config->group, sync_dbs, targets);
|
2007-10-03 22:02:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* get package info */
|
|
|
|
if(config->op_s_info) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return sync_info(sync_dbs, targets);
|
2007-10-03 22:02:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* get a listing of files in sync DBs */
|
|
|
|
if(config->op_q_list) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return sync_list(sync_dbs, targets);
|
2007-10-03 22:02:36 -04:00
|
|
|
}
|
|
|
|
|
2008-05-28 16:55:03 -04:00
|
|
|
if(targets == NULL) {
|
|
|
|
if(config->op_s_upgrade) {
|
|
|
|
/* proceed */
|
|
|
|
} else if(config->op_s_sync) {
|
2011-03-20 20:45:57 -04:00
|
|
|
return 0;
|
2008-05-28 16:55:03 -04:00
|
|
|
} else {
|
|
|
|
/* don't proceed here unless we have an operation that doesn't require a
|
|
|
|
* target list */
|
2011-07-01 12:01:38 -04:00
|
|
|
pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
|
2011-03-20 20:45:57 -04:00
|
|
|
return 1;
|
2008-05-28 16:55:03 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-14 13:32:25 -05:00
|
|
|
return sync_trans(targets);
|
2007-10-03 22:02:36 -04:00
|
|
|
}
|
|
|
|
|
2014-01-22 18:06:11 -05:00
|
|
|
/* vim: set noet: */
|