Index: /trunk/ippTools/src/Makefile.am
===================================================================
--- /trunk/ippTools/src/Makefile.am	(revision 6834)
+++ /trunk/ippTools/src/Makefile.am	(revision 6835)
@@ -1,5 +1,6 @@
 bin_PROGRAMS = pxadmin pzsearch p2search p0search pzgetexp
 
-include_HEADERS = pxtools.h slurp.h
+include_HEADERS = pxtools.h
+noinst_HEADERS = pzgetexp.h slurp.h
 lib_LTLIBRARIES = libpxtools.la
 libpxtools_la_CFLAGS	= $(PSLIB_CFLAGS) $(PSMODULES_CFLAGS) $(METADATADB_CFLAGS) $(pxtools_CFLAGS)
@@ -48,5 +49,6 @@
 pzgetexp_LDADD = $(PSLIB_LIBS) $(PSMODULES_LIBS) $(METADATADB_LIBS) $(top_builddir)/src/libpxtools.la
 pzgetexp_SOURCES = \
-    pzgetexp.c
+    pzgetexp.c \
+    pzgetexpConfig.c
 
 clean-local:
Index: /trunk/ippTools/src/pxtools.h
===================================================================
--- /trunk/ippTools/src/pxtools.h	(revision 6834)
+++ /trunk/ippTools/src/pxtools.h	(revision 6835)
@@ -1,2 +1,5 @@
+#ifndef PXTOOLS_H
+#define PXTOOLS_H 1
+
 # include <stdio.h>
 # include <strings.h>  // for strcasecmp
@@ -154,2 +157,4 @@
 
 bool pzsearchConfig(pxConfig *config, int argc, char **argv);
+
+#endif // PXTOOLS_H
Index: /trunk/ippTools/src/pzgetexp.h
===================================================================
--- /trunk/ippTools/src/pzgetexp.h	(revision 6835)
+++ /trunk/ippTools/src/pzgetexp.h	(revision 6835)
@@ -0,0 +1,8 @@
+#ifndef PZGETEXP_H
+#define PZGETEXP_H 1
+
+#include "pxtools.h"
+
+bool pzgetexpConfig(pxConfig *config, int argc, char **argv);
+
+#endif // PZGETEXP_H
Index: /trunk/ippTools/src/pzgetexpConfig.c
===================================================================
--- /trunk/ippTools/src/pzgetexpConfig.c	(revision 6835)
+++ /trunk/ippTools/src/pzgetexpConfig.c	(revision 6835)
@@ -0,0 +1,126 @@
+#include <pmConfig.h>
+
+#include "pxtools.h"
+
+bool pzgetexpConfig(pxConfig *config, int argc, char **argv) {
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    if (! pmConfigRead(&config->site, &config->camera, &config->recipe, &argc, argv, RECIPE)) {
+        psError(PS_ERR_UNKNOWN, false, "Can't find site configuration!\n");
+        exit(EXIT_FAILURE);
+    }
+
+    int N;
+    config->mode = PX_MODE_NONE;
+    if ((N = psArgumentGet (argc, argv, "-seen"))) {
+        psArgumentRemove (N, &argc, argv);
+        if (config->mode) {
+            psError(PS_ERR_UNKNOWN, true, "only one mode selection is allowed");
+        }
+        config->mode = PX_MODE_SEEN;
+    }
+    if ((N = psArgumentGet (argc, argv, "-pending"))) {
+        psArgumentRemove (N, &argc, argv);
+        if (config->mode) {
+            psError(PS_ERR_UNKNOWN, true, "only one mode selection is allowed");
+        }
+        config->mode = PX_MODE_PENDING;
+    }
+    if ((N = psArgumentGet (argc, argv, "-copydone"))) {
+        psArgumentRemove (N, &argc, argv);
+        if (config->mode) {
+            psError(PS_ERR_UNKNOWN, true, "only one mode selection is allowed");
+        }
+        config->mode = PX_MODE_COPYDONE;
+    }
+    
+    // paul's argument parsing convention requires: -key value 
+    // Parse other command-line arguments
+    psMetadata *args = psMetadataAlloc();
+    psMetadataAddStr(args , PS_LIST_TAIL, "-seen", 0,
+        "list all uncopied exposure IDs", "");
+    psMetadataAddStr(args , PS_LIST_TAIL, "-pending",  0,
+        "list all image files pending download", "");
+    psMetadataAddStr(args , PS_LIST_TAIL, "-copydone",  0,
+        "indicate that an image file has been downloaded", "");
+
+    // -copydone search
+    psMetadata *copydoneArgs = psMetadataAlloc();
+    psMetadataAddStr(copydoneArgs, PS_LIST_TAIL, "-exp_id",  0,
+        "define exposure ID", "");
+    psMetadataAddStr(copydoneArgs, PS_LIST_TAIL, "-class",  0,
+        "define class", "");
+    psMetadataAddStr(copydoneArgs, PS_LIST_TAIL, "-class_id",  0,
+        "define class_id", "");
+    psMetadataAddStr(copydoneArgs, PS_LIST_TAIL, "-suri",  0,
+        "define storage uri", "");
+
+    bool argErr = false;
+    if (config->mode == PX_MODE_NONE) {
+        argErr = true;
+        fprintf (stderr, "mode argument is required\n");
+    } else if (! psArgumentParse(args, &argc, argv) || argc != 1) {
+        argErr = true;
+        fprintf (stderr, "error parsing arguments\n");
+    }
+
+    if (argErr) {
+        printf("\nPan-STARRS Phase Z Search Tool\n");
+        printf("Usage: %s <mode> [<options>]\n\n", argv[0]);
+        printf(" <mode> : -seen | -pending | -copydone\n\n");
+        fprintf (stdout, "-copydone ");
+        psArgumentHelp(copydoneArgs);
+        psFree(args);
+        psFree(copydoneArgs);
+        exit(EXIT_FAILURE);
+    }
+
+    psFree(copydoneArgs);
+
+    // XXX why is "" being returned when -[foo] isn't specified?
+#define EMPTY_TO_NULL_STRING(var) \
+    if (var != NULL && strcmp(var, "") == 0) { \
+        var = NULL; \
+    }
+
+    config->args = args;
+
+if (config->mode == PX_MODE_COPYDONE) {
+    psMetadata *where = psMetadataAlloc();
+
+    bool status;
+    psString str;
+    if ((str = psMetadataLookupStr(&status, args, "-exp_id"))) {
+        if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", str)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+            psFree(where);
+            return NULL;
+        }
+    }
+    if ((str = psMetadataLookupStr(&status, args, "-class"))) {
+        if (!psMetadataAddStr(where, PS_LIST_TAIL, "class", 0, "==", str)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add item class");
+            psFree(where);
+            return NULL;
+        }
+    }
+    if ((str = psMetadataLookupStr(&status, args, "-class_id"))) {
+        if (!psMetadataAddStr(where, PS_LIST_TAIL, "class_id", 0, "==", str)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
+            psFree(where);
+            return NULL;
+        }
+    }
+
+    if (where->list->n < 1) {
+        psFree(where);
+        where = NULL;
+    }
+    config->where = where;
+}
+
+    // define Database handle, if used
+    config->dbh = pmConfigDB(config->site);
+
+    return true;
+} 
