Index: /trunk/locker/bin/cronload
===================================================================
--- /trunk/locker/bin/cronload	(revision 1900)
+++ /trunk/locker/bin/cronload	(revision 1901)
@@ -1,3 +1,17 @@
 #!/bin/sh
+
+usage="Usage \"$0 [-l lockername] [-h] crontab\""
+while getopts "l:h" options; do
+    case $options in 
+        l ) lname=$OPTARG;;
+        h ) echo "$usage"; exit 0;;
+        * ) echo "$usage"; exit 1;;
+    esac
+done
+shift `expr $OPTIND - 1`
+if [ -z "$1" ]; then
+    echo "$usage"
+    exit 1
+fi
 
 echo "This program should print your new crontab below."
@@ -6,5 +20,22 @@
 echo
 
+
 cwd=`pwd`
-lname=`perl -e "\\\$temp = \"$cwd\"; \\\$temp =~ /\\\/([^\\\/]+)\\\/cron_scripts/; print \\\$1"`
+if [ -z "$lname" ]; then
+    lname=`perl -e "\\\$temp = \"$cwd\"; \\\$temp =~ /\\\/([^\\\/]+)\\\/cron_scripts/; print \\\$1"`
+fi
+if [ -z "$lname" ]; then
+    echo "ERROR: Could not detect locker name. Make sure to run"
+    echo "cronload from within /mit/lockername/cron_scripts/"
+    echo "(or pass the -l lockername option)"
+    exit 1
+fi
 athrun scripts scripts-ssh "$lname" /usr/local/bin/cronload "$1" "$cwd" 2>/dev/null
+if ! grep -q "^MAILTO=" "$1"; then
+    echo "WARNING: You have no MAILTO= variable set. This means any"
+    echo "cron errors will go to $lname@scripts.mit.edu (your mail_scripts"
+    echo "account), which is almost certainly not what you want!"
+    echo "Please add a MAILTO= line, e.g., MAILTO=${EMAIL:-${ATHENA_USER:-$USER}@mit.edu},"
+    echo "to your crontab. If you do not want to receive errors, set"
+    echo 'MAILTO="".'
+fi
Index: /trunk/locker/bin/crontab
===================================================================
--- /trunk/locker/bin/crontab	(revision 1900)
+++ /trunk/locker/bin/crontab	(revision 1901)
@@ -9,5 +9,5 @@
 # (can be useful for debugging)
 # You can always redirect the output of individual commands to /dev/null
-MAILTO="SCRIPTS_USER@mit.edu"
+MAILTO="ATHENA_USER@mit.edu"
 # If you do not want to receive any mail from cron, use the line below instead
 #MAILTO=""
@@ -22,5 +22,5 @@
 #  | | | | |
 #  | | | | ----- day of week (0 - 6) (Sunday=0)
-#  | |  | ------- month (1 - 12)
+#  | | | ------- month (1 - 12)
 #  | | --------- day of month (1 - 31)
 #  | ----------- hour (0 - 23)
Index: /trunk/locker/bin/for-each-server
===================================================================
--- /trunk/locker/bin/for-each-server	(revision 1900)
+++ /trunk/locker/bin/for-each-server	(revision 1901)
@@ -1,14 +1,5 @@
 #!/bin/sh
 
-case `machtype` in
-    linux|darwin)
-        TAIL_ARG="-n"
-	;;
-    *)
-        TAIL_ARG=""
-	;;
-esac
-
-for server in `finger @scripts.mit.edu | tail ${TAIL_ARG} +5 | sed -n "s/  -> \([^:]*\):.*/\1/p" | sort -u`; do
+for server in `finger @scripts.mit.edu | sed -n -e "1,5d" -e "s/  -> \([^:]*\):.*/\1/p" | sort -u`; do
     ssh "$server" "$@"
 done
