Index: branches/eam_branches/ipp-20100823/dbconfig/changes.txt
===================================================================
--- branches/eam_branches/ipp-20100823/dbconfig/changes.txt	(revision 29535)
+++ branches/eam_branches/ipp-20100823/dbconfig/changes.txt	(revision 29536)
@@ -1965,2 +1965,18 @@
 -- Version 1.1.66
 
+-- minidvodb copy table (for tracking copying of minidvodbs to other machines
+
+
+CREATE TABLE minidvodbCopy (
+    minidvodbcopy_id     BIGINT AUTO_INCREMENT,
+    minidvodb_id     BIGINT,
+    minidvodb_rsync_path VARCHAR(255) NOT NULL,
+    destination_host VARCHAR(255) NOT NULL,
+    fault  SMALLINT NOT NULL,
+    state   VARCHAR(64) NOT NULL,
+    epoch TIMESTAMP,
+    dtime FLOAT,
+    PRIMARY KEY(minidvodbcopy_id),
+    KEY(minidvodb_id),
+    FOREIGN KEY(minidvodb_id) REFERENCES minidvodbRun(minidvodb_id)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
Index: branches/eam_branches/ipp-20100823/dbconfig/minidvodb.md
===================================================================
--- branches/eam_branches/ipp-20100823/dbconfig/minidvodb.md	(revision 29535)
+++ branches/eam_branches/ipp-20100823/dbconfig/minidvodb.md	(revision 29536)
@@ -19,2 +19,13 @@
     fault	    S16	   0
 END
+
+minidvodbCopy METADATA
+    minidvodbcopy_id	S64 0
+    minidvodb_id    S64    0
+    minidvodb_rsync_path   STR    255
+    destination_host	   STR	  255
+    fault           S16	   0
+    state           STR    64
+    epoch           UTC    0001-01-01T00:00:00Z
+    dtime           F32    0.0
+END
Index: branches/eam_branches/ipp-20100823/ippScripts/Build.PL
===================================================================
--- branches/eam_branches/ipp-20100823/ippScripts/Build.PL	(revision 29535)
+++ branches/eam_branches/ipp-20100823/ippScripts/Build.PL	(revision 29536)
@@ -64,4 +64,5 @@
         scripts/minidvodb_createdb.pl
         scripts/minidvodb_merge.pl
+        scripts/minidvodb_copy.pl
         scripts/ippdb.pl
         scripts/ipp_cleanup.pl
Index: branches/eam_branches/ipp-20100823/ippScripts/scripts/magic_process.pl
===================================================================
--- branches/eam_branches/ipp-20100823/ippScripts/scripts/magic_process.pl	(revision 29535)
+++ branches/eam_branches/ipp-20100823/ippScripts/scripts/magic_process.pl	(revision 29536)
@@ -90,13 +90,13 @@
 
 # list of VerifyStreaks input and output files to copy to nebulous 
-my @verify_outputs = qw(
-clusterPos.txt
-duplicate.png
-mask.png
-original.png
-original.fits
-residual.png
-residual.fits
-clusters.list
+my %verify_outputs = (
+'clusterPos.txt' => 0,
+'duplicate.png' => 0,
+'mask.png' => 0,
+'original.png' => 0,
+'original.fits' => 0,
+'residual.png' => 0,
+'residual.fits' => 0,
+'clusters.list' => 1
 );
 
@@ -403,8 +403,12 @@
     if ($output_streaks and ($output_streaks ne $streaks_file)) {
         copy_to_nebulous($ipprc, $streaks_file, $output_streaks, 1);
-        foreach my $f (@verify_outputs) {
+        my $streaks_map = $outroot . ".streakMap";
+        my $output_streaks_map = $final_outroot . ".streakMap";
+        copy_to_nebulous($ipprc, $streaks_map, $output_streaks_map, 1);
+        foreach my $f (keys %verify_outputs) {
+            my $replicate = $verify_outputs{$f};
             my $src = "$baseroot.verify/${exp_id}_$f";
             my $dest = "$final_outroot.${f}";
-            copy_to_nebulous($ipprc, $src, $dest, 1);
+            copy_to_nebulous($ipprc, $src, $dest, $replicate);
         }
     } else {
Index: branches/eam_branches/ipp-20100823/ippScripts/scripts/minidvodb_copy.pl
===================================================================
--- branches/eam_branches/ipp-20100823/ippScripts/scripts/minidvodb_copy.pl	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippScripts/scripts/minidvodb_copy.pl	(revision 29536)
@@ -0,0 +1,219 @@
+#!/usr/bin/env perl
+
+use warnings;
+use strict;
+use Carp;
+ 
+## report the program and machine
+use Sys::Hostname;
+my $host = hostname();
+print "\n\n";
+print "Starting script $0 on $host\n\n";
+
+use DateTime;
+my $mjd_start = DateTime->now->mjd;   
+
+my $dtime;
+use IPC::Cmd 0.36 qw( can_run run );
+use PS::IPP::Metadata::Config;
+use PS::IPP::Metadata::List qw( parse_md_list );
+use PS::IPP::Config 1.01 qw( :standard );
+use File::Temp qw( tempfile );
+
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+
+# Look for programs we need
+my $missing_tools;
+my $rsync = can_run('rsync') or (warn "Can't find rsync" and $missing_tools = 1);
+my $minidvodbtool = can_run('minidvodbtool') or (warn "Can't find minidvodbtool" and $missing_tools = 1);
+my $ssh = can_run('ssh') or (warn "Can't find ssh" and $missing_tools = 1);
+my $df = can_run('df') or (warn "Can't find df" and $missing_tools = 1);
+
+if ($missing_tools) {
+    warn("Can't find required tools.");
+    exit($PS_EXIT_CONFIG_ERROR);
+}
+
+
+
+my ( $minidvodbcopy_id, $minidvodb_id, $minidvodbrun_path, $minidvodb_rsync_path, $destination_host, $dbname,$verbose, $logfile, $no_op, $redirect, $save_temps);
+GetOptions(
+    'minidvodbcopy_id|w=s'     => \$minidvodbcopy_id, #minidvodb database
+    'minidvodb_id|w=s'  => \$minidvodb_id, #minidvodb_id
+    'minidvodbrun_path|w=s'  => \$minidvodbrun_path, #minidvodb_id
+    'minidvodb_rsync_path|w=s' => \$minidvodb_rsync_path,
+    'destination_host|w=s' => \$destination_host, 
+    'dbname|d=s'        => \$dbname, # Database name
+    'verbose'           => \$verbose,   # Print to stdout
+    'no-op'             => \$no_op, # Don't do any operations?
+    'logfile=s'         => \$logfile,
+    'save-temps'        => \$save_temps, # Save temporary files?
+    ) or pod2usage( 2 );
+
+pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
+pod2usage(
+          -msg => "Required options: --minidvodbcopy_id --minidvodb_rsync_path --minidvodbrun_path --destination_host",
+          -exitval => 3,
+          ) unless
+    defined $minidvodbcopy_id and
+    defined $minidvodb_rsync_path and
+    defined $minidvodbrun_path and
+    defined $destination_host;
+
+
+
+my $ipprc = PS::IPP::Config->new();
+
+my @df;
+
+
+if ($logfile) {
+    $ipprc->redirect_output($logfile) or my_die( "Unable to redirect output", $minidvodbcopy_id, $PS_EXIT_SYS_ERROR );
+    print "\n\n";
+    print "Starting script $0 on $host\n\n";
+    print "COMMAND IS: @ARGV\n\n";
+}
+
+
+{ #can we rsync?
+
+    my $sizes = `du -sk $minidvodbrun_path`;
+    my $total = 0;
+    for(split /[\r\n]+/,$sizes) # split on one or more newline characters
+    { 
+	my($number,$file) = split /\t/,$_,2; # split on tab ($file not used here)
+	$total += $number; 
+    }
+#print 'Total: '.$total;
+{    
+    print "Checking available diskspace on $destination_host\n\n";
+
+    my $command = "$ssh $destination_host df $minidvodb_rsync_path";
+    print "$command\n\n";
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => $verbose);
+    unless ($success) {
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die("Unable to perform '$ssh $destination_host df $minidvodb_rsync_path' $error_code", $minidvodbcopy_id, $error_code);
+    }
+
+    my @fullbuf= split(/\n/, @{$stdout_buf}[0]);
+    #   print $#{$stdout_buf};
+#     print "xx $#df xx";
+#    print $fullbuf[0];
+    if ($#fullbuf ==1 ) {
+#	print $fullbuf[1];
+ 	@df = split /\s+/, $fullbuf[1];
+	if ($#df == 5) {
+#	    
+	    #print $df[3], $df[4];
+	    
+	    $df[4]=~ s/\%//;
+
+	    if ($df[4] <  97 && $df[3]-$total) {
+		print "\nThere is enough available space ($total < $df[3]) for the rsync\n";
+	    } else {
+		&my_die("Not enough available disk space: $df[4]% available, $df[3] on destination, $total free required for copy", $minidvodbcopy_id, $PS_EXIT_PROG_ERROR);
+	    }
+#	    
+
+	} else {
+	    &my_die("Cannot parse df:\n@{$full_buf}[0]\nCan't figure out %free or available", $minidvodbcopy_id, $PS_EXIT_PROG_ERROR); 
+	} 
+    } else {
+	&my_die("Cannot parse df:\n@{$full_buf}[0]\nToo many lines ($#fullbuf) vs 1", $minidvodbcopy_id, $PS_EXIT_PROG_ERROR);
+    }
+}
+}
+
+{#do the rsync
+    my $command = "$rsync -rvuaq";
+    $command .= " $minidvodbrun_path";
+    $command .= " $destination_host";
+    $command .= "2:$minidvodb_rsync_path";
+    print "\nPerforming rsync:\n";
+    print "$command\n\n";
+my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+        run(command => $command, verbose => $verbose);
+    unless ($success) {
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die("Unable to perform rsync: $error_code", $minidvodbcopy_id, $error_code);
+    }
+    
+    print "Rsync complete..\n";
+
+}
+
+{#update the database
+    $dtime = 86400.0*(DateTime->now->mjd - $mjd_start);
+
+    my $command = "$minidvodbtool -updateminidvodbcopy -minidvodbcopy_id $minidvodbcopy_id";
+    $command .= " -set_state full -set_dtime $dtime";
+    $command .= " -dbname $dbname" if defined $dbname;
+    print "$command\n";
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => $verbose);
+    unless ($success) {
+        $error_code = 20;
+        &my_die("Unable to update database - rsync completed without error' $error_code", $minidvodbcopy_id, $error_code);
+    }
+
+}
+
+
+
+
+
+
+
+
+
+#if ($logfile) {
+#    $ipprc->redirect_output($logfile) or my_die( "Unable to redirect output", $minidvodbcopy_id, $PS_EXIT_SYS_ERROR );
+#    print "\n\n";
+#    print "Starting script $0 on $host\n\n";
+#    print "COMMAND IS: @ARGV\n\n";
+#}
+
+
+
+
+exit 0;
+
+
+
+sub my_die
+{
+    my $msg = shift; # Warning message on die
+    my $minidbvodbcopy_id = shift;
+    my $exit_code = shift; # Exit code to add
+
+    print STDERR "$msg $minidvodbcopy_id\n";
+
+if (defined $minidvodb_id ) {
+
+    my $command = "minidvodbtool  -updateminidvodbcopy -minidvodbcopy_id $minidvodbcopy_id";
+   
+        $command .= " -set_fault $exit_code";
+        $command .= " -set_dtime $dtime" if defined $dtime;
+        $command .= " -dbname $dbname" if defined $dbname;
+
+
+
+    print $command;
+    system ($command);
+    }
+
+
+
+
+
+
+
+    $exit_code = $PS_EXIT_PROG_ERROR unless defined $exit_code;
+
+    exit $exit_code;
+}
+
+__END__
Index: branches/eam_branches/ipp-20100823/ippTasks/Makefile.am
===================================================================
--- branches/eam_branches/ipp-20100823/ippTasks/Makefile.am	(revision 29535)
+++ branches/eam_branches/ipp-20100823/ippTasks/Makefile.am	(revision 29536)
@@ -34,4 +34,5 @@
 	science.cleanup.pro \
 	minidvodb.pro \
+	minidvodbcopy.pro \
 	nightly_stacks.pro \
 	burntool.pro \
Index: branches/eam_branches/ipp-20100823/ippTasks/minidvodbcopy.pro
===================================================================
--- branches/eam_branches/ipp-20100823/ippTasks/minidvodbcopy.pro	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTasks/minidvodbcopy.pro	(revision 29536)
@@ -0,0 +1,430 @@
+## addstar.pro : globals and support macros : -*- sh -*-
+## this file contains the tasks for running the addstar analysis stage
+## these tasks use the book addPendingExp
+
+# test for required global variables
+check.globals
+
+
+#There is a book for each task, because I don't use labels. 
+
+if (not($?haveBooks))
+ book create MINIDVODB_COPY
+ book create MINIDVODB_HOST
+ $haveBooks = TRUE
+end
+
+$MINIDVODBCOPY_DB = 0
+$MINIDVODB_HOSTS_DB = 0
+
+book init minidvodbCopylist
+
+macro minidvodb.copy.status
+  book listbook minidvodbCopylist
+end
+
+macro minidvodb.copy.reset
+  book init minidvodbCopylist
+end
+
+#this is the task that manages the copying of minidvodbs to another machine
+macro minidvodb.copy.on
+    task minidvodb.copy.load
+    active true
+  end
+    task minidvodb.copy.run
+    active true
+  end
+    task minidvodb.copy.queue
+    active true
+  end
+end
+
+macro minidvodb.copy.queue.on
+    task minidvodb.copy.queue
+    active true
+  end
+end
+
+macro minidvodb.copy.queue.off   
+    task minidvodb.copy.queue
+    active false
+   end
+end
+
+macro minidvodb.copy.load.on
+    task minidvodb.copy.load
+    active true
+    end
+end
+
+macro minidvodb.copy.load.off
+    task minidvodb.copy.load
+    active false
+    end
+end
+
+macro minidvodb.copy.run.on
+    task minidvodb.copy.run
+    active true
+    end
+end
+
+macro minidvodb.copy.run.off
+    task minidvodb.copy.run
+    active false
+    end
+end
+
+macro minidvodb.copy.off
+   task minidvodb.copy.load
+    active false
+  end
+   task minidvodb.copy.run
+    active false
+  end
+   task minidvodb.copy.queue
+    active false
+  end
+end
+
+
+## you get no choice - you add all of them in at the same time. you can always turn off the tasks you don't want to run.
+macro add.minidvodb.copy
+  if ($0 != 4)
+    echo "USAGE: add.minidvodb.copy (minidvodb_group) (host) (minidvodbcopy_path)"
+    break
+  end
+  $hostandgroup = $2.$1
+  #wait - shoudl be renamed MINIDVODB_WAIT
+  book newpage MINIDVODB_COPY $hostandgroup
+  book setword MINIDVODB_COPY $hostandgroup MINIDVODBHOSTANDGROUP $hostandgroup
+  book setword MINIDVODB_COPY $hostandgroup MINIDVODB_GROUP $1
+  book setword MINIDVODB_COPY $hostandgroup HOST $2
+  book setword MINIDVODB_COPY $hostandgroup MINIDVODB_COPY_PATH $3
+  book setword MINIDVODB_COPY $hostandgroup STATE PENDING
+  book setword MINIDVODB_COPY $hostandgroup QUEUE_STATE PENDING
+end 
+
+macro del.minidvodb.copy
+  if ($0 != 3)
+    echo "USAGE: del.minidvodb.copy (host) (minidvodb_group)"
+    break
+  end
+  book delpage MINIDVODB_COPY $1.$2
+end
+
+macro show.minidvodb.copy
+  if ($0 != 1)
+    echo "USAGE: show.minidvodb.copy"
+    break
+  end
+  echo "minidvodb copy"
+  book listbook MINIDVODB_COPY
+end
+
+macro add.minidvodb.host
+  if ($0 != 2)
+    echo "USAGE: add.minidvodb.host (host)"
+    break
+  end
+    #wait - shoudl be renamed MINIDVODB_WAIT
+  book newpage MINIDVODB_HOST $1
+  book setword MINIDVODB_HOST $1 HOST $1
+  
+end 
+
+macro del.minidvodb.host
+  if ($0 != 2)
+    echo "USAGE: del.minidvodb.host (host)"
+    break
+  end
+  book delpage MINIDVODB_HOST $1
+end
+
+macro show.minidvodb.host
+  if ($0 != 1)
+    echo "USAGE: show.minidvodb.host"
+    break
+  end
+  echo "minidvodb hosts"
+  book listbook MINIDVODB_HOST
+end
+
+task           minidvodb.copy.queue
+  host         local
+
+  periods      -poll $LOADPOLL
+  periods      -exec $LOADEXEC
+  periods      -timeout 300
+  npending     1
+
+  stdout NULL
+  stderr $LOGDIR/minidvodb.copy.queue.log
+
+  task.exec
+    book npages MINIDVODB_COPY -var N
+    if ($N == 0)
+#      echo "No labels for processing"
+      break
+    endif
+
+    book getpage MINIDVODB_COPY 0 -var minidvodbhostandgroup -key QUEUE_STATE NEW
+    if ("$minidvodbhostandgroup" == "NULL")
+      # All labels have been done --- reset
+#      echo "Resetting labels"
+      for i 0 $N
+        book getpage MINIDVODB_COPY $i -var minidvodbhostandgroup
+        book setword MINIDVODB_COPY $minidvodbhostandgroup QUEUE_STATE NEW
+      end
+      book getpage MINIDVODB_COPY 0 -var minidvodbhostandgroup -key QUEUE_STATE NEW
+      book getword MINIDVODB_COPY $minidvodbhostandgroup HOST -var host 
+      book getword MINIDVODB_COPY $minidvodbhostandgroup MINIDVODB_GROUP -var minidvodb_group   
+      book getword MINIDVODB_COPY $minidvodbhostandgroup MINIDVODB_COPY_PATH -var minidvodb_copy_path
+      
+
+   #   echo $minidvodb_group $minidvodb_copy_path 
+   #   book getword MINIDVODB_COPY 0 minidvodb_copy_path -var MINIDVODB_COPY_PATH
+      #this needs work - it is setting everything to null
+      #also, I want the database (I think?)
+
+      # Select different database
+      $MINIDVODB_COPY_DB ++
+      if ($MINIDVODB_COPY_DB >= $DB:n) set MINIDVODB_COPY_DB = 0
+    end
+#using check as opposed to list because it sees if it is done with the addRun state yet.  
+    book setword MINIDVODB_COPY $minidvodbhostandgroup QUEUE_STATE DONE
+    
+    book npages MINIDVODB_HOST -var NUM
+    if ($N ==0)
+         break
+    endif
+
+    book getpage MINIDVODB_HOST $host -var host2 -key HOST $host
+    if ($host2 != $host)
+        break
+    end
+
+    #echo $host $host2
+
+    
+    $run = minidvodbtool -definebyquery -set_destination_host $host -set_minidvodb_rsync_path $minidvodb_copy_path
+    $run = $run -minidvodb_group $minidvodb_group
+       if ($DB:n == 0)
+      option DEFAULT
+    else
+      # save the DB name for the exit tasks
+      option $DB:$MINIDVODB_COPY_DB
+      $run = $run -dbname $DB:$MINIDVODB_COPY_DB
+      $MINIDVODB_COPY_DB ++
+      if ($MINIDVODB_COPY_DB >= $DB:n) set MINIDVODB_COPY_DB = 0
+    end
+    #add_poll_args run
+    #echo $run
+    command $run
+  end
+  # success
+  task.exit    0
+    # convert 'stdout' to book format
+    #ipptool2book stdout minidvodCopylist -key minidvodbcopy_id -uniq -setword dbname $options:0 -setword pantaskState INIT
+    #if ($VERBOSE > 2)
+    #  book listbook minidvodbCopylist
+    #end
+    # delete existing entries in the appropriate pantaskStates
+    #process_cleanup minidvodbCopylist
+  end
+
+  # locked list
+  task.exit    default
+    showcommand failure
+  end
+
+  task.exit    crash
+    showcommand crash
+  end
+
+  # operation times out?
+  task.exit    timeout
+    showcommand timeout
+  end
+end
+
+
+
+
+
+
+
+
+
+
+task           minidvodb.copy.load
+  host         local
+
+  periods      -poll $LOADPOLL
+  periods      -exec $LOADEXEC
+  periods      -timeout 30
+  npending     1
+
+  stdout NULL
+  stderr $LOGDIR/minidvodb.copy.load.log
+
+  task.exec
+    book npages MINIDVODB_COPY -var N
+    if ($N == 0)
+#      echo "No labels for processing"
+      break
+    endif
+
+    book getpage MINIDVODB_COPY 0 -var minidvodbhostandgroup -key STATE NEW
+    if ("$minidvodbhostandgroup" == "NULL")
+      # All labels have been done --- reset
+#      echo "Resetting labels"
+      for i 0 $N
+        book getpage MINIDVODB_COPY $i -var minidvodbhostandgroup
+        book setword MINIDVODB_COPY $minidvodbhostandgroup STATE NEW
+      end
+      book getpage MINIDVODB_COPY 0 -var minidvodbhostandgroup -key STATE NEW
+      book getword MINIDVODB_COPY $minidvodbhostandgroup HOST -var host 
+      book getword MINIDVODB_COPY $minidvodbhostandgroup MINIDVODB_GROUP -var minidvodb_group   
+
+      
+   #   book getword MINIDVODB_COPY 0 minidvodb_copy_path -var MINIDVODB_COPY_PATH
+      #this needs work - it is setting everything to null
+      #also, I want the database (I think?)
+
+      # Select different database
+      $MINIDVODB_COPY_DB ++
+      if ($MINIDVODB_COPY_DB >= $DB:n) set MINIDVODB_COPY_DB = 0
+    end
+#using check as opposed to list because it sees if it is done with the addRun state yet.  
+    book setword MINIDVODB_COPY $minidvodbhostandgroup STATE DONE
+    
+    book npages MINIDVODB_HOST -var NUM
+    if ($N ==0)
+	 break
+    endif
+
+    book getpage MINIDVODB_HOST $host -var host2 -key HOST $host
+    if ($host2 != $host)
+	break
+    end
+
+    #echo $host $host2
+
+    
+    $run = minidvodbtool -listminidvodbcopy -destination_host $host
+    $run = $run -minidvodb_group $minidvodb_group -pending
+    if ($DB:n == 0)
+      option DEFAULT
+    else
+      # save the DB name for the exit tasks
+      option $DB:$MINIDVODB_COPY_DB
+      $run = $run -dbname $DB:$MINIDVODB_COPY_DB
+      $MINIDVODB_COPY_DB ++
+      if ($MINIDVODB_COPY_DB >= $DB:n) set MINIDVODB_COPY_DB = 0
+    end
+    add_poll_args run
+    #echo $run
+    command $run
+  end
+
+  # success
+  task.exit    0
+    # convert 'stdout' to book format
+    ipptool2book stdout minidvodbCopylist -key minidvodbcopy_id -uniq -setword dbname $options:0 -setword pantaskState INIT
+    if ($VERBOSE > 2)
+      book listbook minidvodbCopylist
+    end
+    # delete existing entries in the appropriate pantaskStates
+    process_cleanup minidvodbCopylist
+  end
+
+  # locked list
+  task.exit    default
+    showcommand failure
+  end
+
+  task.exit    crash
+    showcommand crash
+  end
+
+  # operation times out?
+  task.exit    timeout
+    showcommand timeout
+  end
+end
+
+
+
+
+task           minidvodb.copy.run
+  periods      -poll $RUNPOLL
+  periods      -exec $RUNEXEC
+  periods      -timeout 17280 
+ #if rsync is slow I want to make sure it doesn't time out
+
+  task.exec
+    # if we are unable to run the 'exec', use a long retry time
+    periods -exec $RUNEXEC
+
+    book npages minidvodbCopylist -var N
+    if ($N == 0) break
+   
+    # look for new images in minidvodbWaitlist (pantaskState == INIT)
+    book getpage minidvodbCopylist 0 -var pageName -key pantaskState INIT
+    if ("$pageName" == "NULL") break
+    echo "got here"
+    book setword minidvodbCopylist $pageName pantaskState RUN
+    book getword minidvodbCopylist $pageName minidvodbcopy_id -var MINIDVODB_COPY_ID
+    book getword minidvodbCopylist $pageName minidvodb_path -var MINIDVODBRUN_PATH
+    book getword minidvodbCopylist $pageName minidvodb_id -var MINIDVODB_ID
+    book getword minidvodbCopylist $pageName minidvodb_rsync_path -var MINIDVODB_RSYNC_PATH
+    book getword minidvodbCopylist $pageName destination_host -var DESTINATION_HOST
+    book getword minidvodbCopylist $pageName state -var STATE
+    stdout $LOGDIR/minidvodb.copy.run.log
+    stderr $LOGDIR/minidvodb.copy.run.log
+    
+    $run = minidvodb_copy.pl --minidvodbcopy_id $MINIDVODB_COPY_ID --minidvodb_id $MINIDVODB_ID  
+# and more things
+    $run = $run --minidvodbrun_path $MINIDVODBRUN_PATH --minidvodb_rsync_path $MINIDVODB_RSYNC_PATH
+    $run = $run --destination_host $DESTINATION_HOST
+   
+if ($DB:n == 0)
+      option DEFAULT
+    else
+      # save the DB name for the exit tasks
+      option $DB:$MINIDVODB_COPY_DB
+      $run = $run --dbname $DB:$MINIDVODB_COPY_DB
+      $MINIDVODB_COPY_DB ++
+      if ($MINIDVODB_COPY_DB >= $DB:n) set MINIDVODB_COPY_DB = 0
+    end
+    # save the pageName for future reference below
+    options $pageName
+    echo command $run
+    # create the command line
+    if ($VERBOSE > 1)
+      echo command $run
+    end
+    # if we are unable to run the 'exec', use a long retry time
+    periods -exec 0.05
+    command $run
+  end
+  # default exit status
+    task.exit    default
+    process_exit minidvodbCopylist $options:0 $JOB_STATUS
+  end
+
+  # locked list
+  task.exit    crash
+    echo "hostname: $JOB_HOSTNAME"
+    process_exit minidvodbCopylist $options:0 $EXIT_CRASH_ERR
+  end
+
+  # operation timed out?
+    task.exit    timeout
+	showcommand timeout
+    book setword minidvodbCopylist $options:0 pantaskState TIMEOUT
+  end
+end
+
Index: branches/eam_branches/ipp-20100823/ippTools/share/Makefile.am
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/Makefile.am	(revision 29535)
+++ branches/eam_branches/ipp-20100823/ippTools/share/Makefile.am	(revision 29536)
@@ -264,4 +264,7 @@
 	magicdstool_torevert_warp.sql \
 	magicdstool_torevert_diff.sql \
+	minidvodbtool_find_minidvodb_id_dvo.sql \
+	minidvodbtool_find_minidvodbcopy.sql \
+	minidvodbtool_revertminidvodbcopy.sql \
 	pstamptool_completedreq.sql \
 	pstamptool_datastore.sql \
Index: branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_find_minidvodb_id_dvo.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_find_minidvodb_id_dvo.sql	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_find_minidvodb_id_dvo.sql	(revision 29536)
@@ -0,0 +1,8 @@
+SELECT minidvodbRun.* FROM minidvodbRun
+JOIN minidvodbProcessed USING(minidvodb_id)
+WHERE minidvodbRun.state = 'merged'
+    AND minidvodb_id NOT IN (SELECT minidvodb_id
+       FROM minidvodbCopy
+       JOIN minidvodbRun USING(minidvodb_id)
+       WHERE %s
+      )
Index: branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_find_minidvodbcopy.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_find_minidvodbcopy.sql	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_find_minidvodbcopy.sql	(revision 29536)
@@ -0,0 +1,7 @@
+SELECT
+    minidvodbCopy.*,
+    minidvodbRun.minidvodb_path
+FROM minidvodbCopy
+    JOIN minidvodbRun using (minidvodb_id)
+
+
Index: branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_queue_minidvodb_id.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_queue_minidvodb_id.sql	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_queue_minidvodb_id.sql	(revision 29536)
@@ -0,0 +1,15 @@
+INSERT INTO minidvodbCopy
+    SELECT
+        0,              -- minidvodbcopy_id
+        minidvodb_id,         -- minidvodb_id
+        '%s',           -- minidvodb_rsync_path
+        '%s',           -- destination_host
+	%d,           -- fault
+        '%s',           -- state
+        %s,           -- epoch
+        %f           -- dtime
+        
+    FROM minidvodbRun
+    WHERE
+        minidvodbRun.state = 'merged'
+        AND minidvodbRun.minidvodb_id = %lld
Index: branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_revertminidvodbcopy.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_revertminidvodbcopy.sql	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTools/share/minidvodbtool_revertminidvodbcopy.sql	(revision 29536)
@@ -0,0 +1,7 @@
+UPDATE minidvodbCopy
+ --   SET minidvodbCopy.state = 'new',
+    SET minidvodbCopy.fault = 0
+WHERE
+    minidvodbCopy.state = 'new'
+    AND minidvodbCopy.fault >0    
+
Index: branches/eam_branches/ipp-20100823/ippTools/src/Makefile.am
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/Makefile.am	(revision 29535)
+++ branches/eam_branches/ipp-20100823/ippTools/src/Makefile.am	(revision 29536)
@@ -27,5 +27,6 @@
 	receivetool \
 	pubtool \
-	diffphottool
+	diffphottool \
+	minidvodbtool
 
 pkginclude_HEADERS = \
@@ -39,4 +40,5 @@
 	pxdqstats.h
 	pxmagic.h \
+	pxminidvodb.h \
 	pxregister.h \
 	pxspace.h \
@@ -73,5 +75,6 @@
 	warptool.h \
 	pubtool.h \
-	diffphottool.h
+	diffphottool.h \
+	minidvodbtool.h
 
 lib_LTLIBRARIES = libpxtools.la
@@ -90,4 +93,5 @@
 	pxdqstats.c \
 	pxmagic.c \
+	pxminidvodb.c \
 	pxregister.c \
 	pxspace.c \
@@ -280,4 +284,10 @@
     diffphottoolConfig.c
 
+minidvodbtool_CFLAGS = $(PSLIB_CFLAGS) $(PSMODULES_CFLAGS) $(IPPDB_CFLAGS)
+minidvodbtool_LDADD = $(PSLIB_LIBS) $(PSMODULES_LIBS) $(IPPDB_LIBS) libpxtools.la
+minidvodbtool_SOURCES = \
+    minidvodbtool.c \
+    minidvodbtoolConfig.c
+
 clean-local:
 	-rm -f TAGS
Index: branches/eam_branches/ipp-20100823/ippTools/src/minidvodbtool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/minidvodbtool.c	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTools/src/minidvodbtool.c	(revision 29536)
@@ -0,0 +1,499 @@
+/*
+ * addtool.c
+ *
+ * Copyright (C) 2006  Joshua Hoblitt
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "pxtools.h"
+#include "pxadd.h"
+#include "pxminidvodb.h"
+#include "minidvodbtool.h"
+
+static bool definebyqueryMode(pxConfig *config);
+static bool listminidvodbcopyMode(pxConfig *config);
+static bool revertminidvodbcopyMode(pxConfig *config);
+static bool updateminidvodbcopyMode(pxConfig *config);
+
+
+
+# define MODECASE(caseName, func) \
+    case caseName: \
+    if (!func(config)) { \
+        goto FAIL; \
+    } \
+    break;
+
+int main(int argc, char **argv)
+{
+    psLibInit(NULL);
+
+    pxConfig *config = addtoolConfig(NULL, argc, argv);
+    if (!config) {
+        psError(PXTOOLS_ERR_CONFIG, false, "failed to configure");
+        goto FAIL;
+    }
+
+    switch (config->mode) {
+        MODECASE(ADDTOOL_MODE_DEFINEBYQUERY,        definebyqueryMode);
+        MODECASE(ADDTOOL_MODE_LISTMINIDVODBCOPY, listminidvodbcopyMode);
+        MODECASE(ADDTOOL_MODE_REVERTMINIDVODBCOPY, revertminidvodbcopyMode);
+        MODECASE(ADDTOOL_MODE_UPDATEMINIDVODBCOPY, updateminidvodbcopyMode);
+
+        default:
+            psAbort("invalid option (this should not happen)");
+    }
+
+    psFree(config);
+    pmConfigDone();
+    psLibFinalize();
+
+    exit(EXIT_SUCCESS);
+
+FAIL:
+    psErrorStackPrint(stderr, "\n");
+    int exit_status = pxerrorGetExitStatus();
+
+    psFree(config);
+    pmConfigDone();
+    psLibFinalize();
+
+    exit(exit_status);
+}
+
+
+static bool definebyqueryMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    psMetadata *where = psMetadataAlloc();
+    pxcamGetSearchArgs (config, where);
+    PXOPT_COPY_S64(config->args, where,  "-minidvodb_id",    "minidvodbRun.minidvodbRun_id", "==");
+    pxAddLabelSearchArgs (config, where, "-minidvodb_group",     "minidvodbRun.minidvodb_group", "=="); // define using camRun label
+   
+
+
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+
+    PXOPT_LOOKUP_STR(destination_host,     config->args, "-set_destination_host", false, false);
+    PXOPT_LOOKUP_STR(minidvodb_rsync_path, config->args, "-set_minidvodb_rsync_path", false, false);
+    PXOPT_LOOKUP_BOOL(pretend,    config->args, "-pretend", false);
+    PXOPT_LOOKUP_BOOL(simple,     config->args, "-simple", false);
+
+    // prevent queueing an addRun if a given exposure has already been added to
+    // the given dvo database
+    psString dvodb_string = NULL;
+    psString bare_query = NULL;
+    if (destination_host) {
+      psTrace("minidvodbtool.c", PS_LOG_INFO, "destination_host argument found (%s) using minidvodbtool_find_minidvodb_id_dvo.sql\n", destination_host);
+        // find the cam_id of all the exposures that we want to queue up.
+        bare_query = pxDataGet("minidvodbtool_find_minidvodb_id_dvo.sql");
+	// user supplied dvodb
+	psStringAppend(&dvodb_string, "minidvodbCopy.destination_host = '%s'", destination_host);
+    } else {
+      psError(PS_ERR_UNKNOWN, false, "cannot queue minidvodbcopy run without a defined destination_host");
+       
+            return false;
+         }
+    if (!bare_query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retrieve SQL statement");
+	psFree(where);
+	return false;
+    }
+    // Take the bare query and add the dvodb selector
+    psString query = NULL;
+    psStringAppend(&query, bare_query, dvodb_string);
+    psFree(dvodb_string);
+    psFree(bare_query);
+
+    // use psDBGenerateWhereConditionSQL because the SQL ends in a WHERE
+    if (where && psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    } else {
+        psError(PS_ERR_UNKNOWN, true, "search parameters are required");
+        return false;
+    }
+    psFree(where);
+
+   if (!p_psDBRunQuery(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("addtool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (pretend) {
+        // negative simple so the default is true
+        if (!ippdbPrintMetadatas(stdout, output, "minidvodbCopy", !simple)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print array");
+            psFree(output);
+            return false;
+        }
+        psFree(output);
+        return true;
+    }
+
+    // loop over our list of camRun rows to check the supplied and selected dvodb and workdir values:
+    for (long i = 0; i < psArrayLength(output); i++) {
+        psMetadata *md = output->data[i];
+
+        minidvodbRunRow *row = minidvodbRunObjectFromMetadata(md);
+        if (!row) {
+            psError(PS_ERR_UNKNOWN, false, "failed to convert metadata into minidvodbRun");
+            psFree(output);
+            return false;
+        }
+
+        if (!minidvodb_rsync_path) {
+            psError(PS_ERR_UNKNOWN, false, "cannot queue minidvodbcopy run without a defined minidvodb_rsync_path: minidvodb_id %" PRId64, row->minidvodb_id);
+            psFree(output);
+            return false;
+        }
+        if (!destination_host) {
+            psError(PS_ERR_UNKNOWN, false, "cannot queue minidvodbcopy run without a defined destination_host: minidvodb_id %" PRId64, row->minidvodb_id);
+            psFree(output);
+            return false;
+        }
+
+        psFree(row);
+    }
+
+    // start a transaction so we don't end up with an exp without any associted
+    // imfiles
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(output);
+        return false;
+    }
+
+    // would could do this "all in the database" if we didn't want the option
+    // of changing the label/reduction/expgroup/dvodb/etc.  So we're pulling the
+    // data out so we have the option of changing these values or leaving the
+    // old values in place (i.e., passing the values through).
+
+    // loop over our list of camRun rows
+    for (long i = 0; i < psArrayLength(output); i++) {
+        psMetadata *md = output->data[i];
+
+        minidvodbRunRow *row = minidvodbRunObjectFromMetadata(md);
+        if (!row) {
+            psError(PS_ERR_UNKNOWN, false, "failed to convert metadata into camRun");
+            psFree(output);
+            return false;
+        }
+
+        // queue the exp
+        if (!pxaddQueueByMinidvodbID(config,
+                               row->minidvodb_id,
+				     destination_host ? destination_host : "NULL",
+				     minidvodb_rsync_path ?minidvodb_rsync_path : "NULL"
+        )) {
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error sfg");
+            }
+            psError(PS_ERR_UNKNOWN, false,
+                    "failed to trying to queue minidvodb_id: %" PRId64, row->minidvodb_id);
+            psFree(row);
+            psFree(output);
+            return false;
+        }
+        psFree(row);
+    }
+    psFree(output);
+
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    return true;
+}
+
+
+
+
+static bool listminidvodbcopyMode(pxConfig *config) {
+  psMetadata *where = psMetadataAlloc();
+  PXOPT_COPY_S64(config->args, where, "-minidvodb_id", "minidvodbCopy.minidvodb_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-minidvodbcopy_id", "minidvodbCopy.minidvodbcopy_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-destination_host", "minidvodbCopy.destination_host", "==");
+  PXOPT_COPY_STR(config->args, where, "-minidvodb_group", "minidvodbRun.minidvodb_group", "==");
+  PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+  PXOPT_LOOKUP_BOOL(pending, config->args, "-pending", false);
+  PXOPT_LOOKUP_BOOL(faulted, config->args, "-faulted", false);
+  if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+
+  psString query = pxDataGet("minidvodbtool_find_minidvodbcopy.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " WHERE %s", whereClause);
+        psFree(whereClause);
+    }
+
+// we either add AND (condition) or WHERE (condition):
+    if (where->list && faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", " AND minidvodbCopy.fault != 0");
+    }
+    if (where->list && !faulted) {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", " AND minidvodbCopy.fault = 0");
+    }
+    if (!where->list && faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", " WHERE minidvodbCopy.fault != 0");
+    }
+    if (!where->list && !faulted) {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", " WHERE minidvodbCopy.fault = 0");
+    }
+    psFree(where);
+
+    if (pending) {
+       //add the cuts for pending (state new, no faults)
+      psStringAppend(&query, " %s", " AND minidvodbCopy.state = 'new' AND minidvodbCopy.fault = 0 AND minidvodbCopy.destination_host IS NOT NULL AND minidvodbCopy.minidvodb_rsync_path IS NOT NULL");
+    }
+
+
+    // order by epoch
+    psStringAppend(&query, " ORDER BY minidvodbcopy_id");
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+      psError(PS_ERR_UNKNOWN, false, "database error %s ", query);
+        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("addtool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    // negate simple so the default is true
+    if (!ippdbPrintMetadatas(stdout, output, "minidvodbCopy", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+
+    psFree(output);
+
+return true;
+}
+
+
+
+static bool revertminidvodbcopyMode(pxConfig *config) {
+  psMetadata *where = psMetadataAlloc();
+  PS_ASSERT_PTR_NON_NULL(config, false);
+  PXOPT_COPY_S64(config->args, where, "-minidvodbcopy_id", "minidvodbCopy.minidvodbcopy_id", "==");
+  PXOPT_COPY_S64(config->args, where, "-minidvodb_id", "minidvodbCopy.minidvodb_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-destination_host", "destination_host", "==");
+  PXOPT_COPY_S16(config->args, where, "-fault", "minidvodbCopy.fault", "==");
+
+  if (!psListLength(where->list) && !psMetadataLookupBool(NULL, config->args, "-all")) {
+    psFree(where);
+    psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+    return false;
+  }
+
+  if (!psDBTransaction(config->dbh)) {
+      psError(PS_ERR_UNKNOWN, false, "database error");
+      psFree(where);
+      return false;
+  }
+
+  {
+    psString query = pxDataGet("minidvodbtool_revertminidvodbcopy.sql");
+    if (!query) {
+      // rollback
+      if (!psDBRollback(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+      }
+      psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+      psFree(where);
+      return false;
+    }
+
+    // use psDBGenerateWhereConditionalSQL with AND ... because the SQL ends in a WHERE
+    if (where && psListLength(where->list)) {
+      psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+      psStringAppend(&query, " AND %s", whereClause);
+      psFree(whereClause);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+      // rollback
+      if (!psDBRollback(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error %s", query);
+      }
+      psError(PS_ERR_UNKNOWN, false, "database error %s", query );
+      psFree(query);
+      psFree(where);
+            return false;
+    }
+    psFree(query);
+  }
+  psFree(where);
+
+  if (!psDBCommit(config->dbh)) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return false;
+  }
+
+  return true;
+}
+
+
+
+static bool updateminidvodbcopyMode(pxConfig *config) {
+  PS_ASSERT_PTR_NON_NULL(config, false);
+  psMetadata *where = psMetadataAlloc();
+  PXOPT_LOOKUP_U64(minidvodbcopy_id,  config->args, "-minidvodbcopy_id", false, false);
+  PXOPT_LOOKUP_U64(minidvodb_id,  config->args, "-minidvodb_id", false, false);
+  PXOPT_LOOKUP_STR(state,  config->args, "-state", false, false);
+  PXOPT_LOOKUP_STR(host,  config->args, "-host", false, false);
+  PXOPT_LOOKUP_STR(rsync_path,  config->args, "-minidvodb_rsync_path", false, false);
+  PXOPT_LOOKUP_S16(fault,  config->args, "-fault", false, false);
+  
+  PXOPT_LOOKUP_S16(set_fault,  config->args, "-set_fault", false, false);
+  PXOPT_LOOKUP_STR(set_rsync_path,  config->args, "-set_minidvodb_rsync_path", false, false);
+  PXOPT_LOOKUP_STR(set_host,  config->args, "-set_destination_host", false, false);
+  PXOPT_LOOKUP_STR(set_state,  config->args, "-set_state", false, false);
+  PXOPT_LOOKUP_F32(dtime,  config->args, "-set_dtime", false, false);
+  PXOPT_COPY_S64(config->args, where, "-minidvodbcopy_id",     "minidvodbCopy.minidvodbcopy_id", "==");
+  PXOPT_COPY_S64(config->args, where, "-minidvodb_id",     "minidvodbCopy.minidvodb_id", "==");
+  
+  PXOPT_COPY_STR(config->args, where, "-state",     "minidvodbCopy.state", "==");
+  PXOPT_COPY_STR(config->args, where, "-host",     "minidvodbCopy.destination_host", "==");
+  PXOPT_COPY_STR(config->args, where, "-minidvodb_rsync_path",     "minidvodbCopy.minidvodb_rsync_path", "==");
+
+
+  if (!psListLength(where->list)) {
+    psFree(where);
+    psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+    return false;
+  }
+
+  psString query = psStringCopy("UPDATE minidvodbCopy JOIN minidvodbRun USING (minidvodb_id) SET ");
+  int cnt = 0;
+  psString comma = ",";
+  if (set_fault) {
+    psStringAppend(&query, " minidvodbCopy.fault = %d", set_fault);
+  cnt++;
+  }
+
+  if (set_rsync_path) {
+    if (cnt) {
+      psStringAppend(&query, "%s", comma);
+    }
+
+    psStringAppend(&query, " minidvodbCopy.minidvodb_rsync_path = '%s'" , set_rsync_path);
+    cnt++;
+  }
+
+  if (set_host) {
+    if (cnt) {
+      psStringAppend(&query, "%s", comma);
+    }
+
+    psStringAppend(&query, " minidvodbCopy.destination_host = '%s'" , set_host);
+    cnt++;
+  }
+
+
+  if (set_state) {
+    if (cnt) {
+      psStringAppend(&query, "%s", comma);
+    }
+
+    psStringAppend(&query, " minidvodbCopy.state = '%s'" , set_state);
+    cnt++;
+  }
+
+  if (dtime) {
+    if (cnt) {
+      psStringAppend(&query, "%s", comma);
+    }
+    psStringAppend(&query, " minidvodbCopy.dtime = %f", dtime);
+    cnt++;
+  }
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+  psStringAppend(&query, " WHERE %s", whereClause);
+
+  
+  if (!p_psDBRunQuery(config->dbh, query)) {
+    psError(PS_ERR_UNKNOWN, false, "database error %s", query);
+   psFree(query);
+   return false;
+  }
+
+  psFree(query);
+  psFree(where);
+
+  return true;
+}
+
+
Index: branches/eam_branches/ipp-20100823/ippTools/src/minidvodbtool.h
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/minidvodbtool.h	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTools/src/minidvodbtool.h	(revision 29536)
@@ -0,0 +1,35 @@
+/*
+ * addtool.h
+ *
+ * Copyright (C) 2006  Joshua Hoblitt, Christopher Waters
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef ADDTOOL_H
+#define ADDTOOL_H 1
+
+#include "pxtools.h"
+
+typedef enum {
+    ADDTOOL_MODE_NONE      = 0x0,
+    ADDTOOL_MODE_DEFINEBYQUERY,
+    ADDTOOL_MODE_LISTMINIDVODBCOPY,
+    ADDTOOL_MODE_REVERTMINIDVODBCOPY,
+    ADDTOOL_MODE_UPDATEMINIDVODBCOPY
+} addtoolMode;
+
+pxConfig *addtoolConfig(pxConfig *config, int argc, char **argv);
+
+#endif // ADDTOOL_H
Index: branches/eam_branches/ipp-20100823/ippTools/src/minidvodbtoolConfig.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/minidvodbtoolConfig.c	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTools/src/minidvodbtoolConfig.c	(revision 29536)
@@ -0,0 +1,124 @@
+/*
+ * addtoolConfig.c
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+#include <stdint.h>
+
+#include <psmodules.h>
+
+#include "pxtools.h"
+#include "pxadd.h"
+#include "pxminidvodb.h"
+#include "minidvodbtool.h"
+
+pxConfig *addtoolConfig(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();
+    psMetadataAddS64(definebyqueryArgs, PS_LIST_TAIL, "-minidvodb_id",             0, "search by minidvodb_id", 0);
+    pxcamSetSearchArgs(definebyqueryArgs);
+       psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-minidvodb_group", PS_META_DUPLICATE_OK, "search by minidvodbRun minidvodb_group", NULL);
+
+       
+    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_minidvodb_rsync_path",        0, "define workdir", NULL);
+    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_destination_host",          0, "define label", NULL);
+    //    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_reduction",      0, "define reduction class", NULL);
+   psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-pretend",           0, "do not actually modify the database", false);
+    psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-simple",            0, "use the simple output format", false);
+   
+    psMetadata *listminidvodbcopyArgs = psMetadataAlloc();
+    psMetadataAddU64(listminidvodbcopyArgs, PS_LIST_TAIL, "-minidvodb_id",        0, "search by minidvodb_id", 0);
+    psMetadataAddStr(listminidvodbcopyArgs, PS_LIST_TAIL, "-minidvodbcopy_id",        0, "search by minidvodbcopy_id", NULL);
+    psMetadataAddStr(listminidvodbcopyArgs, PS_LIST_TAIL, "-minidvodb_group",         0, "search by minidvodbRun.minidvodb_group", NULL);
+    psMetadataAddStr(listminidvodbcopyArgs, PS_LIST_TAIL, "-destination_host",        0, "search by minidvodbCopy.destination_host", NULL);
+    psMetadataAddBool(listminidvodbcopyArgs, PS_LIST_TAIL, "-pending",        0, "limit to pending items", false);
+    psMetadataAddU64(listminidvodbcopyArgs, PS_LIST_TAIL, "-limit",        0, "limit to N items", 0);
+    psMetadataAddBool(listminidvodbcopyArgs, PS_LIST_TAIL, "-simple",        0, "simple output", false);
+    psMetadataAddBool(listminidvodbcopyArgs, PS_LIST_TAIL, "-faulted",        0, "limit to faulted state", false);
+
+    psMetadata *revertminidvodbcopyArgs = psMetadataAlloc();
+    psMetadataAddU64(revertminidvodbcopyArgs, PS_LIST_TAIL, "-minidvodbcopy_id",        0, "search by minidvodbcopy_id", 0);
+    psMetadataAddU64(revertminidvodbcopyArgs, PS_LIST_TAIL, "-minidvodb_id",        0, "search by minidvodb_id", 0);
+    psMetadataAddStr(revertminidvodbcopyArgs, PS_LIST_TAIL, "-destination_host",        0, "search by destination_host", NULL);
+    psMetadataAddS16(revertminidvodbcopyArgs, PS_LIST_TAIL, "-fault",        0, "search by minidvodbCopyfault", 0);
+    psMetadata *updateminidvodbcopyArgs = psMetadataAlloc();
+    psMetadataAddU64(updateminidvodbcopyArgs, PS_LIST_TAIL, "-minidvodbcopy_id",        0, "search by minidvodbcopy_id", 0);
+    psMetadataAddU64(updateminidvodbcopyArgs, PS_LIST_TAIL, "-minidvodb_id",        0, "search by minidvodb_id", 0);
+    psMetadataAddStr(updateminidvodbcopyArgs, PS_LIST_TAIL, "-state",        0, "search by state", NULL);
+    psMetadataAddStr(updateminidvodbcopyArgs, PS_LIST_TAIL, "-host",        0, "search by host", NULL);
+    psMetadataAddStr(updateminidvodbcopyArgs, PS_LIST_TAIL, "-minidvodb_rsync_path",        0, "search by rsync", NULL);
+    psMetadataAddS16(updateminidvodbcopyArgs, PS_LIST_TAIL, "-fault",  0,            "search by fault code", 0);
+  
+
+    psMetadataAddS16(updateminidvodbcopyArgs, PS_LIST_TAIL, "-set_fault",  0,            "set fault code", 0);
+  
+    psMetadataAddF32(updateminidvodbcopyArgs, PS_LIST_TAIL, "-set_dtime",  0,    "set elapsed time for transfer", 0);
+    psMetadataAddStr(updateminidvodbcopyArgs, PS_LIST_TAIL, "-set_minidvodb_rsync_path",        0, "change the minidvodb_rsync_path", NULL); 
+    psMetadataAddStr(updateminidvodbcopyArgs, PS_LIST_TAIL, "-set_destination_host",        0, "change the host", NULL);
+    psMetadataAddStr(updateminidvodbcopyArgs, PS_LIST_TAIL, "-set_state",        0, "change the state", NULL);
+
+    psMetadata *argSets = psMetadataAlloc();
+    psMetadata *modes = psMetadataAlloc();
+
+    PXOPT_ADD_MODE("-definebyquery",        "create runs from cam stage",           ADDTOOL_MODE_DEFINEBYQUERY, definebyqueryArgs);
+       PXOPT_ADD_MODE("-listminidvodbcopy","list copy minidvodbs",           ADDTOOL_MODE_LISTMINIDVODBCOPY, listminidvodbcopyArgs);
+    PXOPT_ADD_MODE("-revertminidvodbcopy","revert copy minidvobs",        ADDTOOL_MODE_REVERTMINIDVODBCOPY,     revertminidvodbcopyArgs);
+    PXOPT_ADD_MODE("-updateminidvodbcopy","change minidvodb copy properties",ADDTOOL_MODE_UPDATEMINIDVODBCOPY,  updateminidvodbcopyArgs);
+ 
+ 
+
+
+    if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
+        psError(PS_ERR_UNKNOWN, false, "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(PS_ERR_UNKNOWN, false, "Can't configure database");
+        psFree(config);
+        return NULL;
+    }
+
+    return config;
+}
Index: branches/eam_branches/ipp-20100823/ippTools/src/pxminidvodb.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/pxminidvodb.c	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTools/src/pxminidvodb.c	(revision 29536)
@@ -0,0 +1,78 @@
+/*
+ * pxadd.c
+ *
+ * Copyright (C) 2007  Joshua Hoblitt
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <ippdb.h>
+#include <string.h>
+
+#include "pxtools.h"
+#include "pxminidvodb.h"
+
+bool pxaddQueueByMinidvodbID(pxConfig *config,
+                       psS64 minidvodb_id,
+                       char *destination_host,
+                       char *minidvodb_rsync_path
+  )
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // load the SQL to enqueue our exp_ids from disk once
+    static psString query = NULL;
+    if (!query) {
+        query = pxDataGet("minidvodbtool_queue_minidvodb_id.sql");
+        psMemSetPersistent(query, true);
+        if (!query) {
+            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+            return false;
+        }
+    }
+
+    // queue the exp
+    // Note: cam_id is being cast here work around psS64 have a different type different
+    // on 32/64
+    //if (!p_psDBRunQueryF(config->dbh, query,
+    //			 minidvodb_rsync_path   ? minidvodb_rsync_path     : "NULL",
+    //			 destination_host  ? destination_host   : "NULL",
+    //                  	 0,  //fault
+			   //			 "new", // state
+    //			 "NULL",
+						   //                      0, //dtime
+                       
+									     //                    (long long) minidvodb_id
+    //    )) 
+    if (!p_psDBRunQueryF(config->dbh,"INSERT INTO minidvodbCopy SELECT         0,   minidvodb_id, '%s', '%s', 0, 'new', NULL, 0 FROM minidvodbRun     WHERE    minidvodbRun.minidvodb_id = %lld and minidvodbRun.state = 'merged'", minidvodb_rsync_path, destination_host, (long long) minidvodb_id))
+
+    {
+      psError(PS_ERR_UNKNOWN, false, "database error %s", query);
+        return false;
+    }
+
+    // just to be safe, we should have changed at least one row
+    if (psDBAffectedRows(config->dbh) < 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "no rows affected - should have changed at least one row \n%s", query);
+        return false;
+    }
+
+    return true;
+}
Index: branches/eam_branches/ipp-20100823/ippTools/src/pxminidvodb.h
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/pxminidvodb.h	(revision 29536)
+++ branches/eam_branches/ipp-20100823/ippTools/src/pxminidvodb.h	(revision 29536)
@@ -0,0 +1,34 @@
+/*
+ * pxadd.h
+ *
+ * Copyright (C) 2009  Joshua Hoblitt, Chris Waters
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef PXMINIDVODB_H
+#define PXMINIDVODB_H 1
+
+#include <pslib.h>
+
+#include "pxtools.h"
+
+
+bool pxaddQueueByMinidvodbID(pxConfig *config,
+		       psS64 minidvodb_id,
+		       char *destination_host,
+		       char *minidvodb_rsync_path
+		       );
+
+#endif // PXMINIDVODB_H
