--- control_rancid.orig	2011-07-22 13:40:58.000000000 -0400
+++ control_rancid	2011-07-22 22:49:55.000000000 -0400
@@ -104,7 +104,12 @@
     GROUP=$1
 fi
 DIR=$BASEDIR/$GROUP
-TMP=${TMPDIR:=/tmp}/rancid.$GROUP.$$
+TMPDIR=${TMPDIR:=/tmp}; export TMPDIR
+if [ "X$device" != "X" ] ; then
+    TMP=$TMPDIR/rancid.$device.$GROUP.$$
+else
+    TMP=$TMPDIR/rancid.$GROUP.$$
+fi
 trap 'rm -fr $TMP;' 1 2 15
 
 # disable noclobber
@@ -168,6 +173,7 @@
 fi
 
 # do cvs update of router.db in case anyone has fiddled.
+if [ "X$device" = "X" ] ; then
 $RCSSYS update router.db > $TMP 2>&1
 grep "^C" $TMP > /dev/null
 if [ $? -eq 0 ] ; then
@@ -178,6 +184,7 @@
     exit 1
 fi
 rm -f $TMP
+fi
 
 if [ ! -f $DIR/router.db ] ; then
     echo "$DIR/router.db does not exist."
@@ -193,6 +200,8 @@
 
 # generate the list of all, up, & down routers
 cd $DIR
+trap 'rm -fr $TMP;' 1 2 15
+if [ "X$device" = "X" ] ; then
 trap 'rm -fr routers.db routers.all.new routers.down.new routers.up.new \
 	routers.mail routers.added routers.deleted $TMP;' 1 2 15
 sed -e '/^#/d' -e 's/^ *//' -e 's/ *$//' -e 's/ *: */:/g' router.db |
@@ -314,11 +323,43 @@
     echo "Error: could not rename routers.up.new"
 fi
 rm -f routers.db
+fi
 trap 'rm -fr $TMP;' 1 2 15
 
+# if a device (-r) was specified, see if that device is in this group
+if [ "X$device" != "X" ] ; then
+    while [ -f $DIR/configs/$device.new ] ; do
+        sleep 10
+    done
+    devlistfile="$DIR/routers.single.$device"
+    trap 'rm -fr $TMP $devlistfile;' 1 2 15
+    grep "^$device:" routers.up > $devlistfile
+    if [ $? -eq 1 ] ; then
+        rm -fr $devlistfile
+        exit;
+    fi
+else
+    devlistfile="$DIR/routers.multiple"
+    trap 'rm -fr $TMP $devlistfile;' 1 2 15
+    rm -fr $devlistfile
+    touch $devlistfile
+    for router in `cut -d: -f1 $DIR/routers.up` ; do
+        newer=0
+        if [ -f $TMPDIR/$GROUP.upd ]; then
+            newer=`perl5 -e "{\\$t1 = (stat(\\"$DIR/configs/$router\\"))[9];
+                              \\$t2 = (stat(\\"$TMPDIR/$GROUP.upd\\"))[9];
+                              (\\$t1 > \\$t2) ? print "1" : print "0" ;}"`
+        fi
+        if [ ! -f $TMPDIR/.$router.$GROUP.run.lock -a $newer -eq 0 ]; then
+            grep "^$router:" routers.up >> $devlistfile
+        fi
+    done
+fi
+
 cd $DIR/configs
 # check for 'up' routers missing in RCS.  no idea how this happens to some folks
-for router in `cut -d: -f1 ../routers.up` ; do
+for router in `cut -d: -f1 $devlistfile` ; do
+    if [ "X$device" != "X" -o ! -f $TMPDIR/.$router.$GROUP.run.lock ]; then
     if [ $RCSSYS = cvs ] ; then
 	cvs status $router | grep -i 'status: unknown' > /dev/null 2>&1
     else
@@ -333,9 +374,11 @@
 	fi
 	echo "$RCSSYS added missing router $router"
     fi
+    fi
 done
 echo
 # delete configs from RCS for routers not listed in routers.up.
+if [ "X$device" = "X" ] ; then
 for router in `find . \( -name \*.new -prune -o -name CVS -prune -o -name .svn -prune \) -o -type f -print | sed -e 's/^.\///'` ; do
     grep -i "^$router:" ../router.db > /dev/null 2>&1
     if [ $? -eq 1 ] ; then
@@ -358,17 +401,6 @@
     $RCSSYS commit -m updates router.db
     exit;
 fi
-
-# if a device (-r) was specified, see if that device is in this group
-if [ "X$device" != "X" ] ; then
-    trap 'rm -fr $TMP $DIR/routers.single;' 1 2 15
-    devlistfile="$DIR/routers.single"
-    grep -i "^$device:" routers.up > $devlistfile
-    if [ $? -eq 1 ] ; then
-	exit;
-    fi
-else
-    devlistfile="$DIR/routers.up"
 fi
 
 # Now we can actually try to get the configs
@@ -377,7 +409,11 @@
 # The number of processes running at any given time can be
 # tailored to the specific installation.
 echo ""
-echo "Trying to get all of the configs."
+if [ "X$device" = "X" ] ; then
+    echo "Trying to get all of the configs."
+else
+    echo "Trying to get the config of $device."
+fi
 par -q -n $PAR_COUNT -c "rancid-fe {}" $devlistfile
 
 # This section will generate a list of missed routers
@@ -385,8 +421,13 @@
 # $pass times.
 pass=$MAX_ROUNDS
 round=1
