Index: trunk/ppSim/src/ppSimSequence.c
===================================================================
--- trunk/ppSim/src/ppSimSequence.c	(revision 23259)
+++ trunk/ppSim/src/ppSimSequence.c	(revision 27967)
@@ -1,6 +1,4 @@
 # include "ppSimSequence.h"
 # include <sys/stat.h>
-
-// XXX Memory leaks in string variables
 
 int main (int argc, char **argv) {
@@ -135,20 +133,62 @@
     psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS);
 
-    psMetadataItem *item = psMetadataLookup (config, "SEQUENCE");
-    if (item == NULL) {
-        psLogMsg ("ppSimSequence", PS_LOG_WARN, "missing SEQUENCE description");
-        exit (PS_EXIT_CONFIG_ERROR);
-    }
-
+    // global camera option (if not set, we look in each sequence)
+    if (camera == NULL) {
+	camera = psMetadataLookupStr (&status, config, "CAMERA");
+    }
+
+    psArray *files = NULL;
     psArray *sequences = NULL;
-    if (item->type == PS_DATA_METADATA) {
-        sequences = psArrayAlloc(1);
-        sequences->data[0] = psMemIncrRefCounter (item->data.V);
-    } else {
-        if (item->type != PS_DATA_METADATA_MULTI)  {
-            psLogMsg ("ppSimSequence", PS_LOG_WARN, "SEQUENCE is not MULTI or METADATA");
-            exit (1);
-        }
-        sequences = psListToArray (item->data.list);
+
+    { // find the FILERULE (if it exists) to set the file extension (.fits is default)
+	psMetadataItem *filerule = psMetadataLookup (config, "FILERULE");
+	if (filerule == NULL) {
+	    psLogMsg ("ppSimSequence", PS_LOG_INFO, "no FILERULE, assuming .fits ending");
+	    files = psArrayAlloc(1);
+	    files->data[0] = psStringCopy("fits");
+	    goto sequence;
+	} 
+	if (filerule->type == PS_DATA_METADATA_MULTI) {
+	    psArray *rules = psListToArray (filerule->data.list);
+	    psAssert (rules, "failed to get array from list?");
+	    psAssert (rules->n > 1, "supposed to be multiple entries in the list?");
+	    files = psArrayAllocEmpty(rules->n);
+	    for (int i = 0; i < rules->n; i++) {
+		psMetadataItem *item = rules->data[i];
+		if (item->type != PS_DATA_STRING) {
+		    psLogMsg ("ppSimSequence", PS_LOG_WARN, "invalid FILERULE type");
+		    exit (PS_EXIT_CONFIG_ERROR);
+		}
+		psArrayAdd (files, 16, item->data.str);
+	    }
+	    goto sequence;
+	}
+	if (filerule->type == PS_DATA_STRING) {
+	    files = psArrayAlloc(1);
+	    files->data[0] = psStringCopy(filerule->data.str);
+	    goto sequence;
+	}
+	psLogMsg ("ppSimSequence", PS_LOG_WARN, "invalid FILERULE type");
+	exit (PS_EXIT_CONFIG_ERROR);
+    }
+
+sequence:
+    { // find the set of sequences which define the ppSim data to be produced
+	psMetadataItem *item = psMetadataLookup (config, "SEQUENCE");
+	if (item == NULL) {
+	    psLogMsg ("ppSimSequence", PS_LOG_WARN, "missing SEQUENCE description");
+	    exit (PS_EXIT_CONFIG_ERROR);
+	}
+
+	if (item->type == PS_DATA_METADATA) {
+	    sequences = psArrayAlloc(1);
+	    sequences->data[0] = psMemIncrRefCounter (item->data.V);
+	} else {
+	    if (item->type != PS_DATA_METADATA_MULTI)  {
+		psLogMsg ("ppSimSequence", PS_LOG_WARN, "SEQUENCE is not MULTI or METADATA");
+		exit (1);
+	    }
+	    sequences = psListToArray (item->data.list);
+	}
     }
 
@@ -172,4 +212,8 @@
             camera = psMetadataLookupStr (&status, sequence, "CAMERA");
         }
+	if (!camera) {
+            psLogMsg ("ppSimSequence", PS_LOG_WARN, "CAMERA is not defined");
+            exit (1);
+	}
 
         psString injectCommandReal = NULL;
@@ -180,17 +224,25 @@
 
         if (!strcasecmp (type, "BIAS")) {
-            ppSimSequenceBias (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal);
+            ppSimSequenceBias (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal, files);
+	    psFree (injectCommandReal);
+	    psFree (ppSimCommandReal);
             continue;
         }
         if (!strcasecmp (type, "DARK")) {
-            ppSimSequenceDark (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal);
+            ppSimSequenceDark (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal, files);
+	    psFree (injectCommandReal);
+	    psFree (ppSimCommandReal);
             continue;
         }
         if (!strcasecmp (type, "FLAT")) {
-            ppSimSequenceFlat (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal);
+            ppSimSequenceFlat (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal, files);
+	    psFree (injectCommandReal);
+	    psFree (ppSimCommandReal);
             continue;
         }
         if (!strcasecmp (type, "OBJECT")) {
-            ppSimSequenceObject (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal);
+            ppSimSequenceObject (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal, files);
+	    psFree (injectCommandReal);
+	    psFree (ppSimCommandReal);
             continue;
         }
