Index: trunk/ippTools/src/chiptool.c
===================================================================
--- trunk/ippTools/src/chiptool.c	(revision 19324)
+++ trunk/ippTools/src/chiptool.c	(revision 19334)
@@ -50,4 +50,7 @@
 static bool donecleanupMode(pxConfig *config);
 static bool runMode(pxConfig *config);
+static bool tocleanedimfileMode(pxConfig *config);
+static bool tofullimfileMode(pxConfig *config);
+static bool topurgedimfileMode(pxConfig *config);
 
 static bool chipProcessedCompleteExp(pxConfig *config);
@@ -76,5 +79,5 @@
         MODECASE(CHIPTOOL_MODE_PROCESSEDIMFILE,         processedimfileMode);
         MODECASE(CHIPTOOL_MODE_REVERTPROCESSEDIMFILE,   revertprocessedimfileMode);
-        MODECASE(CHIPTOOL_MODE_UPDATEPROCESSEDIMFILE,updateprocessedimfileMode);
+        MODECASE(CHIPTOOL_MODE_UPDATEPROCESSEDIMFILE,   updateprocessedimfileMode);
         MODECASE(CHIPTOOL_MODE_BLOCK,                   blockMode);
         MODECASE(CHIPTOOL_MODE_MASKED,                  maskedMode);
@@ -85,4 +88,7 @@
         MODECASE(CHIPTOOL_MODE_DONECLEANUP,             donecleanupMode);
         MODECASE(CHIPTOOL_MODE_RUN,                     runMode);
+        MODECASE(CHIPTOOL_MODE_TOCLEANEDIMFILE,         tocleanedimfileMode);
+        MODECASE(CHIPTOOL_MODE_TOFULLIMFILE,            tofullimfileMode);
+        MODECASE(CHIPTOOL_MODE_TOPURGEDIMFILE,          topurgedimfileMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -334,5 +340,5 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    // chip_id, ext_tag, class_id are required
+    // chip_id, exp_tag, class_id are required
     PXOPT_LOOKUP_S64(chip_id, config->args, "-chip_id", true, false);
     PXOPT_LOOKUP_S64(exp_id, config->args, "-exp_id", true, false);
@@ -379,4 +385,5 @@
                                    exp_id,
                                    class_id,
+                                   "full",
                                    uri,
                                    bg,
@@ -417,5 +424,5 @@
     // XXX I've decided to make the transaction cover the Exp migration as
     // well.  Otherwise, if the last imfile in an exp is moved and the exp
-    // migration fails then the data base is left in a satuation where the exp
+    // migration fails then the data base is left in a situation where the exp
     // migration can't happen.
 
@@ -1069,2 +1076,69 @@
     return true;
 }
+
+// update chipProcessedImfile.data_state to given value.
+// afterwards, if all imfiles in the exposure have the new state, update the state for the exposure as well
+// shared code for the modes -tocleanedimfile -tofullimfile -topurgedimfile
+
+static bool change_imfile_data_state(pxConfig *config, psString data_state, psString run_state)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // chip_id, class_id are required
+    PXOPT_LOOKUP_S64(chip_id, config->args, "-chip_id", true, false);
+    PXOPT_LOOKUP_STR(class_id, config->args, "-class_id", true, false);
+
+    psString query = pxDataGet("chiptool_change_imfile_data_state.sql");
+
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    // note only updates if chipRun.state = run_state
+    if (!p_psDBRunQuery(config->dbh, query, data_state, chip_id, class_id, run_state)) {
+        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);
+
+    // XXX Comment copied from addpendingimfile
+    // I've decided to make the transaction cover the Exp migration as
+    // well.  Otherwise, if the last imfile in an exp is moved and the exp
+    // migration fails then the data base is left in a situation where the exp
+    // migration can't happen.
+
+    query = pxDataGet("chiptool_change_exp_state.sql");
+    if (!p_psDBRunQuery(config->dbh, query, data_state, chip_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 tocleanedimfileMode(pxConfig *config)
+{
+    return change_imfile_data_state(config, "cleaned", "goto_cleaned");
+}
+static bool tofullimfileMode(pxConfig *config)
+{
+    return change_imfile_data_state(config, "full", "update");
+}
+static bool topurgedimfileMode(pxConfig *config)
+{
+    return change_imfile_data_state(config, "purged", "goto_purged");
+}
