Index: /trunk/ippTools/src/Makefile.am
===================================================================
--- /trunk/ippTools/src/Makefile.am	(revision 36510)
+++ /trunk/ippTools/src/Makefile.am	(revision 36511)
@@ -34,5 +34,6 @@
 	sctool \
 	releasetool \
-	fftool
+	fftool \
+	remotetool
 
 pkginclude_HEADERS = \
@@ -89,5 +90,6 @@
 	sctool.h \
 	releasetool.h \
-	fftool.h
+	fftool.h \
+	remotetool.h 
 
 lib_LTLIBRARIES = libpxtools.la
@@ -340,4 +342,10 @@
     fftoolConfig.c
 
+remotetool_CFLAGS = $(PSLIB_CFLAGS) $(PSMODULES_CFLAGS) $(IPPDB_CFLAGS)
+remotetool_LDADD  = $(PSLIB_LIBS)   $(PSMODULES_LIBS)   $(IPPDB_LIBS)   libpxtools.la
+remotetool_SOURCES = \
+    remotetool.c \
+    remotetoolConfig.c
+
 clean-local:
 	-rm -f TAGS
Index: /trunk/ippTools/src/remotetool.c
===================================================================
--- /trunk/ippTools/src/remotetool.c	(revision 36511)
+++ /trunk/ippTools/src/remotetool.c	(revision 36511)
@@ -0,0 +1,418 @@
+/*
+ * remotetool.c
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#include "pxtools.h"
+#include "pxdata.h"
+#include "remotetool.h"
+
+// Create
+static bool definebyqueryMode(pxConfig *config);
+
+// List
+static bool listrunMode(pxConfig *config);
+static bool listcomponentMode(pxConfig *config);
+
+// Update
+static bool updaterunMode(pxConfig *config);
+static bool updatepollMode(pxConfig *config);
+static bool revertrunMode(pxConfig *config);
+static bool revertauthMode(pxConfig *config);
+
+# define MODECASE(caseName, func) \
+  case caseName: \
+  if (!func(config)) { \
+  goto FAIL; \
+  } \
+  break;
+
+int main(int argc, char **argv)
+{
+  psLibInit(NULL);
+
+  pxConfig *config = remotetoolConfig(NULL, argc, argv);
+  if (!config) {
+    psError(PXTOOLS_ERR_CONFIG, false, "failed to configure");
+    goto FAIL;
+  }
+
+  switch (config->mode) {
+    MODECASE(REMOTETOOL_MODE_DEFINEBYQUERY, definebyqueryMode);
+    MODECASE(REMOTETOOL_MODE_LISTRUN,       listrunMode);
+    MODECASE(REMOTETOOL_MODE_LISTCOMPONENT, listcomponentMode);
+    MODECASE(REMOTETOOL_MODE_UPDATERUN,     updaterunMode);
+    MODECASE(REMOTETOOL_MODE_UPDATEPOLL,    updatepollMode);
+    MODECASE(REMOTETOOL_MODE_REVERTRUN,     revertrunMode);
+    MODECASE(REMOTETOOL_MODE_REVERTAUTH,    revertauthMode);
+
+  default:
+    psAbort("invalid option (this should not happen)");
+  }
+  psTrace("remotetool", 9, "Attempting to free config\n");
+  psFree(config);
+  pmConfigDone();
+  psLibFinalize();
+  exit(EXIT_SUCCESS);
+
+ FAIL:
+  psErrorStackPrint(stderr, "\n");
+  int exit_status = pxerrorGetExitStatus();
+
+  psFree(config);
+  pmConfigDone();
+  psLibFinalize();
+
+  exit(exit_status);
+}
+
+// Create
+
+static bool definebyqueryMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+  // These are required
+  PXOPT_LOOKUP_STR(label,      config->args, "-label",        true, false);
+  PXOPT_LOOKUP_STR(stage,      config->args, "-stage",        true, false);
+  PXOPT_LOOKUP_STR(path_base,  config->args, "-path_base",    true, false);
+
+  // These are not
+  PXOPT_LOOKUP_STR(set_label,  config->args, "-set_label",    false, false);
+  PXOPT_LOOKUP_S16(limit,      config->args, "-limit",        false, false);
+
+  PXOPT_LOOKUP_BOOL(simple,    config->args, "-simple",       false);
+  PXOPT_LOOKUP_BOOL(pretend,   config->args, "-pretend",      false);
+  
+  set_label = set_label ? set_label : label;
+
+  // Get a list of the things we can insert into a new component
+  psString query = NULL;
+  if (!strcmp(stage,"chip")) {
+    query = pxDataGet("remotetool_definebyquery_chip.sql");
+    if (!query) {
+      psError(PXTOOLS_ERR_SYS,false, "failed to retreive SQL statement");
+      return(false);
+    }
+    
+    if (label) {
+      psStringAppend(&query, " AND (chipRun.label = '%s')", label);
+    }
+  }
+  else if (!strcmp(stage,"camera")) {
+    query = pxDataGet("remotetool_definebyquery_cam.sql");
+    if (!query) {
+      psError(PXTOOLS_ERR_SYS,false, "failed to retreive SQL statement");
+      return(false);
+    }
+    
+    if (label) {
+      psStringAppend(&query, " AND (camRun.label = '%s')", label);
+    }
+  }    
+  else if (!strcmp(stage,"warp")) {
+    query = pxDataGet("remotetool_definebyquery_warp.sql");
+    if (!query) {
+      psError(PXTOOLS_ERR_SYS,false, "failed to retreive SQL statement");
+      return(false);
+    }
+    
+    if (label) {
+      psStringAppend(&query, " AND (warpRun.label = '%s')", label);
+    }
+  }    
+  else if (!strcmp(stage,"stack")) {
+    query = pxDataGet("remotetool_definebyquery_stack.sql");
+    if (!query) {
+      psError(PXTOOLS_ERR_SYS,false, "failed to retreive SQL statement");
+      return(false);
+    }
+    
+    if (label) {
+      psStringAppend(&query, " AND (stackRun.label = '%s')", label);
+    }
+  }    
+  else {
+    psError(PS_ERR_UNKNOWN, true, "unknown value for stage: %s", stage);
+    return false;
+  }
+
+  if (limit) {
+    psString limitString = psDBGenerateLimitSQL(limit);
+    psStringAppend(&query, " %s", limitString);
+    psFree(limitString);
+  }
+  if (!p_psDBRunQueryF(config->dbh, query)) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    psFree(query);
+    return false;
+  }
+  psFree(query);
+
+  psArray *output = p_psDBFetchResult(config->dbh);
+  if (!output) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return false;
+  }
+  if (!psArrayLength(output)) {
+    psTrace("remotetool", PS_LOG_INFO, "no rows found");
+    psFree(output);
+    return true;
+  }
+
+  if (pretend) {
+    if (!ippdbPrintMetadatas(stdout, output, "newremoteComponents", !simple)) {
+      psError(PS_ERR_UNKNOWN, false, "failed to print array");
+      psFree(output);
+      return false;
+    }
+    psFree(output);
+    return true;
+  }
+
+  if (!psDBTransaction(config->dbh)) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return false;
+  }
+
+
+  // Insert the top level run object
+  remoteRunRow *run = remoteRunRowAlloc(0, // rem_id
+					"new", // state
+					stage,
+					set_label,
+					path_base,
+					-1, // job_id
+					NULL, // last_poll
+					0   // fault
+					  );
+  if (!run) {
+    psError(PS_ERR_UNKNOWN, false, "failed to alloc lapRun object");
+    return(true);
+  }
+  
+  if (!remoteRunInsertObject(config->dbh, run)) {
+    if (!psDBRollback(config->dbh)) {
+      psError(PS_ERR_UNKNOWN, false, "database error");
+    }
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    psFree(run);
+    return(true);
+  }
+  psS64 rem_id = psDBLastInsertID(config->dbh);
+  
+  psArray *list = psArrayAllocEmpty(limit);
+  for (long i=0; i < psArrayLength(output); i++) {
+    psMetadata *md = output->data[i];
+    psS64 stage_id = psMetadataLookupS64(NULL, md, "stage_id");
+
+    remoteComponentRow *comp = remoteComponentRowAlloc(rem_id,
+						       stage_id);
+    if (!comp) {
+      psError(PS_ERR_UNKNOWN, false, "failed to alloc lapRun object");
+      return(true);
+    }
+    
+    if (!remoteComponentInsertObject(config->dbh, comp)) {
+      if (!psDBRollback(config->dbh)) {
+	psError(PS_ERR_UNKNOWN, false, "database error");
+      }
+      psError(PS_ERR_UNKNOWN, false, "database error");
+      psFree(run);
+      return(true);
+    }
+
+    psArrayAdd(list, list->n, comp);
+    psFree(comp);
+    
+  }
+  psFree(run);
+  // point of no return
+  if (!psDBCommit(config->dbh)) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return false;
+  }
+  
+  if (!remoteRunPrintObjects(stdout, list, !simple)) {
+    if (!psDBRollback(config->dbh)) {
+      psError(PS_ERR_UNKNOWN, false, "database error");
+    }
+    psError(PS_ERR_UNKNOWN, false, "failed to print object");
+    psFree(run);
+    return false;
+  }
+  
+  psFree(list);
+  psFree(output);
+					
+  return true;
+}
+
+// List
+static bool listrunMode(pxConfig *config)
+{
+  psMetadata *where = psMetadataAlloc();
+  
+  PXOPT_COPY_S64(config->args, where, "-rem_id", "rem_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-state", "state", "==");
+  PXOPT_COPY_STR(config->args, where, "-stage",  "stage",  "==");
+  PXOPT_COPY_STR(config->args, where, "-label",  "label",  "==");
+
+  PXOPT_COPY_S64(config->args, where, "-job_id", "job_id", "==");
+  PXOPT_COPY_TIME(config->args, where, "-poll_begin", "last_poll", ">=");
+  PXOPT_COPY_TIME(config->args, where, "-poll_end", "last_poll", "<=");
+  
+  PXOPT_COPY_S16(config->args, where, "-fault", "fault", "==");
+
+  PXOPT_LOOKUP_S16(limit,   config->args, "-limit",  false, false);
+  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+  
+
+  psArray *remRuns = NULL;
+  remRuns = psDBSelectRows(config->dbh, "remoteRun", where, limit);
+  
+  if (!ippdbPrintMetadatas(stdout, remRuns, "remoteRun", !simple)) {
+    psError(PS_ERR_UNKNOWN, false, "failed to print array");
+    psFree(remRuns);
+    return false;
+  }
+  psFree(remRuns);
+
+  return true;
+}
+
+static bool listcomponentMode(pxConfig *config)
+{
+  psMetadata *where = psMetadataAlloc();
+
+  PXOPT_COPY_S64(config->args, where, "-rem_id", "rem_id", "==");
+  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+  
+  psArray *remComps = NULL;
+  remComps = psDBSelectRows(config->dbh, "remoteComponent", where, 0);
+  
+  if (!ippdbPrintMetadatas(stdout, remComps, "remoteComponent", !simple)) {
+    psError(PS_ERR_UNKNOWN, false, "failed to print array");
+    psFree(remComps);
+    return false;
+  }
+  psFree(remComps);
+
+  return true;
+}
+
+// Update
+
+static bool updaterunMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+
+  psMetadata *where = psMetadataAlloc();
+  psMetadata *values = psMetadataAlloc();
+
+  // Wheres
+  PXOPT_COPY_S64(config->args, where, "-rem_id", "rem_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-label",  "label", "==");
+
+  // Values to set
+  PXOPT_COPY_STR(config->args, values, "-set_state", "state", "==");
+  PXOPT_COPY_S16(config->args, values, "-fault",     "fault", "==");
+  PXOPT_COPY_STR(config->args, values, "-set_label", "label", "==");
+
+  long rows = psDBUpdateRows(config->dbh, "remoteRun", where, values);
+  psFree(values);
+
+  if (rows < 1) {
+    psError(PS_ERR_UNKNOWN,false, "no rows affected");
+    return(false);
+  }
+  
+  return(true);
+}
+
+static bool updatepollMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+
+  psMetadata *where = psMetadataAlloc();
+  // Wheres
+  PXOPT_COPY_S64(config->args, where, "-rem_id", "rem_id", "==");
+
+  psString query = NULL;
+  query = pxDataGet("remotetool_updatepoll.sql");
+  if (!query) {
+    psError(PXTOOLS_ERR_SYS,false, "failed to retreive SQL statement");
+    psFree(where);
+    return(false);
+  }
+
+  if (!p_psDBRunQueryF(config->dbh, query,where)) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    psFree(query);
+    return false;
+  }
+  psFree(query);
+  psFree(where);
+  return(true);
+}
+  
+
+  
+
+static bool revertrunMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+
+  psMetadata *where = psMetadataAlloc();
+  psMetadata *values = psMetadataAlloc();
+
+  // required
+  PXOPT_COPY_S64(config->args, where, "-rem_id", "rem_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
+  
+  // Value to set
+  PXOPT_COPY_S16(config->args, values, "-fault", "fault", "==");
+  long rows = psDBUpdateRows(config->dbh, "remoteRun", where, values);
+  psFree(values);
+  psFree(where);
+  if (rows < 1) {
+    psError(PS_ERR_UNKNOWN,false, "no rows affected");
+    return(false);
+  }
+
+  return(true);
+}
+
+static bool revertauthMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+
+  psMetadata *where = psMetadataAlloc();
+  psMetadata *values = psMetadataAlloc();
+
+  // required
+  PXOPT_COPY_S64(config->args, where, "-rem_id", "rem_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
+
+  psMetadataAddStr(where, PS_LIST_TAIL, "state", 0, "==", "auth"); 
+
+  // Value to set
+  psMetadataAddStr(values, PS_LIST_TAIL, "state", 0, "==", "run");
+  
+  long rows = psDBUpdateRows(config->dbh, "remoteRun", where, values);
+  psFree(values);
+  psFree(where);
+  if (rows < 1) {
+    psError(PS_ERR_UNKNOWN,false, "no rows affected");
+    return(false);
+  }
+
+  return(true);
+}
+    
Index: /trunk/ippTools/src/remotetool.h
===================================================================
--- /trunk/ippTools/src/remotetool.h	(revision 36511)
+++ /trunk/ippTools/src/remotetool.h	(revision 36511)
@@ -0,0 +1,23 @@
+/*
+ * remotetool.h
+ */
+
+#ifndef REMOTETOOL_H
+#define REMOTETOOL_H 1
+
+#include "pxtools.h"
+
+typedef enum {
+  REMOTETOOL_MODE_NONE          = 0x0,
+  REMOTETOOL_MODE_DEFINEBYQUERY,
+  REMOTETOOL_MODE_LISTRUN,
+  REMOTETOOL_MODE_LISTCOMPONENT,
+  REMOTETOOL_MODE_UPDATERUN,
+  REMOTETOOL_MODE_UPDATEPOLL,
+  REMOTETOOL_MODE_REVERTRUN,    
+  REMOTETOOL_MODE_REVERTAUTH,   
+} remotetoolMode;
+
+pxConfig *remotetoolConfig(pxConfig *config, int argc, char **argv);
+
+#endif // REMOTETOOL_H
Index: /trunk/ippTools/src/remotetoolConfig.c
===================================================================
--- /trunk/ippTools/src/remotetoolConfig.c	(revision 36511)
+++ /trunk/ippTools/src/remotetoolConfig.c	(revision 36511)
@@ -0,0 +1,118 @@
+/*
+ * remotetoolConfig.c
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+#include <stdint.h>
+#include <psmodules.h>
+#include "pxtools.h"
+#include "remotetool.h"
+
+#define ADD_OPT(TYPE,TARG,NAME,COMMENT,DEFAULT) psMetadataAdd##TYPE(TARG, PS_LIST_TAIL, NAME, 0, COMMENT, DEFAULT)
+
+pxConfig *remotetoolConfig(pxConfig *config, int argc, char **argv)
+{
+  if (!config) {
+    config = pxConfigAlloc();
+  }
+
+  pmConfigReadParamsSet(false);
+
+  // setup site config
+  config->modules = pmConfigRead(&argc, argv, NULL);
+  if (!config->modules) {
+    psError(psErrorCodeLast(), false, "Can't find site configuration");
+    psFree(config);
+    return NULL;
+  }
+
+  // -definebyquery
+  psMetadata *definebyqueryArgs = psMetadataAlloc();
+  ADD_OPT(Str, definebyqueryArgs, "-label",          "stage label to query", NULL);
+  ADD_OPT(Str, definebyqueryArgs, "-set_label",      "remRun label to use", NULL);
+  ADD_OPT(Str, definebyqueryArgs, "-stage",          "stage to query", NULL);
+  ADD_OPT(Str, definebyqueryArgs, "-path_base",      "define base output location", NULL);
+  ADD_OPT(S16, definebyqueryArgs, "-limit",          "limit to number of jobs to bundle",0);
+  ADD_OPT(Bool, definebyqueryArgs,"-simple",         "simple print format",0);
+  
+  // -listrun
+  psMetadata *listrunArgs = psMetadataAlloc();
+  ADD_OPT(S64, listrunArgs, "-rem_id",             "run to list", 0);
+  ADD_OPT(Str, listrunArgs, "-state",              "run state", NULL);
+  ADD_OPT(Str, listrunArgs, "-stage",              "stage to return", NULL);
+  ADD_OPT(Str, listrunArgs, "-label",              "remRun label to use", NULL);
+
+  ADD_OPT(S64, listrunArgs, "-job_id",             "job_id", 0);
+  ADD_OPT(Str, listrunArgs, "-poll_begin",         "last polled time begin", NULL);
+  ADD_OPT(Str, listrunArgs, "-poll_end",           "last polled time begin", NULL);
+
+  ADD_OPT(S16, listrunArgs, "-fault",              "fault code", 0);
+
+  ADD_OPT(Bool, listrunArgs, "-simple",            "simple print format", false);
+  ADD_OPT(S16, listrunArgs,  "-limit",             "limit to number of runs to display", 0);
+
+  // -listcomponents
+  psMetadata *listcomponentArgs = psMetadataAlloc();
+  ADD_OPT(S64, listcomponentArgs, "-rem_id",             "run to list", 0);
+  ADD_OPT(S16, listcomponentArgs, "-limit",              "limit to number of runs to display", 0);
+  
+  // -updaterun
+  psMetadata *updaterunArgs = psMetadataAlloc();
+  ADD_OPT(S64, updaterunArgs, "-rem_id",             "run to update", 0);
+  ADD_OPT(Str, updaterunArgs, "-set_label",          "remRun label to use", NULL);
+  ADD_OPT(S64, updaterunArgs, "-job_id",             "job_id to set", 0);
+  ADD_OPT(S16, updaterunArgs, "-fault",              "fault code", 0);
+  ADD_OPT(Bool, updaterunArgs, "-poll",              "set poll date", NULL);
+
+  // -updatepoll
+  psMetadata *updatepollArgs = psMetadataAlloc();
+  ADD_OPT(S64, updatepollArgs, "-rem_id",            "run to update", 0);
+  
+  // -revertrun
+  psMetadata *revertrunArgs = psMetadataAlloc();
+  ADD_OPT(S64, revertrunArgs, "-rem_id",             "run to revert", 0);
+  ADD_OPT(Str, revertrunArgs, "-label",      "remRun label to use", NULL);
+  ADD_OPT(S16, revertrunArgs, "-fault",              "fault code", 0);
+  
+  // -revertauth
+  psMetadata *revertauthArgs = psMetadataAlloc();
+  ADD_OPT(S64, revertauthArgs, "-rem_id",             "run to revert", 0);
+  ADD_OPT(Str, revertauthArgs, "-label",      "remRun label to use", NULL);
+
+  psMetadata *argSets = psMetadataAlloc();
+  psMetadata *modes   = psMetadataAlloc();
+
+  PXOPT_ADD_MODE("-definebyquery",     "", REMOTETOOL_MODE_DEFINEBYQUERY,  definebyqueryArgs);
+  PXOPT_ADD_MODE("-listrun",           "", REMOTETOOL_MODE_LISTRUN,        listrunArgs);
+  PXOPT_ADD_MODE("-updaterun",         "", REMOTETOOL_MODE_UPDATERUN,      updaterunArgs);
+  PXOPT_ADD_MODE("-updatepoll",        "", REMOTETOOL_MODE_UPDATEPOLL,     updatepollArgs);
+  PXOPT_ADD_MODE("-revertrun",         "", REMOTETOOL_MODE_REVERTRUN,      revertrunArgs);
+  PXOPT_ADD_MODE("-revertauth",        "", REMOTETOOL_MODE_REVERTAUTH,     revertauthArgs);
+
+
+  if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
+    psError(PS_ERR_UNKNOWN, true, "option parsing failed");
+    psFree(argSets);
+    psFree(modes);
+    psFree(config);
+    return NULL;
+  }
+
+  psFree(argSets);
+  psFree(modes);
+
+  // define Database handle, if used
+  config->dbh = psMemIncrRefCounter(pmConfigDB(config->modules));
+  if (!config->dbh) {
+    psError(PXTOOLS_ERR_SYS, false, "Can't configure database");
+    psFree(config);
+    return NULL;
+  }
+
+  return config;
+}
+
