From cc0135f30893b719d34845c088e215900962d8dd Mon Sep 17 00:00:00 2001
From: Esteban Carnevale <alfplayer@mailoo.org>
Date: Sat, 8 Feb 2014 17:49:10 -0300
Subject: [PATCH] add options dbpath and config

---
 README.pod | 12 +++++++++++
 expac.c    | 72 +++++++++++++++++++++++++++++++++++++++++---------------------
 2 files changed, 60 insertions(+), 24 deletions(-)

diff --git a/README.pod b/README.pod
index 8e51329..ba27281 100644
--- a/README.pod
+++ b/README.pod
@@ -24,6 +24,18 @@ a query string (in the case of a search), or in repo/package syntax when the
 
 =over 4
 
+=item B<-b, --dbpath> <path>
+
+Specify an alternative database location (a typical default is
+/var/lib/pacman). This should not be used unless you know what you are doing.
+NOTE: if specified, this is an absolute path and the root path is not 
+automatically prepended.
+
+=item B<-c, --config> <file>
+
+Specify an alternate configuration file (a typical default is 
+/etc/pacman.conf).
+
 =item B<-Q, --query>
 
 Search the local database for provided targets. This is the default behavior.
diff --git a/expac.c b/expac.c
index ae3ef6d..3f9b0ba 100644
--- a/expac.c
+++ b/expac.c
@@ -36,6 +36,8 @@
 #include <time.h>
 
 #define DEFAULT_DELIM        "\n"
+#define DEFAULT_DBPATH       "/var/lib/pacman"
+#define DEFAULT_CONFIGFILE   "/etc/pacman.conf"
 #define DEFAULT_LISTDELIM    "  "
 #define DEFAULT_TIMEFMT      "%c"
 #define FORMAT_TOKENS        "BCDEGLMNOPRSVabdhmnprsuvw%"
@@ -58,10 +60,13 @@ bool local = false;
 bool groups = false;
 bool localpkg = false;
 char humansize = 'B';
+char dbtype = NULL;
 const char *format = NULL;
 const char *timefmt = NULL;
 const char *listdelim = NULL;
 const char *delim = NULL;
+const char *dbpath = NULL;
+const char *configfile = NULL;
 int pkgcounter = 0;
 
 typedef const char *(*extractfn)(void*);
@@ -154,7 +159,7 @@ static alpm_handle_t *alpm_init(void) {
   char line[PATH_MAX];
   char *ptr, *section = NULL;
 
-  handle = alpm_initialize("/", "/var/lib/pacman", &alpm_errno);
+  handle = alpm_initialize("/", dbpath, &alpm_errno);
   if (!handle) {
     alpm_strerror(alpm_errno);
     return NULL;
@@ -162,9 +167,9 @@ static alpm_handle_t *alpm_init(void) {
 
   db_local = alpm_get_localdb(handle);
 
-  fp = fopen("/etc/pacman.conf", "r");
+  fp = fopen(configfile, "r");
   if (!fp) {
-    perror("fopen: /etc/pacman.conf");
+    fprintf(stderr, "fopen:%s\n", configfile);
     return handle;
   }
 
@@ -209,6 +214,8 @@ static void usage(void) {
       " Options:\n"
       "  -Q, --local               search local DB (default)\n"
       "  -S, --sync                search sync DBs\n"
+      "  -b, --dbpath <path>       alternative database location (default: /var/lib/pacman)\n"
+      "  -c, --config <path>       alternative configuration file (default: /etc/pacman.conf)\n"
       "  -s, --search              search for matching regex\n"
       "  -g, --group               return packages matching targets as groups\n"
       "  -H, --humansize <size>    format package sizes in SI units (default: bytes)\n"
@@ -222,41 +229,43 @@ static void usage(void) {
       "For more details see expac(1).\n");
 }
 
-static int parse_options(int argc, char *argv[], alpm_handle_t *handle) {
+static int parse_options(int argc, char *argv[]) {
   int opt, option_index = 0;
   const char *i;
 
   static struct option opts[] = {
-    {"readone",   no_argument,        0, '1'},
-    {"delim",     required_argument,  0, 'd'},
-    {"listdelim", required_argument,  0, 'l'},
-    {"group",     required_argument,  0, 'g'},
-    {"help",      no_argument,        0, 'h'},
-    {"file",      no_argument,        0, 'p'},
-    {"humansize", required_argument,  0, 'H'},
-    {"query",     no_argument,        0, 'Q'},
-    {"sync",      no_argument,        0, 'S'},
-    {"search",    no_argument,        0, 's'},
-    {"timefmt",   required_argument,  0, 't'},
-    {"verbose",   no_argument,        0, 'v'},
+    {"readone",    no_argument,        0, '1'},
+    {"delim",      required_argument,  0, 'd'},
+    {"dbpath",     required_argument,  0, 'b'},
+    {"configfile", required_argument,  0, 'c'},
+    {"listdelim",  required_argument,  0, 'l'},
+    {"group",      required_argument,  0, 'g'},
+    {"help",       no_argument,        0, 'h'},
+    {"file",       no_argument,        0, 'p'},
+    {"humansize",  required_argument,  0, 'H'},
+    {"query",      no_argument,        0, 'Q'},
+    {"sync",       no_argument,        0, 'S'},
+    {"search",     no_argument,        0, 's'},
+    {"timefmt",    required_argument,  0, 't'},
+    {"verbose",    no_argument,        0, 'v'},
     {0, 0, 0, 0}
   };
 
-  while (-1 != (opt = getopt_long(argc, argv, "1l:d:gH:hf:pQSst:v", opts, &option_index))) {
+  while (-1 != (opt = getopt_long(argc, argv, "1l:d:b:c:gH:hf:pQSst:v", opts, &option_index))) {
     switch (opt) {
       case 'S':
-        if (dblist) {
+        if (dbtype) {
           fprintf(stderr, "error: can only select one repo option (use -h for help)\n");
           return 1;
         }
-        dblist = alpm_list_copy(alpm_get_syncdbs(handle));
+        dbtype = 's';
         break;
       case 'Q':
-        if (dblist) {
+        if (dbtype) {
           fprintf(stderr, "error: can only select one repo option (use -h for help)\n");
           return 1;
         }
-        dblist = alpm_list_add(dblist, db_local);
+        dbtype = 'q';
         local = true;
         break;
       case '1':
@@ -265,6 +274,12 @@ static int parse_options(int argc, char *argv[], alpm_handle_t *handle) {
       case 'd':
         delim = optarg;
         break;
+      case 'b':
+        dbpath = optarg;
+        break;
+      case 'c':
+        configfile = optarg;
+        break;
       case 'g':
         groups = true;
         break;
@@ -719,14 +734,23 @@ int main(int argc, char *argv[]) {
   alpm_handle_t *handle;
   alpm_list_t *results = NULL, *i;
 
+  ret = parse_options(argc, argv);
+  if (ret != 0) {
+    goto finish;
+  }
+
+  dbpath = dbpath ? dbpath : DEFAULT_DBPATH;
+  configfile = configfile ? configfile : DEFAULT_CONFIGFILE;
+
   handle = alpm_init();
   if (!handle) {
     return ret;
   }
 
-  ret = parse_options(argc, argv, handle);
-  if (ret != 0) {
-    goto finish;
+  if (dbtype == 's') {
+    dblist = alpm_list_copy(alpm_get_syncdbs(handle));
+  } else if (dbtype == 'q') {
+      dblist = alpm_list_add(dblist, db_local);
   }
 
   /* ensure sane defaults */
-- 
1.9.0