Index: /trunk/ippTools/src/pxtools.h
===================================================================
--- /trunk/ippTools/src/pxtools.h	(revision 6669)
+++ /trunk/ippTools/src/pxtools.h	(revision 6670)
@@ -47,4 +47,5 @@
     char *class_id;
     char *uri;
+    psMetadata *args;
     psMetadata *where;
 } pxConfig;
@@ -129,4 +130,7 @@
 p2DoneExpRow *p2pendingToDoneExp(p2PendingExpRow *pendingExp);
 
+bool pzPendingFramePrint(FILE *stream, pxConfig *config, psArray *frames);
+psArray *pzPendingFrameSearch(pxConfig *config);
+
 bool rawScienceFramePrint(FILE *stream, pxConfig *config, psArray *frames);
 psArray *rawScienceFrameSearch(pxConfig *config);
Index: /trunk/ippTools/src/pztool.c
===================================================================
--- /trunk/ippTools/src/pztool.c	(revision 6669)
+++ /trunk/ippTools/src/pztool.c	(revision 6670)
@@ -7,4 +7,6 @@
 static bool copydoneMode(pxConfig *config);
 bool summitExpPrint(FILE *stream, summitExpRow *summitExp);
+psArray *pzsearchPendingImfiles(pxConfig *config);
+bool pzsearchFlushPendingExp(pxConfig *config);
 
 int main(int argc, char **argv)
@@ -89,12 +91,10 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    psArray *new = pzPendingFrameSearch(config);
-    if (!new) {
+    psArray *pending = pzPendingFrameSearch(config);
+    if (!pending) {
         psError(PS_ERR_UNKNOWN, false, "no pzPendingFrames found");
         return false;
     }
-
-    bool status = pzPendingFramePrint(stdout, config, new);
-    if (!status) {
+    if (!pzPendingFramePrint(stdout, config, pending)) {
         psError(PS_ERR_UNKNOWN, false, "pzPendingFramePrint() failed");
         return false;
@@ -107,4 +107,46 @@
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // we don't have to operate on complete frames here as it's ok to start
+    // downloading the imfiles before the exp has been registered
+    psArray *pending = pzsearchPendingImfiles(config);
+    if (!pending) {
+        psError(PS_ERR_UNKNOWN, false, "no pzPendingImfiles found");
+        return false;
+    }
+
+    // XXX start transaction
+
+    for (long i = 0; i < pending->n; i++) {
+        pzPendingImfileRow *pendingImfile = pending->data[i];
+        newImfileRow *newImfile = newImfileRowAlloc(
+            pendingImfile->exp_id,
+            pendingImfile->class,
+            pendingImfile->class_id,
+            // XXX get this from the CLI
+            pendingImfile->uri
+        );
+
+        if (!newImfileInsertObject(config->dbh, newImfile)) {
+            psError(PS_ERR_UNKNOWN, false, "dbh access failed");
+            return false;
+        }
+    }
+
+    if (pzPendingImfileDeleteRowObjects(config->dbh, pending, MAX_ROWS)
+        < 0) {
+            psError(PS_ERR_UNKNOWN, false, "dbh access failed");
+            return false;
+    }
+
+    // XXX commit transaction
+
+    // check for completed exps
+    if (!pzsearchFlushPendingExp(config)) {
+        psError(PS_ERR_UNKNOWN, false, "pzsearchFlushPendingExp() failed");
+        return false;
+    }
+
+    return true;
 }
 
@@ -124,2 +166,24 @@
     return true;
 }
+
+psArray *pzsearchPendingImfiles(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    psArray *imfiles = pzPendingImfileSelectRowObjects(config->dbh,
+        config->where, MAX_ROWS);
+    if (!imfiles) {
+        psError(PS_ERR_UNKNOWN, false, "no pzPendingImfile rows found");
+
+        return NULL;
+    }
+
+    return imfiles;
+}
+
+bool pzsearchFlushPendingExp(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    return true;
+}
Index: /trunk/ippTools/src/pztoolConfig.c
===================================================================
--- /trunk/ippTools/src/pztoolConfig.c	(revision 6669)
+++ /trunk/ippTools/src/pztoolConfig.c	(revision 6670)
@@ -45,18 +45,14 @@
         "indicate that an image file has been downloaded", "");
 
