summaryrefslogtreecommitdiff
path: root/src/pacman
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman')
-rw-r--r--src/pacman/Makefile.am8
-rw-r--r--src/pacman/callback.c125
-rw-r--r--src/pacman/callback.h2
-rw-r--r--src/pacman/conf.c51
-rw-r--r--src/pacman/conf.h8
-rw-r--r--src/pacman/database.c8
-rw-r--r--src/pacman/deptest.c10
-rw-r--r--src/pacman/package.c153
-rw-r--r--src/pacman/package.h2
-rw-r--r--src/pacman/pacman.c35
-rw-r--r--src/pacman/pacman.h2
-rw-r--r--src/pacman/query.c186
-rw-r--r--src/pacman/remove.c37
-rw-r--r--src/pacman/sync.c283
-rw-r--r--src/pacman/upgrade.c26
-rw-r--r--src/pacman/util.c403
-rw-r--r--src/pacman/util.h21
17 files changed, 763 insertions, 597 deletions
diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am
index 3790bdf4..c8ce9773 100644
--- a/src/pacman/Makefile.am
+++ b/src/pacman/Makefile.am
@@ -11,15 +11,17 @@ bin_PROGRAMS = pacman
DEFS = -DLOCALEDIR=\"@localedir@\" \
-DCONFFILE=\"$(conffile)\" \
- -DROOTDIR=\"$(ROOTDIR)\" \
-DDBPATH=\"$(dbpath)\" \
-DGPGDIR=\"$(gpgdir)\" \
-DCACHEDIR=\"$(cachedir)\" \
-DLOGFILE=\"$(logfile)\" \
@DEFS@
-INCLUDES = -I$(top_srcdir)/lib/libalpm
-AM_CFLAGS = -pedantic -D_GNU_SOURCE
+AM_CPPFLAGS = \
+ -imacros $(top_builddir)/config.h \
+ -I$(top_srcdir)/lib/libalpm
+
+AM_CFLAGS = -pedantic -D_GNU_SOURCE $(WARNING_CFLAGS)
if USE_GIT_VERSION
GIT_VERSION := $(shell sh -c 'git describe --abbrev=4 --dirty | sed s/^v//')
diff --git a/src/pacman/callback.c b/src/pacman/callback.c
index 344f6a58..01c6b619 100644
--- a/src/pacman/callback.c
+++ b/src/pacman/callback.c
@@ -1,7 +1,7 @@
/*
* callback.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,13 +18,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h> /* off_t */
+#include <time.h>
#include <unistd.h>
#include <wchar.h>
#include <limits.h> /* UINT_MAX */
@@ -44,15 +43,19 @@ static off_t list_total = 0.0;
static int on_progress = 0;
static alpm_list_t *output = NULL;
-/* Silly little helper function, determines if the caller needs a visual update
+/* update speed for the fill_progress based functions */
+#define UPDATE_SPEED_MS 200
+
+/**
+ * Silly little helper function, determines if the caller needs a visual update
* since the last time this function was called.
- * This is made for the two progress bar functions, to prevent flicker
- *
- * first_call indicates if this is the first time it is called, for
- * initialization purposes */
-static double get_update_timediff(int first_call)
+ * This is made for the two progress bar functions, to prevent flicker.
+ * @param first_call 1 on first call for initialization purposes, 0 otherwise
+ * @return number of milliseconds since last call
+ */
+static long get_update_timediff(int first_call)
{
- double retval = 0.0;
+ long retval = 0;
static struct timeval last_time = {0, 0};
/* on first call, simply set the last time and return */
@@ -60,18 +63,17 @@ static double get_update_timediff(int first_call)
gettimeofday(&last_time, NULL);
} else {
struct timeval this_time;
- double diff_sec, diff_usec;
+ time_t diff_sec;
+ suseconds_t diff_usec;
gettimeofday(&this_time, NULL);
diff_sec = this_time.tv_sec - last_time.tv_sec;
diff_usec = this_time.tv_usec - last_time.tv_usec;
- retval = diff_sec + (diff_usec / 1000000.0);
+ retval = (diff_sec * 1000) + (diff_usec / 1000);
- /* return 0 and do not update last_time if interval was too short */
- if(retval < UPDATE_SPEED_SEC) {
- retval = 0.0;
- } else {
+ /* do not update last_time if interval was too short */
+ if(retval >= UPDATE_SPEED_MS) {
last_time = this_time;
}
}
@@ -95,41 +97,41 @@ static void fill_progress(const int bar_percent, const int disp_percent,
}
if(hashlen > 0) {
- printf(" [");
+ fputs(" [", stdout);
for(i = hashlen; i > 0; --i) {
/* if special progress bar enabled */
if(config->chomp) {
if(i > hashlen - hash) {
- printf("-");
+ putchar('-');
} else if(i == hashlen - hash) {
if(lasthash == hash) {
if(mouth) {
- printf("\033[1;33mC\033[m");
+ fputs("\033[1;33mC\033[m", stdout);
} else {
- printf("\033[1;33mc\033[m");
+ fputs("\033[1;33mc\033[m", stdout);
}
} else {
lasthash = hash;
mouth = mouth == 1 ? 0 : 1;
if(mouth) {
- printf("\033[1;33mC\033[m");
+ fputs("\033[1;33mC\033[m", stdout);
} else {
- printf("\033[1;33mc\033[m");
+ fputs("\033[1;33mc\033[m", stdout);
}
}
- } else if(i%3 == 0) {
- printf("\033[0;37mo\033[m");
+ } else if(i % 3 == 0) {
+ fputs("\033[0;37mo\033[m", stdout);
} else {
- printf("\033[0;37m \033[m");
+ fputs("\033[0;37m \033[m", stdout);
}
} /* else regular progress bar */
else if(i > hashlen - hash) {
- printf("#");
+ putchar('#');
} else {
- printf("-");
+ putchar('-');
}
}
- printf("]");
+ putchar(']');
}
/* print display percent after progress bar */
/* 5 = 1 space + 3 digits + 1 % */
@@ -138,9 +140,9 @@ static void fill_progress(const int bar_percent, const int disp_percent,
}
if(bar_percent == 100) {
- printf("\n");
+ putchar('\n');
} else {
- printf("\r");
+ putchar('\r');
}
fflush(stdout);
}
@@ -196,9 +198,9 @@ void cb_event(alpm_event_t event, void *data1, void *data2)
break;
case ALPM_EVENT_UPGRADE_DONE:
alpm_logaction(config->handle, "upgraded %s (%s -> %s)\n",
- (char *)alpm_pkg_get_name(data1),
- (char *)alpm_pkg_get_version(data2),
- (char *)alpm_pkg_get_version(data1));
+ alpm_pkg_get_name(data1),
+ alpm_pkg_get_version(data2),
+ alpm_pkg_get_version(data1));
display_new_optdepends(data2,data1);
break;
case ALPM_EVENT_INTEGRITY_START:
@@ -227,10 +229,10 @@ void cb_event(alpm_event_t event, void *data1, void *data2)
printf(_("failed.\n"));
break;
case ALPM_EVENT_SCRIPTLET_INFO:
- printf("%s", (char *)data1);
+ fputs((const char *)data1, stdout);
break;
case ALPM_EVENT_RETRIEVE_START:
- printf(_(":: Retrieving packages from %s...\n"), (char *)data1);
+ printf(_(":: Retrieving packages ...\n"));
break;
case ALPM_EVENT_DISKSPACE_START:
if(config->noprogressbar) {
@@ -294,10 +296,10 @@ void cb_question(alpm_question_t event, void *data1, void *data2,
break;
case ALPM_QUESTION_REMOVE_PKGS:
{
- alpm_list_t *unresolved = (alpm_list_t *) data1;
+ alpm_list_t *unresolved = data1;
alpm_list_t *namelist = NULL, *i;
size_t count = 0;
- for (i = unresolved; i; i = i->next) {
+ for(i = unresolved; i; i = i->next) {
namelist = alpm_list_add(namelist,
(char *)alpm_pkg_get_name(i->data));
count++;
@@ -306,7 +308,7 @@ void cb_question(alpm_question_t event, void *data1, void *data2,
":: The following package cannot be upgraded due to unresolvable dependencies:\n",
":: The following packages cannot be upgraded due to unresolvable dependencies:\n",
count));
- list_display(" ", namelist);
+ list_display(" ", namelist, getcols(fileno(stdout)));
printf("\n");
*response = noyes(_n(
"Do you want to skip the above package for this upgrade?",
@@ -317,7 +319,7 @@ void cb_question(alpm_question_t event, void *data1, void *data2,
break;
case ALPM_QUESTION_SELECT_PROVIDER:
{
- alpm_list_t *providers = (alpm_list_t *)data1;
+ alpm_list_t *providers = data1;
size_t count = alpm_list_count(providers);
char *depstring = alpm_dep_compute_string((alpm_depend_t *)data2);
printf(_(":: There are %zd providers available for %s:\n"), count,
@@ -340,15 +342,22 @@ void cb_question(alpm_question_t event, void *data1, void *data2,
*response = yesno(_(":: File %s is corrupted (%s).\n"
"Do you want to delete it?"),
(char *)data1,
- alpm_strerror(*(enum _alpm_errno_t *)data2));
+ alpm_strerror(*(alpm_errno_t *)data2));
break;
case ALPM_QUESTION_IMPORT_KEY:
{
alpm_pgpkey_t *key = data1;
char created[12];
- strftime(created, 12, "%Y-%m-%d", localtime(&(key->created)));
- *response = yesno(_(":: Import PGP key %s, \"%s\", created %s?"),
- key->fingerprint, key->uid, created);
+ const char *revoked = "";
+ time_t time = (time_t)key->created;
+ strftime(created, 12, "%Y-%m-%d", localtime(&time));
+
+ if(key->revoked) {
+ revoked = " (revoked)";
+ }
+
+ *response = yesno(_(":: Import PGP key %d%c/%s, \"%s\", created: %s%s?"),
+ key->length, key->pubkey_algo, key->fingerprint, key->uid, created, revoked);
}
break;
}
@@ -375,7 +384,7 @@ void cb_progress(alpm_progress_t event, const char *pkgname, int percent,
int len, wclen, wcwid, padwid;
wchar_t *wcstr;
- const unsigned short cols = getcols();
+ const unsigned short cols = getcols(fileno(stdout));
if(config->noprogressbar || cols == 0) {
return;
@@ -393,7 +402,7 @@ void cb_progress(alpm_progress_t event, const char *pkgname, int percent,
if(current != prevcurrent) {
/* update always */
} else if(!pkgname || percent == prevpercent ||
- get_update_timediff(0) < UPDATE_SPEED_SEC) {
+ get_update_timediff(0) < UPDATE_SPEED_MS) {
/* only update the progress bar when we have a package name, the
* percentage has changed, and it has been long enough. */
return;
@@ -493,7 +502,7 @@ void cb_progress(alpm_progress_t event, const char *pkgname, int percent,
alpm_list_t *i = NULL;
on_progress = 0;
for(i = output; i; i = i->next) {
- printf("%s", (char *)i->data);
+ fputs((const char *)i->data, stdout);
}
fflush(stdout);
FREELIST(output);
@@ -528,13 +537,14 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
int totaldownload = 0;
off_t xfered, total;
- double rate = 0.0, timediff = 0.0;
+ double rate = 0.0;
+ long timediff = 0;
unsigned int eta_h = 0, eta_m = 0, eta_s = 0;
double rate_human, xfered_human;
const char *rate_label, *xfered_label;
int file_percent = 0, total_percent = 0;
- const unsigned short cols = getcols();
+ const unsigned short cols = getcols(fileno(stdout));
if(config->noprogressbar || cols == 0 || file_total == -1) {
if(file_xfered == 0) {
@@ -587,16 +597,17 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
} else if(file_xfered == file_total) {
/* compute final values */
struct timeval current_time;
- double diff_sec, diff_usec;
+ time_t diff_sec;
+ suseconds_t diff_usec;
gettimeofday(&current_time, NULL);
diff_sec = current_time.tv_sec - initial_time.tv_sec;
diff_usec = current_time.tv_usec - initial_time.tv_usec;
- timediff = diff_sec + (diff_usec / 1000000.0);
- if(timediff > 0.0) {
- rate = xfered / timediff;
- /* round elapsed time to the nearest second */
- eta_s = (unsigned int)(timediff + 0.5);
+ timediff = (diff_sec * 1000) + (diff_usec / 1000);
+ if(timediff > 0) {
+ rate = (double)xfered / (timediff / 1000.0);
+ /* round elapsed time (in ms) to the nearest second */
+ eta_s = (unsigned int)(timediff + 500) / 1000;
} else {
eta_s = 0;
}
@@ -604,11 +615,11 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
/* compute current average values */
timediff = get_update_timediff(0);
- if(timediff < UPDATE_SPEED_SEC) {
+ if(timediff < UPDATE_SPEED_MS) {
/* return if the calling interval was too short */
return;
}
- rate = (xfered - xfered_last) / timediff;
+ rate = (double)(xfered - xfered_last) / (timediff / 1000.0);
/* average rate to reduce jumpiness */
rate = (rate + 2 * rate_last) / 3;
if(rate > 0.0) {
@@ -713,7 +724,7 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
} else if(eta_h < 100) {
printf("%02u:%02u:%02u", eta_h, eta_m, eta_s);
} else {
- printf("--:--");
+ fputs("--:--", stdout);
}
free(fname);
diff --git a/src/pacman/callback.h b/src/pacman/callback.h
index e328a22a..2215790a 100644
--- a/src/pacman/callback.h
+++ b/src/pacman/callback.h
@@ -1,7 +1,7 @@
/*
* callback.h
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index a9f0de91..f47b92dc 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -1,7 +1,7 @@
/*
* conf.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <errno.h>
#include <glob.h>
#include <limits.h>
@@ -54,6 +52,7 @@ config_t *config_new(void)
newconfig->op = PM_OP_MAIN;
newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING;
newconfig->configfile = strdup(CONFFILE);
+ newconfig->deltaratio = 0.0;
if(alpm_capabilities() & ALPM_CAPABILITY_SIGNATURES) {
newconfig->siglevel = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL |
ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
@@ -72,7 +71,6 @@ int config_free(config_t *oldconfig)
alpm_list_free(oldconfig->explicit_removes);
FREELIST(oldconfig->holdpkg);
- FREELIST(oldconfig->syncfirst);
FREELIST(oldconfig->ignorepkg);
FREELIST(oldconfig->ignoregrp);
FREELIST(oldconfig->noupgrade);
@@ -203,11 +201,14 @@ static int download_with_xfercommand(const char *url, const char *localpath,
cleanup:
/* restore the old cwd if we have it */
if(cwdfd >= 0) {
+ int close_ret;
if(fchdir(cwdfd) != 0) {
pm_printf(ALPM_LOG_ERROR, _("could not restore working directory (%s)\n"),
strerror(errno));
}
- close(cwdfd);
+ do {
+ close_ret = close(cwdfd);
+ } while(close_ret == -1 && errno == EINTR);
}
if(ret == -1) {
@@ -256,11 +257,11 @@ static int process_siglevel(alpm_list_t *values, alpm_siglevel_t *storage,
const char *original = i->data, *value;
int package = 0, database = 0;
- if (strncmp(original, "Package", strlen("Package")) == 0) {
+ if(strncmp(original, "Package", strlen("Package")) == 0) {
/* only packages are affected, don't flip flags for databases */
value = original + strlen("Package");
package = 1;
- } else if (strncmp(original, "Database", strlen("Database")) == 0) {
+ } else if(strncmp(original, "Database", strlen("Database")) == 0) {
/* only databases are affected, don't flip flags for packages */
value = original + strlen("Database");
database = 1;
@@ -396,8 +397,8 @@ static int _parse_options(const char *key, char *value,
config->verbosepkglists = 1;
pm_printf(ALPM_LOG_DEBUG, "config: verbosepkglists\n");
} else if(strcmp(key, "UseDelta") == 0) {
- config->usedelta = 1;
- pm_printf(ALPM_LOG_DEBUG, "config: usedelta\n");
+ config->deltaratio = 0.7;
+ pm_printf(ALPM_LOG_DEBUG, "config: usedelta (default 0.7)\n");
} else if(strcmp(key, "TotalDownload") == 0) {
config->totaldownload = 1;
pm_printf(ALPM_LOG_DEBUG, "config: totaldownload\n");
@@ -420,14 +421,24 @@ static int _parse_options(const char *key, char *value,
setrepeatingoption(value, "IgnoreGroup", &(config->ignoregrp));
} else if(strcmp(key, "HoldPkg") == 0) {
setrepeatingoption(value, "HoldPkg", &(config->holdpkg));
- } else if(strcmp(key, "SyncFirst") == 0) {
- setrepeatingoption(value, "SyncFirst", &(config->syncfirst));
} else if(strcmp(key, "CacheDir") == 0) {
setrepeatingoption(value, "CacheDir", &(config->cachedirs));
} else if(strcmp(key, "Architecture") == 0) {
if(!config->arch) {
config_set_arch(value);
}
+ } else if(strcmp(key, "UseDelta") == 0) {
+ double ratio;
+ char *endptr;
+ ratio = strtod(value, &endptr);
+ if(*endptr != '\0' || ratio < 0.0 || ratio > 2.0) {
+ pm_printf(ALPM_LOG_ERROR,
+ _("config file %s, line %d: invalid value for '%s' : '%s'\n"),
+ file, linenum, "UseDelta", value);
+ return 1;
+ }
+ config->deltaratio = ratio;
+ pm_printf(ALPM_LOG_DEBUG, "config: usedelta = %f\n", ratio);
} else if(strcmp(key, "DBPath") == 0) {
/* don't overwrite a path specified on the command line */
if(!config->dbpath) {
@@ -522,7 +533,7 @@ static int _add_mirror(alpm_db_t *db, char *value)
static int setup_libalpm(void)
{
int ret = 0;
- enum _alpm_errno_t err;
+ alpm_errno_t err;
alpm_handle_t *handle;
pm_printf(ALPM_LOG_DEBUG, "setup_libalpm called\n");
@@ -604,7 +615,7 @@ static int setup_libalpm(void)
alpm_option_set_arch(handle, config->arch);
alpm_option_set_checkspace(handle, config->checkspace);
alpm_option_set_usesyslog(handle, config->usesyslog);
- alpm_option_set_usedelta(handle, config->usedelta);
+ alpm_option_set_deltaratio(handle, config->deltaratio);
alpm_option_set_ignorepkgs(handle, config->ignorepkg);
alpm_option_set_ignoregroups(handle, config->ignoregrp);
@@ -650,7 +661,7 @@ static int finish_section(struct section_t *section, int parse_options)
}
/* if we are not looking at options sections only, register a db */
- db = alpm_db_register_sync(config->handle, section->name, section->siglevel);
+ db = alpm_register_syncdb(config->handle, section->name, section->siglevel);
if(db == NULL) {
pm_printf(ALPM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
section->name, alpm_strerror(alpm_errno(config->handle)));
@@ -659,7 +670,7 @@ static int finish_section(struct section_t *section, int parse_options)
}
for(i = section->servers; i; i = alpm_list_next(i)) {
- char *value = alpm_list_getdata(i);
+ char *value = i->data;
if(_add_mirror(db, value) != 0) {
pm_printf(ALPM_LOG_ERROR,
_("could not add mirror '%s' to database '%s' (%s)\n"),
@@ -709,7 +720,8 @@ static int _parseconfig(const char *file, struct section_t *section,
pm_printf(ALPM_LOG_DEBUG, "config: attempting to read file %s\n", file);
fp = fopen(file, "r");
if(fp == NULL) {
- pm_printf(ALPM_LOG_ERROR, _("config file %s could not be read.\n"), file);
+ pm_printf(ALPM_LOG_ERROR, _("config file %s could not be read: %s\n"),
+ file, strerror(errno));
ret = 1;
goto cleanup;
}
@@ -725,8 +737,7 @@ static int _parseconfig(const char *file, struct section_t *section,
*ptr = '\0';
}
- strtrim(line);
- line_len = strlen(line);
+ line_len = strtrim(line);
if(line_len == 0) {
continue;
@@ -822,7 +833,7 @@ static int _parseconfig(const char *file, struct section_t *section,
if((ret = _parse_options(key, value, file, linenum)) != 0) {
goto cleanup;
}
- } else if (!parse_options && !section->is_options) {
+ } else if(!parse_options && !section->is_options) {
/* ... or in a repo section */
if(strcmp(key, "Server") == 0) {
if(value == NULL) {
@@ -859,7 +870,7 @@ static int _parseconfig(const char *file, struct section_t *section,
}
cleanup:
- if (fp) {
+ if(fp) {
fclose(fp);
}
pm_printf(ALPM_LOG_DEBUG, "config: finished parsing %s\n", file);
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 42f25298..69c955ed 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -1,7 +1,7 @@
/*
* conf.h
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -34,7 +34,7 @@ typedef struct __config_t {
unsigned short print;
unsigned short checkspace;
unsigned short usesyslog;
- unsigned short usedelta;
+ double deltaratio;
char *arch;
char *print_format;
/* unfortunately, we have to keep track of paths both here and in the library
@@ -84,7 +84,6 @@ typedef struct __config_t {
/* select -Sc behavior */
unsigned short cleanmethod;
alpm_list_t *holdpkg;
- alpm_list_t *syncfirst;
alpm_list_t *ignorepkg;
alpm_list_t *ignoregrp;
alpm_list_t *noupgrade;
@@ -127,7 +126,8 @@ enum {
OP_ARCH,
OP_PRINTFORMAT,
OP_GPGDIR,
- OP_DBONLY
+ OP_DBONLY,
+ OP_FORCE
};
/* clean method */
diff --git a/src/pacman/database.c b/src/pacman/database.c
index 3e4a672f..dd160135 100644
--- a/src/pacman/database.c
+++ b/src/pacman/database.c
@@ -1,7 +1,7 @@
/*
* database.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <stdio.h>
#include <alpm.h>
@@ -63,11 +61,11 @@ int pacman_database(alpm_list_t *targets)
return 1;
}
- db_local = alpm_option_get_localdb(config->handle);
+ db_local = alpm_get_localdb(config->handle);
for(i = targets; i; i = alpm_list_next(i)) {
char *pkgname = i->data;
alpm_pkg_t *pkg = alpm_db_get_pkg(db_local, pkgname);
- if(!pkg || alpm_db_set_pkgreason(config->handle, pkg, reason)) {
+ if(!pkg || alpm_pkg_set_reason(pkg, reason)) {
pm_printf(ALPM_LOG_ERROR, _("could not set install reason for package %s (%s)\n"),
pkgname, alpm_strerror(alpm_errno(config->handle)));
retval = 1;
diff --git a/src/pacman/deptest.c b/src/pacman/deptest.c
index 0055c37e..a654c887 100644
--- a/src/pacman/deptest.c
+++ b/src/pacman/deptest.c
@@ -1,7 +1,7 @@
/*
* deptest.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <stdio.h>
#include <alpm.h>
@@ -33,10 +31,10 @@ int pacman_deptest(alpm_list_t *targets)
{
alpm_list_t *i;
alpm_list_t *deps = NULL;
- alpm_db_t *localdb = alpm_option_get_localdb(config->handle);
+ alpm_db_t *localdb = alpm_get_localdb(config->handle);
for(i = targets; i; i = alpm_list_next(i)) {
- char *target = alpm_list_getdata(i);
+ char *target = i->data;
if(!alpm_find_satisfier(alpm_db_get_pkgcache(localdb), target)) {
deps = alpm_list_add(deps, target);
@@ -48,7 +46,7 @@ int pacman_deptest(alpm_list_t *targets)
}
for(i = deps; i; i = alpm_list_next(i)) {
- const char *dep = alpm_list_getdata(i);
+ const char *dep = i->data;
printf("%s\n", dep);
}
diff --git a/src/pacman/package.c b/src/pacman/package.c
index 97d89688..fc869b18 100644
--- a/src/pacman/package.c
+++ b/src/pacman/package.c
@@ -1,7 +1,7 @@
/*
* package.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,14 +18,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
+#include <time.h>
#include <alpm.h>
#include <alpm_list.h>
@@ -39,17 +38,31 @@
/** Turn a depends list into a text list.
* @param deps a list with items of type alpm_depend_t
- * @return a string list, must be freed
*/
static void deplist_display(const char *title,
- alpm_list_t *deps)
+ alpm_list_t *deps, unsigned short cols)
{
alpm_list_t *i, *text = NULL;
for(i = deps; i; i = alpm_list_next(i)) {
- alpm_depend_t *dep = alpm_list_getdata(i);
+ alpm_depend_t *dep = i->data;
text = alpm_list_add(text, alpm_dep_compute_string(dep));
}
- list_display(title, text);
+ list_display(title, text, cols);
+ FREELIST(text);
+}
+
+/** Turn a optdepends list into a text list.
+ * @param optdeps a list with items of type alpm_optdepend_t
+ */
+static void optdeplist_display(const char *title,
+ alpm_list_t *optdeps, unsigned short cols)
+{
+ alpm_list_t *i, *text = NULL;
+ for(i = optdeps; i; i = alpm_list_next(i)) {
+ alpm_depend_t *optdep = i->data;
+ text = alpm_list_add(text, alpm_dep_compute_string(optdep));
+ }
+ list_display_linebreak(title, text, cols);
FREELIST(text);
}
@@ -63,22 +76,22 @@ static void deplist_display(const char *title,
*/
void dump_pkg_full(alpm_pkg_t *pkg, int extra)
{
- const char *reason;
+ unsigned short cols;
time_t bdate, idate;
- char bdatestr[50] = "", idatestr[50] = "";
- const char *label;
- double size;
- alpm_list_t *requiredby = NULL;
alpm_pkgfrom_t from;
+ double size;
+ char bdatestr[50] = "", idatestr[50] = "";
+ const char *label, *reason;
+ alpm_list_t *validation = NULL, *requiredby = NULL;
from = alpm_pkg_get_origin(pkg);
/* set variables here, do all output below */
- bdate = alpm_pkg_get_builddate(pkg);
+ bdate = (time_t)alpm_pkg_get_builddate(pkg);
if(bdate) {
strftime(bdatestr, 50, "%c", localtime(&bdate));
}
- idate = alpm_pkg_get_installdate(pkg);
+ idate = (time_t)alpm_pkg_get_installdate(pkg);
if(idate) {
strftime(idatestr, 50, "%c", localtime(&idate));
}
@@ -95,75 +108,99 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
break;
}
- if(extra || from == PKG_FROM_LOCALDB) {
+ alpm_pkgvalidation_t v = alpm_pkg_get_validation(pkg);
+ if(v) {
+ if(v & ALPM_PKG_VALIDATION_NONE) {
+ validation = alpm_list_add(validation, _("None"));
+ } else {
+ if(v & ALPM_PKG_VALIDATION_MD5SUM) {
+ validation = alpm_list_add(validation, _("MD5 Sum"));
+ }
+ if(v & ALPM_PKG_VALIDATION_SHA256SUM) {
+ validation = alpm_list_add(validation, _("SHA256 Sum"));
+ }
+ if(v & ALPM_PKG_VALIDATION_SIGNATURE) {
+ validation = alpm_list_add(validation, _("Signature"));
+ }
+ }
+ } else {
+ validation = alpm_list_add(validation, _("Unknown"));
+ }
+
+ if(extra || from == ALPM_PKG_FROM_LOCALDB) {
/* compute this here so we don't get a pause in the middle of output */
requiredby = alpm_pkg_compute_requiredby(pkg);
}
+ cols = getcols(fileno(stdout));
+
/* actual output */
- if(from == PKG_FROM_SYNCDB) {
+ if(from == ALPM_PKG_FROM_SYNCDB) {
string_display(_("Repository :"),
- alpm_db_get_name(alpm_pkg_get_db(pkg)));
+ alpm_db_get_name(alpm_pkg_get_db(pkg)), cols);
}
- string_display(_("Name :"), alpm_pkg_get_name(pkg));
- string_display(_("Version :"), alpm_pkg_get_version(pkg));
- string_display(_("URL :"), alpm_pkg_get_url(pkg));
- list_display(_("Licenses :"), alpm_pkg_get_licenses(pkg));
- list_display(_("Groups :"), alpm_pkg_get_groups(pkg));
- deplist_display(_("Provides :"), alpm_pkg_get_provides(pkg));
- deplist_display(_("Depends On :"), alpm_pkg_get_depends(pkg));
- list_display_linebreak(_("Optional Deps :"), alpm_pkg_get_optdepends(pkg));
- if(extra || from == PKG_FROM_LOCALDB) {
- list_display(_("Required By :"), requiredby);
+ string_display(_("Name :"), alpm_pkg_get_name(pkg), cols);
+ string_display(_("Version :"), alpm_pkg_get_version(pkg), cols);
+ string_display(_("Description :"), alpm_pkg_get_desc(pkg), cols);
+ string_display(_("Architecture :"), alpm_pkg_get_arch(pkg), cols);
+ string_display(_("URL :"), alpm_pkg_get_url(pkg), cols);
+ list_display(_("Licenses :"), alpm_pkg_get_licenses(pkg), cols);
+ list_display(_("Groups :"), alpm_pkg_get_groups(pkg), cols);
+ deplist_display(_("Provides :"), alpm_pkg_get_provides(pkg), cols);
+ deplist_display(_("Depends On :"), alpm_pkg_get_depends(pkg), cols);
+ optdeplist_display(_("Optional Deps :"), alpm_pkg_get_optdepends(pkg), cols);
+ if(extra || from == ALPM_PKG_FROM_LOCALDB) {
+ list_display(_("Required By :"), requiredby, cols);
}
- deplist_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
- deplist_display(_("Replaces :"), alpm_pkg_get_replaces(pkg));
+ deplist_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg), cols);
+ deplist_display(_("Replaces :"), alpm_pkg_get_replaces(pkg), cols);
size = humanize_size(alpm_pkg_get_size(pkg), 'K', 2, &label);
- if(from == PKG_FROM_SYNCDB) {
+ if(from == ALPM_PKG_FROM_SYNCDB) {
printf(_("Download Size : %6.2f %s\n"), size, label);
- } else if(from == PKG_FROM_FILE) {
+ } else if(from == ALPM_PKG_FROM_FILE) {
printf(_("Compressed Size: %6.2f %s\n"), size, label);
}
size = humanize_size(alpm_pkg_get_isize(pkg), 'K', 2, &label);
printf(_("Installed Size : %6.2f %s\n"), size, label);
- string_display(_("Packager :"), alpm_pkg_get_packager(pkg));
- string_display(_("Architecture :"), alpm_pkg_get_arch(pkg));
- string_display(_("Build Date :"), bdatestr);
- if(from == PKG_FROM_LOCALDB) {
- string_display(_("Install Date :"), idatestr);
- string_display(_("Install Reason :"), reason);
+ string_display(_("Packager :"), alpm_pkg_get_packager(pkg), cols);
+ string_display(_("Build Date :"), bdatestr, cols);
+ if(from == ALPM_PKG_FROM_LOCALDB) {
+ string_display(_("Install Date :"), idatestr, cols);
+ string_display(_("Install Reason :"), reason, cols);
}
- if(from == PKG_FROM_FILE || from == PKG_FROM_LOCALDB) {
+ if(from == ALPM_PKG_FROM_FILE || from == ALPM_PKG_FROM_LOCALDB) {
string_display(_("Install Script :"),
- alpm_pkg_has_scriptlet(pkg) ? _("Yes") : _("No"));
+ alpm_pkg_has_scriptlet(pkg) ? _("Yes") : _("No"), cols);
}
- if(from == PKG_FROM_SYNCDB) {
- string_display(_("MD5 Sum :"), alpm_pkg_get_md5sum(pkg));
- string_display(_("SHA256 Sum :"), alpm_pkg_get_sha256sum(pkg));
+ if(from == ALPM_PKG_FROM_SYNCDB && extra) {
+ string_display(_("MD5 Sum :"), alpm_pkg_get_md5sum(pkg), cols);
+ string_display(_("SHA256 Sum :"), alpm_pkg_get_sha256sum(pkg), cols);
string_display(_("Signatures :"),
- alpm_pkg_get_base64_sig(pkg) ? _("Yes") : _("None"));
+ alpm_pkg_get_base64_sig(pkg) ? _("Yes") : _("None"), cols);
+ } else {
+ list_display(_("Validated By :"), validation, cols);
}
- if(from == PKG_FROM_FILE) {
+
+ if(from == ALPM_PKG_FROM_FILE) {
alpm_siglist_t siglist;
int err = alpm_pkg_check_pgp_signature(pkg, &siglist);
if(err && alpm_errno(config->handle) == ALPM_ERR_SIG_MISSING) {
- string_display(_("Signatures :"), _("None"));
+ string_display(_("Signatures :"), _("None"), cols);
} else if(err) {
string_display(_("Signatures :"),
- alpm_strerror(alpm_errno(config->handle)));
+ alpm_strerror(alpm_errno(config->handle)), cols);
} else {
- signature_display(_("Signatures :"), &siglist);
+ signature_display(_("Signatures :"), &siglist, cols);
}
alpm_siglist_cleanup(&siglist);
}
- string_display(_("Description :"), alpm_pkg_get_desc(pkg));
/* Print additional package info if info flag passed more than once */
- if(from == PKG_FROM_LOCALDB && extra) {
+ if(from == ALPM_PKG_FROM_LOCALDB && extra) {
dump_pkg_backups(pkg);
}
@@ -171,6 +208,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
printf("\n");
FREELIST(requiredby);
+ alpm_list_free(validation);
}
static const char *get_backup_file_status(const char *root,
@@ -223,7 +261,7 @@ void dump_pkg_backups(alpm_pkg_t *pkg)
if(alpm_pkg_get_backup(pkg)) {
/* package has backup files, so print them */
for(i = alpm_pkg_get_backup(pkg); i; i = alpm_list_next(i)) {
- const alpm_backup_t *backup = alpm_list_getdata(i);
+ const alpm_backup_t *backup = i->data;
const char *value;
if(!backup->hash) {
continue;
@@ -251,11 +289,16 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet)
for(i = 0; i < pkgfiles->count; i++) {
const alpm_file_t *file = pkgfiles->files + i;
+ /* Regular: '<pkgname> <root><filepath>\n'
+ * Quiet : '<root><filepath>\n'
+ */
if(!quiet) {
- printf("%s %s%s\n", pkgname, root, file->name);
- } else {
- printf("%s%s\n", root, file->name);
+ fputs(pkgname, stdout);
+ putchar(' ');
}
+ fputs(root, stdout);
+ fputs(file->name, stdout);
+ putchar('\n');
}
fflush(stdout);
@@ -280,10 +323,10 @@ void dump_pkg_changelog(alpm_pkg_t *pkg)
/* if we hit the end of the file, we need to add a null terminator */
*(buf + ret) = '\0';
}
- printf("%s", buf);
+ fputs(buf, stdout);
}
alpm_pkg_changelog_close(pkg, fp);
- printf("\n");
+ putchar('\n');
}
}
diff --git a/src/pacman/package.h b/src/pacman/package.h
index 890b4fe1..1e021f4d 100644
--- a/src/pacman/package.h
+++ b/src/pacman/package.h
@@ -1,7 +1,7 @@
/*
* package.h
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index c0c3bb8b..478196e2 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -1,7 +1,7 @@
/*
* pacman.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
/* special handling of package version for GIT */
#if defined(GIT_VERSION)
#undef PACKAGE_VERSION
@@ -39,9 +37,6 @@
#include <sys/utsname.h> /* uname */
#include <locale.h> /* setlocale */
#include <errno.h>
-#if defined(PACMAN_DEBUG) && defined(HAVE_MCHECK_H)
-#include <mcheck.h> /* debug tracing (mtrace) */
-#endif
/* alpm */
#include <alpm.h>
@@ -178,7 +173,7 @@ static void usage(int op, const char * const myname)
switch(op) {
case PM_OP_SYNC:
case PM_OP_UPGRADE:
- addlist(_(" -f, --force force install, overwrite conflicting files\n"));
+ addlist(_(" --force force install, overwrite conflicting files\n"));
addlist(_(" --asdeps install packages as non-explicitly installed\n"));
addlist(_(" --asexplicit install packages as explicitly installed\n"));
addlist(_(" --ignore <pkg> ignore a package upgrade (can be used more than once)\n"));
@@ -208,8 +203,8 @@ static void usage(int op, const char * const myname)
addlist(_(" --noconfirm do not ask for any confirmation\n"));
}
list = alpm_list_msort(list, alpm_list_count(list), options_cmp);
- for (i = list; i; i = alpm_list_next(i)) {
- printf("%s", (char *)alpm_list_getdata(i));
+ for(i = list; i; i = alpm_list_next(i)) {
+ fputs((const char *)i->data, stdout);
}
alpm_list_free(list);
#undef addlist
@@ -528,7 +523,7 @@ static int parsearg_upgrade(int opt)
if(parsearg_trans(opt) == 0)
return 0;
switch(opt) {
- case 'f': config->flags |= ALPM_TRANS_FLAG_FORCE; break;
+ case OP_FORCE: config->flags |= ALPM_TRANS_FLAG_FORCE; break;
case OP_ASDEPS: config->flags |= ALPM_TRANS_FLAG_ALLDEPS; break;
case OP_ASEXPLICIT: config->flags |= ALPM_TRANS_FLAG_ALLEXPLICIT; break;
case OP_NEEDED: config->flags |= ALPM_TRANS_FLAG_NEEDED; break;
@@ -593,7 +588,6 @@ static int parseargs(int argc, char *argv[])
{"nodeps", no_argument, 0, 'd'},
{"deps", no_argument, 0, 'd'},
{"explicit", no_argument, 0, 'e'},
- {"force", no_argument, 0, 'f'},
{"groups", no_argument, 0, 'g'},
{"help", no_argument, 0, 'h'},
{"info", no_argument, 0, 'i'},
@@ -620,6 +614,7 @@ static int parseargs(int argc, char *argv[])
{"config", required_argument, 0, OP_CONFIG},
{"ignore", required_argument, 0, OP_IGNORE},
{"debug", optional_argument, 0, OP_DEBUG},
+ {"force", no_argument, 0, OP_FORCE},
{"noprogressbar", no_argument, 0, OP_NOPROGRESSBAR},
{"noscriptlet", no_argument, 0, OP_NOSCRIPTLET},
{"ask", required_argument, 0, OP_ASK},
@@ -724,7 +719,7 @@ static int parseargs(int argc, char *argv[])
* @param argc
* @param argv
*/
-static void cl_to_log(int argc, char* argv[])
+static void cl_to_log(int argc, char *argv[])
{
size_t size = 0;
int i;
@@ -765,11 +760,6 @@ int main(int argc, char *argv[])
uid_t myuid = geteuid();
#endif
-#if defined(PACMAN_DEBUG) && defined(HAVE_MCHECK_H)
- /*setenv("MALLOC_TRACE","pacman.mtrace", 0);*/
- mtrace();
-#endif
-
/* Set signal handlers */
/* Set up the structure to specify the new action. */
new_action.sa_handler = handler;
@@ -818,12 +808,13 @@ int main(int argc, char *argv[])
/* we support reading targets from stdin if a cmdline parameter is '-' */
if(!isatty(fileno(stdin)) && alpm_list_find_str(pm_targets, "-")) {
- size_t current_size = PATH_MAX, i = 0;
+ size_t current_size = PATH_MAX;
char *line = malloc(current_size);
/* remove the '-' from the list */
pm_targets = alpm_list_remove_str(pm_targets, "-", NULL);
+ i = 0;
while((line[i] = (char)fgetc(stdin)) != EOF) {
if(isspace((unsigned char)line[i])) {
/* avoid adding zero length arg when multiple spaces separate args */
@@ -895,19 +886,19 @@ int main(int argc, char *argv[])
#endif
if(config->verbose > 0) {
- alpm_list_t *i;
+ alpm_list_t *j;
printf("Root : %s\n", alpm_option_get_root(config->handle));
printf("Conf File : %s\n", config->configfile);
printf("DB Path : %s\n", alpm_option_get_dbpath(config->handle));
printf("Cache Dirs: ");
- for(i = alpm_option_get_cachedirs(config->handle); i; i = alpm_list_next(i)) {
- printf("%s ", (char *)alpm_list_getdata(i));
+ for(j = alpm_option_get_cachedirs(config->handle); j; j = alpm_list_next(j)) {
+ printf("%s ", (const char *)j->data);
}
printf("\n");
printf("Lock File : %s\n", alpm_option_get_lockfile(config->handle));
printf("Log File : %s\n", alpm_option_get_logfile(config->handle));
printf("GPG Dir : %s\n", alpm_option_get_gpgdir(config->handle));
- list_display("Targets :", pm_targets);
+ list_display("Targets :", pm_targets, 0);
}
/* Log command line */
diff --git a/src/pacman/pacman.h b/src/pacman/pacman.h
index 8bb9cb27..710e8fdc 100644
--- a/src/pacman/pacman.h
+++ b/src/pacman/pacman.h
@@ -1,7 +1,7 @@
/*
* pacman.h
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/pacman/query.c b/src/pacman/query.c
index ab19bab2..fc2c90c4 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -1,7 +1,7 @@
/*
* query.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
@@ -38,22 +36,7 @@
#include "conf.h"
#include "util.h"
-static char *resolve_path(const char *file)
-{
- char *str = NULL;
-
- str = calloc(PATH_MAX, sizeof(char));
- if(!str) {
- return NULL;
- }
-
- if(!realpath(file, str)) {
- free(str);
- return NULL;
- }
-
- return str;
-}
+#define LOCAL_PREFIX "local/"
/* check if filename exists in PATH */
static int search_path(char **filename, struct stat *bufptr)
@@ -75,7 +58,7 @@ static int search_path(char **filename, struct stat *bufptr)
/* strip the trailing slash if one exists */
while(path[plen - 1] == '/') {
- path[--plen] = '\0';
+ path[--plen] = '\0';
}
fullname = malloc(plen + flen + 2);
@@ -111,7 +94,6 @@ static int query_fileowner(alpm_list_t *targets)
{
int ret = 0;
char path[PATH_MAX];
- const char *root;
size_t rootlen;
alpm_list_t *t;
alpm_db_t *db_local;
@@ -125,25 +107,44 @@ static int query_fileowner(alpm_list_t *targets)
/* Set up our root path buffer. We only need to copy the location of root in
* once, then we can just overwrite whatever file was there on the previous
* iteration. */
- root = alpm_option_get_root(config->handle);
- rootlen = strlen(root);
- if(rootlen + 1 > PATH_MAX) {
- /* we are in trouble here */
- pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, "");
+
+ /* resolve root now so any symlinks in it will only have to be resolved once */
+ if(!realpath(alpm_option_get_root(config->handle), path)) {
+ pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"),
+ path, strerror(errno));
+ return 1;
+ }
+
+ /* make sure there's enough room to append the package file to path */
+ rootlen = strlen(path);
+ if(rootlen + 2 > PATH_MAX) {
+ pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), path, "");
return 1;
}
- strcpy(path, root);
- db_local = alpm_option_get_localdb(config->handle);
+ /* append trailing '/' removed by realpath */
+ path[rootlen++] = '/';
+ path[rootlen] = '\0';
+
+ db_local = alpm_get_localdb(config->handle);
for(t = targets; t; t = alpm_list_next(t)) {
- char *filename, *dname, *rpath;
+ char *filename = NULL, *dname = NULL, *rpath = NULL;
const char *bname;
struct stat buf;
alpm_list_t *i;
+ size_t len;
int found = 0;
- filename = strdup(alpm_list_getdata(t));
+ if((filename = strdup(t->data)) == NULL) {
+ goto targcleanup;
+ }
+
+ /* trailing '/' causes lstat to dereference directory symlinks */
+ len = strlen(filename) - 1;
+ while(len > 0 && filename[len] == '/') {
+ filename[len--] = '\0';
+ }
if(lstat(filename, &buf) == -1) {
/* if it is not a path but a program name, then check in PATH */
@@ -151,49 +152,33 @@ static int query_fileowner(alpm_list_t *targets)
if(search_path(&filename, &buf) == -1) {
pm_printf(ALPM_LOG_ERROR, _("failed to find '%s' in PATH: %s\n"),
filename, strerror(errno));
- ret++;
- free(filename);
- continue;
+ goto targcleanup;
}
} else {
pm_printf(ALPM_LOG_ERROR, _("failed to read file '%s': %s\n"),
filename, strerror(errno));
- ret++;
- free(filename);
- continue;
+ goto targcleanup;
}
}
if(S_ISDIR(buf.st_mode)) {
pm_printf(ALPM_LOG_ERROR,
_("cannot determine ownership of directory '%s'\n"), filename);
- ret++;
- free(filename);
- continue;
+ goto targcleanup;
}
bname = mbasename(filename);
dname = mdirname(filename);
- /* for files in '/', there is no directory name to match */
- if(strcmp(dname, "") == 0) {
- rpath = NULL;
- } else {
- rpath = resolve_path(dname);
+ rpath = realpath(dname, NULL);
- if(!rpath) {
- pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"),
- filename, strerror(errno));
- free(filename);
- free(dname);
- free(rpath);
- ret++;
- continue;
- }
+ if(!dname || !rpath) {
+ pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"),
+ filename, strerror(errno));
+ goto targcleanup;
}
- free(dname);
for(i = alpm_db_get_pkgcache(db_local); i && !found; i = alpm_list_next(i)) {
- alpm_pkg_t *info = alpm_list_getdata(i);
+ alpm_pkg_t *info = i->data;
alpm_filelist_t *filelist = alpm_pkg_get_files(info);
size_t j;
@@ -202,41 +187,49 @@ static int query_fileowner(alpm_list_t *targets)
char *ppath, *pdname;
const char *pkgfile = file->name;
- /* avoid the costly resolve_path usage if the basenames don't match */
+ /* avoid the costly realpath usage if the basenames don't match */
if(strcmp(mbasename(pkgfile), bname) != 0) {
continue;
}
- /* for files in '/', there is no directory name to match */
- if(!rpath) {
- print_query_fileowner(filename, info);
- found = 1;
- continue;
- }
-
+ /* concatenate our file and the root path */
if(rootlen + 1 + strlen(pkgfile) > PATH_MAX) {
- pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, pkgfile);
+ path[rootlen] = '\0'; /* reset path for error message */
+ pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), path, pkgfile);
+ continue;
}
- /* concatenate our file and the root path */
strcpy(path + rootlen, pkgfile);
pdname = mdirname(path);
- ppath = resolve_path(pdname);
+ ppath = realpath(pdname, NULL);
free(pdname);
- if(ppath && strcmp(ppath, rpath) == 0) {
+ if(!ppath) {
+ pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"),
+ path, strerror(errno));
+ continue;
+ }
+
+ if(strcmp(ppath, rpath) == 0) {
print_query_fileowner(filename, info);
found = 1;
+ free(ppath);
+ break;
}
free(ppath);
}
}
if(!found) {
pm_printf(ALPM_LOG_ERROR, _("No package owns %s\n"), filename);
+ }
+
+targcleanup:
+ if(!found) {
ret++;
}
free(filename);
free(rpath);
+ free(dname);
}
return ret;
@@ -247,7 +240,8 @@ static int query_search(alpm_list_t *targets)
{
alpm_list_t *i, *searchlist;
int freelist;
- alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
+ alpm_db_t *db_local = alpm_get_localdb(config->handle);
+ unsigned short cols;
/* if we have a targets list, search for packages matching it */
if(targets) {
@@ -261,37 +255,38 @@ static int query_search(alpm_list_t *targets)
return 1;
}
+ cols = getcols(fileno(stdout));
for(i = searchlist; i; i = alpm_list_next(i)) {
alpm_list_t *grp;
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ alpm_pkg_t *pkg = i->data;
if(!config->quiet) {
- printf("local/%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
+ printf(LOCAL_PREFIX "%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
} else {
- printf("%s", alpm_pkg_get_name(pkg));
+ fputs(alpm_pkg_get_name(pkg), stdout);
}
if(!config->quiet) {
if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
alpm_list_t *k;
- printf(" (");
+ fputs(" (", stdout);
for(k = grp; k; k = alpm_list_next(k)) {
- const char *group = alpm_list_getdata(k);
- printf("%s", group);
+ const char *group = k->data;
+ fputs(group, stdout);
if(alpm_list_next(k)) {
/* only print a spacer if there are more groups */
- printf(" ");
+ putchar(' ');
}
}
- printf(")");
+ putchar(')');
}
/* we need a newline and initial indent first */
- printf("\n ");
- indentprint(alpm_pkg_get_desc(pkg), 4);
+ fputs("\n ", stdout);
+ indentprint(alpm_pkg_get_desc(pkg), 4, cols);
}
- printf("\n");
+ fputc('\n', stdout);
}
/* we only want to free if the list was a search list */
@@ -304,33 +299,33 @@ static int query_search(alpm_list_t *targets)
static int query_group(alpm_list_t *targets)
{
alpm_list_t *i, *j;
- char *grpname = NULL;
+ const char *grpname = NULL;
int ret = 0;
- alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
+ alpm_db_t *db_local = alpm_get_localdb(config->handle);
if(targets == NULL) {
for(j = alpm_db_get_groupcache(db_local); j; j = alpm_list_next(j)) {
- alpm_group_t *grp = alpm_list_getdata(j);
+ alpm_group_t *grp = j->data;
const alpm_list_t *p;
for(p = grp->packages; p; p = alpm_list_next(p)) {
- alpm_pkg_t *pkg = alpm_list_getdata(p);
+ alpm_pkg_t *pkg = p->data;
printf("%s %s\n", grp->name, alpm_pkg_get_name(pkg));
}
}
} else {
for(i = targets; i; i = alpm_list_next(i)) {
alpm_group_t *grp;
- grpname = alpm_list_getdata(i);
- grp = alpm_db_readgroup(db_local, grpname);
+ grpname = i->data;
+ grp = alpm_db_get_group(db_local, grpname);
if(grp) {
const alpm_list_t *p;
for(p = grp->packages; p; p = alpm_list_next(p)) {
if(!config->quiet) {
printf("%s %s\n", grpname,
- alpm_pkg_get_name(alpm_list_getdata(p)));
+ alpm_pkg_get_name(p->data));
} else {
- printf("%s\n", alpm_pkg_get_name(alpm_list_getdata(p)));
+ printf("%s\n", alpm_pkg_get_name(p->data));
}
}
} else {
@@ -346,11 +341,11 @@ static int is_foreign(alpm_pkg_t *pkg)
{
const char *pkgname = alpm_pkg_get_name(pkg);
alpm_list_t *j;
- alpm_list_t *sync_dbs = alpm_option_get_syncdbs(config->handle);
+ alpm_list_t *sync_dbs = alpm_get_syncdbs(config->handle);
int match = 0;
for(j = sync_dbs; j; j = alpm_list_next(j)) {
- alpm_db_t *db = alpm_list_getdata(j);
+ alpm_db_t *db = j->data;
alpm_pkg_t *findpkg = alpm_db_get_pkg(db, pkgname);
if(findpkg) {
match = 1;
@@ -395,7 +390,7 @@ static int filter(alpm_pkg_t *pkg)
}
/* check if this pkg is outdated */
if(config->op_q_upgrade && (alpm_sync_newversion(pkg,
- alpm_option_get_syncdbs(config->handle)) == NULL)) {
+ alpm_get_syncdbs(config->handle)) == NULL)) {
return 0;
}
return 1;
@@ -514,7 +509,7 @@ int pacman_query(alpm_list_t *targets)
}
}
- db_local = alpm_option_get_localdb(config->handle);
+ db_local = alpm_get_localdb(config->handle);
/* operations on all packages in the local DB
* valid: no-op (plain -Q), list, info, check
@@ -526,7 +521,7 @@ int pacman_query(alpm_list_t *targets)
}
for(i = alpm_db_get_pkgcache(db_local); i; i = alpm_list_next(i)) {
- pkg = alpm_list_getdata(i);
+ pkg = i->data;
if(filter(pkg)) {
int value = display(pkg);
if(value != 0) {
@@ -552,7 +547,12 @@ int pacman_query(alpm_list_t *targets)
/* operations on named packages in the local DB
* valid: no-op (plain -Q), list, info, check */
for(i = targets; i; i = alpm_list_next(i)) {
- char *strname = alpm_list_getdata(i);
+ const char *strname = i->data;
+
+ /* strip leading part of "local/pkgname" */
+ if(strncmp(strname, LOCAL_PREFIX, strlen(LOCAL_PREFIX)) == 0) {
+ strname += strlen(LOCAL_PREFIX);
+ }
if(config->op_q_isfile) {
alpm_pkg_load(config->handle, strname, 1, 0, &pkg);
diff --git a/src/pacman/remove.c b/src/pacman/remove.c
index e7453c8d..472adb52 100644
--- a/src/pacman/remove.c
+++ b/src/pacman/remove.c
@@ -1,7 +1,7 @@
/*
* remove.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
+#include <fnmatch.h>
#include <stdlib.h>
#include <stdio.h>
@@ -31,10 +30,15 @@
#include "util.h"
#include "conf.h"
+static int fnmatch_cmp(const void *pattern, const void *string)
+{
+ return fnmatch(pattern, string, 0);
+}
+
static int remove_target(const char *target)
{
alpm_pkg_t *pkg;
- alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
+ alpm_db_t *db_local = alpm_get_localdb(config->handle);
alpm_list_t *p;
if((pkg = alpm_db_get_pkg(db_local, target)) != NULL) {
@@ -48,13 +52,13 @@ static int remove_target(const char *target)
}
/* fallback to group */
- alpm_group_t *grp = alpm_db_readgroup(db_local, target);
+ alpm_group_t *grp = alpm_db_get_group(db_local, target);
if(grp == NULL) {
pm_printf(ALPM_LOG_ERROR, _("target not found: %s\n"), target);
return -1;
}
for(p = grp->packages; p; p = alpm_list_next(p)) {
- pkg = alpm_list_getdata(p);
+ pkg = p->data;
if(alpm_remove_pkg(config->handle, pkg) == -1) {
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", target,
alpm_strerror(alpm_errno(config->handle)));
@@ -89,7 +93,7 @@ int pacman_remove(alpm_list_t *targets)
/* Step 1: add targets to the created transaction */
for(i = targets; i; i = alpm_list_next(i)) {
- char *target = alpm_list_getdata(i);
+ char *target = i->data;
char *targ = strchr(target, '/');
if(targ && strncmp(target, "local", 5) == 0) {
targ++;
@@ -98,25 +102,22 @@ int pacman_remove(alpm_list_t *targets)
}
if(remove_target(targ) == -1) {
retval = 1;
- goto cleanup;
}
}
+ if(retval == 1) {
+ goto cleanup;
+ }
+
/* Step 2: prepare the transaction based on its type, targets and flags */
if(alpm_trans_prepare(config->handle, &data) == -1) {
- enum _alpm_errno_t err = alpm_errno(config->handle);
+ alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
alpm_strerror(err));
switch(err) {
- case ALPM_ERR_PKG_INVALID_ARCH:
- for(i = data; i; i = alpm_list_next(i)) {
- char *pkg = alpm_list_getdata(i);
- printf(_(":: package %s does not have a valid architecture\n"), pkg);
- }
- break;
case ALPM_ERR_UNSATISFIED_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
- alpm_depmissing_t *miss = alpm_list_getdata(i);
+ alpm_depmissing_t *miss = i->data;
char *depstring = alpm_dep_compute_string(miss->depend);
printf(_(":: %s: requires %s\n"), miss->target, depstring);
free(depstring);
@@ -133,8 +134,8 @@ int pacman_remove(alpm_list_t *targets)
/* Search for holdpkg in target list */
int holdpkg = 0;
for(i = alpm_trans_get_remove(config->handle); i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
- if(alpm_list_find_str(config->holdpkg, alpm_pkg_get_name(pkg))) {
+ alpm_pkg_t *pkg = i->data;
+ if(alpm_list_find(config->holdpkg, alpm_pkg_get_name(pkg), fnmatch_cmp)) {
pm_printf(ALPM_LOG_WARNING, _("%s is designated as a HoldPkg.\n"),
alpm_pkg_get_name(pkg));
holdpkg = 1;
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index 951ee94c..532a6672 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -18,8 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -68,7 +66,7 @@ static int sync_cleandb(const char *dbpath, int keep_used)
return 1;
}
- syncdbs = alpm_option_get_syncdbs(config->handle);
+ syncdbs = alpm_get_syncdbs(config->handle);
rewinddir(dir);
/* step through the directory one file at a time */
@@ -118,7 +116,7 @@ static int sync_cleandb(const char *dbpath, int keep_used)
if(keep_used) {
alpm_list_t *i;
for(i = syncdbs; i && !found; i = alpm_list_next(i)) {
- alpm_db_t *db = alpm_list_getdata(i);
+ alpm_db_t *db = i->data;
found = !strcmp(dbname, alpm_db_get_name(db));
}
}
@@ -169,15 +167,11 @@ static int sync_cleandb_all(void)
static int sync_cleancache(int level)
{
alpm_list_t *i;
- alpm_list_t *sync_dbs = alpm_option_get_syncdbs(config->handle);
- alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
+ alpm_list_t *sync_dbs = alpm_get_syncdbs(config->handle);
+ alpm_db_t *db_local = alpm_get_localdb(config->handle);
alpm_list_t *cachedirs = alpm_option_get_cachedirs(config->handle);
int ret = 0;
- for(i = cachedirs; i; i = alpm_list_next(i)) {
- printf(_("Cache directory: %s\n"), (char *)alpm_list_getdata(i));
- }
-
if(!config->cleanmethod) {
/* default to KeepInstalled if user did not specify */
config->cleanmethod = PM_CLEAN_KEEPINST;
@@ -191,22 +185,31 @@ static int sync_cleancache(int level)
if(config->cleanmethod & PM_CLEAN_KEEPCUR) {
printf(_(" All current sync database packages\n"));
}
- if(!yesno(_("Do you want to remove all other packages from cache?"))) {
- return 0;
- }
- printf(_("removing old packages from cache...\n"));
- } else {
- if(!noyes(_("Do you want to remove ALL files from cache?"))) {
- return 0;
- }
- printf(_("removing all files from cache...\n"));
}
+ printf("\n");
for(i = cachedirs; i; i = alpm_list_next(i)) {
- const char *cachedir = alpm_list_getdata(i);
- DIR *dir = opendir(cachedir);
+ const char *cachedir = i->data;
+ DIR *dir;
struct dirent *ent;
+ 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);
if(dir == NULL) {
pm_printf(ALPM_LOG_ERROR,
_("could not access cache directory %s\n"), cachedir);
@@ -226,19 +229,30 @@ static int sync_cleancache(int level)
continue;
}
- /* skip signature files - they are removed with their package file */
- if(fnmatch("*.sig", ent->d_name, 0) == 0) {
- continue;
- }
-
- /* skip package database within the cache directory */
- if(fnmatch("*.db*", ent->d_name, 0) == 0) {
- continue;
- }
-
- /* skip source packages within the cache directory */
- if(fnmatch("*.src.tar*", ent->d_name, 0) == 0) {
- continue;
+ if (level <= 1) {
+ static const char * const glob_skips[] = {
+ /* skip signature files - they are removed with their package file */
+ "*.sig",
+ /* skip package database within the cache directory */
+ "*.db*",
+ /* skip source packages within the cache directory */
+ "*.src.tar.*",
+ /* skip package deltas, we aren't smart enough to clean these yet */
+ "*.delta",
+ /* skip any partial downloads */
+ "*.part"
+ };
+ 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;
+ }
}
/* build the full filepath */
@@ -276,7 +290,7 @@ static int sync_cleancache(int level)
alpm_list_t *j;
/* check if this package is in a sync DB */
for(j = sync_dbs; j && delete; j = alpm_list_next(j)) {
- alpm_db_t *db = alpm_list_getdata(j);
+ alpm_db_t *db = j->data;
pkg = alpm_db_get_pkg(db, local_name);
if(pkg != NULL && alpm_pkg_vercmp(local_version,
alpm_pkg_get_version(pkg)) == 0) {
@@ -301,6 +315,7 @@ static int sync_cleancache(int level)
}
}
closedir(dir);
+ printf("\n");
}
return ret;
@@ -309,12 +324,12 @@ static int sync_cleancache(int level)
static int sync_synctree(int level, alpm_list_t *syncs)
{
alpm_list_t *i;
- int success = 0, ret;
+ unsigned int success = 0;
for(i = syncs; i; i = alpm_list_next(i)) {
- alpm_db_t *db = alpm_list_getdata(i);
+ alpm_db_t *db = i->data;
- ret = alpm_db_update((level < 2 ? 0 : 1), db);
+ int ret = alpm_db_update((level < 2 ? 0 : 1), db);
if(ret < 0) {
pm_printf(ALPM_LOG_ERROR, _("failed to update %s (%s)\n"),
alpm_db_get_name(db), alpm_strerror(alpm_errno(config->handle)));
@@ -358,10 +373,11 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
alpm_list_t *i, *j, *ret;
int freelist;
int found = 0;
- alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
+ alpm_db_t *db_local = alpm_get_localdb(config->handle);
for(i = syncs; i; i = alpm_list_next(i)) {
- alpm_db_t *db = alpm_list_getdata(i);
+ alpm_db_t *db = i->data;
+ unsigned short cols;
/* if we have a targets list, search for packages matching it */
if(targets) {
ret = alpm_db_search(db, targets);
@@ -375,39 +391,40 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
} else {
found = 1;
}
+ cols = getcols(fileno(stdout));
for(j = ret; j; j = alpm_list_next(j)) {
alpm_list_t *grp;
- alpm_pkg_t *pkg = alpm_list_getdata(j);
+ alpm_pkg_t *pkg = j->data;
if(!config->quiet) {
printf("%s/%s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
alpm_pkg_get_version(pkg));
} else {
- printf("%s", alpm_pkg_get_name(pkg));
+ fputs(alpm_pkg_get_name(pkg), stdout);
}
if(!config->quiet) {
if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
alpm_list_t *k;
- printf(" (");
+ fputs(" (", stdout);
for(k = grp; k; k = alpm_list_next(k)) {
- const char *group = alpm_list_getdata(k);
- printf("%s", group);
+ const char *group = k->data;
+ fputs(group, stdout);
if(alpm_list_next(k)) {
/* only print a spacer if there are more groups */
- printf(" ");
+ putchar(' ');
}
}
- printf(")");
+ putchar(')');
}
print_installed(db_local, pkg);
/* we need a newline and initial indent first */
- printf("\n ");
- indentprint(alpm_pkg_get_desc(pkg), 4);
+ fputs("\n ", stdout);
+ indentprint(alpm_pkg_get_desc(pkg), 4, cols);
}
- printf("\n");
+ fputc('\n', stdout);
}
/* we only want to free if the list was a search list */
if(freelist) {
@@ -420,23 +437,23 @@ 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, *k;
+ alpm_list_t *i, *j, *k, *s = NULL;
if(targets) {
for(i = targets; i; i = alpm_list_next(i)) {
- const char *grpname = alpm_list_getdata(i);
+ const char *grpname = i->data;
for(j = syncs; j; j = alpm_list_next(j)) {
- alpm_db_t *db = alpm_list_getdata(j);
- alpm_group_t *grp = alpm_db_readgroup(db, grpname);
+ alpm_db_t *db = j->data;
+ alpm_group_t *grp = alpm_db_get_group(db, grpname);
if(grp) {
/* get names of packages in group */
for(k = grp->packages; k; k = alpm_list_next(k)) {
if(!config->quiet) {
printf("%s %s\n", grpname,
- alpm_pkg_get_name(alpm_list_getdata(k)));
+ alpm_pkg_get_name(k->data));
} else {
- printf("%s\n", alpm_pkg_get_name(alpm_list_getdata(k)));
+ printf("%s\n", alpm_pkg_get_name(k->data));
}
}
}
@@ -444,22 +461,26 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
}
} else {
for(i = syncs; i; i = alpm_list_next(i)) {
- alpm_db_t *db = alpm_list_getdata(i);
+ alpm_db_t *db = i->data;
for(j = alpm_db_get_groupcache(db); j; j = alpm_list_next(j)) {
- alpm_group_t *grp = alpm_list_getdata(j);
+ alpm_group_t *grp = j->data;
if(level > 1) {
for(k = grp->packages; k; k = alpm_list_next(k)) {
printf("%s %s\n", grp->name,
- alpm_pkg_get_name(alpm_list_getdata(k)));
+ alpm_pkg_get_name(k->data));
}
} else {
/* print grp names only, no package names */
- printf("%s\n", grp->name);
+ if(!alpm_list_find_str (s, grp->name)) {
+ s = alpm_list_add (s, grp->name);
+ printf("%s\n", grp->name);
+ }
}
}
}
+ alpm_list_free(s);
}
return 0;
@@ -472,7 +493,7 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
if(targets) {
for(i = targets; i; i = alpm_list_next(i)) {
- const char *target = alpm_list_getdata(i);
+ const char *target = i->data;
char *name = strdup(target);
char *repo, *pkgstr;
int foundpkg = 0, founddb = 0;
@@ -488,14 +509,14 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
}
for(j = syncs; j; j = alpm_list_next(j)) {
- alpm_db_t *db = alpm_list_getdata(j);
+ alpm_db_t *db = j->data;
if(repo && strcmp(repo, alpm_db_get_name(db)) != 0) {
continue;
}
founddb = 1;
for(k = alpm_db_get_pkgcache(db); k; k = alpm_list_next(k)) {
- alpm_pkg_t *pkg = alpm_list_getdata(k);
+ alpm_pkg_t *pkg = k->data;
if(strcmp(alpm_pkg_get_name(pkg), pkgstr) == 0) {
dump_pkg_full(pkg, config->op_s_info > 1);
@@ -519,10 +540,10 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
}
} else {
for(i = syncs; i; i = alpm_list_next(i)) {
- alpm_db_t *db = alpm_list_getdata(i);
+ alpm_db_t *db = i->data;
for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) {
- alpm_pkg_t *pkg = alpm_list_getdata(j);
+ alpm_pkg_t *pkg = j->data;
dump_pkg_full(pkg, config->op_s_info > 1);
}
}
@@ -534,15 +555,15 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
{
alpm_list_t *i, *j, *ls = NULL;
- alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
+ alpm_db_t *db_local = alpm_get_localdb(config->handle);
if(targets) {
for(i = targets; i; i = alpm_list_next(i)) {
- const char *repo = alpm_list_getdata(i);
+ const char *repo = i->data;
alpm_db_t *db = NULL;
for(j = syncs; j; j = alpm_list_next(j)) {
- alpm_db_t *d = alpm_list_getdata(j);
+ alpm_db_t *d = j->data;
if(strcmp(repo, alpm_db_get_name(d)) == 0) {
db = d;
@@ -564,10 +585,10 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
}
for(i = ls; i; i = alpm_list_next(i)) {
- alpm_db_t *db = alpm_list_getdata(i);
+ alpm_db_t *db = i->data;
for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) {
- alpm_pkg_t *pkg = alpm_list_getdata(j);
+ alpm_pkg_t *pkg = j->data;
if(!config->quiet) {
printf("%s %s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
@@ -587,30 +608,10 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
return 0;
}
-static alpm_list_t *syncfirst(void) {
- alpm_list_t *i, *res = NULL;
- alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
- alpm_list_t *syncdbs = alpm_option_get_syncdbs(config->handle);
-
- for(i = config->syncfirst; i; i = alpm_list_next(i)) {
- char *pkgname = alpm_list_getdata(i);
- alpm_pkg_t *pkg = alpm_db_get_pkg(db_local, pkgname);
- if(pkg == NULL) {
- continue;
- }
-
- if(alpm_sync_newversion(pkg, syncdbs)) {
- res = alpm_list_add(res, strdup(pkgname));
- }
- }
-
- return res;
-}
-
static alpm_db_t *get_db(const char *dbname)
{
alpm_list_t *i;
- for(i = alpm_option_get_syncdbs(config->handle); i; i = i->next) {
+ for(i = alpm_get_syncdbs(config->handle); i; i = i->next) {
alpm_db_t *db = i->data;
if(strcmp(alpm_db_get_name(db), dbname) == 0) {
return db;
@@ -624,7 +625,7 @@ static int process_pkg(alpm_pkg_t *pkg)
int ret = alpm_add_pkg(config->handle, pkg);
if(ret == -1) {
- enum _alpm_errno_t err = alpm_errno(config->handle);
+ alpm_errno_t err = alpm_errno(config->handle);
if(err == ALPM_ERR_TRANS_DUP_TARGET
|| err == ALPM_ERR_PKG_IGNORED) {
/* just skip duplicate or ignored targets */
@@ -640,7 +641,7 @@ static int process_pkg(alpm_pkg_t *pkg)
return 0;
}
-static int process_group(alpm_list_t *dbs, const char *group)
+static int process_group(alpm_list_t *dbs, const char *group, int error)
{
int ret = 0;
alpm_list_t *i;
@@ -652,6 +653,12 @@ static int process_group(alpm_list_t *dbs, const char *group)
return 1;
}
+ 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;
+ }
if(config->print == 0) {
printf(_(":: There are %d members in group %s:\n"), count,
@@ -671,7 +678,7 @@ static int process_group(alpm_list_t *dbs, const char *group)
for(i = pkgs; i; i = alpm_list_next(i)) {
if(array[n++] == 0)
continue;
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ alpm_pkg_t *pkg = i->data;
if(process_pkg(pkg) == 1) {
ret = 1;
@@ -682,7 +689,7 @@ static int process_group(alpm_list_t *dbs, const char *group)
free(array);
} else {
for(i = pkgs; i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ alpm_pkg_t *pkg = i->data;
if(process_pkg(pkg) == 1) {
ret = 1;
@@ -690,12 +697,14 @@ static int process_group(alpm_list_t *dbs, const char *group)
}
}
}
+
cleanup:
alpm_list_free(pkgs);
return ret;
}
-static int process_targname(alpm_list_t *dblist, const char *targname)
+static int process_targname(alpm_list_t *dblist, const char *targname,
+ int error)
{
alpm_pkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, targname);
@@ -709,20 +718,20 @@ static int process_targname(alpm_list_t *dblist, const char *targname)
return process_pkg(pkg);
}
/* fallback on group */
- return process_group(dblist, targname);
+ return process_group(dblist, targname, error);
}
-static int process_target(const char *target)
+static int process_target(const char *target, int error)
{
/* process targets */
char *targstring = strdup(target);
char *targname = strchr(targstring, '/');
- char *dbname = NULL;
int ret = 0;
- alpm_list_t *dblist = NULL;
+ alpm_list_t *dblist;
if(targname && targname != targstring) {
- alpm_db_t *db = NULL;
+ alpm_db_t *db;
+ const char *dbname;
*targname = '\0';
targname++;
@@ -734,14 +743,15 @@ static int process_target(const char *target)
ret = 1;
goto cleanup;
}
- dblist = alpm_list_add(dblist, db);
- ret = process_targname(dblist, targname);
+ dblist = alpm_list_add(NULL, db);
+ ret = process_targname(dblist, targname, error);
alpm_list_free(dblist);
} else {
targname = targstring;
- dblist = alpm_option_get_syncdbs(config->handle);
- ret = process_targname(dblist, targname);
+ dblist = alpm_get_syncdbs(config->handle);
+ ret = process_targname(dblist, targname, error);
}
+
cleanup:
free(targstring);
if(ret && access(target, R_OK) == 0) {
@@ -754,6 +764,7 @@ cleanup:
static int sync_trans(alpm_list_t *targets)
{
+ int retval = 0;
alpm_list_t *i;
/* Step 1: create a new transaction... */
@@ -763,13 +774,17 @@ static int sync_trans(alpm_list_t *targets)
/* process targets */
for(i = targets; i; i = alpm_list_next(i)) {
- char *targ = alpm_list_getdata(i);
- if(process_target(targ) == 1) {
- trans_release();
- return 1;
+ const char *targ = i->data;
+ if(process_target(targ, retval) == 1) {
+ retval = 1;
}
}
+ if(retval) {
+ trans_release();
+ return retval;
+ }
+
if(config->op_s_upgrade) {
printf(_(":: Starting full system upgrade...\n"));
alpm_logaction(config->handle, "starting full system upgrade\n");
@@ -790,19 +805,19 @@ int sync_prepare_execute(void)
/* Step 2: "compute" the transaction based on targets and flags */
if(alpm_trans_prepare(config->handle, &data) == -1) {
- enum _alpm_errno_t err = alpm_errno(config->handle);
+ alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
alpm_strerror(err));
switch(err) {
case ALPM_ERR_PKG_INVALID_ARCH:
for(i = data; i; i = alpm_list_next(i)) {
- char *pkg = alpm_list_getdata(i);
+ const char *pkg = i->data;
printf(_(":: package %s does not have a valid architecture\n"), pkg);
}
break;
case ALPM_ERR_UNSATISFIED_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
- alpm_depmissing_t *miss = alpm_list_getdata(i);
+ alpm_depmissing_t *miss = i->data;
char *depstring = alpm_dep_compute_string(miss->depend);
printf(_(":: %s: requires %s\n"), miss->target, depstring);
free(depstring);
@@ -810,7 +825,7 @@ int sync_prepare_execute(void)
break;
case ALPM_ERR_CONFLICTING_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
- alpm_conflict_t *conflict = alpm_list_getdata(i);
+ alpm_conflict_t *conflict = i->data;
/* only print reason if it contains new information */
if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
printf(_(":: %s and %s are in conflict\n"),
@@ -859,13 +874,13 @@ int sync_prepare_execute(void)
}
if(alpm_trans_commit(config->handle, &data) == -1) {
- enum _alpm_errno_t err = alpm_errno(config->handle);
+ alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
alpm_strerror(err));
switch(err) {
case ALPM_ERR_FILE_CONFLICTS:
for(i = data; i; i = alpm_list_next(i)) {
- alpm_fileconflict_t *conflict = alpm_list_getdata(i);
+ alpm_fileconflict_t *conflict = i->data;
switch(conflict->type) {
case ALPM_FILECONFLICT_TARGET:
printf(_("%s exists in both '%s' and '%s'\n"),
@@ -883,7 +898,7 @@ int sync_prepare_execute(void)
case ALPM_ERR_PKG_INVALID_SIG:
case ALPM_ERR_DLT_INVALID:
for(i = data; i; i = alpm_list_next(i)) {
- const char *filename = alpm_list_getdata(i);
+ const char *filename = i->data;
printf(_("%s is invalid or corrupted\n"), filename);
}
break;
@@ -921,7 +936,6 @@ int pacman_sync(alpm_list_t *targets)
}
ret += sync_cleancache(config->op_s_clean);
- printf("\n");
ret += sync_cleandb_all();
if(trans_release() == -1) {
@@ -935,7 +949,7 @@ int pacman_sync(alpm_list_t *targets)
return 1;
}
- sync_dbs = alpm_option_get_syncdbs(config->handle);
+ sync_dbs = alpm_get_syncdbs(config->handle);
if(config->op_s_sync) {
/* grab a fresh package list */
@@ -983,38 +997,7 @@ int pacman_sync(alpm_list_t *targets)
}
}
- alpm_list_t *targs = alpm_list_strdup(targets);
- if(!config->op_s_downloadonly && !config->print) {
- /* check for newer versions of packages to be upgraded first */
- alpm_list_t *packages = syncfirst();
- if(packages) {
- /* Do not ask user if all the -S targets are SyncFirst packages, see FS#15810 */
- alpm_list_t *tmp = NULL;
- if(config->op_s_upgrade || (tmp = alpm_list_diff(targets, packages, (alpm_list_fn_cmp)strcmp))) {
- alpm_list_free(tmp);
- printf(_(":: The following packages should be upgraded first :\n"));
- list_display(" ", packages);
- if(yesno(_(":: Do you want to cancel the current operation\n"
- ":: and upgrade these packages now?"))) {
- FREELIST(targs);
- targs = packages;
- config->flags = 0;
- config->op_s_upgrade = 0;
- } else {
- FREELIST(packages);
- }
- printf("\n");
- } else {
- pm_printf(ALPM_LOG_DEBUG, "skipping SyncFirst dialog\n");
- FREELIST(packages);
- }
- }
- }
-
- int ret = sync_trans(targs);
- FREELIST(targs);
-
- return ret;
+ return sync_trans(targets);
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c
index 880aa4c6..eaa36402 100644
--- a/src/pacman/upgrade.c
+++ b/src/pacman/upgrade.c
@@ -1,7 +1,7 @@
/*
* upgrade.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -41,6 +39,7 @@
*/
int pacman_upgrade(alpm_list_t *targets)
{
+ int retval = 0;
alpm_list_t *i;
alpm_siglevel_t level = alpm_option_get_default_siglevel(config->handle);
@@ -57,7 +56,7 @@ int pacman_upgrade(alpm_list_t *targets)
if(str == NULL) {
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n",
(char *)i->data, alpm_strerror(alpm_errno(config->handle)));
- return 1;
+ retval = 1;
} else {
free(i->data);
i->data = str;
@@ -65,6 +64,10 @@ int pacman_upgrade(alpm_list_t *targets)
}
}
+ if(retval) {
+ return retval;
+ }
+
/* Step 1: create a new transaction */
if(trans_init(config->flags, 1) == -1) {
return 1;
@@ -73,25 +76,30 @@ int pacman_upgrade(alpm_list_t *targets)
printf(_("loading packages...\n"));
/* add targets to the created transaction */
for(i = targets; i; i = alpm_list_next(i)) {
- char *targ = alpm_list_getdata(i);
+ const char *targ = i->data;
alpm_pkg_t *pkg;
if(alpm_pkg_load(config->handle, targ, 1, level, &pkg) != 0) {
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n",
targ, alpm_strerror(alpm_errno(config->handle)));
- trans_release();
- return 1;
+ retval = 1;
+ continue;
}
if(alpm_add_pkg(config->handle, pkg) == -1) {
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n",
targ, alpm_strerror(alpm_errno(config->handle)));
alpm_pkg_free(pkg);
- trans_release();
- return 1;
+ retval = 1;
+ continue;
}
config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
}
+ if(retval) {
+ trans_release();
+ return retval;
+ }
+
/* now that targets are resolved, we can hand it all off to the sync code */
return sync_prepare_execute();
}
diff --git a/src/pacman/util.c b/src/pacman/util.c
index f7f8ecf5..5079b4ce 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -18,12 +18,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
-#include <sys/time.h>
+#include <time.h>
#include <stdio.h>
#include <stdlib.h>
@@ -65,7 +63,7 @@ int trans_init(alpm_transflag_t flags, int check_valid)
void trans_init_error(void)
{
- enum _alpm_errno_t err = alpm_errno(config->handle);
+ alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, _("failed to init transaction (%s)\n"),
alpm_strerror(err));
if(err == ALPM_ERR_HANDLE_LOCK) {
@@ -110,7 +108,7 @@ int check_syncdbs(size_t need_repos, int check_valid)
{
int ret = 0;
alpm_list_t *i;
- alpm_list_t *sync_dbs = alpm_option_get_syncdbs(config->handle);
+ alpm_list_t *sync_dbs = alpm_get_syncdbs(config->handle);
if(need_repos && sync_dbs == NULL) {
pm_printf(ALPM_LOG_ERROR, _("no usable package repositories configured.\n"));
@@ -132,10 +130,10 @@ int check_syncdbs(size_t need_repos, int check_valid)
}
/* discard unhandled input on the terminal's input buffer */
-static int flush_term_input(void) {
+static int flush_term_input(int fd) {
#ifdef HAVE_TCFLUSH
- if(isatty(fileno(stdin))) {
- return tcflush(fileno(stdin), TCIFLUSH);
+ if(isatty(fd)) {
+ return tcflush(fd, TCIFLUSH);
}
#endif
@@ -144,24 +142,24 @@ static int flush_term_input(void) {
}
/* gets the current screen column width */
-unsigned short getcols(void)
+unsigned short getcols(int fd)
{
const unsigned short default_tty = 80;
const unsigned short default_notty = 0;
unsigned short termwidth = 0;
- if(!isatty(fileno(stdout))) {
+ if(!isatty(fd)) {
return default_notty;
}
-#ifdef TIOCGSIZE
+#if defined(TIOCGSIZE)
struct ttysize win;
- if(ioctl(1, TIOCGSIZE, &win) == 0) {
+ if(ioctl(fd, TIOCGSIZE, &win) == 0) {
termwidth = win.ts_cols;
}
#elif defined(TIOCGWINSZ)
struct winsize win;
- if(ioctl(1, TIOCGWINSZ, &win) == 0) {
+ if(ioctl(fd, TIOCGWINSZ, &win) == 0) {
termwidth = win.ws_col;
}
#endif
@@ -241,14 +239,22 @@ char *mdirname(const char *path)
return strdup(".");
}
- ret = strdup(path);
+ if((ret = strdup(path)) == NULL) {
+ return NULL;
+ }
+
last = strrchr(ret, '/');
if(last != NULL) {
/* we found a '/', so terminate our string */
+ if(last == ret) {
+ /* return "/" for root */
+ last++;
+ }
*last = '\0';
return ret;
}
+
/* no slash found */
free(ret);
return strdup(".");
@@ -256,12 +262,11 @@ char *mdirname(const char *path)
/* output a string, but wrap words properly with a specified indentation
*/
-void indentprint(const char *str, size_t indent)
+void indentprint(const char *str, unsigned short indent, unsigned short cols)
{
wchar_t *wcstr;
const wchar_t *p;
- int len, cidx;
- const unsigned short cols = getcols();
+ size_t len, cidx;
if(!str) {
return;
@@ -270,7 +275,7 @@ void indentprint(const char *str, size_t indent)
/* if we're not a tty, or our tty is not wide enough that wrapping even makes
* sense, print without indenting */
if(cols == 0 || indent > cols) {
- printf("%s", str);
+ fputs(str, stdout);
return;
}
@@ -318,13 +323,13 @@ void indentprint(const char *str, size_t indent)
/* Trim whitespace and newlines from a string
*/
-char *strtrim(char *str)
+size_t strtrim(char *str)
{
- char *pch = str;
+ char *end, *pch = str;
if(str == NULL || *str == '\0') {
/* string is empty, so we're done. */
- return str;
+ return 0;
}
while(isspace((unsigned char)*pch)) {
@@ -341,16 +346,16 @@ char *strtrim(char *str)
/* check if there wasn't anything but whitespace in the string. */
if(*str == '\0') {
- return str;
+ return 0;
}
- pch = (str + (strlen(str) - 1));
- while(isspace((unsigned char)*pch)) {
- pch--;
+ end = (str + strlen(str) - 1);
+ while(isspace((unsigned char)*end)) {
+ end--;
}
- *++pch = '\0';
+ *++end = '\0';
- return str;
+ return end - pch;
}
/* Replace all occurances of 'needle' with 'replace' in 'str', returning
@@ -391,7 +396,7 @@ char *strreplace(const char *str, const char *needle, const char *replace)
p = str;
newp = newstr;
for(i = list; i; i = alpm_list_next(i)) {
- q = alpm_list_getdata(i);
+ q = i->data;
if(q > p) {
/* add chars between this occurence and last occurence, if any */
memcpy(newp, p, (size_t)(q - p));
@@ -463,7 +468,7 @@ static size_t string_length(const char *s)
return len;
}
-void string_display(const char *title, const char *string)
+void string_display(const char *title, const char *string, unsigned short cols)
{
if(title) {
printf("%s ", title);
@@ -473,82 +478,128 @@ void string_display(const char *title, const char *string)
} else {
/* compute the length of title + a space */
size_t len = string_length(title) + 1;
- indentprint(string, len);
+ indentprint(string, (unsigned short)len, cols);
}
printf("\n");
}
-static void table_print_line(const alpm_list_t *line,
- size_t colcount, size_t *widths)
+static void table_print_line(const alpm_list_t *line, short col_padding,
+ size_t colcount, size_t *widths, int *has_data)
{
- size_t i;
+ size_t i, lastcol = 0;
+ int need_padding = 0;
const alpm_list_t *curcell;
+ for(i = colcount; i > 0; i--) {
+ if(has_data[i - 1]) {
+ lastcol = i - 1;
+ break;
+ }
+ }
+
for(i = 0, curcell = line; curcell && i < colcount;
i++, curcell = alpm_list_next(curcell)) {
- const char *value = curcell->data;
- size_t len = string_length(value);
+ const char *value;
+ int cell_padding;
+
+ if(!has_data[i]) {
+ continue;
+ }
+
+ value = curcell->data;
+ if(!value) {
+ value = "";
+ }
/* silly printf requires padding size to be an int */
- int padding = (int)widths[i] - (int)len;
- if(padding < 0) {
- padding = 0;
+ cell_padding = (int)widths[i] - (int)string_length(value);
+ if(cell_padding < 0) {
+ cell_padding = 0;
+ }
+ if(need_padding) {
+ printf("%*s", col_padding, "");
}
/* left-align all but the last column */
- if(i + 1 < colcount) {
- printf("%s%*s", value, padding, "");
+ if(i != lastcol) {
+ printf("%s%*s", value, cell_padding, "");
} else {
- printf("%*s%s", padding, "", value);
+ printf("%*s%s", cell_padding, "", value);
}
+ need_padding = 1;
}
printf("\n");
}
-/* find the max string width of each column */
+
+
+/**
+ * Find the max string width of each column. Also determines whether values
+ * exist in the column and sets the value in has_data accordingly.
+ * @param header a list of header strings
+ * @param rows a list of lists of rows as strings
+ * @param padding the amount of padding between columns
+ * @param totalcols the total number of columns in the header and each row
+ * @param widths a pointer to store width data
+ * @param has_data a pointer to store whether column has data
+ *
+ * @return the total width of the table; 0 on failure
+ */
static size_t table_calc_widths(const alpm_list_t *header,
- const alpm_list_t *rows, size_t totalcols, size_t **widths)
+ const alpm_list_t *rows, short padding, size_t totalcols,
+ size_t **widths, int **has_data)
{
const alpm_list_t *i;
- const unsigned short padding = 2;
- size_t curcol, totalwidth = 0;
+ size_t curcol, totalwidth = 0, usefulcols = 0;
size_t *colwidths;
+ int *coldata;
if(totalcols <= 0) {
return 0;
}
colwidths = malloc(totalcols * sizeof(size_t));
- if(!colwidths) {
+ coldata = calloc(totalcols, sizeof(int));
+ if(!colwidths || !coldata) {
return 0;
}
/* header determines column count and initial values of longest_strs */
for(i = header, curcol = 0; i; i = alpm_list_next(i), curcol++) {
- colwidths[curcol] = string_length(alpm_list_getdata(i));
+ colwidths[curcol] = string_length(i->data);
+ /* note: header does not determine whether column has data */
}
/* now find the longest string in each column */
for(i = rows; i; i = alpm_list_next(i)) {
/* grab first column of each row and iterate through columns */
- const alpm_list_t *j = alpm_list_getdata(i);
+ const alpm_list_t *j = i->data;
for(curcol = 0; j; j = alpm_list_next(j), curcol++) {
- char *str = alpm_list_getdata(j);
+ const char *str = j->data;
size_t str_len = string_length(str);
if(str_len > colwidths[curcol]) {
colwidths[curcol] = str_len;
}
+ if(str_len > 0) {
+ coldata[curcol] = 1;
+ }
}
}
for(i = header, curcol = 0; i; i = alpm_list_next(i), curcol++) {
- /* pad everything but the last column */
- if(curcol + 1 < totalcols) {
- colwidths[curcol] += padding;
+ /* only include columns that have data */
+ if(coldata[curcol]) {
+ usefulcols++;
+ totalwidth += colwidths[curcol];
}
- totalwidth += colwidths[curcol];
+ }
+
+ /* add padding between columns */
+ if(usefulcols > 0) {
+ totalwidth += padding * (usefulcols - 1);
}
*widths = colwidths;
+ *has_data = coldata;
return totalwidth;
}
@@ -559,28 +610,31 @@ static size_t table_calc_widths(const alpm_list_t *header,
* of headers
* @param rows the rows to display as a list of lists of strings. the outer
* list represents the rows, the inner list the cells (= columns)
- *
+ * @param cols the number of columns available in the terminal
* @return -1 if not enough terminal cols available, else 0
*/
-int table_display(const char *title, const alpm_list_t *header,
- const alpm_list_t *rows)
+static int table_display(const char *title, const alpm_list_t *header,
+ const alpm_list_t *rows, unsigned short cols)
{
+ const unsigned short padding = 2;
const alpm_list_t *i;
size_t *widths = NULL, totalcols, totalwidth;
+ int *has_data = NULL;
if(rows == NULL || header == NULL) {
return 0;
}
totalcols = alpm_list_count(header);
- totalwidth = table_calc_widths(header, rows, totalcols, &widths);
+ totalwidth = table_calc_widths(header, rows, padding, totalcols,
+ &widths, &has_data);
/* return -1 if terminal is not wide enough */
- if(totalwidth > getcols()) {
+ if(totalwidth > cols) {
pm_printf(ALPM_LOG_WARNING,
_("insufficient columns available for table display\n"));
return -1;
}
- if(!totalwidth || !widths) {
+ if(!totalwidth || !widths || !has_data) {
return -1;
}
@@ -588,18 +642,20 @@ int table_display(const char *title, const alpm_list_t *header,
printf("%s\n\n", title);
}
- table_print_line(header, totalcols, widths);
+ table_print_line(header, padding, totalcols, widths, has_data);
printf("\n");
for(i = rows; i; i = alpm_list_next(i)) {
- table_print_line(alpm_list_getdata(i), totalcols, widths);
+ table_print_line(i->data, padding, totalcols, widths, has_data);
}
free(widths);
+ free(has_data);
return 0;
}
-void list_display(const char *title, const alpm_list_t *list)
+void list_display(const char *title, const alpm_list_t *list,
+ unsigned short maxcols)
{
const alpm_list_t *i;
size_t len = 0;
@@ -612,20 +668,19 @@ void list_display(const char *title, const alpm_list_t *list)
if(!list) {
printf("%s\n", _("None"));
} else {
- const unsigned short maxcols = getcols();
size_t cols = len;
- const char *str = alpm_list_getdata(list);
- printf("%s", str);
+ const char *str = list->data;
+ fputs(str, stdout);
cols += string_length(str);
for(i = alpm_list_next(list); i; i = alpm_list_next(i)) {
- str = alpm_list_getdata(i);
+ str = i->data;
size_t s = string_length(str);
/* wrap only if we have enough usable column space */
if(maxcols > len && cols + s + 2 >= maxcols) {
size_t j;
cols = len;
printf("\n");
- for (j = 1; j <= len; j++) {
+ for(j = 1; j <= len; j++) {
printf(" ");
}
} else if(cols != len) {
@@ -633,19 +688,20 @@ void list_display(const char *title, const alpm_list_t *list)
printf(" ");
cols += 2;
}
- printf("%s", str);
+ fputs(str, stdout);
cols += s;
}
- printf("\n");
+ putchar('\n');
}
}
-void list_display_linebreak(const char *title, const alpm_list_t *list)
+void list_display_linebreak(const char *title, const alpm_list_t *list,
+ unsigned short maxcols)
{
- size_t len = 0;
+ unsigned short len = 0;
if(title) {
- len = string_length(title) + 1;
+ len = (unsigned short)string_length(title) + 1;
printf("%s ", title);
}
@@ -654,7 +710,7 @@ void list_display_linebreak(const char *title, const alpm_list_t *list)
} else {
const alpm_list_t *i;
/* Print the first element */
- indentprint((const char *) alpm_list_getdata(list), len);
+ indentprint((const char *)list->data, len, maxcols);
printf("\n");
/* Print the rest */
for(i = alpm_list_next(list); i; i = alpm_list_next(i)) {
@@ -662,18 +718,19 @@ void list_display_linebreak(const char *title, const alpm_list_t *list)
for(j = 1; j <= len; j++) {
printf(" ");
}
- indentprint((const char *) alpm_list_getdata(i), len);
+ indentprint((const char *)i->data, len, maxcols);
printf("\n");
}
}
}
-void signature_display(const char *title, alpm_siglist_t *siglist)
+void signature_display(const char *title, alpm_siglist_t *siglist,
+ unsigned short maxcols)
{
- size_t len = 0;
+ unsigned short len = 0;
if(title) {
- len = string_length(title) + 1;
+ len = (unsigned short)string_length(title) + 1;
printf("%s ", title);
}
if(siglist->count == 0) {
@@ -737,7 +794,7 @@ void signature_display(const char *title, alpm_siglist_t *siglist)
pm_printf(ALPM_LOG_ERROR, _("failed to allocate string\n"));
continue;
}
- indentprint(sigline, len);
+ indentprint(sigline, len, maxcols);
printf("\n");
free(sigline);
}
@@ -745,7 +802,7 @@ void signature_display(const char *title, alpm_siglist_t *siglist)
}
/* creates a header row for use with table_display */
-static alpm_list_t *create_verbose_header(int dl_size)
+static alpm_list_t *create_verbose_header(void)
{
alpm_list_t *res = NULL;
char *str;
@@ -758,16 +815,14 @@ static alpm_list_t *create_verbose_header(int dl_size)
res = alpm_list_add(res, str);
str = _("Net Change");
res = alpm_list_add(res, str);
- if(dl_size) {
- str = _("Download Size");
- res = alpm_list_add(res, str);
- }
+ str = _("Download Size");
+ res = alpm_list_add(res, str);
return res;
}
/* returns package info as list of strings */
-static alpm_list_t *create_verbose_row(pm_target_t *target, int dl_size)
+static alpm_list_t *create_verbose_row(pm_target_t *target)
{
char *str;
off_t size = 0;
@@ -777,7 +832,12 @@ static alpm_list_t *create_verbose_row(pm_target_t *target, int dl_size)
/* a row consists of the package name, */
if(target->install) {
- pm_asprintf(&str, "%s", alpm_pkg_get_name(target->install));
+ const alpm_db_t *db = alpm_pkg_get_db(target->install);
+ if(db) {
+ pm_asprintf(&str, "%s/%s", alpm_db_get_name(db), alpm_pkg_get_name(target->install));
+ } else {
+ pm_asprintf(&str, "%s", alpm_pkg_get_name(target->install));
+ }
} else {
pm_asprintf(&str, "%s", alpm_pkg_get_name(target->remove));
}
@@ -799,16 +859,14 @@ static alpm_list_t *create_verbose_row(pm_target_t *target, int dl_size)
pm_asprintf(&str, "%.2f %s", human_size, label);
ret = alpm_list_add(ret, str);
- if(dl_size) {
- size = target->install ? alpm_pkg_download_size(target->install) : 0;
+ size = target->install ? alpm_pkg_download_size(target->install) : 0;
+ if(size != 0) {
human_size = humanize_size(size, 'M', 2, &label);
- if(size != 0) {
- pm_asprintf(&str, "%.2f %s", human_size, label);
- } else {
- str = strdup("");
- }
- ret = alpm_list_add(ret, str);
+ pm_asprintf(&str, "%.2f %s", human_size, label);
+ } else {
+ str = NULL;
}
+ ret = alpm_list_add(ret, str);
return ret;
}
@@ -820,8 +878,8 @@ static void _display_targets(alpm_list_t *targets, int verbose)
const char *label;
double size;
off_t isize = 0, rsize = 0, dlsize = 0;
+ unsigned short cols;
alpm_list_t *i, *rows = NULL, *names = NULL;
- int show_dl_size = config->op == PM_OP_SYNC;
if(!targets) {
return;
@@ -829,7 +887,7 @@ static void _display_targets(alpm_list_t *targets, int verbose)
/* gather package info */
for(i = targets; i; i = alpm_list_next(i)) {
- pm_target_t *target = alpm_list_getdata(i);
+ pm_target_t *target = i->data;
if(target->install) {
dlsize += alpm_pkg_download_size(target->install);
@@ -845,7 +903,7 @@ static void _display_targets(alpm_list_t *targets, int verbose)
for(i = targets; i; i = alpm_list_next(i)) {
pm_target_t *target = i->data;
- rows = alpm_list_add(rows, create_verbose_row(target, show_dl_size));
+ rows = alpm_list_add(rows, create_verbose_row(target));
if(target->install) {
pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->install),
alpm_pkg_get_version(target->install));
@@ -860,24 +918,25 @@ static void _display_targets(alpm_list_t *targets, int verbose)
}
/* print to screen */
- pm_asprintf(&str, _("Targets (%d):"), alpm_list_count(targets));
-
+ pm_asprintf(&str, _("Packages (%d):"), alpm_list_count(targets));
printf("\n");
+
+ cols = getcols(fileno(stdout));
if(verbose) {
- alpm_list_t *header = create_verbose_header(show_dl_size);
- if(table_display(str, header, rows) != 0) {
+ alpm_list_t *header = create_verbose_header();
+ if(table_display(str, header, rows, cols) != 0) {
/* fallback to list display if table wouldn't fit */
- list_display(str, names);
+ list_display(str, names, cols);
}
alpm_list_free(header);
} else {
- list_display(str, names);
+ list_display(str, names, cols);
}
printf("\n");
/* rows is a list of lists of strings, free inner lists here */
for(i = rows; i; i = alpm_list_next(i)) {
- alpm_list_t *lp = alpm_list_getdata(i);
+ alpm_list_t *lp = i->data;
FREELIST(lp);
}
alpm_list_free(rows);
@@ -931,10 +990,10 @@ static int pkg_cmp(const void *p1, const void *p2)
void display_targets(void)
{
alpm_list_t *i, *targets = NULL;
- alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
+ alpm_db_t *db_local = alpm_get_localdb(config->handle);
for(i = alpm_trans_get_add(config->handle); i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ alpm_pkg_t *pkg = i->data;
pm_target_t *targ = calloc(1, sizeof(pm_target_t));
if(!targ) return;
targ->install = pkg;
@@ -945,7 +1004,7 @@ void display_targets(void)
targets = alpm_list_add(targets, targ);
}
for(i = alpm_trans_get_remove(config->handle); i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ alpm_pkg_t *pkg = i->data;
pm_target_t *targ = calloc(1, sizeof(pm_target_t));
if(!targ) return;
targ->remove = pkg;
@@ -980,7 +1039,7 @@ static char *pkg_get_location(alpm_pkg_t *pkg)
case PM_OP_SYNC:
servers = alpm_db_get_servers(alpm_pkg_get_db(pkg));
if(servers) {
- pm_asprintf(&string, "%s/%s", alpm_list_getdata(servers),
+ pm_asprintf(&string, "%s/%s", servers->data,
alpm_pkg_get_filename(pkg));
return string;
}
@@ -1054,7 +1113,7 @@ void print_packages(const alpm_list_t *packages)
config->print_format = strdup("%l");
}
for(i = packages; i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ alpm_pkg_t *pkg = i->data;
char *string = strdup(config->print_format);
char *temp = string;
/* %n : pkgname */
@@ -1096,46 +1155,104 @@ void print_packages(const alpm_list_t *packages)
free(size);
free(temp);
}
- printf("%s\n",string);
+ printf("%s\n", string);
free(string);
}
}
-/* Helper function for comparing strings using the
- * alpm "compare func" signature */
-int str_cmp(const void *s1, const void *s2)
+/**
+ * Helper function for comparing depends using the alpm "compare func"
+ * signature. The function descends through the structure in the following
+ * comparison order: name, modifier (e.g., '>', '='), version, description.
+ * @param d1 the first depend structure
+ * @param d2 the second depend structure
+ * @return -1, 0, or 1 if first is <, ==, or > second
+ */
+static int depend_cmp(const void *d1, const void *d2)
{
- return strcmp(s1, s2);
+ const alpm_depend_t *dep1 = d1;
+ const alpm_depend_t *dep2 = d2;
+ int ret;
+
+ ret = strcmp(dep1->name, dep2->name);
+ if(ret == 0) {
+ ret = dep1->mod - dep2->mod;
+ }
+ if(ret == 0) {
+ if(dep1->version && dep2->version) {
+ ret = strcmp(dep1->version, dep2->version);
+ } else if(!dep1->version && dep2->version) {
+ ret = -1;
+ } else if(dep1->version && !dep2->version) {
+ ret = 1;
+ }
+ }
+ if(ret == 0) {
+ if(dep1->desc && dep2->desc) {
+ ret = strcmp(dep1->desc, dep2->desc);
+ } else if(!dep1->desc && dep2->desc) {
+ ret = -1;
+ } else if(dep1->desc && !dep2->desc) {
+ ret = 1;
+ }
+ }
+
+ return ret;
}
void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg)
{
- alpm_list_t *old = alpm_pkg_get_optdepends(oldpkg);
- alpm_list_t *new = alpm_pkg_get_optdepends(newpkg);
- alpm_list_t *optdeps = alpm_list_diff(new,old,str_cmp);
- if(optdeps) {
+ alpm_list_t *i, *old, *new, *optdeps, *optstrings = NULL;
+
+ old = alpm_pkg_get_optdepends(oldpkg);
+ new = alpm_pkg_get_optdepends(newpkg);
+ optdeps = alpm_list_diff(new, old, depend_cmp);
+
+ /* turn optdepends list into a text list */
+ for(i = optdeps; i; i = alpm_list_next(i)) {
+ alpm_depend_t *optdep = i->data;
+ optstrings = alpm_list_add(optstrings, alpm_dep_compute_string(optdep));
+ }
+
+ if(optstrings) {
printf(_("New optional dependencies for %s\n"), alpm_pkg_get_name(newpkg));
- list_display_linebreak(" ", optdeps);
+ unsigned short cols = getcols(fileno(stdout));
+ list_display_linebreak(" ", optstrings, cols);
}
+
alpm_list_free(optdeps);
+ FREELIST(optstrings);
}
void display_optdepends(alpm_pkg_t *pkg)
{
- alpm_list_t *optdeps = alpm_pkg_get_optdepends(pkg);
- if(optdeps) {
+ alpm_list_t *i, *optdeps, *optstrings = NULL;
+
+ optdeps = alpm_pkg_get_optdepends(pkg);
+
+ /* turn optdepends list into a text list */
+ for(i = optdeps; i; i = alpm_list_next(i)) {
+ alpm_depend_t *optdep = i->data;
+ optstrings = alpm_list_add(optstrings, alpm_dep_compute_string(optdep));
+ }
+
+ if(optstrings) {
printf(_("Optional dependencies for %s\n"), alpm_pkg_get_name(pkg));
- list_display_linebreak(" ", optdeps);
+ unsigned short cols = getcols(fileno(stdout));
+ list_display_linebreak(" ", optstrings, cols);
}
+
+ FREELIST(optstrings);
}
-static void display_repo_list(const char *dbname, alpm_list_t *list)
+static void display_repo_list(const char *dbname, alpm_list_t *list,
+ unsigned short cols)
{
const char *prefix= " ";
printf(":: ");
printf(_("Repository %s\n"), dbname);
- list_display(prefix, list);
+ list_display(prefix, list, cols);
}
void select_display(const alpm_list_t *pkglist)
@@ -1145,15 +1262,16 @@ void select_display(const alpm_list_t *pkglist)
alpm_list_t *list = NULL;
char *string = NULL;
const char *dbname = NULL;
+ unsigned short cols = getcols(fileno(stdout));
- for (i = pkglist; i; i = i->next) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ for(i = pkglist; i; i = i->next) {
+ alpm_pkg_t *pkg = i->data;
alpm_db_t *db = alpm_pkg_get_db(pkg);
if(!dbname)
dbname = alpm_db_get_name(db);
if(strcmp(alpm_db_get_name(db), dbname) != 0) {
- display_repo_list(dbname, list);
+ display_repo_list(dbname, list, cols);
FREELIST(list);
dbname = alpm_db_get_name(db);
}
@@ -1162,7 +1280,7 @@ void select_display(const alpm_list_t *pkglist)
list = alpm_list_add(list, string);
nth++;
}
- display_repo_list(dbname, list);
+ display_repo_list(dbname, list, cols);
FREELIST(list);
}
@@ -1189,17 +1307,17 @@ static int multiselect_parse(char *array, int count, char *response)
{
char *str, *saveptr;
- for (str = response; ; str = NULL) {
+ for(str = response; ; str = NULL) {
int include = 1;
int start, end;
+ size_t len;
char *ends = NULL;
- char *starts = strtok_r(str, " ", &saveptr);
+ char *starts = strtok_r(str, " ,", &saveptr);
if(starts == NULL) {
break;
}
- strtrim(starts);
- int len = strlen(starts);
+ len = strtrim(starts);
if(len == 0)
continue;
@@ -1274,10 +1392,11 @@ int multiselect_question(char *array, int count)
break;
}
- flush_term_input();
+ flush_term_input(fileno(stdin));
if(fgets(response, response_len, stdin)) {
const size_t response_incr = 64;
+ size_t len;
/* handle buffer not being large enough to read full line case */
while(*lastchar == '\0' && lastchar[-1] != '\n') {
response_len += response_incr;
@@ -1294,8 +1413,9 @@ int multiselect_question(char *array, int count)
return -1;
}
}
- strtrim(response);
- if(strlen(response) > 0) {
+
+ len = strtrim(response);
+ if(len > 0) {
if(multiselect_parse(array, count, response) == -1) {
/* only loop if user gave an invalid answer */
continue;
@@ -1335,11 +1455,11 @@ int select_question(int count)
break;
}
- flush_term_input();
+ flush_term_input(fileno(stdin));
if(fgets(response, sizeof(response), stdin)) {
- strtrim(response);
- if(strlen(response) > 0) {
+ size_t len = strtrim(response);
+ if(len > 0) {
int n;
if(parseindex(response, &n, 1, count) != 0)
continue;
@@ -1358,6 +1478,7 @@ static int question(short preset, char *fmt, va_list args)
{
char response[32];
FILE *stream;
+ int fd_in = fileno(stdin);
if(config->noconfirm) {
stream = stdout;
@@ -1384,17 +1505,17 @@ static int question(short preset, char *fmt, va_list args)
}
fflush(stream);
- flush_term_input();
+ flush_term_input(fd_in);
if(fgets(response, sizeof(response), stdin)) {
- strtrim(response);
- if(strlen(response) == 0) {
+ size_t len = strtrim(response);
+ if(len == 0) {
return preset;
}
/* if stdin is piped, response does not get printed out, and as a result
* a \n is missing, resulting in broken output (FS#27909) */
- if(!isatty(fileno(stdin))) {
+ if(!isatty(fd_in)) {
fprintf(stream, "%s\n", response);
}
diff --git a/src/pacman/util.h b/src/pacman/util.h
index 5ccd480a..0dfdc851 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -36,9 +36,6 @@
#define _n(str1, str2, ct) (ct == 1 ? str1 : str2)
#endif
-/* update speed for the fill_progress based functions */
-#define UPDATE_SPEED_SEC 0.2f
-
typedef struct _pm_target_t {
alpm_pkg_t *remove;
alpm_pkg_t *install;
@@ -50,21 +47,23 @@ int trans_init(alpm_transflag_t flags, int check_valid);
int trans_release(void);
int needs_root(void);
int check_syncdbs(size_t need_repos, int check_valid);
-unsigned short getcols(void);
+unsigned short getcols(int fd);
int rmrf(const char *path);
const char *mbasename(const char *path);
char *mdirname(const char *path);
-void indentprint(const char *str, size_t indent);
-char *strtrim(char *str);
+void indentprint(const char *str, unsigned short indent, unsigned short cols);
+size_t strtrim(char *str);
char *strreplace(const char *str, const char *needle, const char *replace);
alpm_list_t *strsplit(const char *str, const char splitchar);
-void string_display(const char *title, const char *string);
+void string_display(const char *title, const char *string, unsigned short cols);
double humanize_size(off_t bytes, const char target_unit, int precision,
const char **label);
-int table_display(const char *title, const alpm_list_t *header, const alpm_list_t *rows);
-void list_display(const char *title, const alpm_list_t *list);
-void list_display_linebreak(const char *title, const alpm_list_t *list);
-void signature_display(const char *title, alpm_siglist_t *siglist);
+void list_display(const char *title, const alpm_list_t *list,
+ unsigned short maxcols);
+void list_display_linebreak(const char *title, const alpm_list_t *list,
+ unsigned short maxcols);
+void signature_display(const char *title, alpm_siglist_t *siglist,
+ unsigned short maxcols);
void display_targets(void);
int str_cmp(const void *s1, const void *s2);
void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg);