index : pacman | |
Archlinux32 fork of pacman | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | src/pacman/.gitignore | 2 | ||||
-rw-r--r-- | src/pacman/Makefile.am | 5 | ||||
-rw-r--r-- | src/pacman/add.c | 26 | ||||
-rw-r--r-- | src/pacman/callback.c | 3 | ||||
-rw-r--r-- | src/pacman/conf.c | 24 | ||||
-rw-r--r-- | src/pacman/conf.h | 15 | ||||
-rw-r--r-- | src/pacman/deptest.c | 19 | ||||
-rw-r--r-- | src/pacman/package.c | 25 | ||||
-rw-r--r-- | src/pacman/pacman.c | 261 | ||||
-rw-r--r-- | src/pacman/query.c | 262 | ||||
-rw-r--r-- | src/pacman/remove.c | 15 | ||||
-rw-r--r-- | src/pacman/sync.c | 56 | ||||
-rw-r--r-- | src/pacman/util.c | 11 | ||||
-rw-r--r-- | src/util/.gitignore | 3 | ||||
-rw-r--r-- | src/util/Makefile.am | 18 | ||||
-rw-r--r-- | src/util/testdb.c | 193 | ||||
-rw-r--r-- | src/util/testpkg.c | 14 | ||||
-rw-r--r-- | src/util/vercmp.c | 23 |
diff --git a/src/pacman/.gitignore b/src/pacman/.gitignore index f8247c5e..3b2600fd 100644 --- a/src/pacman/.gitignore +++ b/src/pacman/.gitignore @@ -1,6 +1,4 @@ .deps .libs -Makefile -Makefile.in pacman pacman.static diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am index 589ac63c..939ff197 100644 --- a/src/pacman/Makefile.am +++ b/src/pacman/Makefile.am @@ -1,10 +1,15 @@ # paths set at make time conffile = ${sysconfdir}/pacman.conf +dbpath = ${localstatedir}/lib/pacman/ +cachedir = ${localstatedir}/cache/pacman/pkg/ bin_PROGRAMS = pacman pacman.static DEFS = -DLOCALEDIR=\"@localedir@\" \ -DCONFFILE=\"$(conffile)\" \ + -DROOTDIR=\"$(ROOTDIR)\" \ + -DDBPATH=\"$(dbpath)\" \ + -DCACHEDIR=\"$(cachedir)\" \ @DEFS@ INCLUDES = -I$(top_srcdir)/lib/libalpm diff --git a/src/pacman/add.c b/src/pacman/add.c index 71578f63..0b59a236 100644 --- a/src/pacman/add.c +++ b/src/pacman/add.c @@ -42,7 +42,7 @@ static int add_cleanup(void) int ret = alpm_trans_release(); if(ret != 0) { pm_printf(PM_LOG_ERROR, _("failed to release transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); ret = 1; } @@ -105,7 +105,7 @@ int pacman_add(alpm_list_t *targets) if(alpm_trans_init(transtype, config->flags, cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) { /* TODO: error messages should be in the front end, not the back */ - fprintf(stderr, _("error: %s\n"), alpm_strerror(pm_errno)); + fprintf(stderr, _("error: %s\n"), alpm_strerrorlast()); if(pm_errno == PM_ERR_HANDLE_LOCK) { /* TODO this and the 2 other places should probably be on stderr */ printf(_(" if you're sure a package manager is not already\n" @@ -120,7 +120,7 @@ int pacman_add(alpm_list_t *targets) char *targ = alpm_list_getdata(i); if(alpm_trans_addtarget(targ) == -1) { fprintf(stderr, _("error: failed to add target '%s' (%s)"), targ, - alpm_strerror(pm_errno)); + alpm_strerrorlast()); add_cleanup(); return(1); } @@ -131,28 +131,29 @@ int pacman_add(alpm_list_t *targets) /* TODO: No, compute nothing. This is stupid. */ if(alpm_trans_prepare(&data) == -1) { fprintf(stderr, _("error: failed to prepare transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); switch(pm_errno) { case PM_ERR_UNSATISFIED_DEPS: for(i = data; i; i = alpm_list_next(i)) { pmdepmissing_t *miss = alpm_list_getdata(i); + pmdepend_t *dep = alpm_miss_get_dep(miss); /* TODO indicate if the error was a virtual package or not: * :: %s: requires %s, provided by %s */ - printf(_(":: %s: requires %s"), alpm_dep_get_target(miss), - alpm_dep_get_name(miss)); - switch(alpm_dep_get_mod(miss)) { + printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss), + alpm_dep_get_name(dep)); + switch(alpm_dep_get_mod(dep)) { case PM_DEP_MOD_ANY: break; case PM_DEP_MOD_EQ: - printf("=%s", alpm_dep_get_version(miss)); + printf("=%s", alpm_dep_get_version(dep)); break; case PM_DEP_MOD_GE: - printf(">=%s", alpm_dep_get_version(miss)); + printf(">=%s", alpm_dep_get_version(dep)); break; case PM_DEP_MOD_LE: - printf("<=%s", alpm_dep_get_version(miss)); + printf("<=%s", alpm_dep_get_version(dep)); break; } printf("\n"); @@ -161,8 +162,9 @@ int pacman_add(alpm_list_t *targets) case PM_ERR_CONFLICTING_DEPS: for(i = data; i; i = alpm_list_next(i)) { pmdepmissing_t *miss = alpm_list_getdata(i); + pmdepend_t *dep = alpm_miss_get_dep(miss); printf(_(":: %s: conflicts with %s"), - alpm_dep_get_target(miss), alpm_dep_get_name(miss)); + alpm_miss_get_target(miss), alpm_dep_get_name(dep)); } break; case PM_ERR_FILE_CONFLICTS: @@ -195,7 +197,7 @@ int pacman_add(alpm_list_t *targets) /* Step 3: perform the installation */ if(alpm_trans_commit(NULL) == -1) { - fprintf(stderr, _("error: failed to commit transaction (%s)\n"), alpm_strerror(pm_errno)); + fprintf(stderr, _("error: failed to commit transaction (%s)\n"), alpm_strerrorlast()); add_cleanup(); return(1); } diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 0e5d87ee..fac16c5e 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -25,7 +25,6 @@ #include <stdlib.h> #include <string.h> #include <sys/time.h> -#include <sys/stat.h> #include <unistd.h> #include <dirent.h> #include <wchar.h> @@ -61,7 +60,7 @@ static int prevpercent=0; /* for less progressbar output */ static float get_update_timediff(int first_call) { float retval = 0.0; - static struct timeval last_time = {0}; + static struct timeval last_time = {0, 0}; /* on first call, simply set the last time and return */ if(first_call) { diff --git a/src/pacman/conf.c b/src/pacman/conf.c index 245e3c04..2bc69820 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -23,32 +23,36 @@ #include <stdlib.h> #include <stdio.h> +#include <string.h> /* strdup */ /* pacman */ #include "conf.h" config_t *config_new(void) { - config_t *config = calloc(1, sizeof(config_t)); - if(!config) { + config_t *newconfig = calloc(1, sizeof(config_t)); + if(!newconfig) { fprintf(stderr, "malloc failure: could not allocate %d bytes\n", sizeof(config_t)); } - config->op = PM_OP_MAIN; - config->logmask = PM_LOG_ERROR | PM_LOG_WARNING; + /* defaults which may get overridden later */ + newconfig->op = PM_OP_MAIN; + newconfig->logmask = PM_LOG_ERROR | PM_LOG_WARNING; + /* CONFFILE is defined at compile-time */ + newconfig->configfile = strdup(CONFFILE); - return(config); + return(newconfig); } -int config_free(config_t *config) +int config_free(config_t *oldconfig) { - if(config == NULL) { + if(oldconfig == NULL) { return(-1); } - free(config->configfile); - free(config); - config = NULL; + free(oldconfig->configfile); + free(oldconfig); + oldconfig = NULL; return(0); } diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 252bb95a..85889d19 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -24,7 +24,6 @@ #include <alpm.h> typedef struct __config_t { - /* command line options */ char *configfile; unsigned short op; unsigned short verbose; @@ -34,19 +33,23 @@ typedef struct __config_t { unsigned short noconfirm; unsigned short noprogressbar; unsigned short logmask; + /* keep track if we had paths specified on command line */ + unsigned short have_root; + unsigned short have_dbpath; + unsigned short have_logfile; - /* command line options */ - unsigned short op_d_resolve; unsigned short op_q_isfile; unsigned short op_q_info; unsigned short op_q_list; unsigned short op_q_foreign; unsigned short op_q_orphans; + unsigned short op_q_deps; + unsigned short op_q_explicit; unsigned short op_q_owns; unsigned short op_q_search; unsigned short op_q_changelog; - unsigned short op_q_test; unsigned short op_q_upgrade; + unsigned short op_s_clean; unsigned short op_s_dependsonly; unsigned short op_s_downloadonly; @@ -54,10 +57,12 @@ typedef struct __config_t { unsigned short op_s_sync; unsigned short op_s_search; unsigned short op_s_upgrade; + unsigned short group; pmtransflag_t flags; unsigned short noask; unsigned int ask; + /* conf file options */ unsigned short chomp; /* I Love Candy! */ unsigned short usecolor; /* enable colorful output */ @@ -76,7 +81,7 @@ enum { }; config_t *config_new(void); -int config_free(config_t *config); +int config_free(config_t *oldconfig); #endif /* _PM_CONF_H */ diff --git a/src/pacman/deptest.c b/src/pacman/deptest.c index 264ba1c9..7f89f6d2 100644 --- a/src/pacman/deptest.c +++ b/src/pacman/deptest.c @@ -35,6 +35,7 @@ extern config_t *config; +/* TODO: This should use _alpm_checkdeps() */ int pacman_deptest(alpm_list_t *targets) { int retval = 0; @@ -52,20 +53,16 @@ int pacman_deptest(alpm_list_t *targets) alpm_list_t *j, *provides; target = alpm_list_getdata(i); - - /* splitdep modifies the string... we'll compensate for now */ - char *saved_target = NULL; - saved_target = calloc(strlen(target)+1, sizeof(char)); - strncpy(saved_target, target, strlen(target)); - dep = alpm_splitdep(target); - pkg = alpm_db_get_pkg(alpm_option_get_localdb(), target); + pkg = alpm_db_get_pkg(alpm_option_get_localdb(), + alpm_dep_get_name(dep)); if(pkg && alpm_depcmp(pkg, dep)) { found = 1; } else { /* not found, can we find anything that provides this in the local DB? */ - provides = alpm_db_whatprovides(alpm_option_get_localdb(), target); + provides = alpm_db_whatprovides(alpm_option_get_localdb(), + alpm_dep_get_name(dep)); for(j = provides; j; j = alpm_list_next(j)) { pmpkg_t *pkg; pkg = alpm_list_getdata(j); @@ -78,10 +75,10 @@ int pacman_deptest(alpm_list_t *targets) } if(!found) { - printf("%s\n", saved_target); - retval = 1; + printf("%s\n", target); + retval = 127; } - free(saved_target); + free(dep); } return(retval); } diff --git a/src/pacman/package.c b/src/pacman/package.c index a30260ae..86d91ecb 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -43,7 +43,7 @@ */ void dump_pkg_full(pmpkg_t *pkg, int level) { - const char *bdate, *type, *idate, *reason, *descheader; + const char *bdate, *idate, *reason, *descheader; if(pkg == NULL) { return; @@ -51,7 +51,6 @@ void dump_pkg_full(pmpkg_t *pkg, int level) /* set variables here, do all output below */ bdate = alpm_pkg_get_builddate(pkg); - type = alpm_pkg_get_buildtype(pkg); idate = alpm_pkg_get_installdate(pkg); switch((long)alpm_pkg_get_reason(pkg)) { @@ -86,7 +85,6 @@ void dump_pkg_full(pmpkg_t *pkg, int level) printf(_("Packager : %s\n"), (char *)alpm_pkg_get_packager(pkg)); printf(_("Architecture : %s\n"), (char *)alpm_pkg_get_arch(pkg)); printf(_("Build Date : %s %s\n"), bdate, strlen(bdate) ? "UTC" : ""); - printf(_("Build Type : %s\n"), strlen(type) ? type : _("Unknown")); if(level > 0) { printf(_("Install Date : %s %s\n"), idate, strlen(idate) ? "UTC" : ""); printf(_("Install Reason : %s\n"), reason); @@ -112,7 +110,7 @@ void dump_pkg_full(pmpkg_t *pkg, int level) */ void dump_pkg_sync(pmpkg_t *pkg, const char *treename) { - const char *descheader, *md5sum, *sha1sum; + const char *descheader, *md5sum; if(pkg == NULL) { return; } @@ -120,7 +118,6 @@ void dump_pkg_sync(pmpkg_t *pkg, const char *treename) descheader = _("Description : "); md5sum = alpm_pkg_get_md5sum(pkg); - sha1sum = alpm_pkg_get_sha1sum(pkg); printf(_("Repository : %s\n"), treename); printf(_("Name : %s\n"), (char *)alpm_pkg_get_name(pkg)); @@ -141,9 +138,6 @@ void dump_pkg_sync(pmpkg_t *pkg, const char *treename) if (md5sum != NULL && md5sum[0] != '\0') { printf(_("MD5 Sum : %s"), md5sum); } - if (sha1sum != NULL && sha1sum[0] != '\0') { - printf(_("SHA1 Sum : %s"), sha1sum); - } printf("\n"); } @@ -170,31 +164,22 @@ void dump_pkg_backups(pmpkg_t *pkg) snprintf(path, PATH_MAX-1, "%s%s", root, str); /* if we find the file, calculate checksums, otherwise it is missing */ if(!stat(path, &buf)) { - char *sum; char *md5sum = alpm_get_md5sum(path); - char *sha1sum = alpm_get_sha1sum(path); - if(md5sum == NULL || sha1sum == NULL) { + if(md5sum == NULL) { fprintf(stderr, _("error: could not calculate checksums for %s\n"), path); free(str); continue; } - /* TODO Is this a good way to check type of backup stored? - * We aren't storing it anywhere in the database. */ - if (strlen(ptr) == 32) { - sum = md5sum; - } else { /*if (strlen(ptr) == 40) */ - sum = sha1sum; - } + /* if checksums don't match, file has been modified */ - if (strcmp(sum, ptr)) { + if (strcmp(md5sum, ptr)) { printf(_("MODIFIED\t%s\n"), path); } else { printf(_("Not Modified\t%s\n"), path); } free(md5sum); - free(sha1sum); } else { printf(_("MISSING\t\t%s\n"), path); } diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index a345977d..aa128261 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -1,8 +1,8 @@ /* * pacman.c - * - * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> - * + * + * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org> + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -15,14 +15,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include "config.h" -/* TODO hard to believe all these are needed just for this file */ -#include <stdlib.h> +#include <stdlib.h> /* atoi */ #include <stdio.h> #include <limits.h> #include <getopt.h> @@ -30,11 +29,10 @@ #include <signal.h> #include <unistd.h> #include <sys/types.h> -#include <sys/stat.h> -#include <sys/utsname.h> -#include <libintl.h> -#include <locale.h> -#include <time.h> +#include <sys/utsname.h> /* uname */ +#include <libintl.h> /* bindtextdomain, textdomain */ +#include <locale.h> /* setlocale */ +#include <time.h> /* time_t */ #if defined(PACMAN_DEBUG) && defined(HAVE_MTRACE) #include <mcheck.h> /* debug tracing (mtrace) */ #endif @@ -56,9 +54,7 @@ pmdb_t *db_local; /* list of targets specified on command line */ static alpm_list_t *pm_targets; -/** - * @brief Display usage/syntax for the specified operation. - * +/** Display usage/syntax for the specified operation. * @param op the operation code requested * @param myname basename(argv[0]) */ @@ -88,6 +84,7 @@ static void usage(int op, char *myname) if(op == PM_OP_ADD) { printf("%s: %s {-A --add} [%s] <%s>\n", str_usg, myname, str_opt, str_file); printf("%s:\n", str_opt); + printf(_(" --asdeps install packages as non-explicitly installed\n")); printf(_(" -d, --nodeps skip dependency checks\n")); printf(_(" -f, --force force install, overwrite conflicting files\n")); } else if(op == PM_OP_REMOVE) { @@ -106,14 +103,15 @@ static void usage(int op, char *myname) printf("%s: %s {-U --upgrade} [%s] <%s>\n", str_usg, myname, str_opt, str_file); } printf("%s:\n", str_opt); + printf(_(" --asdeps install packages as non-explicitly installed\n")); printf(_(" -d, --nodeps skip dependency checks\n")); printf(_(" -f, --force force install, overwrite conflicting files\n")); } else if(op == PM_OP_QUERY) { printf("%s: %s {-Q --query} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); printf(_(" -c, --changelog view the changelog of a package\n")); - printf(_(" -e, --orphans list all packages installed as dependencies but no longer\n" - " required by any package\n")); + printf(_(" -d, --deps list all packages installed as dependencies\n")); + printf(_(" -e, --explicit list all packages explicitly installed\n")); printf(_(" -g, --groups view all members of a package group\n")); printf(_(" -i, --info view package information\n")); printf(_(" -l, --list list the contents of the queried package\n")); @@ -121,11 +119,12 @@ static void usage(int op, char *myname) printf(_(" -o, --owns <file> query the package that owns <file>\n")); printf(_(" -p, --file <package> query a package file instead of the database\n")); printf(_(" -s, --search <regex> search locally-installed packages for matching strings\n")); - printf(_(" -t, --test check the consistency of the local database\n")); + printf(_(" -t, --orphans list all packages not required by any package\n")); printf(_(" -u, --upgrades list all packages that can be upgraded\n")); } else if(op == PM_OP_SYNC) { printf("%s: %s {-S --sync} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); + printf(_(" --asdeps install packages as non-explicitly installed\n")); printf(_(" -c, --clean remove old packages from cache directory (-cc for all)\n")); printf(_(" -d, --nodeps skip dependency checks\n")); printf(_(" -e, --dependsonly install dependencies only\n")); @@ -152,8 +151,7 @@ static void usage(int op, char *myname) } } -/** - * @brief Output pacman version and copyright. +/** Output pacman version and copyright. */ static void version(void) { @@ -167,9 +165,7 @@ static void version(void) printf("\n"); } -/** - * @brief Sets up gettext localization. - * Safe to call multiple times. +/** Sets up gettext localization. Safe to call multiple times. */ /* Inspired by the monotone function localize_monotone. */ static void localize(void) @@ -183,8 +179,7 @@ static void localize(void) } } -/** - * @brief Set user agent environment variable. +/** Set user agent environment variable. */ static void setuseragent(void) { @@ -199,11 +194,8 @@ static void setuseragent(void) setenv("HTTP_USER_AGENT", agent, 0); } -/** - * @brief Catches thrown signals. - * Performs necessary cleanup to ensure database is in a consistant - * state. - * +/** Catches thrown signals. Performs necessary cleanup to ensure database is + * in a consistant state. * @param signum the thrown signal */ static void cleanup(int signum) @@ -215,14 +207,19 @@ static void cleanup(int signum) pm_fprintf(stderr, PM_LOG_ERROR, "Internal pacman error: Segmentation fault.\n" "Please submit a full bug report with --debug if appropriate.\n"); exit(signum); - } else if((signum == SIGINT) && (alpm_trans_release() == -1) - && (pm_errno == PM_ERR_TRANS_COMMITING)) { - return; + } else if((signum == SIGINT)) { + if(alpm_trans_interrupt() == 0) { + /* a transaction is being interrupted, don't exit pacman yet. */ + return; + } else { + /* no commiting transaction, we can release it now and then exit pacman */ + alpm_trans_release(); + } } /* free alpm library resources */ if(alpm_release() == -1) { - fprintf(stderr, _("error: %s\n"), alpm_strerror(pm_errno)); + pm_printf(PM_LOG_ERROR, alpm_strerrorlast()); } /* free memory */ @@ -235,12 +232,9 @@ static void cleanup(int signum) exit(signum); } -/** - * @brief Parse command-line arguments for each operation - * +/** Parse command-line arguments for each operation. * @param argc argc * @param argv argv - * * @return 0 on success, 1 on error */ static int parseargs(int argc, char *argv[]) @@ -262,8 +256,9 @@ static int parseargs(int argc, char *argv[]) {"changelog", no_argument, 0, 'c'}, {"clean", no_argument, 0, 'c'}, {"nodeps", no_argument, 0, 'd'}, + {"deps", no_argument, 0, 'd'}, {"dependsonly",no_argument, 0, 'e'}, - {"orphans", no_argument, 0, 'e'}, + {"explicit", no_argument, 0, 'e'}, {"force", no_argument, 0, 'f'}, {"groups", no_argument, 0, 'g'}, {"help", no_argument, 0, 'h'}, @@ -278,7 +273,7 @@ static int parseargs(int argc, char *argv[]) {"root", required_argument, 0, 'r'}, {"recursive", no_argument, 0, 's'}, {"search", no_argument, 0, 's'}, - {"test", no_argument, 0, 't'}, + {"orphans", no_argument, 0, 't'}, {"upgrades", no_argument, 0, 'u'}, {"sysupgrade", no_argument, 0, 'u'}, {"verbose", no_argument, 0, 'v'}, @@ -288,13 +283,13 @@ static int parseargs(int argc, char *argv[]) {"config", required_argument, 0, 1001}, {"ignore", required_argument, 0, 1002}, {"debug", optional_argument, 0, 1003}, - {"noprogressbar", no_argument, 0, 1004}, + {"noprogressbar", no_argument, 0, 1004}, {"noscriptlet", no_argument, 0, 1005}, {"ask", required_argument, 0, 1006}, {"cachedir", required_argument, 0, 1007}, + {"asdeps", no_argument, 0, 1008}, {0, 0, 0, 0} }; - struct stat st; while((opt = getopt_long(argc, argv, "ARUFQSTr:b:vkhscVfmnoldepituwygz", opts, &option_index))) { if(opt < 0) { @@ -323,8 +318,8 @@ static int parseargs(int argc, char *argv[]) config->logmask |= PM_LOG_DEBUG; break; default: - fprintf(stderr, _("error: '%s' is not a valid debug level\n"), - optarg); + pm_printf(PM_LOG_ERROR, _("'%s' is not a valid debug level\n"), + optarg); return(1); } } else { @@ -337,13 +332,14 @@ static int parseargs(int argc, char *argv[]) case 1005: config->flags |= PM_TRANS_FLAG_NOSCRIPTLET; break; case 1006: config->noask = 1; config->ask = atoi(optarg); break; case 1007: - /* TODO redo this logic- check path somewhere else, delete other cachedirs, etc */ - if(stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) { - fprintf(stderr, _("error: '%s' is not a valid cache directory\n"), - optarg); + if(alpm_option_add_cachedir(optarg) != 0) { + pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"), + optarg, alpm_strerrorlast()); return(1); } - alpm_option_add_cachedir(optarg); + break; + case 1008: + config->flags |= PM_TRANS_FLAG_ALLDEPS; break; case 'A': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_ADD); break; case 'F': @@ -357,21 +353,24 @@ static int parseargs(int argc, char *argv[]) case 'U': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_UPGRADE); break; case 'V': config->version = 1; break; case 'b': - if(stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) { - fprintf(stderr, _("error: '%s' is not a valid db path\n"), - optarg); + if(alpm_option_set_dbpath(optarg) != 0) { + pm_printf(PM_LOG_ERROR, _("problem setting dbpath '%s' (%s)\n"), + optarg, alpm_strerrorlast()); return(1); } - alpm_option_set_dbpath(optarg); + config->have_dbpath = 1; break; case 'c': (config->op_s_clean)++; config->flags |= PM_TRANS_FLAG_CASCADE; config->op_q_changelog = 1; break; - case 'd': config->flags |= PM_TRANS_FLAG_NODEPS; break; + case 'd': + config->op_q_deps = 1; + config->flags |= PM_TRANS_FLAG_NODEPS; + break; case 'e': - config->op_q_orphans++; + config->op_q_explicit = 1; config->flags |= PM_TRANS_FLAG_DEPENDSONLY; break; case 'f': config->flags |= PM_TRANS_FLAG_FORCE; break; @@ -388,12 +387,12 @@ static int parseargs(int argc, char *argv[]) config->flags |= PM_TRANS_FLAG_PRINTURIS; break; case 'r': - if(stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) { - fprintf(stderr, _("error: '%s' is not a valid root path\n"), - optarg); + if(alpm_option_set_root(optarg) != 0) { + pm_printf(PM_LOG_ERROR, _("problem setting root '%s' (%s)\n"), + optarg, alpm_strerrorlast()); return(1); } - alpm_option_set_root(optarg); + config->have_root = 1; break; case 's': config->op_s_search = 1; @@ -401,7 +400,7 @@ static int parseargs(int argc, char *argv[]) config->flags |= PM_TRANS_FLAG_RECURSE; break; case 't': - config->op_q_test = 1; + config->op_q_orphans = 1; break; case 'u': config->op_s_upgrade = 1; @@ -420,7 +419,7 @@ static int parseargs(int argc, char *argv[]) } if(config->op == 0) { - fprintf(stderr, _("error: only one operation may be used at a time\n")); + pm_printf(PM_LOG_ERROR, _("only one operation may be used at a time\n")); return(1); } @@ -453,7 +452,7 @@ static int _parseconfig(const char *file, const char *givensection, char *ptr, *section = NULL; pmdb_t *db = NULL; - pm_printf(PM_LOG_DEBUG, _("config: attempting to read file %s\n"), file); + 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); @@ -490,26 +489,19 @@ static int _parseconfig(const char *file, const char *givensection, } section = strdup(ptr); section[strlen(section)-1] = '\0'; - pm_printf(PM_LOG_DEBUG, _("config: new section '%s'\n"), section); + 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); return(1); } - /* a section/database named local is not allowed */ - if(!strcmp(section, "local")) { - pm_printf(PM_LOG_ERROR, _("config file %s, line %d: 'local' cannot be used as section name.\n"), - file, linenum); - return(1); - } /* if we are not looking at the options section, register a db */ if(strcmp(section, "options") != 0) { - db = alpm_db_register(section); + db = alpm_db_register_sync(section); } } else { /* directive */ - char *key; - const char *upperkey; + char *key, *upperkey; /* strsep modifies the 'line' string: 'key \0 ptr' */ key = line; ptr = line; @@ -522,6 +514,10 @@ static int _parseconfig(const char *file, const char *givensection, file, linenum); return(1); } + /* For each directive, compare to the uppercase and camelcase string. + * This prevents issues with certain locales where characters don't + * follow the toupper() rules we may expect, e.g. tr_TR where i != I. + */ upperkey = strtoupper(strdup(key)); if(section == NULL && (strcmp(key, "Include") == 0 || strcmp(upperkey, "INCLUDE") == 0)) { pm_printf(PM_LOG_ERROR, _("config file %s, line %d: 'Include' directive must belong to a section.\n"), @@ -532,19 +528,19 @@ static int _parseconfig(const char *file, const char *givensection, /* directives without settings, all in [options] */ if(strcmp(key, "NoPassiveFTP") == 0 || strcmp(upperkey, "NOPASSIVEFTP") == 0) { alpm_option_set_nopassiveftp(1); - pm_printf(PM_LOG_DEBUG, _("config: nopassiveftp\n")); + pm_printf(PM_LOG_DEBUG, "config: nopassiveftp\n"); } else if(strcmp(key, "UseSyslog") == 0 || strcmp(upperkey, "USESYSLOG") == 0) { alpm_option_set_usesyslog(1); - pm_printf(PM_LOG_DEBUG, _("config: usesyslog\n")); + pm_printf(PM_LOG_DEBUG, "config: usesyslog\n"); } else if(strcmp(key, "ILoveCandy") == 0 || strcmp(upperkey, "ILOVECANDY") == 0) { config->chomp = 1; - pm_printf(PM_LOG_DEBUG, _("config: chomp\n")); + pm_printf(PM_LOG_DEBUG, "config: chomp\n"); } else if(strcmp(key, "UseColor") == 0 || strcmp(upperkey, "USECOLOR") == 0) { config->usecolor = 1; - pm_printf(PM_LOG_DEBUG, _("config: usecolor\n")); + pm_printf(PM_LOG_DEBUG, "config: usecolor\n"); } else if(strcmp(key, "ShowSize") == 0 || strcmp(upperkey, "SHOWSIZE") == 0) { config->showsize= 1; - pm_printf(PM_LOG_DEBUG, _("config: showsize\n")); + pm_printf(PM_LOG_DEBUG, "config: showsize\n"); } else { pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' not recognized.\n"), file, linenum, key); @@ -554,7 +550,7 @@ static int _parseconfig(const char *file, const char *givensection, /* directives with settings */ if(strcmp(key, "Include") == 0 || strcmp(upperkey, "INCLUDE") == 0) { int ret; - pm_printf(PM_LOG_DEBUG, _("config: including %s\n"), ptr); + pm_printf(PM_LOG_DEBUG, "config: including %s\n", ptr); ret = _parseconfig(ptr, section, db); if(ret != 0) { return(ret); @@ -568,12 +564,12 @@ static int _parseconfig(const char *file, const char *givensection, while((q = strchr(p, ' '))) { *q = '\0'; alpm_option_add_noupgrade(p); - pm_printf(PM_LOG_DEBUG, _("config: noupgrade: %s\n"), p); + pm_printf(PM_LOG_DEBUG, "config: noupgrade: %s\n", p); p = q; p++; } alpm_option_add_noupgrade(p); - pm_printf(PM_LOG_DEBUG, _("config: noupgrade: %s\n"), p); + pm_printf(PM_LOG_DEBUG, "config: noupgrade: %s\n", p); } else if(strcmp(key, "NoExtract") == 0 || strcmp(upperkey, "NOEXTRACT") == 0) { char *p = ptr; char *q; @@ -581,12 +577,12 @@ static int _parseconfig(const char *file, const char *givensection, while((q = strchr(p, ' '))) { *q = '\0'; alpm_option_add_noextract(p); - pm_printf(PM_LOG_DEBUG, _("config: noextract: %s\n"), p); + pm_printf(PM_LOG_DEBUG, "config: noextract: %s\n", p); p = q; p++; } alpm_option_add_noextract(p); - pm_printf(PM_LOG_DEBUG, _("config: noextract: %s\n"), p); + pm_printf(PM_LOG_DEBUG, "config: noextract: %s\n", p); } else if(strcmp(key, "IgnorePkg") == 0 || strcmp(upperkey, "IGNOREPKG") == 0) { char *p = ptr; char *q; @@ -594,12 +590,12 @@ static int _parseconfig(const char *file, const char *givensection, while((q = strchr(p, ' '))) { *q = '\0'; alpm_option_add_ignorepkg(p); - pm_printf(PM_LOG_DEBUG, _("config: ignorepkg: %s"), p); + pm_printf(PM_LOG_DEBUG, "config: ignorepkg: %s", p); p = q; p++; } alpm_option_add_ignorepkg(p); - pm_printf(PM_LOG_DEBUG, _("config: ignorepkg: %s\n"), p); + pm_printf(PM_LOG_DEBUG, "config: ignorepkg: %s\n", p); } else if(strcmp(key, "HoldPkg") == 0 || strcmp(upperkey, "HOLDPKG") == 0) { char *p = ptr; char *q; @@ -607,38 +603,56 @@ static int _parseconfig(const char *file, const char *givensection, while((q = strchr(p, ' '))) { *q = '\0'; alpm_option_add_holdpkg(p); - pm_printf(PM_LOG_DEBUG, _("config: holdpkg: %s\n"), p); + pm_printf(PM_LOG_DEBUG, "config: holdpkg: %s\n", p); p = q; p++; } alpm_option_add_holdpkg(p); - pm_printf(PM_LOG_DEBUG, _("config: holdpkg: %s\n"), p); + pm_printf(PM_LOG_DEBUG, "config: holdpkg: %s\n", p); } else if(strcmp(key, "DBPath") == 0 || strcmp(upperkey, "DBPATH") == 0) { - if(alpm_option_get_dbpath() == NULL) { - alpm_option_set_dbpath(ptr); - pm_printf(PM_LOG_DEBUG, _("config: dbpath: %s\n"), ptr); + /* don't overwrite a path specified on the command line */ + if(!config->have_dbpath) { + if(alpm_option_set_dbpath(ptr) != 0) { + pm_printf(PM_LOG_ERROR, _("problem setting dbpath '%s' (%s)\n"), + ptr, alpm_strerrorlast()); + return(1); + } + pm_printf(PM_LOG_DEBUG, "config: dbpath: %s\n", ptr); } } else if(strcmp(key, "CacheDir") == 0 || strcmp(upperkey, "CACHEDIR") == 0) { - alpm_option_add_cachedir(ptr); - pm_printf(PM_LOG_DEBUG, _("config: cachedir: %s\n"), ptr); + if(alpm_option_add_cachedir(ptr) != 0) { + pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"), + ptr, alpm_strerrorlast()); + return(1); + } + pm_printf(PM_LOG_DEBUG, "config: cachedir: %s\n", ptr); } else if(strcmp(key, "RootDir") == 0 || strcmp(upperkey, "ROOTDIR") == 0) { - if(alpm_option_get_root() == NULL) { - alpm_option_set_root(ptr); - pm_printf(PM_LOG_DEBUG, _("config: rootdir: %s\n"), ptr); + /* don't overwrite a path specified on the command line */ + if(!config->have_root) { + if(alpm_option_set_root(ptr) != 0) { + pm_printf(PM_LOG_ERROR, _("problem setting root '%s' (%s)\n"), + ptr, alpm_strerrorlast()); + return(1); + } + pm_printf(PM_LOG_DEBUG, "config: rootdir: %s\n", ptr); } } else if (strcmp(key, "LogFile") == 0 || strcmp(upperkey, "LOGFILE") == 0) { - if(alpm_option_get_logfile() == NULL) { - alpm_option_set_logfile(ptr); - pm_printf(PM_LOG_DEBUG, _("config: logfile: %s\n"), ptr); + if(!config->have_logfile) { + if(alpm_option_set_logfile(ptr) != 0) { + pm_printf(PM_LOG_ERROR, _("problem setting logfile '%s' (%s)\n"), + ptr, alpm_strerrorlast()); + return(1); + } + pm_printf(PM_LOG_DEBUG, "config: logfile: %s\n", ptr); } } else if (strcmp(key, "XferCommand") == 0 || strcmp(upperkey, "XFERCOMMAND") == 0) { alpm_option_set_xfercommand(ptr); - pm_printf(PM_LOG_DEBUG, _("config: xfercommand: %s\n"), ptr); + pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", ptr); } else if (strcmp(key, "UpgradeDelay") == 0 || strcmp(upperkey, "UPGRADEDELAY") == 0) { /* The config value is in days, we use seconds */ time_t ud = atol(ptr) * 60 * 60 *24; alpm_option_set_upgradedelay(ud); - pm_printf(PM_LOG_DEBUG, _("config: upgradedelay: %d\n"), (int)ud); + pm_printf(PM_LOG_DEBUG, "config: upgradedelay: %d\n", (int)ud); } else { pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' not recognized.\n"), file, linenum, key); @@ -660,9 +674,13 @@ static int _parseconfig(const char *file, const char *givensection, return(1); } } + free(upperkey); } } fclose(fp); + if(section){ + free(section); + } pm_printf(PM_LOG_DEBUG, "config: finished parsing %s\n", file); return(0); @@ -678,12 +696,9 @@ int parseconfig(const char *file) return(_parseconfig(file, NULL, NULL)); } -/** - * @brief Main function. - * +/** Main function. * @param argc argc * @param argv argv - * * @return A return code indicating success, failure, etc. */ int main(int argc, char *argv[]) @@ -718,16 +733,28 @@ int main(int argc, char *argv[]) config->noprogressbar = 1; } - /* initialize pm library */ + /* initialize library */ if(alpm_initialize() == -1) { - fprintf(stderr, _("error: failed to initialize alpm library (%s)\n"), - alpm_strerror(pm_errno)); + pm_printf(PM_LOG_ERROR, _("failed to initialize alpm library (%s)\n"), + alpm_strerrorlast()); cleanup(EXIT_FAILURE); } /* Setup logging as soon as possible, to print out maximum debugging info */ alpm_option_set_logcb(cb_log); alpm_option_set_dlcb(cb_dl_progress); + /* define root and dbpath to reasonable defaults */ + alpm_option_set_root(ROOTDIR); + alpm_option_set_dbpath(DBPATH); + + /* Priority of options: + * 1. command line + * 2. config file + * 3. compiled-in defaults + * However, we have to parse the command line first because a config file + * location can be specified here, so we need to make sure we prefer these + * options over the config file coming second. + */ /* parse the command line */ ret = parseargs(argc, argv); @@ -735,37 +762,35 @@ int main(int argc, char *argv[]) cleanup(ret); } - /* use default config file if location wasn't specified on cmdline */ - if(config->configfile == NULL) { - config->configfile = strdup(CONFFILE); - } - /* parse the config file */ ret = parseconfig(config->configfile); if(ret != 0) { cleanup(ret); } + /* add a default cachedir if one wasn't specified */ + if(alpm_option_get_cachedirs() == NULL) { + alpm_option_add_cachedir(CACHEDIR); + } + #if defined(HAVE_GETEUID) /* check if we have sufficient permission for the requested operation */ -if(0) { if(myuid > 0) { if(config->op != PM_OP_MAIN && config->op != PM_OP_QUERY && config->op != PM_OP_DEPTEST) { if((config->op == PM_OP_SYNC && !config->op_s_sync && (config->op_s_search || config->group || config->op_q_list || config->op_q_info || config->flags & PM_TRANS_FLAG_PRINTURIS)) - || (config->op == PM_OP_DEPTEST && config->op_d_resolve) + || config->op == PM_OP_DEPTEST || (strcmp(alpm_option_get_root(), "/") != 0)) { /* special case: PM_OP_SYNC can be used w/ config->op_s_search by any user */ /* special case: ignore root user check if -r is specified, fall back on * normal FS checking */ } else { - fprintf(stderr, _("error: you cannot perform this operation unless you are root.\n")); + pm_printf(PM_LOG_ERROR, _("you cannot perform this operation unless you are root.\n")); cleanup(EXIT_FAILURE); } } } -} #endif if(config->verbose > 0) { @@ -784,10 +809,10 @@ if(0) { } /* Opening local database */ - db_local = alpm_db_register("local"); + db_local = alpm_db_register_local(); if(db_local == NULL) { - fprintf(stderr, _("error: could not register 'local' database (%s)\n"), - alpm_strerror(pm_errno)); + pm_printf(PM_LOG_ERROR, _("could not register 'local' database (%s)\n"), + alpm_strerrorlast()); cleanup(EXIT_FAILURE); } @@ -812,7 +837,7 @@ if(0) { ret = pacman_deptest(pm_targets); break; default: - fprintf(stderr, _("error: no operation specified (use -h for help)\n")); + pm_printf(PM_LOG_ERROR, _("no operation specified (use -h for help)\n")); ret = EXIT_FAILURE; } diff --git a/src/pacman/query.c b/src/pacman/query.c index cfd53df7..26a1bd8f 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -153,7 +153,7 @@ static int query_search(alpm_list_t *targets) /* print the package size with the output if ShowSize option set */ if(config->showsize) { /* Convert byte size to MB */ - double mbsize = alpm_pkg_get_size(pkg) / (1024.0 * 1024.0); + double mbsize = (double)alpm_pkg_get_size(pkg) / (1024.0 * 1024.0); printf(" [%.2f MB]", mbsize); } @@ -168,10 +168,11 @@ static int query_search(alpm_list_t *targets) indentprint(alpm_pkg_get_desc(pkg), 4); printf("\n"); } - /* we only want to free if the list was a search list */ - if(freelist) { - alpm_list_free(searchlist); - } + + /* we only want to free if the list was a search list */ + if(freelist) { + alpm_list_free(searchlist); + } return(0); } @@ -195,8 +196,9 @@ static int query_group(alpm_list_t *targets) } } else { for(i = targets; i; i = alpm_list_next(i)) { + pmgrp_t *grp; package = alpm_list_getdata(i); - pmgrp_t *grp = alpm_db_readgrp(db_local, package); + grp = alpm_db_readgrp(db_local, package); if(grp) { const alpm_list_t *p, *pkgnames = alpm_grp_get_pkgs(grp); for(p = pkgnames; p; p = alpm_list_next(p)) { @@ -211,131 +213,93 @@ static int query_group(alpm_list_t *targets) return ret; } -static int query_isfile(alpm_list_t *targets) -{ - int ret = 0; - char *package = NULL; - alpm_list_t *i; - pmpkg_t *info = NULL; - if(targets == NULL) { - fprintf(stderr, _("error: no package file was specified for --file\n")); - return(1); - } else { - for(i = targets; i; i = alpm_list_next(i)) { - package = alpm_list_getdata(i); - if(alpm_pkg_load(package, &info) == -1) { - fprintf(stderr, _("error: failed to load package '%s' (%s)\n"), - package, alpm_strerror(pm_errno)); - ret++; - continue; - } - if(config->op_q_info) { - dump_pkg_full(info, config->op_q_info); - } - if(config->op_q_list) { - dump_pkg_files(info); - } - if(!config->op_q_info && !config->op_q_list) { - printf("%s %s\n", alpm_pkg_get_name(info), - alpm_pkg_get_version(info)); - } - alpm_pkg_free(info); - info = NULL; - } - } - return(ret); -} - -static int query_test(void) -{ - int ret = 0; - alpm_list_t *testlist; - - printf(_("Checking database for consistency...")); - testlist = alpm_db_test(db_local); - if(testlist == NULL) { - printf(_("check complete.\n")); - return(0); - } else { - /* on failure, increment the ret val by 1 for each failure */ - alpm_list_t *i; - printf(_("check failed!\n")); - fflush(stdout); - for(i = testlist; i; i = alpm_list_next(i)) { - fprintf(stderr, "%s\n", (char*)alpm_list_getdata(i)); - ret++; - } - return(ret); - } -} - static int query_upgrades(void) { - printf(_("Checking for package upgrades...")); alpm_list_t *syncpkgs; + printf(_("Checking for package upgrades... \n")); if((syncpkgs = alpm_db_get_upgrades()) != NULL) { display_targets(syncpkgs); return(0); } - printf(_("no upgrades found")); + printf(_("no upgrades found.\n")); return(1); } -static int query_foreign(void) +static int is_foreign(pmpkg_t *pkg) { - alpm_list_t *sync_dbs = NULL; - alpm_list_t *i; - - /* 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")); + const char *pkgname = alpm_pkg_get_name(pkg); + alpm_list_t *j; + alpm_list_t *sync_dbs = alpm_option_get_syncdbs(); + + int match = 0; + for(j = sync_dbs; j; j = alpm_list_next(j)) { + pmdb_t *db = alpm_list_getdata(j); + pmpkg_t *findpkg = alpm_db_get_pkg(db, pkgname); + if(findpkg) { + match = 1; + break; + } + } + if(match == 0) { return(1); } + return(0); +} - for(i = alpm_db_getpkgcache(db_local); i; i = alpm_list_next(i)) { - pmpkg_t *pkg = alpm_list_getdata(i); - const char *pkgname = alpm_pkg_get_name(pkg); - const char *pkgver = alpm_pkg_get_version(pkg); - alpm_list_t *j; - - int match = 0; - for(j = sync_dbs; j; j = alpm_list_next(j)) { - pmdb_t *db = alpm_list_getdata(j); - pmpkg_t *pkg = alpm_db_get_pkg(db, pkgname); - if(pkg) { - match = 1; - break; - } - } - if(match == 0) { - printf("%s %s\n", pkgname, pkgver); - } +static int is_orphan(pmpkg_t *pkg) +{ + if(alpm_pkg_get_requiredby(pkg) == NULL) { + return(1); } return(0); } -static int query_orphans(void) +static int filter(pmpkg_t *pkg) { - alpm_list_t *i; + /* check if this package was explicitly installed */ + if(config->op_q_explicit && + alpm_pkg_get_reason(pkg) != PM_PKG_REASON_EXPLICIT) { + 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); + } + /* check if this pkg isn't in a sync DB */ + if(config->op_q_foreign && !is_foreign(pkg)) { + return(0); + } + /* check if this pkg is orphaned */ + if(config->op_q_orphans && !is_orphan(pkg)) { + return(0); + } + return(1); +} - for(i = alpm_db_getpkgcache(db_local); i; i = alpm_list_next(i)) { - pmpkg_t *pkg = alpm_list_getdata(i); - const char *pkgname = alpm_pkg_get_name(pkg); - const char *pkgver = alpm_pkg_get_version(pkg); - - /* two cases here: - * 1. one -e option was specified, return only those installed as dep - * 2. more than one -e specified, return all with empty requiredby */ - if(alpm_pkg_get_requiredby(pkg) == NULL - && (alpm_pkg_get_reason(pkg) == PM_PKG_REASON_DEPEND - || config->op_q_orphans > 1)) { - printf("%s %s\n", pkgname, pkgver); - } +static void display(pmpkg_t *pkg) +{ + if(config->op_q_info) { + dump_pkg_full(pkg, config->op_q_info); + } + if(config->op_q_list) { + dump_pkg_files(pkg); + } + if(config->op_q_changelog) { + char changelog[PATH_MAX]; + /* TODO should be done in the backend- no raw DB stuff up front */ + snprintf(changelog, PATH_MAX, "%s/%s/%s-%s/changelog", + alpm_option_get_dbpath(), + alpm_db_get_name(db_local), + alpm_pkg_get_name(pkg), + alpm_pkg_get_version(pkg)); + dump_pkg_changelog(changelog, alpm_pkg_get_name(pkg)); + } + if(!config->op_q_info && !config->op_q_list && !config->op_q_changelog) { + printf("%s %s\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); } - return(0); } int pacman_query(alpm_list_t *targets) @@ -351,12 +315,6 @@ int pacman_query(alpm_list_t *targets) return(ret); } - /* check DB consistancy */ - if(config->op_q_test) { - ret = query_test(); - return(ret); - } - /* check for package upgrades */ if(config->op_q_upgrade) { ret = query_upgrades(); @@ -369,35 +327,28 @@ int pacman_query(alpm_list_t *targets) return(ret); } - /* search for installed packages not in a sync DB */ if(config->op_q_foreign) { - ret = query_foreign(); - return(ret); - } - - /* list orphaned packages */ - if(config->op_q_orphans) { - ret = query_orphans(); - return(ret); + /* ensure we have at least one valid sync db set up */ + 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); + } } /* operations on all packages in the local DB * valid: no-op (plain -Q), list, info * invalid: isfile, owns */ - if(targets == NULL && !(config->op_q_isfile || config->op_q_owns)) { + 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); + } + for(i = alpm_db_getpkgcache(db_local); i; i = alpm_list_next(i)) { pmpkg_t *pkg = alpm_list_getdata(i); - const char *pkgname = alpm_pkg_get_name(pkg); - const char *pkgver = alpm_pkg_get_version(pkg); - - if(config->op_q_info) { - dump_pkg_full(pkg, config->op_q_info); - } - if(config->op_q_list) { - dump_pkg_files(pkg); - } - if(!config->op_q_info && !config->op_q_list) { - printf("%s %s\n", pkgname, pkgver); + if(filter(pkg)) { + display(pkg); } } return(0); @@ -405,17 +356,6 @@ int pacman_query(alpm_list_t *targets) /* Second: operations that require target(s) */ - if(targets == NULL) { - pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n")); - return(1); - } - - /* output info for a .tar.gz package */ - if(config->op_q_isfile) { - ret = query_isfile(targets); - return(ret); - } - /* determine the owner of a file */ if(config->op_q_owns) { ret = query_fileowner(targets); @@ -426,32 +366,22 @@ int pacman_query(alpm_list_t *targets) * valid: no-op (plain -Q), list, info */ for(i = targets; i; i = alpm_list_next(i)) { char *strname = alpm_list_getdata(i); - pmpkg_t *pkg = alpm_db_get_pkg(db_local, strname); + pmpkg_t *pkg = NULL; + + if(config->op_q_isfile) { + alpm_pkg_load(strname, &pkg); + } else { + pkg = alpm_db_get_pkg(db_local, strname); + } + if(pkg == NULL) { fprintf(stderr, _("error: package \"%s\" not found\n"), strname); ret++; continue; } - /* find a target */ - if(config->op_q_info) { - dump_pkg_full(pkg, config->op_q_info); - } - if(config->op_q_list) { - dump_pkg_files(pkg); - } - if(config->op_q_changelog) { - char changelog[PATH_MAX]; - /* TODO should be done in the backend- no raw DB stuff up front */ - snprintf(changelog, PATH_MAX, "%s/%s/%s-%s/changelog", - alpm_option_get_dbpath(), - alpm_db_get_name(db_local), - alpm_pkg_get_name(pkg), - alpm_pkg_get_version(pkg)); - dump_pkg_changelog(changelog, alpm_pkg_get_name(pkg)); - } - if(!config->op_q_info && !config->op_q_list && !config->op_q_changelog) { - printf("%s %s\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); + if(filter(pkg)) { + display(pkg); } } diff --git a/src/pacman/remove.c b/src/pacman/remove.c index 0b6b4ce2..860bf491 100644 --- a/src/pacman/remove.c +++ b/src/pacman/remove.c @@ -44,7 +44,7 @@ static int remove_cleanup(void) int ret = alpm_trans_release(); if(ret != 0) { pm_printf(PM_LOG_ERROR, _("failed to release transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); ret = 1; } @@ -97,7 +97,7 @@ int pacman_remove(alpm_list_t *targets) if(alpm_trans_init(PM_TRANS_TYPE_REMOVE, config->flags, cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) { fprintf(stderr, _("error: failed to init transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); if(pm_errno == PM_ERR_HANDLE_LOCK) { printf(_(" if you're sure a package manager is not already\n" " running, you can remove %s.\n"), alpm_option_get_lockfile()); @@ -113,7 +113,7 @@ int pacman_remove(alpm_list_t *targets) if(alpm_trans_addtarget(targ) == -1) { printf("failed.\n"); fprintf(stderr, _("error: failed to add target '%s' (%s)\n"), targ, - alpm_strerror(pm_errno)); + alpm_strerrorlast()); remove_cleanup(); FREELIST(finaltargs); return(1); @@ -123,13 +123,14 @@ int pacman_remove(alpm_list_t *targets) /* Step 2: prepare the transaction based on its type, targets and flags */ if(alpm_trans_prepare(&data) == -1) { fprintf(stderr, _("error: failed to prepare transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); switch(pm_errno) { case PM_ERR_UNSATISFIED_DEPS: for(i = data; i; i = alpm_list_next(i)) { pmdepmissing_t *miss = alpm_list_getdata(i); - printf(_(":: %s depends on %s\n"), alpm_dep_get_target(miss), - alpm_dep_get_name(miss)); + pmdepend_t *dep = alpm_miss_get_dep(miss); + printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss), + alpm_dep_get_name(dep)); } alpm_list_free(data); break; @@ -166,7 +167,7 @@ int pacman_remove(alpm_list_t *targets) /* Step 3: actually perform the removal */ if(alpm_trans_commit(NULL) == -1) { fprintf(stderr, _("error: failed to commit transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); remove_cleanup(); FREELIST(finaltargs); return(1); diff --git a/src/pacman/sync.c b/src/pacman/sync.c index d5888a57..3e599830 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -24,7 +24,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/stat.h> #include <unistd.h> #include <dirent.h> @@ -206,7 +205,7 @@ static int sync_synctree(int level, alpm_list_t *syncs) alpm_db_get_name(db), downloadLastErrString); } else { fprintf(stderr, _("error: failed to update %s (%s)\n"), - alpm_db_get_name(db), alpm_strerror(pm_errno)); + alpm_db_get_name(db), alpm_strerrorlast()); } } else if(ret == 1) { printf(_(" %s is up to date\n"), alpm_db_get_name(db)); @@ -228,6 +227,7 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets) { alpm_list_t *i, *j, *ret; int freelist; + int found = 0; for(i = syncs; i; i = alpm_list_next(i)) { pmdb_t *db = alpm_list_getdata(i); @@ -241,6 +241,8 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets) } if(ret == NULL) { continue; + } else { + found = 1; } for(j = ret; j; j = alpm_list_next(j)) { /* print repo/name (group) info about each package in our list */ @@ -261,7 +263,7 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets) if((grp = alpm_pkg_get_groups(pkg)) != NULL) { group = alpm_list_getdata(grp); - printf(" (%s)\n", (char *)alpm_list_getdata(grp)); + printf(" (%s)", (char *)alpm_list_getdata(grp)); } /* we need a newline and initial indent first */ @@ -275,7 +277,7 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets) } } - return(0); + return(!found); } static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets) @@ -496,7 +498,7 @@ int pacman_sync(alpm_list_t *targets) if(alpm_trans_init(PM_TRANS_TYPE_SYNC, config->flags, cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) { fprintf(stderr, _("error: failed to init transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); if(pm_errno == PM_ERR_HANDLE_LOCK) { printf(_(" if you're sure a package manager is not already\n" " running, you can remove %s.\n"), alpm_option_get_lockfile()); @@ -520,7 +522,7 @@ int pacman_sync(alpm_list_t *targets) printf(_(":: Starting full system upgrade...\n")); alpm_logaction("starting full system upgrade"); if(alpm_trans_sysupgrade() == -1) { - fprintf(stderr, _("error: %s\n"), alpm_strerror(pm_errno)); + fprintf(stderr, _("error: %s\n"), alpm_strerrorlast()); retval = 1; goto cleanup; } @@ -546,18 +548,18 @@ int pacman_sync(alpm_list_t *targets) if(yesno(_(":: Cancel current operation? [Y/n] "))) { if(alpm_trans_release() == -1) { fprintf(stderr, _("error: failed to release transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); retval = 1; goto cleanup; } if(alpm_trans_init(PM_TRANS_TYPE_SYNC, config->flags, cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) { fprintf(stderr, _("error: failed to init transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); return(1); } if(alpm_trans_addtarget("pacman") == -1) { - fprintf(stderr, _("error: pacman: %s\n"), alpm_strerror(pm_errno)); + fprintf(stderr, _("error: pacman: %s\n"), alpm_strerrorlast()); retval = 1; goto cleanup; } @@ -582,7 +584,7 @@ int pacman_sync(alpm_list_t *targets) } if(pm_errno != PM_ERR_PKG_NOT_FOUND) { fprintf(stderr, _("'error: %s': %s\n"), - (char *)i->data, alpm_strerror(pm_errno)); + (char *)i->data, alpm_strerrorlast()); retval = 1; goto cleanup; } @@ -644,25 +646,26 @@ int pacman_sync(alpm_list_t *targets) alpm_list_t *data; if(alpm_trans_prepare(&data) == -1) { fprintf(stderr, _("error: failed to prepare transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); switch(pm_errno) { alpm_list_t *i; case PM_ERR_UNSATISFIED_DEPS: for(i = data; i; i = alpm_list_next(i)) { pmdepmissing_t *miss = alpm_list_getdata(i); - printf(_(":: %s depends on %s\n"), alpm_dep_get_target(miss), - alpm_dep_get_name(miss)); - switch(alpm_dep_get_mod(miss)) { + pmdepend_t *dep = alpm_miss_get_dep(miss); + printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss), + alpm_dep_get_name(dep)); + switch(alpm_dep_get_mod(dep)) { case PM_DEP_MOD_ANY: break; case PM_DEP_MOD_EQ: - printf("=%s", alpm_dep_get_version(miss)); + printf("=%s", alpm_dep_get_version(dep)); break; case PM_DEP_MOD_GE: - printf(">=%s", alpm_dep_get_version(miss)); + printf(">=%s", alpm_dep_get_version(dep)); break; case PM_DEP_MOD_LE: - printf("<=%s", alpm_dep_get_version(miss)); + printf("<=%s", alpm_dep_get_version(dep)); break; } printf("\n"); @@ -671,9 +674,9 @@ int pacman_sync(alpm_list_t *targets) case PM_ERR_CONFLICTING_DEPS: for(i = data; i; i = alpm_list_next(i)) { pmdepmissing_t *miss = alpm_list_getdata(i); - + pmdepend_t *dep = alpm_miss_get_dep(miss); printf(_(":: %s: conflicts with %s"), - alpm_dep_get_target(miss), alpm_dep_get_name(miss)); + alpm_miss_get_target(miss), alpm_dep_get_name(dep)); } break; default: @@ -704,16 +707,11 @@ int pacman_sync(alpm_list_t *targets) confirm = yesno(_("Proceed with download? [Y/n] ")); } } else { - /* don't get any confirmation if we're called from makepkg */ - if(config->op_d_resolve) { + if(config->noconfirm) { + printf(_("Beginning upgrade process...\n")); confirm = 1; } else { - if(config->noconfirm) { - printf(_("Beginning upgrade process...\n")); - confirm = 1; - } else { - confirm = yesno(_("Proceed with installation? [Y/n] ")); - } + confirm = yesno(_("Proceed with installation? [Y/n] ")); } } if(!confirm) { @@ -724,7 +722,7 @@ int pacman_sync(alpm_list_t *targets) /* Step 3: actually perform the installation */ if(alpm_trans_commit(&data) == -1) { fprintf(stderr, _("error: failed to commit transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); switch(pm_errno) { alpm_list_t *i; case PM_ERR_FILE_CONFLICTS: @@ -766,7 +764,7 @@ cleanup: } if(alpm_trans_release() == -1) { fprintf(stderr, _("error: failed to release transaction (%s)\n"), - alpm_strerror(pm_errno)); + alpm_strerrorlast()); retval = 1; } diff --git a/src/pacman/util.c b/src/pacman/util.c index a0829e64..8bf4ec14 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -34,6 +34,7 @@ #include <ctype.h> #include <dirent.h> #include <unistd.h> +#include <limits.h> #include <alpm.h> #include <alpm_list.h> @@ -162,12 +163,12 @@ void indentprint(const char *str, int indent) while(*p) { if(*p == ' ') { const char *next = NULL; - unsigned int len; + int len; p++; if(p == NULL || *p == ' ') continue; next = strchr(p, ' '); if(next == NULL) { - next = p + strlen(p); + next = p + mbstowcs(NULL, p, 0); } len = next - p; if(len > (getcols() - cidx - 1)) { @@ -283,13 +284,13 @@ void list_display(const char *title, const alpm_list_t *list) const alpm_list_t *i; int cols, len; - len = strlen(title); + len = mbstowcs(NULL, title, 0); printf("%s ", title); if(list) { for(i = list, cols = len; i; i = alpm_list_next(i)) { char *str = alpm_list_getdata(i); - int s = strlen(str) + 2; + int s = mbstowcs(NULL, str, 0) + 2; int maxcols = getcols(); if(s + cols >= maxcols) { int i; @@ -503,8 +504,6 @@ 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); - /* TEMP HACK because libalpm strings don't have \n */ - fprintf(stream, "\n"); return(ret); } diff --git a/src/util/.gitignore b/src/util/.gitignore index 8bfb0085..36688806 100644 --- a/src/util/.gitignore +++ b/src/util/.gitignore @@ -1,6 +1,5 @@ .deps .libs -Makefile -Makefile.in vercmp testpkg +testdb diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 0c48f10e..97a0ffa1 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -1,8 +1,19 @@ -bin_PROGRAMS = vercmp testpkg +# paths set at make time +conffile = ${sysconfdir}/pacman.conf +dbpath = ${localstatedir}/lib/pacman/ +cachedir = ${localstatedir}/cache/pacman/pkg/ +bin_PROGRAMS = vercmp testpkg testdb + +DEFS = -DLOCALEDIR=\"@localedir@\" \ + -DCONFFILE=\"$(conffile)\" \ + -DROOTDIR=\"$(ROOTDIR)\" \ + -DDBPATH=\"$(dbpath)\" \ + -DCACHEDIR=\"$(cachedir)\" \ + @DEFS@ INCLUDES = -I$(top_srcdir)/lib/libalpm -AM_CFLAGS = -pedantic +AM_CFLAGS = -pedantic -D_GNU_SOURCE vercmp_SOURCES = vercmp.c vercmp_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la @@ -10,4 +21,7 @@ vercmp_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la testpkg_SOURCES = testpkg.c testpkg_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la +testdb_SOURCES = testdb.c +testdb_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la + # vim:set ts=2 sw=2 noet: diff --git a/src/util/testdb.c b/src/util/testdb.c new file mode 100644 index 00000000..d59d0108 --- /dev/null +++ b/src/util/testdb.c @@ -0,0 +1,193 @@ +/* + * testdb.c : Test a pacman local database for validity + * + * Copyright (c) 2007 by Aaron Griffin <aaronmgriffin@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <sys/stat.h> +#include <dirent.h> +#include <libgen.h> + +#include <alpm.h> +#include <alpm_list.h> + +int _alpm_str_cmp(const void *s1, const void *s2) +{ + return(strcmp(s1, s2)); +} + +static void diffrqdby(const char *pkgname, alpm_list_t *oldrqdby, alpm_list_t *newrqdby) +{ + oldrqdby = alpm_list_msort(oldrqdby, alpm_list_count(oldrqdby), _alpm_str_cmp); + newrqdby = alpm_list_msort(newrqdby, alpm_list_count(newrqdby), _alpm_str_cmp); + + alpm_list_t *i = oldrqdby; + alpm_list_t *j = newrqdby; + + while(i || j) { + char *s1 = NULL; + char *s2 = NULL; + int n; + if(i && !j) { + n = -1; + } else if(!i && j) { + n = 1; + } else { + s1 = i->data; + s2 = j->data; + n = strcmp(s1, s2); + } + if(n < 0) { + s1 = i->data; + printf("wrong requiredby for %s : %s\n", pkgname, s1); + i = i->next; + } else if (n > 0) { + s2 = j->data; + printf("missing requiredby for %s : %s\n", pkgname, s2); + j = j->next; + } else { + i = i->next; + j = j->next; + } + } +} + +static void cleanup(int signum) { + if(alpm_release() == -1) { + fprintf(stderr, "error releasing alpm: %s\n", alpm_strerrorlast()); + } + + exit(signum); +} + +void output_cb(pmloglevel_t level, char *fmt, va_list args) +{ + if(strlen(fmt)) { + switch(level) { + case PM_LOG_ERROR: printf("error: "); break; + case PM_LOG_WARNING: printf("warning: "); break; + default: return; + } + vprintf(fmt, args); + printf("\n"); + } +} + +int db_test(char *dbpath) +{ + struct dirent *ent; + char path[PATH_MAX]; + struct stat buf; + int ret = 0; + + DIR *dir; + + if(!(dir = opendir(dbpath))) { + fprintf(stderr, "error : %s : %s\n", dbpath, strerror(errno)); + return(1); + } + + while ((ent = readdir(dir)) != NULL) { + if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { + continue; + } + /* check for desc, depends, and files */ + snprintf(path, PATH_MAX, "%s/%s/desc", dbpath, ent->d_name); + if(stat(path, &buf)) { + printf("%s: description file is missing\n", ent->d_name); + ret++; + } + snprintf(path, PATH_MAX, "%s/%s/depends", dbpath, ent->d_name); + if(stat(path, &buf)) { + printf("%s: dependency file is missing\n", ent->d_name); + ret++; + } + snprintf(path, PATH_MAX, "%s/%s/files", dbpath, ent->d_name); + if(stat(path, &buf)) { + printf("%s: file list is missing\n", ent->d_name); + ret++; + } + } + return(ret); +} + +int main(int argc, char **argv) +{ + int retval = 0; /* default = false */ + pmdb_t *db = NULL; + char *dbpath; + char localdbpath[PATH_MAX]; + alpm_list_t *i; + + if(argc == 1) { + dbpath = DBPATH; + } else if(argc == 3 && strcmp(argv[1], "-b") == 0) { + dbpath = argv[2]; + } else { + fprintf(stderr, "usage: %s -b <pacman db>\n", basename(argv[0])); + return(1); + } + + snprintf(localdbpath, PATH_MAX, "%s/local", dbpath); + retval = db_test(localdbpath); + if(retval) { + return(retval); + } + + if(alpm_initialize() == -1) { + fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerrorlast()); + return(1); + } + + /* let us get log messages from libalpm */ + alpm_option_set_logcb(output_cb); + + alpm_option_set_dbpath(dbpath); + + db = alpm_db_register_local(); + if(db == NULL) { + fprintf(stderr, "error: could not register 'local' database (%s)\n", + alpm_strerrorlast()); + cleanup(EXIT_FAILURE); + } + + /* check dependencies */ + alpm_list_t *data; + data = alpm_checkdeps(db, PM_TRANS_TYPE_ADD, alpm_db_getpkgcache(db)); + for(i = data; i; i = alpm_list_next(i)) { + pmdepmissing_t *miss = alpm_list_getdata(i); + pmdepend_t *dep = alpm_miss_get_dep(miss); + printf("missing dependency for %s : %s\n", alpm_miss_get_target(miss), + alpm_dep_get_name(dep)); + } + + /* check requiredby */ + for(i = alpm_db_getpkgcache(db); i; i = alpm_list_next(i)) { + pmpkg_t *pkg = alpm_list_getdata(i); + const char *pkgname = alpm_pkg_get_name(pkg); + alpm_list_t *rqdby = alpm_pkg_compute_requiredby(pkg); + diffrqdby(pkgname, alpm_pkg_get_requiredby(pkg), rqdby); + } + + cleanup(retval); +} diff --git a/src/util/testpkg.c b/src/util/testpkg.c index 1ad1d14b..7da18ca6 100644 --- a/src/util/testpkg.c +++ b/src/util/testpkg.c @@ -21,15 +21,13 @@ #include "config.h" -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <libgen.h> +#include <stdio.h> /* printf */ +#include <stdarg.h> /* va_list */ +#include <string.h> /* strlen */ #include <alpm.h> -void output_cb(pmloglevel_t level, char *fmt, va_list args) +static void output_cb(pmloglevel_t level, char *fmt, va_list args) { if(strlen(fmt)) { switch(level) { @@ -52,7 +50,7 @@ int main(int argc, char **argv) } if(alpm_initialize() == -1) { - fprintf(stderr, "cannot initilize alpm: %s\n", alpm_strerror(pm_errno)); + fprintf(stderr, "cannot initilize alpm: %s\n", alpm_strerrorlast()); return(1); } @@ -67,7 +65,7 @@ int main(int argc, char **argv) } if(alpm_release() == -1) { - fprintf(stderr, "error releasing alpm: %s\n", alpm_strerror(pm_errno)); + fprintf(stderr, "error releasing alpm: %s\n", alpm_strerrorlast()); } return(retval); diff --git a/src/util/vercmp.c b/src/util/vercmp.c index cc951988..873ef1c9 100644 --- a/src/util/vercmp.c +++ b/src/util/vercmp.c @@ -21,29 +21,26 @@ #include "config.h" -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <limits.h> -/* TODO this is probably not the best way to do this */ -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif +#include <stdio.h> /* printf */ +#include <string.h> /* strncpy */ #include <alpm.h> +#define MAX_LEN 255 + int main(int argc, char *argv[]) { - char s1[255] = ""; - char s2[255] = ""; + char s1[MAX_LEN] = ""; + char s2[MAX_LEN] = ""; int ret; if(argc > 1) { - strncpy(s1, argv[1], 255); + strncpy(s1, argv[1], MAX_LEN); + s1[MAX_LEN -1] = '\0'; } if(argc > 2) { - strncpy(s2, argv[2], 255); + strncpy(s2, argv[2], MAX_LEN); + s2[MAX_LEN -1] = '\0'; } else { printf("0\n"); return(0); |