Index: trunk/ippTools/src/difftool.c
===================================================================
--- trunk/ippTools/src/difftool.c	(revision 25790)
+++ trunk/ippTools/src/difftool.c	(revision 25800)
@@ -51,4 +51,11 @@
 
 static bool setdiffRunState(pxConfig *config, psS64 diff_id, const char *state, psS64 magicked);
+static bool setdiffRunStateByLabel(pxConfig *config, const char* label, const char *state);
+static bool change_skyfile_data_state(pxConfig *config, psString data_state, psString run_state);
+static bool tocleanedskyfileMode(pxConfig *config);
+static bool topurgedskyfileMode(pxConfig *config);
+static bool toscrubbedskyfileMode(pxConfig *config);
+
+
 
 # define MODECASE(caseName, func) \
@@ -88,4 +95,8 @@
         MODECASE(DIFFTOOL_MODE_EXPORTRUN,             exportrunMode);
         MODECASE(DIFFTOOL_MODE_IMPORTRUN,             importrunMode);
+        MODECASE(DIFFTOOL_MODE_TOCLEANEDSKYFILE,   tocleanedskyfileMode);
+	MODECASE(DIFFTOOL_MODE_TOPURGEDSKYFILE,    topurgedskyfileMode);
+	MODECASE(DIFFTOOL_MODE_TOSCRUBBEDSKYFILE,  toscrubbedskyfileMode);
+
         default:
             psAbort("invalid option (this should not happen)");
@@ -169,13 +180,21 @@
 
     // required options
-    PXOPT_LOOKUP_S64(diff_id, config->args, "-diff_id", true, false);
+    PXOPT_LOOKUP_S64(diff_id, config->args, "-diff_id", false, false);
     PXOPT_LOOKUP_STR(state, config->args, "-state", true, false);
-
-    if (state) {
+    PXOPT_LOOKUP_STR(label, config->args, "-label", false, false);
+    
+    // Copy of my hacky work around from stacktool.c
+    if ((state)&&(diff_id)) {
         // set detRun.state to state
         return setdiffRunState(config, diff_id, state, false);
     }
 
-    return true;
+    if ((state)&&(label)) {
+      return setdiffRunStateByLabel(config, label, state);
+    }
+
+    psError(PS_ERR_UNKNOWN, false, "Required options not found.");
+
+    return false;
 }
 
@@ -865,13 +884,44 @@
     }
 
-    char *query = "UPDATE diffRun SET state = '%s', magicked = %" PRId64 " WHERE diff_id = %"PRId64;
-
-    if (!p_psDBRunQueryF(config->dbh, query, state, magicked, diff_id)) {
+    if (magicked) {
+      char *query = "UPDATE diffRun SET state = '%s', magicked = %" PRId64 " WHERE diff_id = %"PRId64;
+      
+      if (!p_psDBRunQueryF(config->dbh, query, state, magicked, diff_id)) {
         psError(PS_ERR_UNKNOWN, false,
                 "failed to change state for diff_id %"PRId64, diff_id);
         return false;
-    }
-
+      }
+    }
+    else {
+      char *query = "UPDATE diffRun SET state = '%s' WHERE diff_id = %"PRId64;
+      
+      if (!p_psDBRunQueryF(config->dbh, query, state, diff_id)) {
+        psError(PS_ERR_UNKNOWN, false,
+                "failed to change state for diff_id %"PRId64, diff_id);
+        return false;
+      }
+    }
+    
     return true;
+}
+
+
+static bool setdiffRunStateByLabel(pxConfig *config, const char *label, const char *state) {
+  PS_ASSERT_PTR_NON_NULL(state,false);
+
+  // check that state is a valid string value
+  if (!pxIsValidState(state)) {
+    psError(PS_ERR_UNKNOWN, false, "invalid diffRun state: %s", state);
+    return false;
+  }
+
+  char *query = "UPDATE diffRun SET state = '%s' WHERE label = '%s'";
+  if (!p_psDBRunQueryF(config->dbh,query,state,label)) {
+    psError(PS_ERR_UNKNOWN, false,
+	    "failed to change state for label %s", label);
+    return(false);
+  }
+
+  return true;
 }
 
@@ -1725,5 +1775,5 @@
 
     psMetadata *where = psMetadataAlloc();
-    pxAddLabelSearchArgs (config, where, "-label", "diffRun.label", "==");
+    pxAddLabelSearchArgs (config, where, "-label", "label", "==");
 
     psString query = pxDataGet("difftool_pendingcleanuprun.sql");
@@ -1747,4 +1797,5 @@
     }
 
+    //    fprintf(stderr,"%s",query);
     if (!p_psDBRunQuery(config->dbh, query)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
@@ -1918,4 +1969,59 @@
 
     return true;
+}
+
+static bool change_skyfile_data_state(pxConfig *config, psString data_state, psString run_state) {
+  PS_ASSERT_PTR_NON_NULL(config, false);
+
+  // diff_id, skycell_id are required
+  PXOPT_LOOKUP_S64(diff_id, config->args, "-diff_id", true, false);
+  PXOPT_LOOKUP_STR(skycell_id, config->args, "-skycell_id", true, false);
+
+  psString query = pxDataGet("difftool_change_skyfile_data_state.sql");
+
+  if (!psDBTransaction(config->dbh)) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+
+  // Uses the unconstrained (diffRun.state [NEED NOT EQUAL] run_state) version from warptool.c
+
+  if (!p_psDBRunQueryF(config->dbh, query, data_state, diff_id, skycell_id)) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    // rollback
+    if (!psDBRollback(config->dbh)) {
+      psError(PS_ERR_UNKNOWN, false, "database error");
+    }
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+  psFree(query);
+
+  query = pxDataGet("difftool_change_run_state.sql");
+  if (!p_psDBRunQueryF(config->dbh, query, data_state, diff_id, data_state)) {
+    // rollback
+    if (!psDBRollback(config->dbh)) {
+      psError(PS_ERR_UNKNOWN, false, "database error");
+    }
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+
+  if (!psDBCommit(config->dbh)) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+  
+  return(true);
+}
+
+static bool tocleanedskyfileMode(pxConfig *config) {
+  return change_skyfile_data_state(config, "cleaned","goto_cleaned");
+}
+static bool topurgedskyfileMode(pxConfig *config) {
+  return change_skyfile_data_state(config, "purged", "goto_purged");
+}
+static bool toscrubbedskyfileMode(pxConfig *config) {
+  return change_skyfile_data_state(config, "scrubbed", "goto_scrubbed");
 }
 