-if [ -f $DIR/routers.up.missed ] ; then
-    rm -f $DIR/routers.up.missed
+if [ "X$device" != "X" ] ; then
+    MISSEDFILE=$DIR/$device.up.missed
+else
+    MISSEDFILE=$DIR/routers.up.missed
+fi
+if [ -f $MISSEDFILE ]; then
+    rm -f $MISSEDFILE
 fi
 while [ $round -le $pass ]
 do
@@ -400,16 +441,16 @@
 
 	if [ ! -s $router.new ]
 	then
-	    echo "$router:$mfg" >> $DIR/routers.up.missed
+	    echo "$router:$mfg" >> $MISSEDFILE
 	    rm -f $router.new
 	fi
     done
 
-    if [ -f $DIR/routers.up.missed ] ; then
+    if [ -f $MISSEDFILE ]; then
 	echo "====================================="
 	echo "Getting missed routers: round $round."
-	par -q -n $PAR_COUNT -c "rancid-fe \{}" $DIR/routers.up.missed
-	rm -f $DIR/routers.up.missed
+	par -q -n $PAR_COUNT -c "rancid-fe \{}" $MISSEDFILE
+	rm -f $MISSEDFILE
 	round=`expr $round + 1`
     else
 	echo "All routers sucessfully completed."
@@ -442,6 +483,7 @@
 	    rm -f $router.new
 	else
 	    mv $router.new $router
+	    chmod 644 $router
 	    if [ $? -ne 0 ] ; then
 		echo "Error: could not rename $router.new to $router"
 		rm -f $router.new
@@ -450,16 +492,62 @@
     fi
 done
 
+# If any machines have not been reached within the last $OLDTIME
+# hours, mail out a list of them.
+cd $DIR/configs
+if [ "X$device" != "X" ] ; then
+    FAILEDFILE=$DIR/$device.failed
+    SUBJECT="Subject: config fetcher problems - $device $GROUP"
+else
+    FAILEDFILE=$DIR/routers.failed
+    SUBJECT="Subject: config fetcher problems - $GROUP"
+fi
+rm -f FAILEDFILE
+if [ "X$OLDTIME" = "X" ] ; then
+    OLDTIME=48
+fi
+perl5 -F: -ane "{\$t = (stat(\$F[0]))[9]; print \`ls -ld \$F[0]\`
+      if (time() - \$t >= $OLDTIME*60*60);}" $devlistfile | sort -u > $FAILEDFILE
+if [ -s $FAILEDFILE ]
+then
+      (
+        echo "To: $adminmailrcpt"
+        echo "$SUBJECT"
+        echo "Precedence: bulk"
+        echo ""
+        echo "The following routers have not been successfully contacted for"
+        echo "more than $OLDTIME hours."
+
+        cat $FAILEDFILE
+      ) | sendmail -t
+fi
+if [ "X$device" != "X" ] ; then
+    rm -f $FAILEDFILE
+fi
+
 # This has been different for different machines...
 # Diff the directory and then checkin.
-trap 'rm -fr $TMP $TMP.diff $DIR/routers.single;' 1 2 15
+trap 'rm -fr $TMP $TMP.diff $devlistfile;' 1 2 15
 cd $DIR
+
+# Cleanup
+rm -f $devlistfile
+
+if [ "X$device" != "X" ] ; then
+if [ $RCSSYS = "cvs" ] ; then
+    cvs -f diff -u -4 -ko configs/$device | sed -e '/^RCS file: /d' -e '/^--- /d' \
+	-e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff
+else
+    svn diff configs/$device | sed -e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff
+fi
+else
 if [ $RCSSYS = "cvs" ] ; then
     cvs -f diff -u -4 -ko | sed -e '/^RCS file: /d' -e '/^--- /d' \
 	-e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff
 else
     svn diff | sed -e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff
 fi
+fi
 
 if [ $alt_mailrcpt -eq 1 ] ; then
     subject="router config diffs - courtesy of $mailrcpt"
@@ -467,7 +555,7 @@
     subject="router config diffs"
 fi
 if [ "X$device" != "X" ] ; then
-    $RCSSYS commit -m "updates - courtesy of $mailrcpt"
+    $RCSSYS commit -m 'single update' configs/$device
     subject="$GROUP/$device $subject"
 else
     $RCSSYS commit -m updates
@@ -485,28 +573,11 @@
 	) | sendmail -t
 fi
 
-# If any machines have not been reached within the last $OLDTIME
-# hours, mail out a list of them.
-cd $DIR/configs
-rm -f $DIR/routers.failed
-if [ "X$OLDTIME" = "X" ] ; then
-    OLDTIME=24
-fi
-perl5 -F: -ane "{\$t = (stat(\$F[0]))[9]; print \`ls -ld \$F[0]\`
-	if (time() - \$t >= $OLDTIME*60*60);}" $devlistfile | sort -u > $DIR/routers.failed
-if [ -s $DIR/routers.failed ] ; then
-	(
-	  echo "To: $adminmailrcpt"
-	  echo "Subject: config fetcher problems - $GROUP"
-	  echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}'
-	  echo ""
-	  echo "The following routers have not been successfully contacted for"
-	  echo "more than $OLDTIME hours."
-
-	  cat $DIR/routers.failed
-	) | sendmail -t
-fi
-
 # Cleanup
-rm -f $TMP.diff $DIR/routers.single $DIR/routers.failed
+rm -f $TMP.diff
+if [ "X$device" = "X" ] ; then
+    sleep 1
+    touch $TMPDIR/$GROUP.upd
+fi
 trap '' 1 2 15
+
