Index: trunk/ippTools/share/Makefile.am
===================================================================
--- trunk/ippTools/share/Makefile.am	(revision 41296)
+++ trunk/ippTools/share/Makefile.am	(revision 41297)
@@ -426,4 +426,6 @@
 	stacktool_revertsummary.sql \
 	stacktool_summary.sql \
+	stacktool_addexternal.sql \
+	stacktool_insertexternal_link.sql \
 	staticskytool_definebyquery_select.sql \
 	staticskytool_definebyquery_select_by_dg.sql \
Index: trunk/ippTools/share/stacktool_addexternal.sql
===================================================================
--- trunk/ippTools/share/stacktool_addexternal.sql	(revision 41297)
+++ trunk/ippTools/share/stacktool_addexternal.sql	(revision 41297)
@@ -0,0 +1,3 @@
+
+INSERT INTO stackExternalCamera
+ (ext_camera_id, ext_camera) VALUES (0, '@EXT_CAMERA@')
Index: trunk/ippTools/share/stacktool_insertexternal_link.sql
===================================================================
--- trunk/ippTools/share/stacktool_insertexternal_link.sql	(revision 41297)
+++ trunk/ippTools/share/stacktool_insertexternal_link.sql	(revision 41297)
@@ -0,0 +1,3 @@
+
+INSERT INTO stackExternalStack
+ (stack_id, ext_stack_id, ext_camera_id) VALUES (%lld, %lld, %lld)
Index: trunk/ippTools/src/stacktool.c
===================================================================
--- trunk/ippTools/src/stacktool.c	(revision 41296)
+++ trunk/ippTools/src/stacktool.c	(revision 41297)
@@ -53,4 +53,6 @@
 static bool exportrunMode(pxConfig *config);
 static bool importrunMode(pxConfig *config);
+static bool importexternalMode(pxConfig *config);
+static bool addexternalMode(pxConfig *config);
 
 static bool setstackRunState(pxConfig *config, psS64 stack_id, const char *state);
@@ -96,4 +98,6 @@
         MODECASE(STACKTOOL_MODE_EXPORTRUN,             exportrunMode);
         MODECASE(STACKTOOL_MODE_IMPORTRUN,             importrunMode);
+        MODECASE(STACKTOOL_MODE_IMPORTEXTERNAL,        importexternalMode);
+        MODECASE(STACKTOOL_MODE_ADDEXTERNAL,           addexternalMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -2138,2 +2142,130 @@
   return true;
 }