Index: /trunk/locker/bin/scripts-git
===================================================================
--- /trunk/locker/bin/scripts-git	(revision 1901)
+++ /trunk/locker/bin/scripts-git	(revision 1901)
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+sname="git repository"
+deploy="git"
+create_scripts_dir=1
+requires_sql=0
+prompt_username=1
+prompt_password=0
+. /mit/scripts/deploy$scriptsdev/bin/onathena
Index: /trunk/locker/bin/scripts-mediawiki
===================================================================
--- /trunk/locker/bin/scripts-mediawiki	(revision 1900)
+++ /trunk/locker/bin/scripts-mediawiki	(revision 1901)
@@ -2,6 +2,6 @@
 
 sname="MediaWiki"
-deploy="mediawiki$scriptsstar"
+deploy="mediawiki"
 prompt_username=1
 wizard="mediawiki"
-. /mit/scripts/deploy$scriptsdev/bin/onathena$scriptsstar
+. /mit/scripts/deploy$scriptsdev/bin/onathena
Index: /trunk/locker/bin/scripts-wordpress
===================================================================
--- /trunk/locker/bin/scripts-wordpress	(revision 1900)
+++ /trunk/locker/bin/scripts-wordpress	(revision 1901)
@@ -2,6 +2,6 @@
 
 sname="WordPress"
-deploy="wordpress$scriptsstar"
+deploy="wordpress"
 prompt_password=0
 wizard="wordpress"
-. /mit/scripts/deploy$scriptsdev/bin/onathena$scriptsstar
+. /mit/scripts/deploy$scriptsdev/bin/onathena
Index: /trunk/locker/bin/signup-cron
===================================================================
--- /trunk/locker/bin/signup-cron	(revision 1900)
+++ /trunk/locker/bin/signup-cron	(revision 1901)
@@ -10,5 +10,9 @@
   fs sa /mit/$lname/cron_scripts daemon.scripts write
   DATE=`date`
-  sed '/SCRIPTS_USER/s//'"$lname"'/g' /mit/scripts/deploy/crontab | sed '/SCRIPTS_DATE/s//'"$DATE"'/g' > /mit/$lname/cron_scripts/crontab
+  signupuser=`echo "$principal" | sed 's/[/@].*$//'`
+  sed '/SCRIPTS_USER/s//'"$lname"'/g' /mit/scripts/bin$scriptsdev/crontab | sed '/ATHENA_USER/s//'"$signupuser"'/g' | sed '/SCRIPTS_DATE/s//'"$DATE"'/g' > /mit/$lname/cron_scripts/crontab
+  echo "By default, output from cron jobs for the $lname locker will be mailed"
+  echo "to $signupuser@mit.edu.  You should edit /mit/$lname/cron_scripts/crontab"
+  echo "to change this and set up your cron jobs."
   success "the cron script service" "The directory /mit/$lname/cron_scripts has been created."
 else
Index: /trunk/locker/bin/signup-mail
===================================================================
--- /trunk/locker/bin/signup-mail	(revision 1900)
+++ /trunk/locker/bin/signup-mail	(revision 1901)
@@ -9,5 +9,5 @@
   fs sa /mit/$lname/mail_scripts system:authuser none
   fs sa /mit/$lname/mail_scripts daemon.scripts read
-  signupuser=`echo "$principal" | sed 's/@.*$//'`
+  signupuser=`echo "$principal" | sed 's/[/@].*$//'`
   sed /SCRIPTS_USER/s//$signupuser/ /mit/scripts/bin/procmailrc > /mit/$lname/mail_scripts/procmailrc
   echo "By default, mail sent to $lname@scripts.mit.edu will be forwarded to"
Index: /trunk/locker/deploy/bin/django
===================================================================
--- /trunk/locker/deploy/bin/django	(revision 1900)
+++ /trunk/locker/deploy/bin/django	(revision 1901)
@@ -39,4 +39,7 @@
 print HTACCESS <<EOF;
 RewriteEngine On
+
+RewriteRule ^\$ index.fcgi/ [QSA,L]
+
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
@@ -47,5 +50,5 @@
 
 chdir "/mit/$USER/Scripts/django/";