-    // -pending search
-    /*
-    psMetadata *pendingArgs = psMetadataAlloc();
-    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-exp_id",  0,
+    // -copydone search
+    psMetadata *copydoneArgs = psMetadataAlloc();
+    psMetadataAddStr(copydoneArgs, PS_LIST_TAIL, "-exp_id",  0,
         "define exposure ID", "");
-    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-inst",  0,
-        "define camera of interest", "");
-    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-telescope",  0,
-        "define camera of interest", "");
-    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-exp_type",  0,
+    psMetadataAddStr(copydoneArgs, PS_LIST_TAIL, "-class",  0,
         "define class", "");
-    psMetadataAddStr(pendingArgs, 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;
@@ -73,17 +69,12 @@
         printf("Usage: %s <mode> [<options>]\n\n", argv[0]);
         printf(" <mode> : -seen | -pending | -copydone\n\n");
-        /*
-        fprintf (stdout, "-pending ");
-        psArgumentHelp(pendingArgs);
-        fprintf (stdout, "-update ");
-        psArgumentHelp(updateArgs);
-        */
+        fprintf (stdout, "-copydone ");
+        psArgumentHelp(copydoneArgs);
         psFree(args);
-        /*
-        psFree(pendingArgs);
-        psFree(updateArgs);
-        */
+        psFree(copydoneArgs);
         exit(EXIT_FAILURE);
     }
+
+    psFree(copydoneArgs);
 
     // XXX why is "" being returned when -[foo] isn't specified?
@@ -93,89 +84,32 @@
     }
 
-    /*
-    switch (config->mode) {
-        bool status;
-        case PX_MODE_PENDING:
-            // -exp_id
-            config->exp_id = psMetadataLookupStr(&status, args, "-exp_id");
-            psMemIncrRefCounter(config->exp_id);
-            EMPTY_TO_NULL_STRING(config->exp_id);
-            // -inst
-            config->camera_name = psMetadataLookupStr(&status, args, "-inst");
-            psMemIncrRefCounter(config->camera_name);
-            EMPTY_TO_NULL_STRING(config->camera_name);
-            // -telescope
-            config->camera_name = psMetadataLookupStr(&status, args,
-                "-telescope");
-            psMemIncrRefCounter(config->telescope);
-            EMPTY_TO_NULL_STRING(config->telescope);
-            // -exp_type
-            config->class = psMetadataLookupStr(&status, args, "-exp_type");
-            psMemIncrRefCounter(config->exp_type);
-            EMPTY_TO_NULL_STRING(config->exp_type);
-            // -class
-            config->class = psMetadataLookupStr(&status, args, "-class");
-            psMemIncrRefCounter(config->class);
-            EMPTY_TO_NULL_STRING(config->class);
-            break;
-        case PX_MODE_UPDATE:
-            // -exp_id
-            config->exp_id = psMetadataLookupStr(&status, args, "-exp_id");
-            psMemIncrRefCounter(config->exp_id);
-            EMPTY_TO_NULL_STRING(config->exp_id);
-            // -filter
-            config->filter = psMetadataLookupStr(&status, args, "-filter");
-            psMemIncrRefCounter(config->filter);
-            EMPTY_TO_NULL_STRING(config->filter);
+    config->args = args;
 
-            break;
-        default:
-            psAbort(argv[0], "invalid option (this should not happen)");
-    }
-    */
-
-    psFree(args);
-    /*
-    psFree(pendingArgs);
-    psFree(updateArgs);
-    */
-
-
+if (config->mode == PX_MODE_COPYDONE) {
     psMetadata *where = psMetadataAlloc();
 
-    /*
-    if (config->camera_name != NULL) {
-        if (!psMetadataAddStr(where, PS_LIST_TAIL, "camera", 0, "==",
-            config->camera_name)) {
-            psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
+    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 (config->filter != NULL) {
-        psMetadataAddStr(where, PS_LIST_TAIL, "filter", 0, "==",
-            config->filter);
+    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 (config->exp_id != NULL) {
-        psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==",
-            config->exp_id);
+    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 (config->class != NULL) {
-        psMetadataAddStr(where, PS_LIST_TAIL, "class", 0, "==",
-            config->class);
-    }
-    if (config->class_id != NULL) {
-        psMetadataAddStr(where, PS_LIST_TAIL, "class_id", 0, "==",
-             config->class_id);
-    }
-    */
-
-    /*
-    // psMetadataConfig does not support times yet
-    if (!psTimeIsZero(config->start) && !psTimeIsZero(config->stop)) {
-        psMetadataAddTime (where, PS_LIST_TAIL, "TIME_START", 0, "<", config->stop);
-        psMetadataAddTime (where, PS_LIST_TAIL, "TIME_STOP", 0, ">", config->start);
-    }
-    */
 
     if (where->list->n < 1) {
@@ -183,10 +117,6 @@
         where = NULL;
     }
-
     config->where = where;
-
-
-    // add the input and output images to the args list
-    //psMetadataAddStr (args, PS_LIST_TAIL, "-output", 0, "Name of the output image", argv[1]);
+}
 
     // define Database handle, if used
