Index: /trunk/ippTools/src/pzgetimfiles.c
===================================================================
--- /trunk/ippTools/src/pzgetimfiles.c	(revision 6972)
+++ /trunk/ippTools/src/pzgetimfiles.c	(revision 6973)
@@ -9,10 +9,132 @@
 #include "pzgetimfiles.h"
 
+#define FILESET_LS_CMD "dsfilesetls"
+
+static psArray *parseFiles(pxConfig *config, const char *str);
+
 int main(int argc, char **argv)
 {
     pxConfig *config = pzgetimfilesConfig(NULL, argc, argv);
 
+    // invoke dsfilesetls
+    bool status = false;
+    psString uri = psMetadataLookupStr(&status, config->args, "-uri");
+    psString cmd = NULL;
+    psStringAppend(&cmd, "%s --uri %s", FILESET_LS_CMD, uri);
+
+    fprintf(stderr, "cmd is: %s\n", cmd);
+
+    FILE *output = popen(cmd, "r");
+    psFree(cmd);
+
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, true, "popen() failed");
+        goto FAIL;
+    }
+
+    psString cmdOutput = fslurp(output);
+    int exitStatus = pclose(output);
+
+    if (exitStatus != 0) {
+        psError(PS_ERR_UNKNOWN, true, "%s failed with exit status %d",
+            FILESET_LS_CMD, exitStatus);
+        goto FAIL;
+    }
+
+    // prase output of dsfilesetls
+    psArray *newImfiles = parseFiles(config, cmdOutput);
+    if (!newImfiles) {
+        // XXX not nessicarily an error
+        psError(PS_ERR_UNKNOWN, true, "no new files/imfiles"); 
+        goto FAIL;
+    }
+
+    // try not to insert duplicate pzPendingExp/pzPendingImfile entries
+    // XXX this will become very expensive as the number of records grows
+    // XXX change psDB to support inserting data with 'not exists'
+    psArray *pzPendingImfiles =
+        pzPendingImfileSelectRowObjects(config->dbh, NULL, 0);
+    if (pzPendingImfiles) {
+        for (long i = 0; i < psArrayLength(newImfiles); i++) {
+            pzPendingImfileRow *newImfile = newImfiles->data[i];
+            for (long j = 0; j < psArrayLength(pzPendingImfiles); j++) {
+                pzPendingImfileRow *pendingImfile = pzPendingImfiles->data[j];
+                if (strcmp(newImfile->exp_id,
+                           pendingImfile->exp_id) == 0) {
+                    psArrayRemove(newImfiles, newImfile);
+                    // dec the counter as the array just got shorter
+                    // and we don't want to skip elemnts
+                    i--;
+                    break;
+                }
+            }
+        }
+        psFree(pzPendingImfiles);
+    }
+
+    // insert new entries into the database
+    for (long i = 0; i < psArrayLength(newImfiles); i++) {
+        if (!pzPendingImfileInsertObject(config->dbh, newImfiles->data[i])) {
+            psError(PS_ERR_UNKNOWN, false, "dbh access failed");
+            goto FAIL;
+        }
+    }
+
+    // save the number of new Imfiles;
+    long nImfiles = psArrayLength(newImfiles);
+    psFree(newImfiles);
+
+    // find the summitExp entry for our exp_id
+    psArray *summitExps = NULL;
+    {
+        psMetadata *where = psMetadataAlloc();
+        bool status = false;
+        psString exp_id = psMetadataLookupStr(&status, config->args,
+            "-filesetid");
+        if (!status) {
+                psError(PS_ERR_UNKNOWN, false, "failed to find arg exp_id");
+                psFree(where);
+                goto FAIL;
+        }
+        if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", exp_id)) {
+                psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+                psFree(where);
+                goto FAIL;
+        }
+        summitExps = summitExpSelectRowObjects(config->dbh, where, 0);
+        psFree(where);
+        if (!summitExps) {
+            // this REALLY should not happen
+            psError(PS_ERR_UNKNOWN, false,
+                "failed to find summitExp with exp_id %s (should not happen)"
+                , exp_id);
+            goto FAIL; 
+        }
+    }
+
+    // insert a new pzPendingExp
+    summitExpRow *summitExp = summitExps->data[0]; 
+    pzPendingExpRow *pzPendingExp = pzPendingExpRowAlloc(
+        summitExp->exp_id,
+        summitExp->camera,
+        summitExp->telescope,
+        summitExp->exp_type,
+        nImfiles 
+    );
+    psFree(summitExps);
+    if (!pzPendingExp) {
+        psError(PS_ERR_UNKNOWN, false, "pzPendingExpRowAlloc() failed");
+        goto FAIL;
+    }
+
+    if (!pzPendingExpInsertObject(config->dbh, pzPendingExp)) {
+        psError(PS_ERR_UNKNOWN, false, "dbh access failed");
+        psFree(pzPendingExp);
+        goto FAIL;
+    }
+
+    psFree(pzPendingExp);
+
     psFree(config);
-
     exit(EXIT_SUCCESS);
 
@@ -22,2 +144,65 @@
     exit(EXIT_FAILURE);
 }
+
+static psArray *parseFiles(pxConfig *config, const char *str)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(str, NULL);
+
+    psList *doc = psStringSplit(str, "\n");
+
+    psListIterator *lineCursor = psListIteratorAlloc(doc, 0, false);
+
+    psArray *pzPendingImfiles = psArrayAlloc(psListLength(doc));
+    psString line;
+    while ((line = psListGetAndIncrement(lineCursor))) {
+        printf("-> %s\n", line);
+
+        // split line into tokens
+        psList *tokens = psStringSplit(line, " ");
+
+        // check to see if this line is a comment (or if the first token is
+        // NULL)
+        if (!psListGet(tokens, 0) || *((char *)psListGet(tokens, 0)) == '#') {
+            psFree(tokens);
+            continue;
+        }
+
+        // check that we have the right number of tokens
+        // print "# uri fileid bytes md5sum type \n";
+        if (psListLength(tokens) != 5) {
+            psError(PS_ERR_UNKNOWN, true, "invalid line format: %s", line);
+            return false;
+        }
+
+        psListIterator *tokenCursor = psListIteratorAlloc(tokens, 0, false);
+        char *uri       = psListGetAndIncrement(tokenCursor);
+        char *class_id  = psListGetAndIncrement(tokenCursor); // fileid
+        char *bytes     = psListGetAndIncrement(tokenCursor); // bytes
+        char *md5sum    = psListGetAndIncrement(tokenCursor); // md5sum
+        char *class     = psListGetAndIncrement(tokenCursor); // type
+
+        bool status = false;
+        psString exp_id = psMetadataLookupStr(&status, config->args,
+            "-filesetid");
+
+        pzPendingImfileRow *row = pzPendingImfileRowAlloc(
+            exp_id,
+            bytes,
+            md5sum,
+            class,
+            class_id,
+            uri
+        );
+
+        psFree(tokenCursor);
+        psFree(tokens);
+
+        psArrayAdd(pzPendingImfiles, 0, row);
+    }
+
+    psFree(lineCursor);
+    psFree(doc);
+
+    return pzPendingImfiles;;
+}
