Index: branches/locker-dev/locker/bin/fix-php-ini
===================================================================
--- branches/locker-dev/locker/bin/fix-php-ini	(revision 1413)
+++ branches/locker-dev/locker/bin/fix-php-ini	(revision 1414)
@@ -8,5 +8,5 @@
 if [ -f php.ini ]; then
 	echo "Creating php.ini symlinks in child directories..."
-	athrun scripts gfind . -mindepth 1 -type d -exec sh -c 'ln -sf "`echo "$1" | sed '\''s,[^/],,g; s,/,../,g'\''`php.ini" "$1/"' -- {} \;
+	athrun scripts gfind . -mindepth 1 -type d \( -not -name .svn -not -name .git -or -not -prune \) -exec sh -c 'ln -sf "`echo "$1" | sed '\''s,[^/],,g; s,/,../,g'\''`php.ini" "$1/"' -- {} \;
 	echo "Done!"
 else
Index: branches/locker-dev/locker/deploy/bin/django
===================================================================
--- branches/locker-dev/locker/deploy/bin/django	(revision 1413)
+++ branches/locker-dev/locker/deploy/bin/django	(revision 1414)
@@ -16,8 +16,17 @@
 print FASTCGI <<EOF;
 #!/usr/bin/env python
-import sys, os
+import sys, os, time, threading, django.utils.autoreload
 sys.path.insert(0, "/mit/$USER/Scripts/django")
 os.chdir("/mit/$USER/Scripts/django/$name")
 os.environ['DJANGO_SETTINGS_MODULE'] = "$name.settings"
+
+def reloader_thread():
+  while True:
+    if django.utils.autoreload.code_changed():
+      os._exit(3)
+    time.sleep(1)
+t = threading.Thread(target=reloader_thread)
+t.daemon = True
+t.start()
 
 from django.core.servers.fastcgi import runfastcgi
@@ -38,5 +47,5 @@
 
 chdir "/mit/$USER/Scripts/django/";
-system qw{django-admin.py startproject}, $name;
+system qw{django-admin startproject}, $name;
 chdir "$name";
 
@@ -65,6 +74,6 @@
     while (<SETTINGS>) {
       if (/^\)/) {
-	print NEWSETTINGS "    'django.contrib.admin',\n";
-	print NEWSETTINGS "    'django.contrib.admindocs',\n";
+        print NEWSETTINGS "    'django.contrib.admin',\n";
+        print NEWSETTINGS "    'django.contrib.admindocs',\n";
       }
       print NEWSETTINGS $_;
@@ -114,7 +123,4 @@
 print "  /mit/$USER/Scripts/django/$name/\n";
 print "To access manage.py, run 'ssh -k $USER\@scripts' and cd to the above directory.\n\n";
-print "When you edit your code, run the command\n";
-print "  touch /mit/$USER/web_scripts/$addrend/index.fcgi\n";
-print "before testing, to cause your site to reload the new code.\n";
 press_enter;
 
Index: branches/locker-dev/locker/doc/tickets/cnames.txt
===================================================================
--- branches/locker-dev/locker/doc/tickets/cnames.txt	(revision 1413)
+++ branches/locker-dev/locker/doc/tickets/cnames.txt	(revision 1414)
@@ -23,6 +23,6 @@
    reap it; they should do so quickly. If it belongs to an FSILG, e-mail
    ht-$ILG-acl (ht-et-acl, ht-pika-acl, etc.) and ask nicely. If it belongs
-   to an academic network, they're not getting the name back unless they can
-   negotiate with the current owner of the name
+   to an academic network, they're not getting even deleted names back unless
+   they can negotiate with the current owner of the name.
 
 2. Check that they're requesting a scripts.mit.edu path that they control
@@ -36,18 +36,31 @@
    before proceeding.
 
+   Confirm that they're signed up for scripts. http://locker.scripts.mit.edu/
+   should give something that isn't the "Account unknown" page.
+
 3. E-mail jweiss.
    * Open the ticket in RT
    * Click 'Comment' to the right of the body of the e-mail they sent
    * CC: jweiss@mit.edu (Don't use "To:", there's a bug)
-   * Write something nice. I typically use
+   * Write something nice, preferably including the stella command line.
+   I typically use
    Subject: scripts CNAME request: foo.mit.edu
 
-   At your convenience, please make foo.mit.edu an alias of scripts.mit.edu.
+   At your convenience, please make foo.mit.edu an alias of scripts-vhosts.mit.edu.
+
+   stella scripts-vhosts -a foo
        (or)
    At your convenience, please move the alias foo.mit.edu from bar.mit.edu to
-     scripts.mit.edu.
+     scripts-vhosts.mit.edu.
+
+   stella bar -d foo
+   stella scripts-vhosts -a foo
        (or)
    At your convenience, please rename the current host foo.mit.edu to
-     foo-old.mit.edu and make foo.mit.edu an alias of scripts.mit.edu.
+   foo-old.mit.edu and mark it as deleted, and make foo.mit.edu an
+   alias of scripts-vhosts.mit.edu.
+
+   stella foo -S 3 -R foo-old
+   stella scripts-vhosts -a foo
        (or)
    If the request below is sufficient authorization, please remove....
@@ -55,6 +68,6 @@
    * Set Status => Waiting and Blocking On => Moira
 
-   Occasionally jweiss is on vacation; check /mit/ops/Pager.Schedule for
-   "!jweiss" entries. It's worth asking him ahead of time if he's around. If
+   Occasionally jweiss is on vacation; generally he sets an auto-responder,
+   so you can just try emailing him and hoping, or ask him if he's around. If
    not, see if zacheiss or cfox or computing-help will handle the requests.
    (zacheiss has been willing to do them in the past.)
@@ -72,3 +85,3 @@
    or RewriteRules if they're having trouble.
 
---geofft, last updated 2008-08-02
+--geofft with minor edits by adehnert, last updated 2009-12-01
Index: branches/locker-dev/locker/doc/tickets/rt.txt
===================================================================
--- branches/locker-dev/locker/doc/tickets/rt.txt	(revision 1413)
+++ branches/locker-dev/locker/doc/tickets/rt.txt	(revision 1414)
@@ -10,14 +10,35 @@
 yourself of own updates" is on. You can also set the "Default Working Queue"
 to Scripts, and give yourself a signature referring to scripts@mit.edu.
-Another useful option here is to set a password, so you don't need certs to
-log in (and so you can use the zephyrbot).
 
-The zephyrbot (currently down) will take commands to -c scripts -i [ticket
-number] of the form /set status=resolved or /set owner=geofft.
+Another useful option here is to set an RT passwordfor your account, so you
+don't need certs to log in (though it sometimes will keep asking you for
+your password on each page load if you don't have certs) and so you can use
+the zephyrbot).  The zephyrbot will take commands to
+-c scripts -i [ticket number] of the form /set status=resolved or
+/set owner=geofft.  You need to drop a file in
+/mit/geofft/web_scripts/rt/rt-passwords by your username with the format:
+
+"username" "yourawesomepassword"
+
+And then ask geofft (zwrite geofft) to restart the RT bot.
+
+Note that in the event that Geoff's account is compromised, it is possible
+for an attacker to use this password do manipulate tickets in *any*
+queue you have bits on, not just the Scripts one.
+
+The RT bot will post ticket notifications as -c scripts -i nnn.  If you are
+responding to a ticket, it is conventional to post "lock" to the appropriate
+instance, so others know not to pre-empt you.  You should post "unlock" once
+you are done handling the ticket.
 
 You can also place these commands on a line by themselves inside e-mail; they
 will be acted upon and removed before the e-mail gets sent back out.
 
-Don't use the To field, it doesn't work. If you want to send the ticket somewhere else, use CC.
+If you're adding a *comment* (such as when you're forwarding a cname request
+on to IS&T), don't use the 'To:' field, because it'll be clobbered by our
+RT scrips and the mail won't actually go to the destination you added.
+Instead, you should use the 'Cc:' field.  Similarly, if you're adding
+*correspondence*, the 'Cc:' field will be clobbered and you need to use
+the 'To:' field.
 
 Don't CC other RT queues, it doesn't work. If you really need to, use your
Index: branches/locker-dev/locker/sbin/commit-email.pl
===================================================================
--- branches/locker-dev/locker/sbin/commit-email.pl	(revision 1413)
+++ branches/locker-dev/locker/sbin/commit-email.pl	(revision 1414)
@@ -1,3 +1,11 @@
 #!/usr/bin/env perl
+
+# ====================================================================
+# This script is deprecated.  The Subversion developers recommend
+# using mailer.py for post-commit and post-revprop change
+# notifications.  If you wish to improve or add features to a
+# post-commit notification script, please do that work on mailer.py.
+# See http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/mailer .
+# ====================================================================
 
 # ====================================================================
@@ -10,8 +18,8 @@
 # This script requires Subversion 1.2.0 or later.
 #
-# $HeadURL: http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/commit-email.pl.in $
-# $LastChangedDate: 2008-04-01 13:19:34 -0400 (Tue, 01 Apr 2008) $
-# $LastChangedBy: glasser $
-# $LastChangedRevision: 30158 $
+# $HeadURL: http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/commit-email.pl.in $
+# $LastChangedDate: 2009-05-12 13:25:35 -0400 (Tue, 12 May 2009) $
+# $LastChangedBy: blair $
+# $LastChangedRevision: 37715 $
 #
 # ====================================================================
@@ -44,4 +52,6 @@
 ######################################################################
 # Configuration section.
+
+$ENV{'LC_ALL'} = 'en_US.UTF-8';
 
 # Sendmail path, or SMTP server address.
@@ -558,5 +568,5 @@
     my @head;
     my $formatted_date;
-    if (defined $stdout)
+    if ($stdout)
       {
         $formatted_date = strftime('%a %b %e %X %Y', localtime());
@@ -753,5 +763,5 @@
     }
 
-  my $openfork_available = $^O ne "MSWin32"; 
+  my $openfork_available = $^O ne "MSWin32";
   if ($openfork_available) # We can fork on this system.
     {
@@ -769,9 +779,9 @@
         }
     }
-  else  # Running on Windows.  No fork. 
+  else  # Running on Windows.  No fork.
     {
       my @commandline = ();
       my $arg;
-      
+
       while ($arg = shift)
         {
@@ -780,5 +790,5 @@
           push(@commandline, $arg);
         }
-        
+
       # Now do the pipe.
       open(SAFE_READ, "@commandline |")
Index: branches/locker-dev/locker/sbin/commit-zephyr
===================================================================
--- branches/locker-dev/locker/sbin/commit-zephyr	(revision 1413)
+++ branches/locker-dev/locker/sbin/commit-zephyr	(revision 1414)
@@ -1,5 +1,16 @@
-#!/bin/sh
+#!/bin/bash
+#
+# This is a script that can be called from a Subversion post-commit hook
+# to zephyr a summary of the commit or the full commit.
+#
+# Use by putting something like the following in hooks/post-commit:
+# REPOS="$1"
+# REV="$2"
+# /mit/snippets/svn-hooks/commit-zephyr "$REPOS" "$REV" -c scripts
+# /mit/snippets/svn-hooks/commit-zephyr "$REPOS" "$REV" --full -c scripts-auto -i commits
 
-CLASS=scripts
+export LC_ALL=en_US.UTF-8
+
+CLASS=test
 INSTANCE=@
 FULL=0
@@ -39,3 +50,3 @@
 	echo svnlook diff "$REPOS" -r "$REV"
     fi
-) | zwrite -d -c "$CLASS" -i "$INSTANCE" -s "r$REV - $dirs"
+) | zwrite -d -c "$CLASS" -i "$INSTANCE" -O "auto" -s "SVN: r$REV"
Index: branches/locker-dev/locker/sbin/parallel-find.pl
===================================================================
--- branches/locker-dev/locker/sbin/parallel-find.pl	(revision 1413)
+++ branches/locker-dev/locker/sbin/parallel-find.pl	(revision 1414)
@@ -2,4 +2,7 @@
 
 # Script to help generate find the .scripts-version files
+
+use LockFile::Simple qw(trylock unlock);
+use File::stat;
 
 use lib '/mit/scripts/sec-tools/perl';
@@ -7,7 +10,24 @@
 open(FILE, "</mit/scripts/sec-tools/store/scriptslist");
 my $dump = "/mit/scripts/sec-tools/store/versions";
+my $dumpbackup = "/mit/scripts/sec-tools/store/versions-backup";
 
-(! -e $dump) || die "Output directory exists: $dump";
-system("mkdir", $dump) && die;
+# try to grab a lock on the version directory
+trylock($dump) || die "Can't acquire lock; lockfile already exists at <$dump.lock>.  Another parallel-find may be running.  If you are SURE there is not, remove the lock file and retry.";
+
+sub unlock_and_die ($) {
+    my $msg = shift;
+    unlock($dump);
+    die $msg;
+}
+
+# if the versions directory exists, move it to versions-backup
+# (removing the backup directory if necessary).  Then make a new copy.
+if (-e $dump){
+    if (-e $dumpbackup){
+        system("rm -rf $dumpbackup") && unlock_and_die "Can't remove old backup directory $dumpbackup";
+    }
+    system("mv", $dump, $dumpbackup) && unlock_and_die "Unable to back up current directory $dump";
+}
+system("mkdir", $dump) && unlock_and_die "mkdir failed to create $dump";
 
 use Proc::Queue size => 40, debug => 0, trace => 0;
@@ -28,8 +48,20 @@
 }
 
+sub old_version ($) {
+    my $dirname = shift;
+    open my $h, "$dirname/.scripts-version";
+    chomp (my $v = (<$h>)[-1]);
+    return $v;
+}
+
 sub version ($) {
     my $dirname = shift;
-    open my $h, "$dirname/.scripts-version";
-    return (<$h>)[-1];
+    $uid = stat($dirname)->uid;
+    open my $h, "sudo -u#$uid git --git-dir=$dirname/.git describe --tags --always 2>/dev/null |";
+    chomp($val = <$h>);
+    if (! $val) {
+        print "Failed to read value for $dirname\n"
+    }
+    return $val;
 }
 
@@ -38,15 +70,23 @@
     my $homedir = shift;
 
-    open my $files, "find $homedir/web_scripts -xdev -name .scripts-version 2>/dev/null |";
+    open my $files, "find $homedir/web_scripts -xdev -name .scripts-version -o -name .scripts 2>/dev/null |";
     open my $out, ">$dump/$user";
     while (my $f = <$files>) {
         chomp $f;
-        $f =~ s!/\.scripts-version$!!;
+        my $new_style;
+        $new_style = ($f =~ s!/\.scripts$!!);
+        if (! $new_style) {
+            $f =~ s!/\.scripts-version$!!;
+            # Don't use .scripts-version of .scripts is around!
+            if (-d "$f/.scripts") {
+                next;
+            }
+        }
         if (! updatable($f)) {
             print STDERR "not updatable: $f";
             next;
         }
-        $v = version($f);
-        print $out "$f:$v";
+        $v = $new_style ? version($f) : old_version($f);
+        print $out "$f:$v\n";
     }
     return 0;
@@ -57,13 +97,16 @@
     my $f=fork;
     if(defined ($f) and $f==0) {
-        if ($homedir !~ m|^/afs/athena|) {
-            print "ignoring non-athena-cell $user $homedir\n";
+        if ($homedir !~ m|^/afs/athena| && $homedir !~ m|^/afs/sipb| && $homedir !~ m|^/afs/zone|) {
+            print "ignoring foreign-cell $user $homedir\n";
             exit(0);
         }
-	print "$user\n";
+        print "$user\n";
         $ret = find($user, $homedir);
-	sleep rand 1;
-	exit($ret);
+        sleep rand 1;
+        exit($ret);
     }
     1 while waitpid(-1, WNOHANG)>0; # avoids memory leaks in Proc::Queue
 }
+
+unlock($dump);
+1;
Index: branches/locker-dev/locker/sql/bin/get-password
===================================================================
--- branches/locker-dev/locker/sql/bin/get-password	(revision 1413)
+++ branches/locker-dev/locker/sql/bin/get-password	(revision 1414)
@@ -48,5 +48,5 @@
 	case 1:
 		$myPassword = `/usr/bin/sql-signup`;
-        file_put_contents($cnfPath, "[mysql]\nhost=$host\nuser=$env_user\npassword=$myPassword\n");
+        file_put_contents($cnfPath, "[client]\nhost=$host\nuser=$env_user\npassword=$myPassword\n");
         $cnfinfo = getMyCnfInfo($cnfPath);
         if (is_array($cnfinfo)) {
Index: branches/locker-dev/locker/sql/bin/save-password
===================================================================
--- branches/locker-dev/locker/sql/bin/save-password	(revision 1413)
+++ branches/locker-dev/locker/sql/bin/save-password	(revision 1414)
@@ -8,5 +8,5 @@
 rm -f $lroot/.sql/my.cnf $lroot/.my.cnf
 
-echo "[mysql]
+echo "[client]
 host=sql.mit.edu
 user=$sqluser