-system qw{django-admin startproject}, $name;
+system(qw{django-admin startproject}, $name)==0 or die "\nFailed to create app.\n\n";
 chdir "$name";
 
Index: /trunk/locker/deploy/bin/git
===================================================================
--- /trunk/locker/deploy/bin/git	(revision 1901)
+++ /trunk/locker/deploy/bin/git	(revision 1901)
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+use strict;
+use FindBin qw($Bin);
+use lib $Bin;
+use onserver;
+
+setup();
+
+my $gitbase = "$scriptsdir/git";
+my $htpasswd = "$gitbase/$addrend.git/.htpasswd";
+
+open HTACCESS, ">.htaccess";
+print HTACCESS <<EOF;
+RewriteEngine On
+
+RewriteCond %{QUERY_STRING} =service=git-receive-pack [OR]
+RewriteCond %{REQUEST_URI} /git-receive-pack\$
+RewriteRule ^($addrend\\.git/.*)\$ /~$USER/$addrend/_git-auth.cgi/\$1
+<Files _git-auth.cgi>
+    AuthName "Git Access"
+    AuthType basic
+    AuthUserFile $htpasswd
+    Require user $admin_username
+
+    # Alternatively, replace "require user" with:
+    #Require group somegroup
+    #AuthGroupFile $gitbase/$addrend/.htgroup
+    # and set up .htgroup appropriately
+</Files>
+
+RewriteRule ^($addrend\\.git/.*)\$ /~$USER/$addrend/_git.cgi/\$1
+EOF
+close HTACCESS;
+chmod 0777, ".htaccess";
+
+open GIT_CGI, ">_git.cgi";
+print GIT_CGI <<EOF;
+#!/bin/sh
+case "\$PATH_INFO" in
+    .. | ../* | */.. | */../*)
+        echo "Content-type: text/plain"
+        echo "Status: 403 Forbidden"
+        echo ""
+        echo "Error: Illegally found '..' in PATH_INFO='\$PATH_INFO'"
+        echo "gitautoinstaller: \$HOME: found '..' in PATH_INFO='\$PATH_INFO'" >&2
+        exit 1;;
+    /$addrend.git/*)
+        # pass
+        ;;
+    *)
+        echo "Content-type: text/plain"
+        echo "Status: 403 Forbidden"
+        echo ""
+        echo "Error: PATH_INFO='\$PATH_INFO' must start with /$addrend.git/"
+        echo "gitautoinstaller: \$HOME: found bad start in PATH_INFO='\$PATH_INFO'" >&2
+        exit 1;;
+esac
+export GIT_PROJECT_ROOT="$gitbase"
+export PATH_TRANSLATED="\$GIT_PROJECT_ROOT\$PATH_INFO"
+exec git http-backend
+EOF
+close GIT_CGI;
+chmod 0755, "_git.cgi";
+symlink "_git.cgi","_git-auth.cgi";
+
+chdir $gitbase;
+system qw{git init --bare}, "$addrend.git";
+chdir "$addrend.git";
+
+open ENABLE, ">git-daemon-export-ok";
+print ENABLE "";
+close ENABLE;
+
+system qw{htpasswd -c}, $htpasswd, $admin_username;
+
+print "Your git repository is located in:\n";
+print "  $gitbase/$addrend.git/\n";
+print "To clone, run\n  git clone https://$USER.scripts.mit.edu/$addrend/$addrend.git\n\n";
+press_enter;
+
+exit 0;
Index: /trunk/locker/deploy/bin/onathena
===================================================================
--- /trunk/locker/deploy/bin/onathena	(revision 1900)
+++ /trunk/locker/deploy/bin/onathena	(revision 1901)
@@ -62,35 +62,41 @@
 echo
 echo "Please report problems with this installer to $aicontact."
-echo
-echo "Are you performing this install for:"
-echo "1. Your personal Athena account"
-echo "2. A locker that you control (a club, a course, etc)"
-echo "If you do not understand this question, you should answer '1'."
-printf "Please enter either '1' or '2' (without quotes): "
-read whofor
-if [ "$whofor" = 1 ]; then
-    lname="${ATHENA_USER:-$USER}"
-elif [ "$whofor" = 2 ]; then
-    echo
-    echo "OK.  $sname will be installed into a locker of your choice that"
-    echo "you control.  Please enter the name of the selected locker below."
-    echo "(For the locker /mit/lsc -- which has a full path of"
-    echo "/afs/athena.mit.edu/activity/l/lsc -- you would simply enter lsc)."
-    printf "Locker name: "
-    read lname
+
+if [ -n "$SCRIPTS_INSTALL_LOCKER" ]; then
+    lname=$SCRIPTS_INSTALL_LOCKER
 else
     echo
-    echo "ERROR:"
-    echo "You must select either '1' or '2'."
-    exit 1
-fi
-while true; do
-    if attach "$lname"; then
-        break
-    fi
-    echo "$lname is not a valid locker name."
-    printf "Locker name: "
-    read lname
-done
+    echo "Are you performing this install for:"
+    echo "1. Your personal Athena account"
+    echo "2. A locker that you control (a club, a course, etc)"
+    echo "If you do not understand this question, you should answer '1'."
+    printf "Please enter either '1' or '2' (without quotes): "
+    read whofor
+    if [ "$whofor" = 1 ]; then
+        lname="${ATHENA_USER:-$USER}"
+    elif [ "$whofor" = 2 ]; then
+        echo
+        echo "OK.  $sname will be installed into a locker of your choice that"
+        echo "you control.  Please enter the name of the selected locker below."
+        echo "(For the locker /mit/lsc -- which has a full path of"
+        echo "/afs/athena.mit.edu/activity/l/lsc -- you would simply enter lsc)."
+        printf "Locker name: "
+        read lname
+    else
+        echo
+        echo "ERROR:"
+        echo "You must select either '1' or '2'."
+        exit 1
+    fi
+    while true; do
+        if attach "$lname"; then
+            break
+        fi
+        echo "$lname is not a valid locker name."
+        printf "Locker name: "
+        read lname
+    done
+    unset whofor
+fi
 lroot="/mit/$lname" 
 
@@ -101,12 +107,16 @@
 . "/mit/scripts/bin$scriptsdev/signup-web"
 
-echo
-echo "Your new copy of $sname will appear on the web at a URL"
-echo "that starts with http://$lname.scripts.mit.edu/"
-echo "Please decide upon a complete URL and enter it below."
-echo "You must enter one or more characters after mit.edu/"
-echo "The completed address must only contain a-z, 0-9, and /."
-printf "Desired address: http://$lname.scripts.mit.edu/"
-read addrend
+if [ -n "$SCRIPTS_INSTALL_ADDREND" ]; then
+    addrend=$SCRIPTS_INSTALL_ADDREND
+else
+    echo
+    echo "Your new copy of $sname will appear on the web at a URL"
+    echo "that starts with http://$lname.scripts.mit.edu/"
+    echo "Please decide upon a complete URL and enter it below."
+    echo "You must enter one or more characters after mit.edu/"
+    echo "The completed address must only contain a-z, 0-9, and /."
+    printf "Desired address: http://$lname.scripts.mit.edu/"
+    read addrend
+fi
 
 addrend=`perl -0e 'print $ARGV[0] =~ /^([\w\/-]*[\w-])\/*$/' -- "$addrend"`
@@ -209,5 +219,9 @@
 
 if [ "$wizard" != "" ]; then
-  vsshrun "/mit/$ailocker/wizard/bin/wizard" "install" "$@" "$wizard" "$lroot/web_scripts/$addrend"
+  if [ "$create_scripts_dir" -eq 1 ]; then
+    vsshrun "/mit/$ailocker/wizard/bin/wizard" "install" "--web-stub-path" "$lroot/web_scripts/$addrend" "$@" "$wizard" "$lroot/Scripts/$deploy/$addrend"
+  else
+    vsshrun "/mit/$ailocker/wizard/bin/wizard" "install" "$@" "$wizard" "$lroot/web_scripts/$addrend"
+  fi
   exit 0
 fi
Index: /trunk/locker/deploy/bin/onserver.pm
===================================================================
--- /trunk/locker/deploy/bin/onserver.pm	(revision 1900)
+++ /trunk/locker/deploy/bin/onserver.pm	(revision 1901)
@@ -11,9 +11,9 @@
 use URI;
 our @ISA = qw(Exporter);
-our @EXPORT = qw(setup totmp fetch_uri print_login_info press_enter $server $tmp $USER $HOME $sname $deploy $addrend $base_uri $ua $admin_username $requires_sql $addrlast $sqlhost $sqluser $sqlpass $sqldb $admin_password $scriptsdev $human $email);
+our @EXPORT = qw(setup totmp fetch_uri print_login_info press_enter $server $tmp $USER $HOME $scriptsdir $sname $deploy $addrend $base_uri $ua $admin_username $requires_sql $addrlast $sqlhost $sqluser $sqlpass $sqldb $admin_password $scriptsdev $human $email);
 
 our $server = "scripts.mit.edu";
 
-our ($tmp, $USER, $HOME, $sname, $deploy, $addrend, $base_uri, $ua, $admin_username, $requires_sql, $addrlast, $sqlhost, $sqluser, $sqlpass, $sqldb, $admin_password, $scriptsdev, $human, $email);
+our ($tmp, $USER, $HOME, $scriptsdir, $sname, $deploy, $addrend, $base_uri, $ua, $admin_username, $requires_sql, $addrlast, $sqlhost, $sqluser, $sqlpass, $sqldb, $admin_password, $scriptsdev, $human, $email);
 
 $tmp = ".scripts-tmp";
@@ -77,4 +77,7 @@
   $USER = $ENV{USER};
   $HOME = $ENV{HOME};
+  $scriptsdir = $HOME;
+  $scriptsdir =~ s/\/Scripts$//;
+  $scriptsdir .= "/Scripts";
   
   ($sname, $deploy, $addrend, $admin_username, $requires_sql, $scriptsdev, $human) = @ARGV;
Index: /trunk/locker/deploy/bin/trac
===================================================================
--- /trunk/locker/deploy/bin/trac	(revision 1900)
+++ /trunk/locker/deploy/bin/trac	(revision 1901)
@@ -54,4 +54,5 @@
 $cfg->newval('components', 'webadmin.*', 'enabled');
 $cfg->newval('components', 'tracext.git.*', 'enabled') if $repotype eq "git";
+$cfg->newval('components', 'tracext.hg.*', 'enabled') if $repotype eq "hg";
 $cfg->RewriteConfig();
 
Index: /trunk/locker/deploy/trac/trac.fcgi
===================================================================
--- /trunk/locker/deploy/trac/trac.fcgi	(revision 1900)
+++ /trunk/locker/deploy/trac/trac.fcgi	(revision 1901)
@@ -2,5 +2,6 @@
 
 import os, os.path, sys
-from trac.web import fcgi_frontend
+from trac.web.main import dispatch_request
+from trac.web._fcgi import WSGIServer
 import urlparse
 
@@ -38,5 +39,5 @@
         env.log.exception(e)
     if env.needs_upgrade():
-        fcgi_frontend._fcgi.WSGIServer(send_upgrade_message).run()
+        WSGIServer(send_upgrade_message).run()
         sys.exit(0)
     if hasattr(trac.env, 'env_cache'):
@@ -65,5 +66,5 @@
                  referrer.path, referrer.query, referrer.fragment))
 
-    return fcgi_frontend.dispatch_request(environ, start_response)
+    return dispatch_request(environ, start_response)
 
-fcgi_frontend._fcgi.WSGIServer(my_dispatch_request).run()
+WSGIServer(my_dispatch_request).run()
