summaryrefslogtreecommitdiff
path: root/src/pacman
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman')
-rw-r--r--src/pacman/Makefile.am2
-rw-r--r--src/pacman/callback.c55
-rw-r--r--src/pacman/conf.c632
-rw-r--r--src/pacman/conf.h15
-rw-r--r--src/pacman/database.c11
-rw-r--r--src/pacman/deptest.c8
-rw-r--r--src/pacman/package.c77
-rw-r--r--src/pacman/package.h10
-rw-r--r--src/pacman/pacman.c651
-rw-r--r--src/pacman/pacman.h5
-rw-r--r--src/pacman/query.c84
-rw-r--r--src/pacman/remove.c16
-rw-r--r--src/pacman/sync.c135
-rw-r--r--src/pacman/upgrade.c25
-rw-r--r--src/pacman/util.c424
-rw-r--r--src/pacman/util.h2
16 files changed, 1231 insertions, 921 deletions
diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am
index 31e8b134..333b8193 100644
--- a/src/pacman/Makefile.am
+++ b/src/pacman/Makefile.am
@@ -1,6 +1,7 @@
# paths set at make time
conffile = ${sysconfdir}/pacman.conf
dbpath = ${localstatedir}/lib/pacman/
+gpgdir = ${sysconfdir}/pacman.d/gnupg/
cachedir = ${localstatedir}/cache/pacman/pkg/
logfile = ${localstatedir}/log/pacman.log
@@ -10,6 +11,7 @@ DEFS = -DLOCALEDIR=\"@localedir@\" \
-DCONFFILE=\"$(conffile)\" \
-DROOTDIR=\"$(ROOTDIR)\" \
-DDBPATH=\"$(dbpath)\" \
+ -DGPGDIR=\"$(gpgdir)\" \
-DCACHEDIR=\"$(cachedir)\" \
-DLOGFILE=\"$(logfile)\" \
@DEFS@
diff --git a/src/pacman/callback.c b/src/pacman/callback.c
index 5edcc966..d3dc7440 100644
--- a/src/pacman/callback.c
+++ b/src/pacman/callback.c
@@ -81,7 +81,7 @@ static double get_update_timediff(int first_call)
}
}
- return(retval);
+ return retval;
}
/* refactored from cb_trans_progress */
@@ -224,10 +224,10 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)
printf(_("failed.\n"));
break;
case PM_TRANS_EVT_SCRIPTLET_INFO:
- printf("%s", (char*)data1);
+ printf("%s", (char *)data1);
break;
case PM_TRANS_EVT_RETRIEVE_START:
- printf(_(":: Retrieving packages from %s...\n"), (char*)data1);
+ printf(_(":: Retrieving packages from %s...\n"), (char *)data1);
break;
case PM_TRANS_EVT_DISKSPACE_START:
if(config->noprogressbar) {
@@ -398,7 +398,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,
}
infolen = getcols() * 6 / 10;
- if (infolen < 50) {
+ if(infolen < 50) {
infolen = 50;
}
@@ -492,10 +492,11 @@ 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, f_xfered = 0.0;
+ double rate = 0.0, timediff = 0.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;
- char rate_size = 'K', xfered_size = 'K';
if(config->noprogressbar || file_total == -1) {
if(file_xfered == 0) {
@@ -506,7 +507,7 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
}
infolen = getcols() * 6 / 10;
- if (infolen < 50) {
+ if(infolen < 50) {
infolen = 50;
}
/* explanation of magic 28 number at the end */
@@ -557,7 +558,7 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
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);
- rate = xfered / (timediff * 1024.0);
+ rate = xfered / timediff;
/* round elapsed time to the nearest second */
eta_s = (int)(timediff + 0.5);
@@ -569,10 +570,10 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
/* return if the calling interval was too short */
return;
}
- rate = (xfered - xfered_last) / (timediff * 1024.0);
+ rate = (xfered - xfered_last) / timediff;
/* average rate to reduce jumpiness */
rate = (rate + 2 * rate_last) / 3;
- eta_s = (total - xfered) / (rate * 1024.0);
+ eta_s = (total - xfered) / rate;
rate_last = rate;
xfered_last = xfered;
}
@@ -626,37 +627,13 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
}
- /* Awesome formatting for progress bar. We need a mess of Kb->Mb->Gb stuff
- * here. We'll use limit of 2048 for each until we get some empirical */
- /* rate_size = 'K'; was set above */
- if(rate > 2048.0) {
- rate /= 1024.0;
- rate_size = 'M';
- if(rate > 2048.0) {
- rate /= 1024.0;
- rate_size = 'G';
- /* we should not go higher than this for a few years (9999.9 Gb/s?)*/
- }
- }
-
- f_xfered = xfered / 1024.0; /* convert to K by default */
- /* xfered_size = 'K'; was set above */
- if(f_xfered > 2048.0) {
- f_xfered /= 1024.0;
- xfered_size = 'M';
- if(f_xfered > 2048.0) {
- f_xfered /= 1024.0;
- xfered_size = 'G';
- /* I should seriously hope that archlinux packages never break
- * the 9999.9GB mark... we'd have more serious problems than the progress
- * bar in pacman */
- }
- }
+ rate_human = humanize_size((off_t)rate, '\0', 0, &rate_label);
+ xfered_human = humanize_size(xfered, '\0', 0, &xfered_label);
/* 1 space + filenamelen + 1 space + 7 for size + 1 + 7 for rate + 2 for /s + 1 space + 8 for eta */
- printf(" %ls%-*s %6.1f%c %#6.1f%c/s %02u:%02u:%02u", wcfname,
- padwid, "", f_xfered, xfered_size,
- rate, rate_size, eta_h, eta_m, eta_s);
+ printf(" %ls%-*s %6.1f%s %#6.1f%s/s %02u:%02u:%02u", wcfname,
+ padwid, "", xfered_human, xfered_label, rate_human, rate_label,
+ eta_h, eta_m, eta_s);
free(fname);
free(wcfname);
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index e2a168ee..370ec510 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -20,13 +20,20 @@
#include "config.h"
+#include <errno.h>
+#include <glob.h>
+#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h> /* strdup */
+#include <sys/stat.h>
+#include <sys/utsname.h> /* uname */
+#include <unistd.h>
/* pacman */
#include "conf.h"
#include "util.h"
+#include "pacman.h"
/* global config variable */
config_t *config = NULL;
@@ -38,7 +45,7 @@ config_t *config_new(void)
pm_fprintf(stderr, PM_LOG_ERROR,
_("malloc failure: could not allocate %zd bytes\n"),
sizeof(config_t));
- return(NULL);
+ return NULL;
}
/* defaults which may get overridden later */
newconfig->op = PM_OP_MAIN;
@@ -46,13 +53,13 @@ config_t *config_new(void)
/* CONFFILE is defined at compile-time */
newconfig->configfile = strdup(CONFFILE);
- return(newconfig);
+ return newconfig;
}
int config_free(config_t *oldconfig)
{
if(oldconfig == NULL) {
- return(-1);
+ return -1;
}
FREELIST(oldconfig->holdpkg);
@@ -66,7 +73,624 @@ int config_free(config_t *oldconfig)
free(oldconfig);
oldconfig = NULL;
- return(0);
+ return 0;
+}
+
+/** Helper function for download_with_xfercommand() */
+static char *get_filename(const char *url) {
+ char *filename = strrchr(url, '/');
+ if(filename != NULL) {
+ filename++;
+ }
+ return filename;
+}
+
+/** Helper function for download_with_xfercommand() */
+static char *get_destfile(const char *path, const char *filename) {
+ char *destfile;
+ /* len = localpath len + filename len + null */
+ size_t len = strlen(path) + strlen(filename) + 1;
+ destfile = calloc(len, sizeof(char));
+ snprintf(destfile, len, "%s%s", path, filename);
+
+ return destfile;
+}
+
+/** Helper function for download_with_xfercommand() */
+static char *get_tempfile(const char *path, const char *filename) {
+ char *tempfile;
+ /* len = localpath len + filename len + '.part' len + null */
+ size_t len = strlen(path) + strlen(filename) + 6;
+ tempfile = calloc(len, sizeof(char));
+ snprintf(tempfile, len, "%s%s.part", path, filename);
+
+ return tempfile;
+}
+
+/** External fetch callback */
+static int download_with_xfercommand(const char *url, const char *localpath,
+ int force) {
+ int ret = 0;
+ int retval;
+ int usepart = 0;
+ struct stat st;
+ char *parsedcmd,*tempcmd;
+ char cwd[PATH_MAX];
+ int restore_cwd = 0;
+ char *destfile, *tempfile, *filename;
+
+ if(!config->xfercommand) {
+ return -1;
+ }
+
+ filename = get_filename(url);
+ if(!filename) {
+ return -1;
+ }
+ destfile = get_destfile(localpath, filename);
+ tempfile = get_tempfile(localpath, filename);
+
+ if(force && stat(tempfile, &st) == 0) {
+ unlink(tempfile);
+ }
+ if(force && stat(destfile, &st) == 0) {
+ unlink(destfile);
+ }
+
+ tempcmd = strdup(config->xfercommand);
+ /* replace all occurrences of %o with fn.part */
+ if(strstr(tempcmd, "%o")) {
+ usepart = 1;
+ parsedcmd = strreplace(tempcmd, "%o", tempfile);
+ free(tempcmd);
+ tempcmd = parsedcmd;
+ }
+ /* replace all occurrences of %u with the download URL */
+ parsedcmd = strreplace(tempcmd, "%u", url);
+ free(tempcmd);
+
+ /* save the cwd so we can restore it later */
+ if(getcwd(cwd, PATH_MAX) == NULL) {
+ pm_printf(PM_LOG_ERROR, _("could not get current working directory\n"));
+ } else {
+ restore_cwd = 1;
+ }
+
+ /* cwd to the download directory */
+ if(chdir(localpath)) {
+ pm_printf(PM_LOG_WARNING, _("could not chdir to download directory %s\n"), localpath);
+ ret = -1;
+ goto cleanup;
+ }
+ /* execute the parsed command via /bin/sh -c */
+ pm_printf(PM_LOG_DEBUG, "running command: %s\n", parsedcmd);
+ retval = system(parsedcmd);
+
+ if(retval == -1) {
+ pm_printf(PM_LOG_WARNING, _("running XferCommand: fork failed!\n"));
+ ret = -1;
+ } else if(retval != 0) {
+ /* download failed */
+ pm_printf(PM_LOG_DEBUG, "XferCommand command returned non-zero status "
+ "code (%d)\n", retval);
+ ret = -1;
+ } else {
+ /* download was successful */
+ if(usepart) {
+ rename(tempfile, destfile);
+ }
+ ret = 0;
+ }
+
+cleanup:
+ /* restore the old cwd if we have it */
+ if(restore_cwd && chdir(cwd) != 0) {
+ pm_printf(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
+ cwd, strerror(errno));
+ }
+
+ if(ret == -1) {
+ /* hack to let an user the time to cancel a download */
+ sleep(2);
+ }
+ free(destfile);
+ free(tempfile);
+ free(parsedcmd);
+
+ return ret;
+}
+
+
+int config_set_arch(const char *arch)
+{
+ if(strcmp(arch, "auto") == 0) {
+ struct utsname un;
+ uname(&un);
+ pm_printf(PM_LOG_DEBUG, "config: Architecture: %s\n", un.machine);
+ return alpm_option_set_arch(un.machine);
+ } else {
+ pm_printf(PM_LOG_DEBUG, "config: Architecture: %s\n", arch);
+ return alpm_option_set_arch(arch);
+ }
+}
+
+static pgp_verify_t option_verifysig(const char *value)
+{
+ pgp_verify_t level;
+ if(strcmp(value, "Always") == 0) {
+ level = PM_PGP_VERIFY_ALWAYS;
+ } else if(strcmp(value, "Optional") == 0) {
+ level = PM_PGP_VERIFY_OPTIONAL;
+ } else if(strcmp(value, "Never") == 0) {
+ level = PM_PGP_VERIFY_NEVER;
+ } else {
+ level = PM_PGP_VERIFY_UNKNOWN;
+ }
+ pm_printf(PM_LOG_DEBUG, "config: VerifySig = %s (%d)\n", value, level);
+ return level;
+}
+
+/* helper for being used with setrepeatingoption */
+static int option_add_holdpkg(const char *name) {
+ config->holdpkg = alpm_list_add(config->holdpkg, strdup(name));
+ return 0;
+}
+
+/* helper for being used with setrepeatingoption */
+static int option_add_syncfirst(const char *name) {
+ config->syncfirst = alpm_list_add(config->syncfirst, strdup(name));
+ return 0;
+}
+
+/* helper for being used with setrepeatingoption */
+static int option_add_cleanmethod(const char *value) {
+ if(strcmp(value, "KeepInstalled") == 0) {
+ config->cleanmethod |= PM_CLEAN_KEEPINST;
+ } else if(strcmp(value, "KeepCurrent") == 0) {
+ config->cleanmethod |= PM_CLEAN_KEEPCUR;
+ } else {
+ pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"),
+ value);
+ }
+ return 0;
+}
+
+/** Add repeating options such as NoExtract, NoUpgrade, etc to libalpm
+ * settings. Refactored out of the parseconfig code since all of them did
+ * the exact same thing and duplicated code.
+ * @param ptr a pointer to the start of the multiple options
+ * @param option the string (friendly) name of the option, used for messages
+ * @param optionfunc a function pointer to an alpm_option_add_* function
+ */
+static void setrepeatingoption(char *ptr, const char *option,
+ int (*optionfunc)(const char *))
+{
+ char *q;
+
+ while((q = strchr(ptr, ' '))) {
+ *q = '\0';
+ (*optionfunc)(ptr);
+ pm_printf(PM_LOG_DEBUG, "config: %s: %s\n", option, ptr);
+ ptr = q;
+ ptr++;
+ }
+ (*optionfunc)(ptr);
+ pm_printf(PM_LOG_DEBUG, "config: %s: %s\n", option, ptr);
+}
+
+static int _parse_options(const char *key, char *value,
+ const char *file, int linenum)
+{
+ if(value == NULL) {
+ /* options without settings */
+ if(strcmp(key, "UseSyslog") == 0) {
+ alpm_option_set_usesyslog(1);
+ pm_printf(PM_LOG_DEBUG, "config: usesyslog\n");
+ } else if(strcmp(key, "ILoveCandy") == 0) {
+ config->chomp = 1;
+ pm_printf(PM_LOG_DEBUG, "config: chomp\n");
+ } else if(strcmp(key, "VerbosePkgLists") == 0) {
+ config->verbosepkglists = 1;
+ pm_printf(PM_LOG_DEBUG, "config: verbosepkglists\n");
+ } else if(strcmp(key, "UseDelta") == 0) {
+ alpm_option_set_usedelta(1);
+ pm_printf(PM_LOG_DEBUG, "config: usedelta\n");
+ } else if(strcmp(key, "TotalDownload") == 0) {
+ config->totaldownload = 1;
+ pm_printf(PM_LOG_DEBUG, "config: totaldownload\n");
+ } else if(strcmp(key, "CheckSpace") == 0) {
+ alpm_option_set_checkspace(1);
+ } else {
+ pm_printf(PM_LOG_WARNING,
+ _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
+ file, linenum, key, "options");
+ }
+ } else {
+ /* options with settings */
+ if(strcmp(key, "NoUpgrade") == 0) {
+ setrepeatingoption(value, "NoUpgrade", alpm_option_add_noupgrade);
+ } else if(strcmp(key, "NoExtract") == 0) {
+ setrepeatingoption(value, "NoExtract", alpm_option_add_noextract);
+ } else if(strcmp(key, "IgnorePkg") == 0) {
+ setrepeatingoption(value, "IgnorePkg", alpm_option_add_ignorepkg);
+ } else if(strcmp(key, "IgnoreGroup") == 0) {
+ setrepeatingoption(value, "IgnoreGroup", alpm_option_add_ignoregrp);
+ } else if(strcmp(key, "HoldPkg") == 0) {
+ setrepeatingoption(value, "HoldPkg", option_add_holdpkg);
+ } else if(strcmp(key, "SyncFirst") == 0) {
+ setrepeatingoption(value, "SyncFirst", option_add_syncfirst);
+ } else if(strcmp(key, "Architecture") == 0) {
+ if(!alpm_option_get_arch()) {
+ config_set_arch(value);
+ }
+ } else if(strcmp(key, "DBPath") == 0) {
+ /* don't overwrite a path specified on the command line */
+ if(!config->dbpath) {
+ config->dbpath = strdup(value);
+ pm_printf(PM_LOG_DEBUG, "config: dbpath: %s\n", value);
+ }
+ } else if(strcmp(key, "CacheDir") == 0) {
+ if(alpm_option_add_cachedir(value) != 0) {
+ pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"),
+ value, alpm_strerrorlast());
+ return 1;
+ }
+ pm_printf(PM_LOG_DEBUG, "config: cachedir: %s\n", value);
+ } else if(strcmp(key, "RootDir") == 0) {
+ /* don't overwrite a path specified on the command line */
+ if(!config->rootdir) {
+ config->rootdir = strdup(value);
+ pm_printf(PM_LOG_DEBUG, "config: rootdir: %s\n", value);
+ }
+ } else if(strcmp(key, "GPGDir") == 0) {
+ if(!config->gpgdir) {
+ config->gpgdir = strdup(value);
+ pm_printf(PM_LOG_DEBUG, "config: gpgdir: %s\n", value);
+ }
+ } else if(strcmp(key, "LogFile") == 0) {
+ if(!config->logfile) {
+ config->logfile = strdup(value);
+ pm_printf(PM_LOG_DEBUG, "config: logfile: %s\n", value);
+ }
+ } else if(strcmp(key, "XferCommand") == 0) {
+ config->xfercommand = strdup(value);
+ alpm_option_set_fetchcb(download_with_xfercommand);
+ pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", value);
+ } else if(strcmp(key, "CleanMethod") == 0) {
+ setrepeatingoption(value, "CleanMethod", option_add_cleanmethod);
+ } else if(strcmp(key, "VerifySig") == 0) {
+ pgp_verify_t level = option_verifysig(value);
+ if(level != PM_PGP_VERIFY_UNKNOWN) {
+ alpm_option_set_default_sigverify(level);
+ } else {
+ pm_printf(PM_LOG_ERROR,
+ _("config file %s, line %d: directive '%s' has invalid value '%s'\n"),
+ file, linenum, key, value);
+ return 1;
+ }
+ } else {
+ pm_printf(PM_LOG_WARNING,
+ _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
+ file, linenum, key, "options");
+ }
+
+ }
+ return 0;
+}
+
+static int _add_mirror(pmdb_t *db, char *value)
+{
+ const char *dbname = alpm_db_get_name(db);
+ /* let's attempt a replacement for the current repo */
+ char *temp = strreplace(value, "$repo", dbname);
+ /* let's attempt a replacement for the arch */
+ const char *arch = alpm_option_get_arch();
+ char *server;
+ if(arch) {
+ server = strreplace(temp, "$arch", arch);
+ free(temp);
+ } else {
+ if(strstr(temp, "$arch")) {
+ free(temp);
+ pm_printf(PM_LOG_ERROR, _("The mirror '%s' contains the $arch"
+ " variable, but no Architecture is defined.\n"), value);
+ return 1;
+ }
+ server = temp;
+ }
+
+ if(alpm_db_add_server(db, server) != 0) {
+ /* pm_errno is set by alpm_db_setserver */
+ pm_printf(PM_LOG_ERROR, _("could not add server URL to database '%s': %s (%s)\n"),
+ dbname, server, alpm_strerrorlast());
+ free(server);
+ return 1;
+ }
+
+ free(server);
+ return 0;
+}
+
+/** Sets all libalpm required paths in one go. Called after the command line
+ * and inital config file parsing. Once this is complete, we can see if any
+ * paths were defined. If a rootdir was defined and nothing else, we want all
+ * of our paths to live under the rootdir that was specified. Safe to call
+ * multiple times (will only do anything the first time).
+ */
+static int setlibpaths(void)
+{
+ int ret = 0;
+
+ pm_printf(PM_LOG_DEBUG, "setlibpaths() called\n");
+ /* Configure root path first. If it is set and dbpath/logfile were not
+ * set, then set those as well to reside under the root. */
+ if(config->rootdir) {
+ char path[PATH_MAX];
+ ret = alpm_option_set_root(config->rootdir);
+ if(ret != 0) {
+ pm_printf(PM_LOG_ERROR, _("problem setting rootdir '%s' (%s)\n"),
+ config->rootdir, alpm_strerrorlast());
+ return ret;
+ }
+ if(!config->dbpath) {
+ /* omit leading slash from our static DBPATH, root handles it */
+ snprintf(path, PATH_MAX, "%s%s", alpm_option_get_root(), DBPATH + 1);
+ config->dbpath = strdup(path);
+ }
+ if(!config->logfile) {
+ /* omit leading slash from our static LOGFILE path, root handles it */
+ snprintf(path, PATH_MAX, "%s%s", alpm_option_get_root(), LOGFILE + 1);
+ config->logfile = strdup(path);
+ }
+ }
+ /* Set other paths if they were configured. Note that unless rootdir
+ * was left undefined, these two paths (dbpath and logfile) will have
+ * been set locally above, so the if cases below will now trigger. */
+ if(config->dbpath) {
+ ret = alpm_option_set_dbpath(config->dbpath);
+ if(ret != 0) {
+ pm_printf(PM_LOG_ERROR, _("problem setting dbpath '%s' (%s)\n"),
+ config->dbpath, alpm_strerrorlast());
+ return ret;
+ }
+ }
+ if(config->logfile) {
+ ret = alpm_option_set_logfile(config->logfile);
+ if(ret != 0) {
+ pm_printf(PM_LOG_ERROR, _("problem setting logfile '%s' (%s)\n"),
+ config->logfile, alpm_strerrorlast());
+ return ret;
+ }
+ }
+
+ /* Set GnuPG's home directory. This is not relative to rootdir, even if
+ * rootdir is defined. Reasoning: gpgdir contains configuration data. */
+ if(config->gpgdir) {
+ ret = alpm_option_set_signaturedir(config->gpgdir);
+ if(ret != 0) {
+ pm_printf(PM_LOG_ERROR, _("problem setting gpgdir '%s' (%s)\n"),
+ config->gpgdir, alpm_strerrorlast());
+ return ret;
+ }
+ }
+
+ /* add a default cachedir if one wasn't specified */
+ if(alpm_option_get_cachedirs() == NULL) {
+ alpm_option_add_cachedir(CACHEDIR);
+ }
+ return 0;
+}
+
+
+/* The real parseconfig. Called with a null section argument by the publicly
+ * visible parseconfig so we can recall from within ourself on an include */
+static int _parseconfig(const char *file, int parse_options,
+ char **section, pmdb_t *db)
+{
+ FILE *fp = NULL;
+ char line[PATH_MAX+1];
+ int linenum = 0;
+ char *ptr;
+ int ret = 0;
+
+ pm_printf(PM_LOG_DEBUG, "config: attempting to read file %s\n", file);
+ fp = fopen(file, "r");
+ if(fp == NULL) {
+ pm_printf(PM_LOG_ERROR, _("config file %s could not be read.\n"), file);
+ return 1;
+ }
+
+ while(fgets(line, PATH_MAX, fp)) {
+ char *key, *value;
+
+ linenum++;
+ strtrim(line);
+
+ /* ignore whole line and end of line comments */
+ if(strlen(line) == 0 || line[0] == '#') {
+ continue;
+ }
+ if((ptr = strchr(line, '#'))) {
+ *ptr = '\0';
+ }
+
+ /* sanity check */
+ if(parse_options && db) {
+ pm_printf(PM_LOG_ERROR, _("config file %s, line %d: parsing options but have a database.\n"),
+ file, linenum);
+ ret = 1;
+ goto cleanup;
+ }
+
+ if(line[0] == '[' && line[strlen(line)-1] == ']') {
+ char *name;
+ /* new config section, skip the '[' */
+ ptr = line;
+ ptr++;
+ name = strdup(ptr);
+ name[strlen(name)-1] = '\0';
+ if(!strlen(name)) {
+ pm_printf(PM_LOG_ERROR, _("config file %s, line %d: bad section name.\n"),
+ file, linenum);
+ ret = 1;
+ goto cleanup;
+ }
+ pm_printf(PM_LOG_DEBUG, "config: new section '%s'\n", name);
+ /* if we are not looking at the options section, register a db */
+ if(!parse_options && strcmp(name, "options") != 0) {
+ db = alpm_db_register_sync(name);
+ if(db == NULL) {
+ pm_printf(PM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
+ name, alpm_strerrorlast());
+ ret = 1;
+ goto cleanup;
+ }
+ }
+ if(*section) {
+ free(*section);
+ }
+ *section = name;
+ continue;
+ }
+
+ /* directive */
+ /* strsep modifies the 'line' string: 'key \0 value' */
+ key = line;
+ value = line;
+ strsep(&value, "=");
+ strtrim(key);
+ strtrim(value);
+
+ if(key == NULL) {
+ pm_printf(PM_LOG_ERROR, _("config file %s, line %d: syntax error in config file- missing key.\n"),
+ file, linenum);
+ ret = 1;
+ goto cleanup;
+ }
+ /* For each directive, compare to the camelcase string. */
+ if(*section == NULL) {
+ pm_printf(PM_LOG_ERROR, _("config file %s, line %d: All directives must belong to a section.\n"),
+ file, linenum);
+ ret = 1;
+ goto cleanup;
+ }
+ /* Include is allowed in both options and repo sections */
+ if(strcmp(key, "Include") == 0) {
+ glob_t globbuf;
+ int globret;
+ size_t gindex;
+
+ if(value == NULL) {
+ pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"),
+ file, linenum, key);
+ ret = 1;
+ goto cleanup;
+ }
+ /* Ignore include failures... assume non-critical */
+ globret = glob(value, GLOB_NOCHECK, NULL, &globbuf);
+ switch(globret) {
+ case GLOB_NOSPACE:
+ pm_printf(PM_LOG_DEBUG,
+ "config file %s, line %d: include globbing out of space\n",
+ file, linenum);
+ break;
+ case GLOB_ABORTED:
+ pm_printf(PM_LOG_DEBUG,
+ "config file %s, line %d: include globbing read error for %s\n",
+ file, linenum, value);
+ break;
+ case GLOB_NOMATCH:
+ pm_printf(PM_LOG_DEBUG,
+ "config file %s, line %d: no include found for %s\n",
+ file, linenum, value);
+ break;
+ default:
+ for(gindex = 0; gindex < globbuf.gl_pathc; gindex++) {
+ pm_printf(PM_LOG_DEBUG, "config file %s, line %d: including %s\n",
+ file, linenum, globbuf.gl_pathv[gindex]);
+ _parseconfig(globbuf.gl_pathv[gindex], parse_options, section, db);
+ }
+ break;
+ }
+ globfree(&globbuf);
+ continue;
+ }
+ if(parse_options && strcmp(*section, "options") == 0) {
+ /* we are either in options ... */
+ if((ret = _parse_options(key, value, file, linenum)) != 0) {
+ goto cleanup;
+ }
+ } else if (!parse_options && strcmp(*section, "options") != 0) {
+ /* ... or in a repo section */
+ if(strcmp(key, "Server") == 0) {
+ if(value == NULL) {
+ pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"),
+ file, linenum, key);
+ ret = 1;
+ goto cleanup;
+ }
+ if(_add_mirror(db, value) != 0) {
+ ret = 1;
+ goto cleanup;
+ }
+ } else if(strcmp(key, "VerifySig") == 0) {
+ pgp_verify_t level = option_verifysig(value);
+ if(level != PM_PGP_VERIFY_UNKNOWN) {
+ ret = alpm_db_set_pgp_verify(db, level);
+ if(ret != 0) {
+ pm_printf(PM_LOG_ERROR, _("could not add set verify option for database '%s': %s (%s)\n"),
+ alpm_db_get_name(db), value, alpm_strerrorlast());
+ goto cleanup;
+ }
+ } else {
+ pm_printf(PM_LOG_ERROR,
+ _("config file %s, line %d: directive '%s' has invalid value '%s'\n"),
+ file, linenum, key, value);
+ ret = 1;
+ goto cleanup;
+ }
+ } else {
+ pm_printf(PM_LOG_WARNING,
+ _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
+ file, linenum, key, *section);
+ }
+ }
+ }
+
+cleanup:
+ fclose(fp);
+ pm_printf(PM_LOG_DEBUG, "config: finished parsing %s\n", file);
+ return ret;
+}
+
+/** Parse a configuration file.
+ * @param file path to the config file.
+ * @return 0 on success, non-zero on error
+ */
+int parseconfig(const char *file)
+{
+ int ret;
+ char *section = NULL;
+ /* the config parse is a two-pass affair. We first parse the entire thing for
+ * the [options] section so we can get all default and path options set.
+ * Next, we go back and parse everything but [options]. */
+
+ /* call the real parseconfig function with a null section & db argument */
+ pm_printf(PM_LOG_DEBUG, "parseconfig: options pass\n");
+ if((ret = _parseconfig(file, 1, &section, NULL))) {
+ free(section);
+ return ret;
+ }
+ free(section);
+ /* call setlibpaths here to ensure we have called it at least once */
+ if((ret = setlibpaths())) {
+ return ret;
+ }
+ /* second pass, repo section parsing */
+ section = NULL;
+ pm_printf(PM_LOG_DEBUG, "parseconfig: repo pass\n");
+ return _parseconfig(file, 0, &section, NULL);
+ free(section);
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 92c379fc..76c76cf5 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -40,6 +40,7 @@ typedef struct __config_t {
char *rootdir;
char *dbpath;
char *logfile;
+ char *gpgdir;
/* TODO how to handle cachedirs? */
unsigned short op_q_isfile;
@@ -68,12 +69,15 @@ typedef struct __config_t {
unsigned int ask;
/* conf file options */
- unsigned short chomp; /* I Love Candy! */
- unsigned short showsize; /* show individual package sizes */
+ /* I Love Candy! */
+ unsigned short chomp;
+ /* format target pkg lists as table */
+ unsigned short verbosepkglists;
/* When downloading, display the amount downloaded, rate, ETA, and percent
* downloaded of the total download list */
unsigned short totaldownload;
- unsigned short cleanmethod; /* select -Sc behavior */
+ /* select -Sc behavior */
+ unsigned short cleanmethod;
alpm_list_t *holdpkg;
alpm_list_t *syncfirst;
char *xfercommand;
@@ -106,7 +110,8 @@ enum {
OP_NEEDED,
OP_ASEXPLICIT,
OP_ARCH,
- OP_PRINTFORMAT
+ OP_PRINTFORMAT,
+ OP_GPGDIR
};
/* clean method */
@@ -121,6 +126,8 @@ extern config_t *config;
config_t *config_new(void);
int config_free(config_t *oldconfig);
+int config_set_arch(const char *arch);
+int parseconfig(const char *file);
#endif /* _PM_CONF_H */
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/database.c b/src/pacman/database.c
index 36433f33..123f72d2 100644
--- a/src/pacman/database.c
+++ b/src/pacman/database.c
@@ -20,7 +20,6 @@
#include "config.h"
-#include <stdlib.h>
#include <stdio.h>
#include <alpm.h>
@@ -47,7 +46,7 @@ int pacman_database(alpm_list_t *targets)
if(targets == NULL) {
pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
- return(1);
+ return 1;
}
if(config->flags & PM_TRANS_FLAG_ALLDEPS) { /* --asdeps */
@@ -56,12 +55,12 @@ int pacman_database(alpm_list_t *targets)
reason = PM_PKG_REASON_EXPLICIT;
} else {
pm_printf(PM_LOG_ERROR, _("no install reason specified (use -h for help)\n"));
- return(1);
+ return 1;
}
/* Lock database */
if(trans_init(0) == -1) {
- return(1);
+ return 1;
}
db_local = alpm_option_get_localdb();
@@ -82,9 +81,9 @@ int pacman_database(alpm_list_t *targets)
/* Unlock database */
if(trans_release() == -1) {
- return(1);
+ return 1;
}
- return(retval);
+ return retval;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/deptest.c b/src/pacman/deptest.c
index 8895b487..19e4da4a 100644
--- a/src/pacman/deptest.c
+++ b/src/pacman/deptest.c
@@ -20,17 +20,13 @@
#include "config.h"
-#include <stdlib.h>
#include <stdio.h>
-#include <string.h>
#include <alpm.h>
#include <alpm_list.h>
/* pacman */
#include "pacman.h"
-#include "util.h"
-#include "conf.h"
int pacman_deptest(alpm_list_t *targets)
{
@@ -47,7 +43,7 @@ int pacman_deptest(alpm_list_t *targets)
}
if(deps == NULL) {
- return(0);
+ return 0;
}
for(i = deps; i; i = alpm_list_next(i)) {
@@ -56,7 +52,7 @@ int pacman_deptest(alpm_list_t *targets)
printf("%s\n", dep);
}
alpm_list_free(deps);
- return(127);
+ return 127;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/package.c b/src/pacman/package.c
index 77a5ee72..e256dda5 100644
--- a/src/pacman/package.c
+++ b/src/pacman/package.c
@@ -26,7 +26,6 @@
#include <unistd.h>
#include <limits.h>
#include <errno.h>
-#include <wchar.h>
#include <alpm.h>
#include <alpm_list.h>
@@ -37,20 +36,21 @@
#define CLBUF_SIZE 4096
-/* Display the content of a package
- *
- * levels:
- * <-1 - sync package, extra information (required by) [-Sii]
- * -1 - sync package, normal level [-Si]
- * =0 - file query [-Qip]
- * 1 - localdb query, normal level [-Qi]
- * >1 - localdb query, extra information (backup files) [-Qii]
+/**
+ * Display the details of a package.
+ * Extra information entails 'required by' info for sync packages and backup
+ * files info for local packages.
+ * @param pkg package to display information for
+ * @param from the type of package we are dealing with
+ * @param extra should we show extra information
*/
-void dump_pkg_full(pmpkg_t *pkg, int level)
+void dump_pkg_full(pmpkg_t *pkg, enum pkg_from from, int extra)
{
const char *reason;
time_t bdate, idate;
char bdatestr[50] = "", idatestr[50] = "";
+ const char *label;
+ double size;
const alpm_list_t *i;
alpm_list_t *requiredby = NULL, *depstrings = NULL;
@@ -82,16 +82,20 @@ void dump_pkg_full(pmpkg_t *pkg, int level)
/* turn depends list into a text list */
for(i = alpm_pkg_get_depends(pkg); i; i = alpm_list_next(i)) {
- pmdepend_t *dep = (pmdepend_t*)alpm_list_getdata(i);
+ pmdepend_t *dep = (pmdepend_t *)alpm_list_getdata(i);
depstrings = alpm_list_add(depstrings, alpm_dep_compute_string(dep));
}
- if(level > 0 || level < -1) {
+ if(extra || from == PKG_FROM_LOCALDB) {
/* compute this here so we don't get a pause in the middle of output */
requiredby = alpm_pkg_compute_requiredby(pkg);
}
/* actual output */
+ if(from == PKG_FROM_SYNCDB) {
+ string_display(_("Repository :"),
+ alpm_db_get_name(alpm_pkg_get_db(pkg)));
+ }
string_display(_("Name :"), alpm_pkg_get_name(pkg));
string_display(_("Version :"), alpm_pkg_get_version(pkg));
string_display(_("URL :"), alpm_pkg_get_url(pkg));
@@ -100,42 +104,41 @@ void dump_pkg_full(pmpkg_t *pkg, int level)
list_display(_("Provides :"), alpm_pkg_get_provides(pkg));
list_display(_("Depends On :"), depstrings);
list_display_linebreak(_("Optional Deps :"), alpm_pkg_get_optdepends(pkg));
- if(level > 0 || level < -1) {
+ if(extra || from == PKG_FROM_LOCALDB) {
list_display(_("Required By :"), requiredby);
}
list_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
list_display(_("Replaces :"), alpm_pkg_get_replaces(pkg));
- if(level < 0) {
- printf(_("Download Size : %6.2f K\n"),
- (double)alpm_pkg_get_size(pkg) / 1024.0);
- }
- if(level == 0) {
- printf(_("Compressed Size: %6.2f K\n"),
- (double)alpm_pkg_get_size(pkg) / 1024.0);
+
+ size = humanize_size(alpm_pkg_get_size(pkg), 'K', 1, &label);
+ if(from == PKG_FROM_SYNCDB) {
+ printf(_("Download Size : %6.2f %s\n"), size, label);
+ } else if(from == PKG_FROM_FILE) {
+ printf(_("Compressed Size: %6.2f %s\n"), size, label);
}
- printf(_("Installed Size : %6.2f K\n"),
- (double)alpm_pkg_get_isize(pkg) / 1024.0);
+ size = humanize_size(alpm_pkg_get_isize(pkg), 'K', 1, &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(level > 0) {
+ if(from == PKG_FROM_LOCALDB) {
string_display(_("Install Date :"), idatestr);
string_display(_("Install Reason :"), reason);
}
- if(level >= 0) {
+ if(from == PKG_FROM_FILE || from == PKG_FROM_LOCALDB) {
string_display(_("Install Script :"),
alpm_pkg_has_scriptlet(pkg) ? _("Yes") : _("No"));
}
- /* MD5 Sum for sync package */
- if(level < 0) {
+ if(from == PKG_FROM_SYNCDB) {
string_display(_("MD5 Sum :"), alpm_pkg_get_md5sum(pkg));
}
string_display(_("Description :"), alpm_pkg_get_desc(pkg));
/* Print additional package info if info flag passed more than once */
- if(level > 1) {
+ if(from == PKG_FROM_LOCALDB && extra) {
dump_pkg_backups(pkg);
}
@@ -146,23 +149,11 @@ void dump_pkg_full(pmpkg_t *pkg, int level)
FREELIST(requiredby);
}
-/* Display the content of a sync package
- */
-void dump_pkg_sync(pmpkg_t *pkg, const char *treename, int level)
-{
- if(pkg == NULL) {
- return;
- }
- string_display(_("Repository :"), treename);
- /* invert the level since we are a sync package */
- dump_pkg_full(pkg, -level);
-}
-
static const char *get_backup_file_status(const char *root,
const char *filename, const char *expected_md5)
{
char path[PATH_MAX];
- char *ret;
+ const char *ret;
snprintf(path, PATH_MAX, "%s%s", root, filename);
@@ -173,11 +164,11 @@ static const char *get_backup_file_status(const char *root,
if(md5sum == NULL) {
pm_fprintf(stderr, PM_LOG_ERROR,
_("could not calculate checksums for %s\n"), path);
- return(NULL);
+ return NULL;
}
/* if checksums don't match, file has been modified */
- if (strcmp(md5sum, expected_md5) != 0) {
+ if(strcmp(md5sum, expected_md5) != 0) {
ret = "MODIFIED";
} else {
ret = "UNMODIFIED";
@@ -195,7 +186,7 @@ static const char *get_backup_file_status(const char *root,
ret = "UNKNOWN";
}
}
- return(ret);
+ return ret;
}
/* Display list of backup files and their modification states
diff --git a/src/pacman/package.h b/src/pacman/package.h
index 26333c5a..7a5e5853 100644
--- a/src/pacman/package.h
+++ b/src/pacman/package.h
@@ -22,8 +22,14 @@
#include <alpm.h>
-void dump_pkg_full(pmpkg_t *pkg, int level);
-void dump_pkg_sync(pmpkg_t *pkg, const char *treename, int level);
+/* TODO it would be nice if we didn't duplicate a backend type */
+enum pkg_from {
+ PKG_FROM_FILE = 1,
+ PKG_FROM_LOCALDB,
+ PKG_FROM_SYNCDB
+};
+
+void dump_pkg_full(pmpkg_t *pkg, enum pkg_from from, int extra);
void dump_pkg_backups(pmpkg_t *pkg);
void dump_pkg_files(pmpkg_t *pkg, int quiet);
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 347d8af9..8458c976 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -36,12 +36,9 @@
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/utsname.h> /* uname */
#include <locale.h> /* setlocale */
-#include <time.h> /* time_t */
#include <errno.h>
-#include <glob.h>
#if defined(PACMAN_DEBUG) && defined(HAVE_MCHECK_H)
#include <mcheck.h> /* debug tracing (mtrace) */
#endif
@@ -55,7 +52,6 @@
#include "util.h"
#include "callback.h"
#include "conf.h"
-#include "package.h"
/* list of targets specified on command line */
static alpm_list_t *pm_targets;
@@ -66,9 +62,9 @@ static int options_cmp(const void *p1, const void *p2)
const char *s1 = p1;
const char *s2 = p2;
- if(s1 == s2) return(0);
- if(!s1) return(-1);
- if(!s2) return(1);
+ if(s1 == s2) return 0;
+ if(!s1) return -1;
+ if(!s2) return 1;
/* First skip all spaces in both strings */
while(isspace((unsigned char)*s1)) {
s1++;
@@ -87,15 +83,15 @@ static int options_cmp(const void *p1, const void *p2)
s2++;
} else if(*s2 == '-') {
/* s1 short, s2 long */
- return(-1);
+ return -1;
} else if(*s1 == '-') {
/* s1 long, s2 short */
- return(1);
+ return 1;
}
/* two short -> strcmp */
}
- return(strcmp(s1, s2));
+ return strcmp(s1, s2);
}
/** Display usage/syntax for the specified operation.
@@ -170,7 +166,7 @@ static void usage(int op, const char * const myname)
addlist(_(" -w, --downloadonly download packages but do not install/upgrade anything\n"));
addlist(_(" -y, --refresh download fresh package databases from the server\n"));
addlist(_(" --needed don't reinstall up to date packages\n"));
- } else if (op == PM_OP_DATABASE) {
+ } else if(op == PM_OP_DATABASE) {
printf("%s: %s {-D --database} <%s> <%s>\n", str_usg, myname, str_opt, str_pkg);
printf("%s:\n", str_opt);
addlist(_(" --asdeps mark packages as non-explicitly installed\n"));
@@ -207,6 +203,7 @@ static void usage(int op, const char * const myname)
addlist(_(" --cachedir <dir> set an alternate package cache location\n"));
addlist(_(" --config <path> set an alternate configuration file\n"));
addlist(_(" --debug display debug messages\n"));
+ addlist(_(" --gpgdir <path> set an alternate home directory for GnuPG\n"));
addlist(_(" --logfile <path> set an alternate log file\n"));
addlist(_(" --noconfirm do not ask for any confirmation\n"));
}
@@ -239,7 +236,7 @@ static void version(void)
static void localize(void)
{
static int init = 0;
- if (!init) {
+ if(!init) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
@@ -261,19 +258,6 @@ static void setuseragent(void)
setenv("HTTP_USER_AGENT", agent, 0);
}
-static void setarch(const char *arch)
-{
- if (strcmp(arch, "auto") == 0) {
- struct utsname un;
- uname(&un);
- pm_printf(PM_LOG_DEBUG, "config: Architecture: %s\n", un.machine);
- alpm_option_set_arch(un.machine);
- } else {
- pm_printf(PM_LOG_DEBUG, "config: Architecture: %s\n", arch);
- alpm_option_set_arch(arch);
- }
-}
-
/** Free the resources.
*
* @param ret the return value
@@ -302,7 +286,7 @@ static ssize_t xwrite(int fd, const void *buf, size_t count)
do {
ret = write(fd, buf, count);
} while(ret == -1 && errno == EINTR);
- return(ret);
+ return ret;
}
/** Catches thrown signals. Performs necessary cleanup to ensure database is
@@ -321,7 +305,7 @@ static void handler(int signum)
xwrite(out, msg1, strlen(msg1));
xwrite(err, msg2, strlen(msg2));
exit(signum);
- } else if((signum == SIGINT)) {
+ } else if(signum == SIGINT) {
const char *msg = "\nInterrupt signal received\n";
xwrite(err, msg, strlen(msg));
if(alpm_trans_interrupt() == 0) {
@@ -336,71 +320,9 @@ static void handler(int signum)
cleanup(signum);
}
-/** Sets all libalpm required paths in one go. Called after the command line
- * and inital config file parsing. Once this is complete, we can see if any
- * paths were defined. If a rootdir was defined and nothing else, we want all
- * of our paths to live under the rootdir that was specified. Safe to call
- * multiple times (will only do anything the first time).
- */
-static void setlibpaths(void)
-{
- static int init = 0;
- if (!init) {
- int ret = 0;
-
- pm_printf(PM_LOG_DEBUG, "setlibpaths() called\n");
- /* Configure root path first. If it is set and dbpath/logfile were not
- * set, then set those as well to reside under the root. */
- if(config->rootdir) {
- char path[PATH_MAX];
- ret = alpm_option_set_root(config->rootdir);
- if(ret != 0) {
- pm_printf(PM_LOG_ERROR, _("problem setting rootdir '%s' (%s)\n"),
- config->rootdir, alpm_strerrorlast());
- cleanup(ret);
- }
- if(!config->dbpath) {
- /* omit leading slash from our static DBPATH, root handles it */
- snprintf(path, PATH_MAX, "%s%s", alpm_option_get_root(), DBPATH + 1);
- config->dbpath = strdup(path);
- }
- if(!config->logfile) {
- /* omit leading slash from our static LOGFILE path, root handles it */
- snprintf(path, PATH_MAX, "%s%s", alpm_option_get_root(), LOGFILE + 1);
- config->logfile = strdup(path);
- }
- }
- /* Set other paths if they were configured. Note that unless rootdir
- * was left undefined, these two paths (dbpath and logfile) will have
- * been set locally above, so the if cases below will now trigger. */
- if(config->dbpath) {
- ret = alpm_option_set_dbpath(config->dbpath);
- if(ret != 0) {
- pm_printf(PM_LOG_ERROR, _("problem setting dbpath '%s' (%s)\n"),
- config->dbpath, alpm_strerrorlast());
- cleanup(ret);
- }
- }
- if(config->logfile) {
- ret = alpm_option_set_logfile(config->logfile);
- if(ret != 0) {
- pm_printf(PM_LOG_ERROR, _("problem setting logfile '%s' (%s)\n"),
- config->logfile, alpm_strerrorlast());
- cleanup(ret);
- }
- }
+#define check_optarg() if(!optarg) { return 1; }
- /* add a default cachedir if one wasn't specified */
- if(alpm_option_get_cachedirs() == NULL) {
- alpm_option_add_cachedir(CACHEDIR);
- }
- init = 1;
- }
-}
-
-#define check_optarg() if(!optarg) { return(1); }
-
-typedef void (*fn_add) (const char *s);
+typedef int (*fn_add) (const char *s);
static int parsearg_util_addlist(fn_add fn)
{
@@ -412,7 +334,7 @@ static int parsearg_util_addlist(fn_add fn)
fn((char *)alpm_list_getdata(item));
}
FREELIST(list);
- return(0);
+ return 0;
}
/** Helper function for parsing operation from command-line arguments.
@@ -449,9 +371,9 @@ static int parsearg_op(int opt, int dryrun)
if(dryrun) break;
config->help = 1; break;
default:
- return(1);
+ return 1;
}
- return(0);
+ return 0;
}
/** Helper functions for parsing command-line arguments.
@@ -461,7 +383,10 @@ static int parsearg_op(int opt, int dryrun)
static int parsearg_global(int opt)
{
switch(opt) {
- case OP_ARCH: check_optarg(); setarch(optarg); break;
+ case OP_ARCH:
+ check_optarg();
+ config_set_arch(optarg);
+ break;
case OP_ASK:
check_optarg();
config->noask = 1;
@@ -472,7 +397,7 @@ static int parsearg_global(int opt)
if(alpm_option_add_cachedir(optarg) != 0) {
pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"),
optarg, alpm_strerrorlast());
- return(1);
+ return 1;
}
break;
case OP_CONFIG:
@@ -497,7 +422,7 @@ static int parsearg_global(int opt)
default:
pm_printf(PM_LOG_ERROR, _("'%s' is not a valid debug level\n"),
optarg);
- return(1);
+ return 1;
}
} else {
config->logmask |= PM_LOG_DEBUG;
@@ -505,6 +430,9 @@ static int parsearg_global(int opt)
/* progress bars get wonky with debug on, shut them off */
config->noprogressbar = 1;
break;
+ case OP_GPGDIR:
+ config->gpgdir = strdup(optarg);
+ break;
case OP_LOGFILE:
check_optarg();
config->logfile = strndup(optarg, PATH_MAX);
@@ -516,9 +444,9 @@ static int parsearg_global(int opt)
break;
case 'r': check_optarg(); config->rootdir = strdup(optarg); break;
case 'v': (config->verbose)++; break;
- default: return(1);
+ default: return 1;
}
- return(0);
+ return 0;
}
static int parsearg_database(int opt)
@@ -526,9 +454,9 @@ static int parsearg_database(int opt)
switch(opt) {
case OP_ASDEPS: config->flags |= PM_TRANS_FLAG_ALLDEPS; break;
case OP_ASEXPLICIT: config->flags |= PM_TRANS_FLAG_ALLEXPLICIT; break;
- default: return(1);
+ default: return 1;
}
- return(0);
+ return 0;
}
static int parsearg_query(int opt)
@@ -548,9 +476,9 @@ static int parsearg_query(int opt)
case 's': config->op_q_search = 1; break;
case 't': config->op_q_unrequired = 1; break;
case 'u': config->op_q_upgrade = 1; break;
- default: return(1);
+ default: return 1;
}
- return(0);
+ return 0;
}
/* options common to -S -R -U */
@@ -572,15 +500,15 @@ static int parsearg_trans(int opt)
check_optarg();
config->print_format = strdup(optarg);
break;
- default: return(1);
+ default: return 1;
}
- return(0);
+ return 0;
}
static int parsearg_remove(int opt)
{
- if (parsearg_trans(opt) == 0)
- return(0);
+ if(parsearg_trans(opt) == 0)
+ return 0;
switch(opt) {
case 'c': config->flags |= PM_TRANS_FLAG_CASCADE; break;
case 'n': config->flags |= PM_TRANS_FLAG_NOSAVE; break;
@@ -592,16 +520,16 @@ static int parsearg_remove(int opt)
}
break;
case 'u': config->flags |= PM_TRANS_FLAG_UNNEEDED; break;
- default: return(1);
+ default: return 1;
}
- return(0);
+ return 0;
}
/* options common to -S -U */
static int parsearg_upgrade(int opt)
{
- if (parsearg_trans(opt) == 0)
- return(0);
+ if(parsearg_trans(opt) == 0)
+ return 0;
switch(opt) {
case 'f': config->flags |= PM_TRANS_FLAG_FORCE; break;
case OP_ASDEPS: config->flags |= PM_TRANS_FLAG_ALLDEPS; break;
@@ -612,15 +540,15 @@ static int parsearg_upgrade(int opt)
case OP_IGNOREGROUP:
parsearg_util_addlist(alpm_option_add_ignoregrp);
break;
- default: return(1);
+ default: return 1;
}
- return(0);
+ return 0;
}
static int parsearg_sync(int opt)
{
- if (parsearg_upgrade(opt) == 0)
- return(0);
+ if(parsearg_upgrade(opt) == 0)
+ return 0;
switch(opt) {
case OP_NEEDED: config->flags |= PM_TRANS_FLAG_NEEDED; break;
case 'c': (config->op_s_clean)++; break;
@@ -636,9 +564,9 @@ static int parsearg_sync(int opt)
config->flags |= PM_TRANS_FLAG_NOCONFLICTS;
break;
case 'y': (config->op_s_sync)++; break;
- default: return(1);
+ default: return 1;
}
- return(0);
+ return 0;
}
/** Parse command-line arguments for each operation.
@@ -706,6 +634,7 @@ static int parseargs(int argc, char *argv[])
{"asexplicit", no_argument, 0, OP_ASEXPLICIT},
{"arch", required_argument, 0, OP_ARCH},
{"print-format", required_argument, 0, OP_PRINTFORMAT},
+ {"gpgdir", required_argument, 0, OP_GPGDIR},
{0, 0, 0, 0}
};
@@ -717,22 +646,22 @@ static int parseargs(int argc, char *argv[])
continue;
} else if(opt == '?') {
/* unknown option, getopt printed an error */
- return(1);
+ return 1;
}
parsearg_op(opt, 0);
}
if(config->op == 0) {
pm_printf(PM_LOG_ERROR, _("only one operation may be used at a time\n"));
- return(1);
+ return 1;
}
if(config->help) {
usage(config->op, mbasename(argv[0]));
- return(2);
+ return 2;
}
if(config->version) {
version();
- return(2);
+ return 2;
}
/* parse all other options */
@@ -744,7 +673,7 @@ static int parseargs(int argc, char *argv[])
continue;
} else if(opt == '?') {
/* this should have failed during first pass already */
- return(1);
+ return 1;
} else if(parsearg_op(opt, 1) == 0) {
/* opt is an operation */
continue;
@@ -771,7 +700,7 @@ static int parseargs(int argc, char *argv[])
result = 1;
break;
}
- if (result == 0) {
+ if(result == 0) {
continue;
}
@@ -780,7 +709,7 @@ static int parseargs(int argc, char *argv[])
if(result != 0) {
/* global option parsing failed, abort */
pm_printf(PM_LOG_ERROR, _("invalid option\n"));
- return(result);
+ return result;
}
}
@@ -790,469 +719,7 @@ static int parseargs(int argc, char *argv[])
optind++;
}
- return(0);
-}
-
-/* helper for being used with setrepeatingoption */
-static void option_add_holdpkg(const char *name) {
- config->holdpkg = alpm_list_add(config->holdpkg, strdup(name));
-}
-
-/* helper for being used with setrepeatingoption */
-static void option_add_syncfirst(const char *name) {
- config->syncfirst = alpm_list_add(config->syncfirst, strdup(name));
-}
-
-/* helper for being used with setrepeatingoption */
-static void option_add_cleanmethod(const char *value) {
- if (strcmp(value, "KeepInstalled") == 0) {
- config->cleanmethod |= PM_CLEAN_KEEPINST;
- } else if (strcmp(value, "KeepCurrent") == 0) {
- config->cleanmethod |= PM_CLEAN_KEEPCUR;
- } else {
- pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"),
- value);
- }
-}
-
-/** Add repeating options such as NoExtract, NoUpgrade, etc to libalpm
- * settings. Refactored out of the parseconfig code since all of them did
- * the exact same thing and duplicated code.
- * @param ptr a pointer to the start of the multiple options
- * @param option the string (friendly) name of the option, used for messages
- * @param optionfunc a function pointer to an alpm_option_add_* function
- */
-static void setrepeatingoption(char *ptr, const char *option,
- void (*optionfunc)(const char*))
-{
- char *q;
-
- while((q = strchr(ptr, ' '))) {
- *q = '\0';
- (*optionfunc)(ptr);
- pm_printf(PM_LOG_DEBUG, "config: %s: %s\n", option, ptr);
- ptr = q;
- ptr++;
- }
- (*optionfunc)(ptr);
- pm_printf(PM_LOG_DEBUG, "config: %s: %s\n", option, ptr);
-}
-
-static char *get_filename(const char *url) {
- char *filename = strrchr(url, '/');
- if(filename != NULL) {
- filename++;
- }
- return(filename);
-}
-
-static char *get_destfile(const char *path, const char *filename) {
- char *destfile;
- /* len = localpath len + filename len + null */
- size_t len = strlen(path) + strlen(filename) + 1;
- destfile = calloc(len, sizeof(char));
- snprintf(destfile, len, "%s%s", path, filename);
-
- return(destfile);
-}
-
-static char *get_tempfile(const char *path, const char *filename) {
- char *tempfile;
- /* len = localpath len + filename len + '.part' len + null */
- size_t len = strlen(path) + strlen(filename) + 6;
- tempfile = calloc(len, sizeof(char));
- snprintf(tempfile, len, "%s%s.part", path, filename);
-
- return(tempfile);
-}
-
-/** External fetch callback */
-static int download_with_xfercommand(const char *url, const char *localpath,
- int force) {
- int ret = 0;
- int retval;
- int usepart = 0;
- struct stat st;
- char *parsedcmd,*tempcmd;
- char cwd[PATH_MAX];
- int restore_cwd = 0;
- char *destfile, *tempfile, *filename;
-
- if(!config->xfercommand) {
- return -1;
- }
-
- filename = get_filename(url);
- if(!filename) {
- return -1;
- }
- destfile = get_destfile(localpath, filename);
- tempfile = get_tempfile(localpath, filename);
-
- if(force && stat(tempfile, &st) == 0) {
- unlink(tempfile);
- }
- if(force && stat(destfile, &st) == 0) {
- unlink(destfile);
- }
-
- tempcmd = strdup(config->xfercommand);
- /* replace all occurrences of %o with fn.part */
- if(strstr(tempcmd, "%o")) {
- usepart = 1;
- parsedcmd = strreplace(tempcmd, "%o", tempfile);
- free(tempcmd);
- tempcmd = parsedcmd;
- }
- /* replace all occurrences of %u with the download URL */
- parsedcmd = strreplace(tempcmd, "%u", url);
- free(tempcmd);
-
- /* save the cwd so we can restore it later */
- if(getcwd(cwd, PATH_MAX) == NULL) {
- pm_printf(PM_LOG_ERROR, _("could not get current working directory\n"));
- } else {
- restore_cwd = 1;
- }
-
- /* cwd to the download directory */
- if(chdir(localpath)) {
- pm_printf(PM_LOG_WARNING, _("could not chdir to download directory %s\n"), localpath);
- ret = -1;
- goto cleanup;
- }
- /* execute the parsed command via /bin/sh -c */
- pm_printf(PM_LOG_DEBUG, "running command: %s\n", parsedcmd);
- retval = system(parsedcmd);
-
- if(retval == -1) {
- pm_printf(PM_LOG_WARNING, _("running XferCommand: fork failed!\n"));
- ret = -1;
- } else if(retval != 0) {
- /* download failed */
- pm_printf(PM_LOG_DEBUG, "XferCommand command returned non-zero status "
- "code (%d)\n", retval);
- ret = -1;
- } else {
- /* download was successful */
- if(usepart) {
- rename(tempfile, destfile);
- }
- ret = 0;
- }
-
-cleanup:
- /* restore the old cwd if we have it */
- if(restore_cwd && chdir(cwd) != 0) {
- pm_printf(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno));
- }
-
- if(ret == -1) {
- /* hack to let an user the time to cancel a download */
- sleep(2);
- }
- free(destfile);
- free(tempfile);
- free(parsedcmd);
-
- return(ret);
-}
-
-static int _parse_options(const char *key, char *value,
- const char *file, int linenum)
-{
- if(value == NULL) {
- /* options without settings */
- if(strcmp(key, "UseSyslog") == 0) {
- alpm_option_set_usesyslog(1);
- pm_printf(PM_LOG_DEBUG, "config: usesyslog\n");
- } else if(strcmp(key, "ILoveCandy") == 0) {
- config->chomp = 1;
- pm_printf(PM_LOG_DEBUG, "config: chomp\n");
- } else if(strcmp(key, "ShowSize") == 0) {
- config->showsize = 1;
- pm_printf(PM_LOG_DEBUG, "config: showsize\n");
- } else if(strcmp(key, "UseDelta") == 0) {
- alpm_option_set_usedelta(1);
- pm_printf(PM_LOG_DEBUG, "config: usedelta\n");
- } else if(strcmp(key, "TotalDownload") == 0) {
- config->totaldownload = 1;
- pm_printf(PM_LOG_DEBUG, "config: totaldownload\n");
- } else if(strcmp(key, "CheckSpace") == 0) {
- alpm_option_set_checkspace(1);
- } else {
- pm_printf(PM_LOG_WARNING,
- _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
- file, linenum, key, "options");
- }
- } else {
- /* options with settings */
- if(strcmp(key, "NoUpgrade") == 0) {
- setrepeatingoption(value, "NoUpgrade", alpm_option_add_noupgrade);
- } else if(strcmp(key, "NoExtract") == 0) {
- setrepeatingoption(value, "NoExtract", alpm_option_add_noextract);
- } else if(strcmp(key, "IgnorePkg") == 0) {
- setrepeatingoption(value, "IgnorePkg", alpm_option_add_ignorepkg);
- } else if(strcmp(key, "IgnoreGroup") == 0) {
- setrepeatingoption(value, "IgnoreGroup", alpm_option_add_ignoregrp);
- } else if(strcmp(key, "HoldPkg") == 0) {
- setrepeatingoption(value, "HoldPkg", option_add_holdpkg);
- } else if(strcmp(key, "SyncFirst") == 0) {
- setrepeatingoption(value, "SyncFirst", option_add_syncfirst);
- } else if(strcmp(key, "Architecture") == 0) {
- if(!alpm_option_get_arch()) {
- setarch(value);
- }
- } else if(strcmp(key, "DBPath") == 0) {
- /* don't overwrite a path specified on the command line */
- if(!config->dbpath) {
- config->dbpath = strdup(value);
- pm_printf(PM_LOG_DEBUG, "config: dbpath: %s\n", value);
- }
- } else if(strcmp(key, "CacheDir") == 0) {
- if(alpm_option_add_cachedir(value) != 0) {
- pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"),
- value, alpm_strerrorlast());
- return(1);
- }
- pm_printf(PM_LOG_DEBUG, "config: cachedir: %s\n", value);
- } else if(strcmp(key, "RootDir") == 0) {
- /* don't overwrite a path specified on the command line */
- if(!config->rootdir) {
- config->rootdir = strdup(value);
- pm_printf(PM_LOG_DEBUG, "config: rootdir: %s\n", value);
- }
- } else if (strcmp(key, "LogFile") == 0) {
- if(!config->logfile) {
- config->logfile = strdup(value);
- pm_printf(PM_LOG_DEBUG, "config: logfile: %s\n", value);
- }
- } else if (strcmp(key, "XferCommand") == 0) {
- config->xfercommand = strdup(value);
- alpm_option_set_fetchcb(download_with_xfercommand);
- pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", value);
- } else if (strcmp(key, "CleanMethod") == 0) {
- setrepeatingoption(value, "CleanMethod", option_add_cleanmethod);
- } else {
-
- pm_printf(PM_LOG_WARNING,
- _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
- file, linenum, key, "options");
- }
-
- }
- return(0);
-}
-
-static int _add_mirror(pmdb_t *db, char *value)
-{
- const char *dbname = alpm_db_get_name(db);
- /* let's attempt a replacement for the current repo */
- char *temp = strreplace(value, "$repo", dbname);
- /* let's attempt a replacement for the arch */
- const char *arch = alpm_option_get_arch();
- char *server;
- if(arch) {
- server = strreplace(temp, "$arch", arch);
- free(temp);
- } else {
- if(strstr(temp, "$arch")) {
- free(temp);
- pm_printf(PM_LOG_ERROR, _("The mirror '%s' contains the $arch"
- " variable, but no Architecture is defined.\n"), value);
- return(1);
- }
- server = temp;
- }
-
- if(alpm_db_setserver(db, server) != 0) {
- /* pm_errno is set by alpm_db_setserver */
- pm_printf(PM_LOG_ERROR, _("could not add server URL to database '%s': %s (%s)\n"),
- dbname, server, alpm_strerrorlast());
- free(server);
- return(1);
- }
-
- free(server);
- return(0);
-}
-
-/* The real parseconfig. Called with a null section argument by the publicly
- * visible parseconfig so we can recall from within ourself on an include */
-static int _parseconfig(const char *file, const char *givensection,
- pmdb_t * const givendb)
-{
- FILE *fp = NULL;
- char line[PATH_MAX+1];
- int linenum = 0;
- char *ptr, *section = NULL;
- pmdb_t *db = NULL;
- int ret = 0;
-
- pm_printf(PM_LOG_DEBUG, "config: attempting to read file %s\n", file);
- fp = fopen(file, "r");
- if(fp == NULL) {
- pm_printf(PM_LOG_ERROR, _("config file %s could not be read.\n"), file);
- return(1);
- }
-
- /* if we are passed a section, use it as our starting point */
- if(givensection != NULL) {
- section = strdup(givensection);
- }
- /* if we are passed a db, use it as our starting point */
- if(givendb != NULL) {
- db = givendb;
- }
-
- while(fgets(line, PATH_MAX, fp)) {
- linenum++;
- strtrim(line);
-
- /* ignore whole line and end of line comments */
- if(strlen(line) == 0 || line[0] == '#') {
- continue;
- }
- if((ptr = strchr(line, '#'))) {
- *ptr = '\0';
- }
-
- if(line[0] == '[' && line[strlen(line)-1] == ']') {
- /* new config section, skip the '[' */
- ptr = line;
- ptr++;
- if(section) {
- free(section);
- }
- section = strdup(ptr);
- section[strlen(section)-1] = '\0';
- pm_printf(PM_LOG_DEBUG, "config: new section '%s'\n", section);
- if(!strlen(section)) {
- pm_printf(PM_LOG_ERROR, _("config file %s, line %d: bad section name.\n"),
- file, linenum);
- ret = 1;
- goto cleanup;
- }
- /* if we are not looking at the options section, register a db */
- if(strcmp(section, "options") != 0) {
- db = alpm_db_register_sync(section);
- if(db == NULL) {
- pm_printf(PM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
- section, alpm_strerrorlast());
- ret = 1;
- goto cleanup;
- }
- }
- continue;
- }
-
- /* directive */
- char *key, *value;
- /* strsep modifies the 'line' string: 'key \0 value' */
- key = line;
- value = line;
- strsep(&value, "=");
- strtrim(key);
- strtrim(value);
-
- if(key == NULL) {
- pm_printf(PM_LOG_ERROR, _("config file %s, line %d: syntax error in config file- missing key.\n"),
- file, linenum);
- ret = 1;
- goto cleanup;
- }
- /* For each directive, compare to the camelcase string. */
- if(section == NULL) {
- pm_printf(PM_LOG_ERROR, _("config file %s, line %d: All directives must belong to a section.\n"),
- file, linenum);
- ret = 1;
- goto cleanup;
- }
- /* Include is allowed in both options and repo sections */
- if(strcmp(key, "Include") == 0) {
- if(value == NULL) {
- pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"),
- file, linenum, key);
- ret = 1;
- goto cleanup;
- }
- /* Ignore include failures... assume non-critical */
- int globret;
- glob_t globbuf;
- globret = glob(value, GLOB_NOCHECK, NULL, &globbuf);
- switch(globret) {
- case GLOB_NOSPACE:
- pm_printf(PM_LOG_DEBUG,
- "config file %s, line %d: include globbing out of space\n",
- file, linenum);
- break;
- case GLOB_ABORTED:
- pm_printf(PM_LOG_DEBUG,
- "config file %s, line %d: include globbing read error for %s\n",
- file, linenum, value);
- break;
- case GLOB_NOMATCH:
- pm_printf(PM_LOG_DEBUG,
- "config file %s, line %d: no include found for %s\n",
- file, linenum, value);
- break;
- default:
- for(size_t gindex = 0; gindex < globbuf.gl_pathc; gindex++) {
- pm_printf(PM_LOG_DEBUG, "config file %s, line %d: including %s\n",
- file, linenum, globbuf.gl_pathv[gindex]);
- _parseconfig(globbuf.gl_pathv[gindex], section, db);
- }
- break;
- }
- globfree(&globbuf);
- continue;
- }
- if(strcmp(section, "options") == 0) {
- /* we are either in options ... */
- if((ret = _parse_options(key, value, file, linenum)) != 0) {
- goto cleanup;
- }
- } else {
- /* ... or in a repo section */
- if(strcmp(key, "Server") == 0) {
- if(value == NULL) {
- pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"),
- file, linenum, key);
- ret = 1;
- goto cleanup;
- }
- if(_add_mirror(db, value) != 0) {
- ret = 1;
- goto cleanup;
- }
- } else {
- pm_printf(PM_LOG_WARNING,
- _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
- file, linenum, key, section);
- }
- }
-
- }
-
-cleanup:
- fclose(fp);
- if(section){
- free(section);
- }
- /* call setlibpaths here to ensure we have called it at least once */
- setlibpaths();
- pm_printf(PM_LOG_DEBUG, "config: finished parsing %s\n", file);
- return(ret);
-}
-
-/** Parse a configuration file.
- * @param file path to the config file.
- * @return 0 on success, non-zero on error
- */
-static int parseconfig(const char *file)
-{
- /* call the real parseconfig function with a null section & db argument */
- return(_parseconfig(file, NULL, NULL));
+ return 0;
}
/** print commandline to logfile
@@ -1346,6 +813,7 @@ int main(int argc, char *argv[])
/* define paths to reasonable defaults */
alpm_option_set_root(ROOTDIR);
alpm_option_set_dbpath(DBPATH);
+ alpm_option_set_signaturedir(GPGDIR);
alpm_option_set_logfile(LOGFILE);
/* Priority of options:
@@ -1384,7 +852,7 @@ int main(int argc, char *argv[])
}
}
/* check for buffer overflow */
- if (i >= PATH_MAX) {
+ if(i >= PATH_MAX) {
pm_printf(PM_LOG_ERROR, _("buffer overflow detected in arg parsing\n"));
cleanup(EXIT_FAILURE);
}
@@ -1394,7 +862,7 @@ int main(int argc, char *argv[])
line[i] = '\0';
pm_targets = alpm_list_add(pm_targets, strdup(line));
}
- if (!freopen(ctermid(NULL), "r", stdin)) {
+ if(!freopen(ctermid(NULL), "r", stdin)) {
pm_printf(PM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"),
strerror(errno));
}
@@ -1440,11 +908,12 @@ int main(int argc, char *argv[])
printf("DB Path : %s\n", alpm_option_get_dbpath());
printf("Cache Dirs: ");
for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) {
- printf("%s ", (char*)alpm_list_getdata(i));
+ printf("%s ", (char *)alpm_list_getdata(i));
}
printf("\n");
printf("Lock File : %s\n", alpm_option_get_lockfile());
printf("Log File : %s\n", alpm_option_get_logfile());
+ printf("GPG Dir : %s\n", alpm_option_get_signaturedir());
list_display("Targets :", pm_targets);
}
@@ -1480,7 +949,7 @@ int main(int argc, char *argv[])
cleanup(ret);
/* not reached */
- return(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/pacman.h b/src/pacman/pacman.h
index f5b972bb..762e112d 100644
--- a/src/pacman/pacman.h
+++ b/src/pacman/pacman.h
@@ -24,6 +24,8 @@
/* database.c */
int pacman_database(alpm_list_t *targets);
+/* deptest.c */
+int pacman_deptest(alpm_list_t *targets);
/* query.c */
int pacman_query(alpm_list_t *targets);
/* remove.c */
@@ -33,9 +35,6 @@ int pacman_sync(alpm_list_t *targets);
/* upgrade.c */
int pacman_upgrade(alpm_list_t *targets);
-/* deptest.c */
-int pacman_deptest(alpm_list_t *targets);
-
#endif /* _PM_PACMAN_H */
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/query.c b/src/pacman/query.c
index 6c63774f..d1105b4a 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -26,7 +26,6 @@
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
-#include <unistd.h>
#include <alpm.h>
#include <alpm_list.h>
@@ -43,15 +42,15 @@ static char *resolve_path(const char *file)
str = calloc(PATH_MAX + 1, sizeof(char));
if(!str) {
- return(NULL);
+ return NULL;
}
if(!realpath(file, str)) {
free(str);
- return(NULL);
+ return NULL;
}
- return(str);
+ return str;
}
/* check if filename exists in PATH */
@@ -61,10 +60,10 @@ static int search_path(char **filename, struct stat *bufptr)
size_t flen;
if((envpath = getenv("PATH")) == NULL) {
- return(-1);
+ return -1;
}
if((envpath = envpathsplit = strdup(envpath)) == NULL) {
- return(-1);
+ return -1;
}
flen = strlen(*filename);
@@ -88,12 +87,12 @@ static int search_path(char **filename, struct stat *bufptr)
free(*filename);
*filename = fullname;
free(envpath);
- return(0);
+ return 0;
}
free(fullname);
}
free(envpath);
- return(-1);
+ return -1;
}
static void print_query_fileowner(const char *filename, pmpkg_t *info)
@@ -119,7 +118,7 @@ static int query_fileowner(alpm_list_t *targets)
/* This code is here for safety only */
if(targets == NULL) {
pm_fprintf(stderr, PM_LOG_ERROR, _("no file was specified for --owns\n"));
- return(1);
+ return 1;
}
/* Set up our root path buffer. We only need to copy the location of root in
@@ -171,7 +170,7 @@ static int query_fileowner(alpm_list_t *targets)
bname = mbasename(filename);
dname = mdirname(filename);
/* for files in '/', there is no directory name to match */
- if (strcmp(dname, "") == 0) {
+ if(strcmp(dname, "") == 0) {
rpath = NULL;
} else {
rpath = resolve_path(dname);
@@ -252,29 +251,21 @@ static int query_search(alpm_list_t *targets)
freelist = 0;
}
if(searchlist == NULL) {
- return(1);
+ return 1;
}
for(i = searchlist; i; i = alpm_list_next(i)) {
alpm_list_t *grp;
pmpkg_t *pkg = alpm_list_getdata(i);
- if (!config->quiet) {
+ if(!config->quiet) {
printf("local/%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
} else {
printf("%s", alpm_pkg_get_name(pkg));
}
- /* print the package size with the output if ShowSize option set */
- if(!config->quiet && config->showsize) {
- /* Convert byte size to MB */
- double mbsize = (double)alpm_pkg_get_size(pkg) / (1024.0 * 1024.0);
- printf(" [%.2f MB]", mbsize);
- }
-
-
- if (!config->quiet) {
+ if(!config->quiet) {
if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
alpm_list_t *k;
printf(" (");
@@ -300,7 +291,7 @@ static int query_search(alpm_list_t *targets)
if(freelist) {
alpm_list_free(searchlist);
}
- return(0);
+ return 0;
}
static int query_group(alpm_list_t *targets)
@@ -363,19 +354,19 @@ static int is_foreign(pmpkg_t *pkg)
}
}
if(match == 0) {
- return(1);
+ return 1;
}
- return(0);
+ return 0;
}
static int is_unrequired(pmpkg_t *pkg)
{
alpm_list_t *requiredby = alpm_pkg_compute_requiredby(pkg);
if(requiredby == NULL) {
- return(1);
+ return 1;
}
FREELIST(requiredby);
- return(0);
+ return 0;
}
static int filter(pmpkg_t *pkg)
@@ -383,26 +374,26 @@ static int filter(pmpkg_t *pkg)
/* check if this package was explicitly installed */
if(config->op_q_explicit &&
alpm_pkg_get_reason(pkg) != PM_PKG_REASON_EXPLICIT) {
- return(0);
+ return 0;
}
/* check if this package was installed as a dependency */
if(config->op_q_deps &&
alpm_pkg_get_reason(pkg) != PM_PKG_REASON_DEPEND) {
- return(0);
+ return 0;
}
/* check if this pkg isn't in a sync DB */
if(config->op_q_foreign && !is_foreign(pkg)) {
- return(0);
+ return 0;
}
/* check if this pkg is unrequired */
if(config->op_q_unrequired && !is_unrequired(pkg)) {
- return(0);
+ return 0;
}
/* check if this pkg is outdated */
if(config->op_q_upgrade && (alpm_sync_newversion(pkg, alpm_option_get_syncdbs()) == NULL)) {
- return(0);
+ return 0;
}
- return(1);
+ return 1;
}
/* Loop through the packages. For each package,
@@ -420,7 +411,7 @@ static int check(pmpkg_t *pkg)
if(rootlen + 1 > PATH_MAX) {
/* we are in trouble here */
pm_fprintf(stderr, PM_LOG_ERROR, _("path too long: %s%s\n"), root, "");
- return(1);
+ return 1;
}
strcpy(f, root);
@@ -454,7 +445,7 @@ static int check(pmpkg_t *pkg)
(unsigned long)errors), errors);
}
- return(errors != 0 ? 1 : 0);
+ return (errors != 0 ? 1 : 0);
}
static int display(pmpkg_t *pkg)
@@ -463,10 +454,9 @@ static int display(pmpkg_t *pkg)
if(config->op_q_info) {
if(config->op_q_isfile) {
- /* omit info that isn't applicable for a file package */
- dump_pkg_full(pkg, 0);
+ dump_pkg_full(pkg, PKG_FROM_FILE, 0);
} else {
- dump_pkg_full(pkg, config->op_q_info);
+ dump_pkg_full(pkg, PKG_FROM_LOCALDB, config->op_q_info > 1);
}
}
if(config->op_q_list) {
@@ -480,13 +470,13 @@ static int display(pmpkg_t *pkg)
}
if(!config->op_q_info && !config->op_q_list
&& !config->op_q_changelog && !config->op_q_check) {
- if (!config->quiet) {
+ if(!config->quiet) {
printf("%s %s\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
} else {
printf("%s\n", alpm_pkg_get_name(pkg));
}
}
- return(ret);
+ return ret;
}
int pacman_query(alpm_list_t *targets)
@@ -502,13 +492,13 @@ int pacman_query(alpm_list_t *targets)
/* search for a package */
if(config->op_q_search) {
ret = query_search(targets);
- return(ret);
+ return ret;
}
/* looking for groups */
if(config->group) {
ret = query_group(targets);
- return(ret);
+ return ret;
}
if(config->op_q_foreign) {
@@ -516,7 +506,7 @@ int pacman_query(alpm_list_t *targets)
alpm_list_t *sync_dbs = alpm_option_get_syncdbs();
if(sync_dbs == NULL || alpm_list_count(sync_dbs) == 0) {
pm_printf(PM_LOG_ERROR, _("no usable package repositories configured.\n"));
- return(1);
+ return 1;
}
}
@@ -528,7 +518,7 @@ int pacman_query(alpm_list_t *targets)
if(targets == NULL) {
if(config->op_q_isfile || config->op_q_owns) {
pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
- return(1);
+ return 1;
}
for(i = alpm_db_get_pkgcache(db_local); i; i = alpm_list_next(i)) {
@@ -544,7 +534,7 @@ int pacman_query(alpm_list_t *targets)
if(!match) {
ret = 1;
}
- return(ret);
+ return ret;
}
/* Second: operations that require target(s) */
@@ -552,7 +542,7 @@ int pacman_query(alpm_list_t *targets)
/* determine the owner of a file */
if(config->op_q_owns) {
ret = query_fileowner(targets);
- return(ret);
+ return ret;
}
/* operations on named packages in the local DB
@@ -561,7 +551,7 @@ int pacman_query(alpm_list_t *targets)
char *strname = alpm_list_getdata(i);
if(config->op_q_isfile) {
- alpm_pkg_load(strname, 1, &pkg);
+ alpm_pkg_load(strname, 1, PM_PGP_VERIFY_OPTIONAL, &pkg);
} else {
pkg = alpm_db_get_pkg(db_local, strname);
}
@@ -590,7 +580,7 @@ int pacman_query(alpm_list_t *targets)
ret = 1;
}
- return(ret);
+ return ret;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/remove.c b/src/pacman/remove.c
index fb02e242..58e6edd5 100644
--- a/src/pacman/remove.c
+++ b/src/pacman/remove.c
@@ -40,25 +40,25 @@ static int remove_target(char *target)
if((info = alpm_db_get_pkg(db_local, target)) != NULL) {
if(alpm_remove_pkg(info) == -1) {
pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", target, alpm_strerrorlast());
- return(-1);
+ return -1;
}
- return(0);
+ return 0;
}
/* fallback to group */
pmgrp_t *grp = alpm_db_readgrp(db_local, target);
if(grp == NULL) {
pm_fprintf(stderr, PM_LOG_ERROR, "'%s': target not found\n", target);
- return(-1);
+ return -1;
}
for(p = alpm_grp_get_pkgs(grp); p; p = alpm_list_next(p)) {
pmpkg_t *pkg = alpm_list_getdata(p);
if(alpm_remove_pkg(pkg) == -1) {
pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", target, alpm_strerrorlast());
- return(-1);
+ return -1;
}
}
- return(0);
+ return 0;
}
/**
@@ -75,12 +75,12 @@ int pacman_remove(alpm_list_t *targets)
if(targets == NULL) {
pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
- return(1);
+ return 1;
}
/* Step 0: create a new transaction */
if(trans_init(config->flags) == -1) {
- return(1);
+ return 1;
}
/* Step 1: add targets to the created transaction */
@@ -173,7 +173,7 @@ cleanup:
if(trans_release() == -1) {
retval = 1;
}
- return(retval);
+ return retval;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index c56934b6..884504f3 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -39,7 +39,8 @@
/* if keep_used != 0, then the db files which match an used syncdb
* will be kept */
-static int sync_cleandb(const char *dbpath, int keep_used) {
+static int sync_cleandb(const char *dbpath, int keep_used)
+{
DIR *dir;
struct dirent *ent;
alpm_list_t *syncdbs;
@@ -47,7 +48,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) {
dir = opendir(dbpath);
if(dir == NULL) {
pm_fprintf(stderr, PM_LOG_ERROR, _("could not access database directory\n"));
- return(1);
+ return 1;
}
syncdbs = alpm_option_get_syncdbs();
@@ -84,7 +85,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) {
pm_fprintf(stderr, PM_LOG_ERROR,
_("could not remove %s\n"), path);
closedir(dir);
- return(1);
+ return 1;
}
continue;
}
@@ -110,15 +111,16 @@ static int sync_cleandb(const char *dbpath, int keep_used) {
pm_fprintf(stderr, PM_LOG_ERROR,
_("could not remove %s\n"), path);
closedir(dir);
- return(1);
+ return 1;
}
}
}
closedir(dir);
- return(0);
+ return 0;
}
-static int sync_cleandb_all(void) {
+static int sync_cleandb_all(void)
+{
const char *dbpath;
char newdbpath[PATH_MAX];
int ret = 0;
@@ -126,7 +128,7 @@ static int sync_cleandb_all(void) {
dbpath = alpm_option_get_dbpath();
printf(_("Database directory: %s\n"), dbpath);
if(!yesno(_("Do you want to remove unused repositories?"))) {
- return(0);
+ return 0;
}
/* The sync dbs were previously put in dbpath/ but are now in dbpath/sync/.
* We will clean everything in dbpath/ except local/, sync/ and db.lck, and
@@ -137,7 +139,7 @@ static int sync_cleandb_all(void) {
ret += sync_cleandb(newdbpath, 1);
printf(_("Database directory cleaned up\n"));
- return(ret);
+ return ret;
}
static int sync_cleancache(int level)
@@ -148,7 +150,7 @@ static int sync_cleancache(int level)
int ret = 0;
for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) {
- printf(_("Cache directory: %s\n"), (char*)alpm_list_getdata(i));
+ printf(_("Cache directory: %s\n"), (char *)alpm_list_getdata(i));
}
if(!config->cleanmethod) {
@@ -165,12 +167,12 @@ static int sync_cleancache(int level)
printf(_(" All current sync database packages\n"));
}
if(!yesno(_("Do you want to remove all other packages from cache?"))) {
- return(0);
+ return 0;
}
printf(_("removing old packages from cache...\n"));
} else {
if(!noyes(_("Do you want to remove ALL files from cache?"))) {
- return(0);
+ return 0;
}
printf(_("removing all files from cache...\n"));
}
@@ -191,10 +193,10 @@ static int sync_cleancache(int level)
/* step through the directory one file at a time */
while((ent = readdir(dir)) != NULL) {
char path[PATH_MAX];
+ size_t pathlen;
int delete = 1;
pmpkg_t *localpkg = NULL, *pkg = NULL;
const char *local_name, *local_version;
- alpm_list_t *j;
if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
continue;
@@ -208,11 +210,19 @@ static int sync_cleancache(int level)
continue;
}
+ /* we handle .sig files with packages, not separately */
+ pathlen = strlen(path);
+ if(strcmp(path + pathlen - 4, ".sig") == 0) {
+ continue;
+ }
+
/* attempt to load the package, prompt removal on failures as we may have
* files here that aren't valid packages. we also don't need a full
* load of the package, just the metadata. */
- if(alpm_pkg_load(path, 0, &localpkg) != 0 || localpkg == NULL) {
- if(yesno(_("File %s does not seem to be a valid package, remove it?"), path)) {
+ if(alpm_pkg_load(path, 0, PM_PGP_VERIFY_NEVER, &localpkg) != 0
+ || localpkg == NULL) {
+ if(yesno(_("File %s does not seem to be a valid package, remove it?"),
+ path)) {
if(localpkg) {
alpm_pkg_free(localpkg);
}
@@ -235,6 +245,7 @@ static int sync_cleancache(int level)
}
}
if(config->cleanmethod & PM_CLEAN_KEEPCUR) {
+ alpm_list_t *j;
/* check if this package is in a sync DB */
for(j = sync_dbs; j && delete; j = alpm_list_next(j)) {
pmdb_t *db = alpm_list_getdata(j);
@@ -253,12 +264,17 @@ static int sync_cleancache(int level)
if(delete) {
unlink(path);
+ /* unlink a signature file if present too */
+ if(PATH_MAX - 5 >= pathlen) {
+ strcpy(path + pathlen, ".sig");
+ unlink(path);
+ }
}
}
closedir(dir);
}
- return(ret);
+ return ret;
}
static int sync_synctree(int level, alpm_list_t *syncs)
@@ -267,7 +283,7 @@ static int sync_synctree(int level, alpm_list_t *syncs)
int success = 0, ret;
if(trans_init(0) == -1) {
- return(0);
+ return 0;
}
for(i = syncs; i; i = alpm_list_next(i)) {
@@ -286,7 +302,7 @@ static int sync_synctree(int level, alpm_list_t *syncs)
}
if(trans_release() == -1) {
- return(0);
+ return 0;
}
/* We should always succeed if at least one DB was upgraded - we may possibly
* fail later with unresolved deps, but that should be rare, and would be
@@ -295,7 +311,7 @@ static int sync_synctree(int level, alpm_list_t *syncs)
if(!success) {
pm_fprintf(stderr, PM_LOG_ERROR, _("failed to synchronize any databases\n"));
}
- return(success > 0);
+ return (success > 0);
}
static void print_installed(pmdb_t *db_local, pmpkg_t *pkg)
@@ -340,22 +356,14 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
alpm_list_t *grp;
pmpkg_t *pkg = alpm_list_getdata(j);
- if (!config->quiet) {
+ 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));
}
- /* print the package size with the output if ShowSize option set */
- if(!config->quiet && config->showsize) {
- /* Convert byte size to MB */
- double mbsize = (double)alpm_pkg_get_size(pkg) / (1024.0 * 1024.0);
-
- printf(" [%.2f MB]", mbsize);
- }
-
- if (!config->quiet) {
+ if(!config->quiet) {
if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
alpm_list_t *k;
printf(" (");
@@ -384,7 +392,7 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
}
}
- return(!found);
+ return !found;
}
static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
@@ -432,7 +440,7 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
}
}
- return(0);
+ return 0;
}
static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
@@ -466,14 +474,14 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
if(!db) {
pm_fprintf(stderr, PM_LOG_ERROR,
_("repository '%s' does not exist\n"), repo);
- return(1);
+ return 1;
}
for(k = alpm_db_get_pkgcache(db); k; k = alpm_list_next(k)) {
pmpkg_t *pkg = alpm_list_getdata(k);
if(strcmp(alpm_pkg_get_name(pkg), pkgstr) == 0) {
- dump_pkg_sync(pkg, alpm_db_get_name(db), config->op_s_info);
+ dump_pkg_full(pkg, PKG_FROM_SYNCDB, config->op_s_info > 1);
foundpkg = 1;
break;
}
@@ -494,7 +502,7 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
pmpkg_t *pkg = alpm_list_getdata(k);
if(strcmp(alpm_pkg_get_name(pkg), pkgstr) == 0) {
- dump_pkg_sync(pkg, alpm_db_get_name(db), config->op_s_info);
+ dump_pkg_full(pkg, PKG_FROM_SYNCDB, config->op_s_info > 1);
foundpkg = 1;
break;
}
@@ -512,12 +520,13 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets)
pmdb_t *db = alpm_list_getdata(i);
for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) {
- dump_pkg_sync(alpm_list_getdata(j), alpm_db_get_name(db), config->op_s_info);
+ pmpkg_t *pkg = alpm_list_getdata(j);
+ dump_pkg_full(pkg, PKG_FROM_SYNCDB, config->op_s_info > 1);
}
}
}
- return(ret);
+ return ret;
}
static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
@@ -543,7 +552,7 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
pm_fprintf(stderr, PM_LOG_ERROR,
_("repository \"%s\" was not found.\n"),repo);
alpm_list_free(ls);
- return(1);
+ return 1;
}
ls = alpm_list_add(ls, db);
@@ -558,7 +567,7 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) {
pmpkg_t *pkg = alpm_list_getdata(j);
- if (!config->quiet) {
+ if(!config->quiet) {
printf("%s %s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
alpm_pkg_get_version(pkg));
print_installed(db_local, pkg);
@@ -573,7 +582,7 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
alpm_list_free(ls);
}
- return(0);
+ return 0;
}
static alpm_list_t *syncfirst(void) {
@@ -592,7 +601,7 @@ static alpm_list_t *syncfirst(void) {
}
}
- return(res);
+ return res;
}
static pmdb_t *get_db(const char *dbname)
@@ -601,10 +610,10 @@ static pmdb_t *get_db(const char *dbname)
for(i = alpm_option_get_syncdbs(); i; i = i->next) {
pmdb_t *db = i->data;
if(strcmp(alpm_db_get_name(db), dbname) == 0) {
- return(db);
+ return db;
}
}
- return(NULL);
+ return NULL;
}
static int process_pkg(pmpkg_t *pkg)
@@ -616,14 +625,14 @@ static int process_pkg(pmpkg_t *pkg)
|| pm_errno == PM_ERR_PKG_IGNORED) {
/* just skip duplicate or ignored targets */
pm_printf(PM_LOG_WARNING, _("skipping target: %s\n"), alpm_pkg_get_name(pkg));
- return(0);
+ return 0;
} else {
pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg),
alpm_strerrorlast());
- return(1);
+ return 1;
}
}
- return(0);
+ return 0;
}
static int process_group(alpm_list_t *dbs, char *group)
@@ -635,7 +644,7 @@ static int process_group(alpm_list_t *dbs, char *group)
if(!count) {
pm_fprintf(stderr, PM_LOG_ERROR, _("target not found: %s\n"), group);
- return(1);
+ return 1;
}
@@ -669,7 +678,7 @@ static int process_group(alpm_list_t *dbs, char *group)
}
cleanup:
alpm_list_free(pkgs);
- return(ret);
+ return ret;
}
static int process_targname(alpm_list_t *dblist, char *targname)
@@ -680,14 +689,14 @@ static int process_targname(alpm_list_t *dblist, char *targname)
if(pm_errno == PM_ERR_PKG_IGNORED) {
pm_printf(PM_LOG_WARNING, _("skipping target: %s\n"), targname);
pm_errno = 0;
- return(0);
+ return 0;
}
if(pkg) {
- return(process_pkg(pkg));
+ return process_pkg(pkg);
}
/* fallback on group */
- return(process_group(dblist, targname));
+ return process_group(dblist, targname);
}
static int process_target(char *target)
@@ -722,7 +731,7 @@ static int process_target(char *target)
}
cleanup:
free(targstring);
- return(ret);
+ return ret;
}
static int sync_trans(alpm_list_t *targets)
@@ -734,7 +743,7 @@ static int sync_trans(alpm_list_t *targets)
/* Step 1: create a new transaction... */
if(trans_init(config->flags) == -1) {
- return(1);
+ return 1;
}
/* process targets */
@@ -874,7 +883,7 @@ cleanup:
retval = 1;
}
- return(retval);
+ return retval;
}
int pacman_sync(alpm_list_t *targets)
@@ -886,7 +895,7 @@ int pacman_sync(alpm_list_t *targets)
int ret = 0;
if(trans_init(0) == -1) {
- return(1);
+ return 1;
}
ret += sync_cleancache(config->op_s_clean);
@@ -897,14 +906,14 @@ int pacman_sync(alpm_list_t *targets)
ret++;
}
- return(ret);
+ return ret;
}
/* ensure we have at least one valid sync db set up */
sync_dbs = alpm_option_get_syncdbs();
if(sync_dbs == NULL || alpm_list_count(sync_dbs) == 0) {
pm_printf(PM_LOG_ERROR, _("no usable package repositories configured.\n"));
- return(1);
+ return 1;
}
if(config->op_s_sync) {
@@ -912,40 +921,40 @@ int pacman_sync(alpm_list_t *targets)
printf(_(":: Synchronizing package databases...\n"));
alpm_logaction("synchronizing package lists\n");
if(!sync_synctree(config->op_s_sync, sync_dbs)) {
- return(1);
+ return 1;
}
}
/* search for a package */
if(config->op_s_search) {
- return(sync_search(sync_dbs, targets));
+ return sync_search(sync_dbs, targets);
}
/* look for groups */
if(config->group) {
- return(sync_group(config->group, sync_dbs, targets));
+ return sync_group(config->group, sync_dbs, targets);
}
/* get package info */
if(config->op_s_info) {
- return(sync_info(sync_dbs, targets));
+ return sync_info(sync_dbs, targets);
}
/* get a listing of files in sync DBs */
if(config->op_q_list) {
- return(sync_list(sync_dbs, targets));
+ return sync_list(sync_dbs, targets);
}
if(targets == NULL) {
if(config->op_s_upgrade) {
/* proceed */
} else if(config->op_s_sync) {
- return(0);
+ return 0;
} else {
/* don't proceed here unless we have an operation that doesn't require a
* target list */
pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
- return(1);
+ return 1;
}
}
@@ -980,7 +989,7 @@ int pacman_sync(alpm_list_t *targets)
int ret = sync_trans(targs);
FREELIST(targs);
- return(ret);
+ return ret;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c
index 8cd29da0..0ffc94c4 100644
--- a/src/pacman/upgrade.c
+++ b/src/pacman/upgrade.c
@@ -42,11 +42,12 @@
int pacman_upgrade(alpm_list_t *targets)
{
alpm_list_t *i, *data = NULL;
+ pgp_verify_t check_sig = alpm_option_get_default_sigverify();
int retval = 0;
if(targets == NULL) {
pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
- return(1);
+ return 1;
}
/* Check for URL targets and process them
@@ -57,7 +58,7 @@ int pacman_upgrade(alpm_list_t *targets)
if(str == NULL) {
pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
(char *)i->data, alpm_strerrorlast());
- return(1);
+ return 1;
} else {
free(i->data);
i->data = str;
@@ -67,7 +68,7 @@ int pacman_upgrade(alpm_list_t *targets)
/* Step 1: create a new transaction */
if(trans_init(config->flags) == -1) {
- return(1);
+ return 1;
}
/* add targets to the created transaction */
@@ -75,18 +76,18 @@ int pacman_upgrade(alpm_list_t *targets)
char *targ = alpm_list_getdata(i);
pmpkg_t *pkg;
- if(alpm_pkg_load(targ, 1, &pkg) != 0) {
+ if(alpm_pkg_load(targ, 1, check_sig, &pkg) != 0) {
pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
targ, alpm_strerrorlast());
trans_release();
- return(1);
+ return 1;
}
if(alpm_add_pkg(pkg) == -1) {
pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
targ, alpm_strerrorlast());
alpm_pkg_free(pkg);
trans_release();
- return(1);
+ return 1;
}
}
@@ -135,7 +136,7 @@ int pacman_upgrade(alpm_list_t *targets)
}
trans_release();
FREELIST(data);
- return(1);
+ return 1;
}
/* Step 3: perform the installation */
@@ -143,7 +144,7 @@ int pacman_upgrade(alpm_list_t *targets)
if(config->print) {
print_packages(alpm_trans_get_add());
trans_release();
- return(0);
+ return 0;
}
/* print targets and ask user confirmation */
@@ -151,7 +152,7 @@ int pacman_upgrade(alpm_list_t *targets)
if(packages == NULL) { /* we are done */
printf(_(" there is nothing to do\n"));
trans_release();
- return(retval);
+ return retval;
}
display_targets(alpm_trans_get_remove(), 0);
display_targets(alpm_trans_get_add(), 1);
@@ -159,7 +160,7 @@ int pacman_upgrade(alpm_list_t *targets)
int confirm = yesno(_("Proceed with installation?"));
if(!confirm) {
trans_release();
- return(retval);
+ return retval;
}
if(alpm_trans_commit(&data) == -1) {
@@ -197,13 +198,13 @@ int pacman_upgrade(alpm_list_t *targets)
}
FREELIST(data);
trans_release();
- return(1);
+ return 1;
}
if(trans_release() == -1) {
retval = 1;
}
- return(retval);
+ return retval;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 3d268031..8631075f 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -31,12 +31,14 @@
#include <stdint.h> /* intmax_t */
#include <string.h>
#include <errno.h>
-#include <fcntl.h>
#include <ctype.h>
#include <dirent.h>
#include <unistd.h>
#include <limits.h>
#include <wchar.h>
+#ifdef HAVE_TERMIOS_H
+#include <termios.h> /* tcflush */
+#endif
#include <alpm.h>
#include <alpm_list.h>
@@ -68,9 +70,9 @@ int trans_init(pmtransflag_t flags)
fprintf(stderr, _(" try running pacman-db-upgrade\n"));
}
- return(-1);
+ return -1;
}
- return(0);
+ return 0;
}
int trans_release(void)
@@ -78,28 +80,40 @@ int trans_release(void)
if(alpm_trans_release() == -1) {
pm_fprintf(stderr, PM_LOG_ERROR, _("failed to release transaction (%s)\n"),
alpm_strerrorlast());
- return(-1);
+ return -1;
}
- return(0);
+ return 0;
}
int needs_root(void)
{
switch(config->op) {
case PM_OP_DATABASE:
- return(1);
+ return 1;
case PM_OP_UPGRADE:
case PM_OP_REMOVE:
- return(!config->print);
+ return !config->print;
case PM_OP_SYNC:
- return(config->op_s_clean || config->op_s_sync ||
+ return (config->op_s_clean || config->op_s_sync ||
(!config->group && !config->op_s_info && !config->op_q_list &&
!config->op_s_search && !config->print));
default:
- return(0);
+ return 0;
}
}
+/* discard unhandled input on the terminal's input buffer */
+static int flush_term_input(void) {
+#ifdef HAVE_TCFLUSH
+ if(isatty(fileno(stdin))) {
+ return(tcflush(fileno(stdin), TCIFLUSH));
+ }
+#endif
+
+ /* fail silently */
+ return 0;
+}
+
/* gets the current screen column width */
int getcols(void)
{
@@ -125,24 +139,24 @@ int rmrf(const char *path)
DIR *dirp;
if(!unlink(path)) {
- return(0);
+ return 0;
} else {
if(errno == ENOENT) {
- return(0);
+ return 0;
} else if(errno == EPERM) {
/* fallthrough */
} else if(errno == EISDIR) {
/* fallthrough */
} else if(errno == ENOTDIR) {
- return(1);
+ return 1;
} else {
/* not a directory */
- return(1);
+ return 1;
}
dirp = opendir(path);
if(!dirp) {
- return(1);
+ return 1;
}
for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
if(dp->d_ino) {
@@ -157,7 +171,7 @@ int rmrf(const char *path)
if(rmdir(path)) {
errflag++;
}
- return(errflag);
+ return errflag;
}
}
@@ -170,9 +184,9 @@ const char *mbasename(const char *path)
{
const char *last = strrchr(path, '/');
if(last) {
- return(last + 1);
+ return last + 1;
}
- return(path);
+ return path;
}
/** Parse the dirname of a program from a path.
@@ -187,7 +201,7 @@ char *mdirname(const char *path)
/* null or empty path */
if(path == NULL || path == '\0') {
- return(strdup("."));
+ return strdup(".");
}
ret = strdup(path);
@@ -196,11 +210,11 @@ char *mdirname(const char *path)
if(last != NULL) {
/* we found a '/', so terminate our string */
*last = '\0';
- return(ret);
+ return ret;
}
/* no slash found */
free(ret);
- return(strdup("."));
+ return strdup(".");
}
/* output a string, but wrap words properly with a specified indentation
@@ -286,7 +300,7 @@ char *strtrim(char *str)
if(str == NULL || *str == '\0') {
/* string is empty, so we're done. */
- return(str);
+ return str;
}
while(isspace((unsigned char)*pch)) {
@@ -298,7 +312,7 @@ char *strtrim(char *str)
/* check if there wasn't anything but whitespace in the string. */
if(*str == '\0') {
- return(str);
+ return str;
}
pch = (str + (strlen(str) - 1));
@@ -307,7 +321,7 @@ char *strtrim(char *str)
}
*++pch = '\0';
- return(str);
+ return str;
}
/* Replace all occurances of 'needle' with 'replace' in 'str', returning
@@ -321,7 +335,7 @@ char *strreplace(const char *str, const char *needle, const char *replace)
size_t newsz;
if(!str) {
- return(NULL);
+ return NULL;
}
p = str;
@@ -334,7 +348,7 @@ char *strreplace(const char *str, const char *needle, const char *replace)
/* no occurences of needle found */
if(!list) {
- return(strdup(str));
+ return strdup(str);
}
/* size of new string = size of old string + "number of occurences of needle"
* x "size difference between replace and needle" */
@@ -342,7 +356,7 @@ char *strreplace(const char *str, const char *needle, const char *replace)
alpm_list_count(list) * (replacesz - needlesz);
newstr = malloc(newsz);
if(!newstr) {
- return(NULL);
+ return NULL;
}
*newstr = '\0';
@@ -368,7 +382,7 @@ char *strreplace(const char *str, const char *needle, const char *replace)
}
*newp = '\0';
- return(newstr);
+ return newstr;
}
/** Splits a string into a list of strings using the chosen character as
@@ -388,7 +402,7 @@ alpm_list_t *strsplit(const char *str, const char splitchar)
while((str = strchr(str, splitchar))) {
dup = strndup(prev, (size_t)(str - prev));
if(dup == NULL) {
- return(NULL);
+ return NULL;
}
list = alpm_list_add(list, dup);
@@ -398,11 +412,11 @@ alpm_list_t *strsplit(const char *str, const char splitchar)
dup = strdup(prev);
if(dup == NULL) {
- return(NULL);
+ return NULL;
}
list = alpm_list_add(list, dup);
- return(list);
+ return list;
}
static int string_length(const char *s)
@@ -411,7 +425,7 @@ static int string_length(const char *s)
wchar_t *wcstr;
if(!s) {
- return(0);
+ return 0;
}
/* len goes from # bytes -> # chars -> # cols */
len = strlen(s) + 1;
@@ -420,7 +434,7 @@ static int string_length(const char *s)
len = wcswidth(wcstr, len);
free(wcstr);
- return(len);
+ return len;
}
void string_display(const char *title, const char *string)
@@ -440,6 +454,117 @@ void string_display(const char *title, const char *string)
printf("\n");
}
+static void table_print_line(const alpm_list_t *line,
+ const alpm_list_t *formats)
+{
+ const alpm_list_t *curformat = formats;
+ const alpm_list_t *curcell = line;
+
+ while(curcell && curformat) {
+ printf(alpm_list_getdata(curformat), alpm_list_getdata(curcell));
+ curcell = alpm_list_next(curcell);
+ curformat = alpm_list_next(curformat);
+ }
+
+ printf("\n");
+}
+
+/* creates format strings by checking max cell lengths in cols */
+static alpm_list_t *table_create_format(const alpm_list_t *header,
+ const alpm_list_t *rows)
+{
+ alpm_list_t *longest_str, *longest_strs = NULL;
+ alpm_list_t *formats = NULL;
+ const alpm_list_t *i, *row, *cell;
+ char *str, *formatstr;
+ const int padding = 2;
+ int colwidth, totalwidth = 0;
+ int curcol = 0;
+
+ /* header determines column count and initial values of longest_strs */
+ for(i = header; i; i = alpm_list_next(i)) {
+ longest_strs = alpm_list_add(longest_strs, alpm_list_getdata(i));
+ }
+
+ /* now find the longest string in each column */
+ for(longest_str = longest_strs; longest_str;
+ longest_str = alpm_list_next(longest_str), curcol++) {
+ for(i = rows; i; i = alpm_list_next(i)) {
+ row = alpm_list_getdata(i);
+ cell = alpm_list_nth(row, curcol);
+ str = alpm_list_getdata(cell);
+
+ if(strlen(str) > strlen(alpm_list_getdata(longest_str))) {
+ longest_str->data = str;
+ }
+ }
+ }
+
+ /* now use the column width info to generate format strings */
+ for(i = longest_strs; i; i = alpm_list_next(i)) {
+ const char *display;
+ colwidth = strlen(alpm_list_getdata(i)) + padding;
+ totalwidth += colwidth;
+
+ /* right align the last column for a cleaner table display */
+ display = (alpm_list_next(i) != NULL) ? "%%-%ds" : "%%%ds";
+ pm_asprintf(&formatstr, display, colwidth);
+
+ formats = alpm_list_add(formats, formatstr);
+ }
+
+ alpm_list_free(longest_strs);
+
+ /* return NULL if terminal is not wide enough */
+ if(totalwidth > getcols()) {
+ fprintf(stderr, _("insufficient columns available for table display\n"));
+ FREELIST(formats);
+ return(NULL);
+ }
+
+ return(formats);
+}
+
+/** Displays the list in table format
+ *
+ * @param title the tables title
+ * @param header the column headers. column count is determined by the nr
+ * 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)
+ *
+ * @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)
+{
+ const alpm_list_t *i;
+ alpm_list_t *formats;
+
+ if(rows == NULL || header == NULL) {
+ return(0);
+ }
+
+ formats = table_create_format(header, rows);
+ if(formats == NULL) {
+ return(-1);
+ }
+
+ if(title != NULL) {
+ printf("%s\n\n", title);
+ }
+
+ table_print_line(header, formats);
+ printf("\n");
+
+ for(i = rows; i; i = alpm_list_next(i)) {
+ table_print_line(alpm_list_getdata(i), formats);
+ }
+
+ FREELIST(formats);
+ return(0);
+}
+
void list_display(const char *title, const alpm_list_t *list)
{
const alpm_list_t *i;
@@ -464,7 +589,7 @@ void list_display(const char *title, const alpm_list_t *list)
for (j = 1; j <= len; j++) {
printf(" ");
}
- } else if (cols != len) {
+ } else if(cols != len) {
/* 2 spaces are added if this is not the first element on a line. */
printf(" ");
cols += 2;
@@ -503,20 +628,74 @@ void list_display_linebreak(const char *title, const alpm_list_t *list)
}
}
}
+
+/* creates a header row for use with table_display */
+static alpm_list_t *create_verbose_header(int install)
+{
+ alpm_list_t *res = NULL;
+ char *str;
+
+ pm_asprintf(&str, "%s", _("Name"));
+ res = alpm_list_add(res, str);
+ pm_asprintf(&str, "%s", _("Old Version"));
+ res = alpm_list_add(res, str);
+ if(install) {
+ pm_asprintf(&str, "%s", _("New Version"));
+ res = alpm_list_add(res, str);
+ }
+ pm_asprintf(&str, "%s", _("Size"));
+ res = alpm_list_add(res, str);
+
+ return(res);
+}
+
+/* returns package info as list of strings */
+static alpm_list_t *create_verbose_row(pmpkg_t *pkg, int install)
+{
+ char *str;
+ double size;
+ const char *label;
+ alpm_list_t *ret = NULL;
+ pmdb_t *ldb = alpm_option_get_localdb();
+
+ /* a row consists of the package name, */
+ pm_asprintf(&str, "%s", alpm_pkg_get_name(pkg));
+ ret = alpm_list_add(ret, str);
+
+ /* old and new versions */
+ if(install) {
+ pmpkg_t *oldpkg = alpm_db_get_pkg(ldb, alpm_pkg_get_name(pkg));
+ pm_asprintf(&str, "%s",
+ oldpkg != NULL ? alpm_pkg_get_version(oldpkg) : "");
+ ret = alpm_list_add(ret, str);
+ }
+
+ pm_asprintf(&str, "%s", alpm_pkg_get_version(pkg));
+ ret = alpm_list_add(ret, str);
+
+ /* and size */
+ size = humanize_size(alpm_pkg_get_size(pkg), 'M', 1, &label);
+ pm_asprintf(&str, "%.2f %s", size, label);
+ ret = alpm_list_add(ret, str);
+
+ return(ret);
+}
+
/* prepare a list of pkgs to display */
void display_targets(const alpm_list_t *pkgs, int install)
{
char *str;
+ const char *title, *label;
+ double size;
const alpm_list_t *i;
off_t isize = 0, dlsize = 0;
- double mbisize = 0.0, mbdlsize = 0.0;
- alpm_list_t *targets = NULL;
+ alpm_list_t *j, *lp, *header = NULL, *targets = NULL;
if(!pkgs) {
return;
}
- printf("\n");
+ /* gather pkg infos */
for(i = pkgs; i; i = alpm_list_next(i)) {
pmpkg_t *pkg = alpm_list_getdata(i);
@@ -525,54 +704,69 @@ void display_targets(const alpm_list_t *pkgs, int install)
}
isize += alpm_pkg_get_isize(pkg);
- /* print the package size with the output if ShowSize option set */
- if(config->showsize) {
- double mbsize = (double)alpm_pkg_get_size(pkg) / (1024.0 * 1024.0);
-
- pm_asprintf(&str, "%s-%s [%.2f MB]", alpm_pkg_get_name(pkg),
- alpm_pkg_get_version(pkg), mbsize);
+ if(config->verbosepkglists) {
+ targets = alpm_list_add(targets, create_verbose_row(pkg, install));
} else {
pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(pkg),
alpm_pkg_get_version(pkg));
+ targets = alpm_list_add(targets, str);
}
- targets = alpm_list_add(targets, str);
}
- /* Convert byte sizes to MB */
- mbdlsize = (double)dlsize / (1024.0 * 1024.0);
- mbisize = (double)isize / (1024.0 * 1024.0);
+ /* print to screen */
+ title = install ? _("Targets (%d):") : _("Remove (%d):");
+ pm_asprintf(&str, title, alpm_list_count(pkgs));
- if(install) {
- pm_asprintf(&str, _("Targets (%d):"), alpm_list_count(targets));
+ printf("\n");
+ if(config->verbosepkglists) {
+ header = create_verbose_header(install);
+ if(table_display(str, header, targets) != 0) {
+ config->verbosepkglists = 0;
+ display_targets(pkgs, install);
+ goto out;
+ }
+ } else {
list_display(str, targets);
- free(str);
- printf("\n");
+ }
+ printf("\n");
- printf(_("Total Download Size: %.2f MB\n"), mbdlsize);
+ if(install) {
+ size = humanize_size(dlsize, 'M', 1, &label);
+ printf(_("Total Download Size: %.2f %s\n"), size, label);
if(!(config->flags & PM_TRANS_FLAG_DOWNLOADONLY)) {
- printf(_("Total Installed Size: %.2f MB\n"), mbisize);
+ size = humanize_size(isize, 'M', 1, &label);
+ printf(_("Total Installed Size: %.2f %s\n"), size, label);
}
} else {
- pm_asprintf(&str, _("Remove (%d):"), alpm_list_count(targets));
- list_display(str, targets);
- free(str);
- printf("\n");
-
- printf(_("Total Removed Size: %.2f MB\n"), mbisize);
+ size = humanize_size(isize, 'M', 1, &label);
+ printf(_("Total Removed Size: %.2f %s\n"), size, label);
}
- FREELIST(targets);
+out:
+ /* cleanup */
+ if(config->verbosepkglists) {
+ /* targets is a list of lists of strings, free inner lists here */
+ for(j = alpm_list_first(targets); j; j = alpm_list_next(j)) {
+ lp = alpm_list_getdata(j);
+ FREELIST(lp);
+ }
+ alpm_list_free(targets);
+ FREELIST(header);
+ } else {
+ FREELIST(targets);
+ }
+ free(str);
}
static off_t pkg_get_size(pmpkg_t *pkg)
{
switch(config->op) {
case PM_OP_SYNC:
- return(alpm_pkg_download_size(pkg));
+ return alpm_pkg_download_size(pkg);
case PM_OP_UPGRADE:
- return(alpm_pkg_get_size(pkg));
+ return alpm_pkg_get_size(pkg);
default:
- return(alpm_pkg_get_isize(pkg));
+ return alpm_pkg_get_isize(pkg);
}
}
@@ -588,17 +782,55 @@ static char *pkg_get_location(pmpkg_t *pkg)
if(dburl) {
char *pkgurl = NULL;
pm_asprintf(&pkgurl, "%s/%s", dburl, alpm_pkg_get_filename(pkg));
- return(pkgurl);
+ return pkgurl;
}
case PM_OP_UPGRADE:
- return(strdup(alpm_pkg_get_filename(pkg)));
+ return strdup(alpm_pkg_get_filename(pkg));
default:
string = NULL;
pm_asprintf(&string, "%s-%s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
- return(string);
+ return string;
}
}
+/** Converts sizes in bytes into human readable units.
+ *
+ * @param bytes the size in bytes
+ * @param target_unit '\0' or a short label. If equal to one of the short unit
+ * labels ('B', 'K', ...) bytes is converted to target_unit; if '\0', the first
+ * unit which will bring the value to below a threshold of 2048 will be chosen.
+ * @param long_labels whether to use short ("K") or long ("KiB") unit labels
+ * @param label will be set to the appropriate unit label
+ *
+ * @return the size in the appropriate unit
+ */
+double humanize_size(off_t bytes, const char target_unit, int long_labels,
+ const char **label)
+{
+ static const char *shortlabels[] = {"B", "K", "M", "G", "T", "P"};
+ static const char *longlabels[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
+ static const int unitcount = sizeof(shortlabels) / sizeof(shortlabels[0]);
+
+ const char **labels = long_labels ? longlabels : shortlabels;
+ double val = (double)bytes;
+ int index;
+
+ for(index = 0; index < unitcount - 1; index++) {
+ if(target_unit != '\0' && shortlabels[index][0] == target_unit) {
+ break;
+ } else if(target_unit == '\0' && val <= 2048.0) {
+ break;
+ }
+ val /= 1024.0;
+ }
+
+ if(label) {
+ *label = labels[index];
+ }
+
+ return(val);
+}
+
void print_packages(const alpm_list_t *packages)
{
const alpm_list_t *i;
@@ -657,7 +889,7 @@ void print_packages(const alpm_list_t *packages)
* alpm "compare func" signature */
int str_cmp(const void *s1, const void *s2)
{
- return(strcmp(s1, s2));
+ return strcmp(s1, s2);
}
void display_new_optdepends(pmpkg_t *oldpkg, pmpkg_t *newpkg)
@@ -726,13 +958,13 @@ static int parseindex(char *s, int *val, int min, int max)
if(n < min || n > max) {
fprintf(stderr, _("Invalid value: %d is not between %d and %d\n"),
n, min, max);
- return(-1);
+ return -1;
}
*val = n;
- return(0);
+ return 0;
} else {
fprintf(stderr, _("Invalid number: %s\n"), s);
- return(-1);
+ return -1;
}
}
@@ -746,7 +978,7 @@ static int multiselect_parse(char *array, int count, char *response)
char *ends = NULL;
char *starts = strtok_r(str, " ", &saveptr);
- if (starts == NULL) {
+ if(starts == NULL) {
break;
}
strtrim(starts);
@@ -754,7 +986,7 @@ static int multiselect_parse(char *array, int count, char *response)
if(len == 0)
continue;
- if (*starts == '^') {
+ if(*starts == '^') {
starts++;
len--;
include = 0;
@@ -773,14 +1005,14 @@ static int multiselect_parse(char *array, int count, char *response)
}
if(parseindex(starts, &start, 1, count) != 0)
- return(-1);
+ return -1;
if(!ends) {
array[start-1] = include;
} else {
int d;
if(parseindex(ends, &end, start, count) != 0) {
- return(-1);
+ return -1;
}
for(d = start; d <= end; d++) {
array[d-1] = include;
@@ -788,7 +1020,7 @@ static int multiselect_parse(char *array, int count, char *response)
}
}
- return(0);
+ return 0;
}
int multiselect_question(char *array, int count)
@@ -815,6 +1047,8 @@ int multiselect_question(char *array, int count)
break;
}
+ flush_term_input();
+
if(fgets(response, sizeof(response), stdin)) {
strtrim(response);
if(strlen(response) > 0) {
@@ -826,7 +1060,7 @@ int multiselect_question(char *array, int count)
}
break;
}
- return(0);
+ return 0;
}
int select_question(int count)
@@ -852,19 +1086,21 @@ int select_question(int count)
break;
}
+ flush_term_input();
+
if(fgets(response, sizeof(response), stdin)) {
strtrim(response);
if(strlen(response) > 0) {
int n;
if(parseindex(response, &n, 1, count) != 0)
continue;
- return(n-1);
+ return (n - 1);
}
}
break;
}
- return(preset-1);
+ return (preset - 1);
}
@@ -895,23 +1131,25 @@ static int question(short preset, char *fmt, va_list args)
if(config->noconfirm) {
fprintf(stream, "\n");
- return(preset);
+ return preset;
}
fflush(stream);
+ flush_term_input();
+
if(fgets(response, sizeof(response), stdin)) {
strtrim(response);
if(strlen(response) == 0) {
- return(preset);
+ return preset;
}
if(strcasecmp(response, _("Y")) == 0 || strcasecmp(response, _("YES")) == 0) {
- return(1);
- } else if (strcasecmp(response, _("N")) == 0 || strcasecmp(response, _("NO")) == 0) {
- return(0);
+ return 1;
+ } else if(strcasecmp(response, _("N")) == 0 || strcasecmp(response, _("NO")) == 0) {
+ return 0;
}
}
- return(0);
+ return 0;
}
int yesno(char *fmt, ...)
@@ -923,7 +1161,7 @@ int yesno(char *fmt, ...)
ret = question(1, fmt, args);
va_end(args);
- return(ret);
+ return ret;
}
int noyes(char *fmt, ...)
@@ -935,7 +1173,7 @@ int noyes(char *fmt, ...)
ret = question(0, fmt, args);
va_end(args);
- return(ret);
+ return ret;
}
int pm_printf(pmloglevel_t level, const char *format, ...)
@@ -948,7 +1186,7 @@ int pm_printf(pmloglevel_t level, const char *format, ...)
ret = pm_vfprintf(stdout, level, format, args);
va_end(args);
- return(ret);
+ return ret;
}
int pm_fprintf(FILE *stream, pmloglevel_t level, const char *format, ...)
@@ -961,7 +1199,7 @@ int pm_fprintf(FILE *stream, pmloglevel_t level, const char *format, ...)
ret = pm_vfprintf(stream, level, format, args);
va_end(args);
- return(ret);
+ return ret;
}
int pm_asprintf(char **string, const char *format, ...)
@@ -977,7 +1215,7 @@ int pm_asprintf(char **string, const char *format, ...)
}
va_end(args);
- return(ret);
+ return ret;
}
int pm_vasprintf(char **string, pmloglevel_t level, const char *format, va_list args)
@@ -1013,7 +1251,7 @@ int pm_vasprintf(char **string, pmloglevel_t level, const char *format, va_list
}
free(msg);
- return(ret);
+ return ret;
}
int pm_vfprintf(FILE *stream, pmloglevel_t level, const char *format, va_list args)
@@ -1061,7 +1299,7 @@ int pm_vfprintf(FILE *stream, pmloglevel_t level, const char *format, va_list ar
/* print the message using va_arg list */
ret = vfprintf(stream, format, args);
- return(ret);
+ return ret;
}
#ifndef HAVE_STRNDUP
@@ -1070,7 +1308,7 @@ static size_t strnlen(const char *s, size_t max)
{
register const char *p;
for(p = s; *p && max--; ++p);
- return(p - s);
+ return (p - s);
}
char *strndup(const char *s, size_t n)
@@ -1078,11 +1316,11 @@ char *strndup(const char *s, size_t n)
size_t len = strnlen(s, n);
char *new = (char *) malloc(len + 1);
- if (new == NULL)
+ if(new == NULL)
return NULL;
new[len] = '\0';
- return (char *) memcpy(new, s, len);
+ return (char *)memcpy(new, s, len);
}
#endif
diff --git a/src/pacman/util.h b/src/pacman/util.h
index 234a631d..d8ae7d80 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -52,6 +52,8 @@ char *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);
+double humanize_size(off_t bytes, const char target_unit, int long_labels, 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 display_targets(const alpm_list_t *pkgs, int install);