+
+// in this mode, the supplied stacks are inserted into the db and the
+// StackExternalStack table is updated with the IDs of the inserted stack
+bool importexternalMode(pxConfig *config)
+{
+    unsigned int nFail;
+
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    PXOPT_LOOKUP_STR(infile, config->args, "-infile", true,  false);
+    PXOPT_LOOKUP_S64(ext_camera_id, config->args, "-ext_camera_id", true, false);
+
+    // optionally let the user change the filter:
+    PXOPT_LOOKUP_STR(new_filter, config->args, "-set_filter", false, false);
+
+    psMetadata *input = psMetadataConfigRead (NULL, &nFail, infile, false);
+
+    // XXX for TEST: psMetadataPrint (stderr, input, 1);
+
+    psMetadataItem *itemRun = psMetadataLookup (input, "stackRun");
+    psAssert (itemRun, "entry not in input?");
+    psAssert (itemRun->type == PS_DATA_METADATA_MULTI, "entry not multi?");
+
+    psMetadataItem *entry = psListGet (itemRun->data.list, 0);
+    assert (entry);
+    assert (entry->type == PS_DATA_METADATA);
+
+    // grab the data for the stackRun & format as stackRunRow:
+    stackRunRow *stackRun = stackRunObjectFromMetadata (entry->data.md);
+
+    // save the original stack_id and insert with stack_id = 0 to force a
+    // new iD.  we then need to retrieve that ID and use it below
+    // the new stackRun should 
+
+    psS64 ext_stack_id = stackRun->stack_id;
+    stackRun->stack_id = 0;
+
+    // update filter as well..
+    if (new_filter) {
+      stackRun->filter = psMemIncrRefCounter(new_filter);
+    }
+
+    // start the transaction so we can ensure stackRun, stackSumSkyfile, stackExternalStack table entries are consistent
+    if (!psDBTransaction(config->dbh)) {
+	psError(PS_ERR_UNKNOWN, false, "database error");
+	return false;
+    }
+
+    // now insert the new stackRun object:
+    stackRunInsertObject (config->dbh, stackRun);
+
+    // get the new stack_id
+    psS64 stack_id = psDBLastInsertID(config->dbh);
+
+    // add an entry in the stackExternalStack table:
+    psString query = pxDataGet("stacktool_insertexternal_link.sql");
+    if (!query) {
+	psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+	return false;
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, stack_id, ext_stack_id, ext_camera_id)) {
+	psError(PS_ERR_UNKNOWN,false, "database error");
+	return(NULL);
+    }
+
+    // now insert the stackSumSkyfile data
+    psMetadataItem *itemSum = psMetadataLookup (input, "stackSumSkyfile");
+
+    psAssert (itemSum, "entry not in input?");
+    psAssert (itemSum->type == PS_DATA_METADATA_MULTI, "entry not multi?");
+
+    for (int i = 0; i < itemSum->data.list->n; i++) {
+	entry = psListGet (itemSum->data.list, i);
+	assert (entry);
+	assert (entry->type == PS_DATA_METADATA);
+	stackSumSkyfileRow *stackSumSkyfile = stackSumSkyfileObjectFromMetadata (entry->data.md);
+
+	// need to update stack_id
+	stackSumSkyfile->stack_id = stack_id;
+	stackSumSkyfileInsertObject (config->dbh, stackSumSkyfile);
+
+	// fprintf (stdout, "---- row %d ----\n", i);
+	// psMetadataPrint (stderr, entry->data.md, 1);
+    }
+
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    return true;
+}
+
+bool addexternalMode(pxConfig *config) {
+
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    PXOPT_LOOKUP_STR(ext_camera, config->args, "-ext_camera", true,  false);
+
+    psString query = pxDataGet("stacktool_addexternal.sql");
+    if (!query) {
+	psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+	return false;
+    }
+
+    psStringSubstitute(&query, ext_camera, "@EXT_CAMERA@");
+
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+	psError(PS_ERR_UNKNOWN,false, "database error");
+	return(NULL);
+    }
+
+    int ext_camera_id = psDBLastInsertID(config->dbh);
+    psLogMsg("stacktool", PS_LOG_INFO, "Added new external camera %s (ID = %d)", ext_camera, ext_camera_id);
+
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    return true;
+}
Index: trunk/ippTools/src/stacktool.h
===================================================================
--- trunk/ippTools/src/stacktool.h	(revision 41296)
+++ trunk/ippTools/src/stacktool.h	(revision 41297)
@@ -46,5 +46,7 @@
     STACKTOOL_MODE_UPDATESUMSKYFILE,
     STACKTOOL_MODE_EXPORTRUN,
-    STACKTOOL_MODE_IMPORTRUN
+    STACKTOOL_MODE_IMPORTRUN,
+    STACKTOOL_MODE_IMPORTEXTERNAL,
+    STACKTOOL_MODE_ADDEXTERNAL
 } stacktoolMode;
 
Index: trunk/ippTools/src/stacktoolConfig.c
===================================================================
--- trunk/ippTools/src/stacktoolConfig.c	(revision 41296)
+++ trunk/ippTools/src/stacktoolConfig.c	(revision 41297)
@@ -335,4 +335,13 @@
     psMetadataAddStr(importrunArgs, PS_LIST_TAIL, "-infile",  0,          "import from this file (required)", NULL);
 
+    // -importexternal
+    psMetadata *importexternalArgs = psMetadataAlloc();
+    psMetadataAddStr(importexternalArgs, PS_LIST_TAIL, "-infile",  0,          "import from this file (required)", NULL);
+    psMetadataAddS64(importexternalArgs, PS_LIST_TAIL, "-ext_camera_id",  0,   "external stacks come from this camera (required)", 0);
+    psMetadataAddStr(importexternalArgs, PS_LIST_TAIL, "-set_filter",  0,      "replace the filter names with this value", NULL);
+
+    // -addexternalcamera
+    psMetadata *addexternalArgs = psMetadataAlloc();
+    psMetadataAddStr(addexternalArgs, PS_LIST_TAIL, "-ext_camera",  0,      "external camera which can supply stacks (required)", NULL);
 
     psFree(now);
@@ -368,4 +377,7 @@
     PXOPT_ADD_MODE("-importrun",            "import run from metadata file",           STACKTOOL_MODE_IMPORTRUN, importrunArgs);
 
+    PXOPT_ADD_MODE("-importexternal",       "import stacks from external camera from metadata file", STACKTOOL_MODE_IMPORTEXTERNAL, importexternalArgs);
+    PXOPT_ADD_MODE("-addexternal",          "add external camera which can supply stacks", STACKTOOL_MODE_ADDEXTERNAL, addexternalArgs);
+
     if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
         psError(PS_ERR_UNKNOWN, true, "option parsing failed");
