Index: /trunk/locker/bin/disable-scripts-test
===================================================================
--- /trunk/locker/bin/disable-scripts-test	(revision 1422)
+++ /trunk/locker/bin/disable-scripts-test	(revision 1422)
@@ -0,0 +1,5 @@
+#!/bin/sh
+echo Removing iptables rules.
+iptables -t nat -D OUTPUT -d 18.181.0.46 -j DNAT --to-destination 18.181.0.229
+iptables -t nat -D OUTPUT -d 18.181.0.43 -j DNAT --to-destination 18.181.0.229
+iptables -t nat -D OUTPUT -d 18.181.0.50 -j DNAT --to-destination 18.181.0.229
Index: /trunk/locker/bin/enable-scripts-test
===================================================================
--- /trunk/locker/bin/enable-scripts-test	(revision 1422)
+++ /trunk/locker/bin/enable-scripts-test	(revision 1422)
@@ -0,0 +1,5 @@
+#!/bin/sh
+echo Adding iptables rules.
+iptables -t nat -A OUTPUT -d 18.181.0.46 -j DNAT --to-destination 18.181.0.229
+iptables -t nat -A OUTPUT -d 18.181.0.43 -j DNAT --to-destination 18.181.0.229
+iptables -t nat -A OUTPUT -d 18.181.0.50 -j DNAT --to-destination 18.181.0.229
Index: /trunk/locker/bin/firefox-test
===================================================================
--- /trunk/locker/bin/firefox-test	(revision 1422)
+++ /trunk/locker/bin/firefox-test	(revision 1422)
@@ -0,0 +1,5 @@
+#!/bin/sh
+attach -q scripts
+LD_PRELOAD=/mit/scripts/scripts-test/@sys/scripts-test-preload.so
+export LD_PRELOAD
+exec firefox
Index: /trunk/locker/bin/fix-php-ini-scripts
===================================================================
--- /trunk/locker/bin/fix-php-ini-scripts	(revision 1422)
+++ /trunk/locker/bin/fix-php-ini-scripts	(revision 1422)
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# This script is meant to help people who have somehow lost their
+# php.ini files.  It is meant to be run in the top level directory
+# of an application once a reasonable php.ini file has been placed
+# there, and will make the symlinks to it in all child directories.
+
+if [ -f php.ini ]; then
+	echo "Creating php.ini symlinks in child directories..."
+	find . -mindepth 1 -type d -exec sh -c 'ln -sf "`echo "$1" | sed '\''s,[^/],,g; s,/,../,g'\''`php.ini" "$1/"' -- {} \;
+	echo "Done!"
+else
+	echo "There is no php.ini file in this directory.  You should first"
+	echo "put a valid php.ini file in the top level directory of your"
+	echo "application, then change to that directory, and then run this"
+	echo "script to make the symlinks to your php.ini file from all the"
+	echo "child directories."
+	exit 1
+fi
+
Index: /trunk/locker/deploy/bin/turbogears
===================================================================
--- /trunk/locker/deploy/bin/turbogears	(revision 1422)
+++ /trunk/locker/deploy/bin/turbogears	(revision 1422)
@@ -0,0 +1,171 @@
+#!/usr/bin/perl
+use strict;
+use FindBin qw($Bin);
+use lib $Bin;
+use onserver;
+use Cwd;
+use File::Path;
+use URI::Escape;
+use DBI;
+use Config::IniFiles;
+use FileHandle;
+
+setup();
+
+print "\nEnter the name of your project (the title of this TurboGears instance).\n";
+my $name;
+while (1) {
+    print "Project name: ";
+    $name=<STDIN>;
+    chomp($name);
+    if ($name =~ /^[a-zA-Z][a-zA-Z0-9_ -]+$/) {
+	last;
+    }
+    print "Invalid project name; it should start with a letter and not contain\npunctuation other than dashes or underscores.\n";
+}	
+
+# quickstart turns spaces or underscores into dashes...
+$name =~ s/[ _-]+/-/g;
+
+my $defpack=lc($name);
+$defpack =~ s/[ -]/_/g;
+$defpack =~ s/[^a-z0-9_]//g;
+if (! ($defpack =~ /^[a-zA-Z]/)) {
+    $defpack = "p$defpack";
+}
+print "\nEnter the name for your project's python package.\n";
+my $pack;
+while (1) {
+    print "Package name [${defpack}]: ";
+    $pack=<STDIN>;
+    chomp($pack);
+    if (!($pack)) {
+	$pack=$defpack;
+	last;
+    } elsif ($pack =~ /^[a-zA-Z][a-zA-Z0-9_]+$/) {
+	last;
+    }
+    print "Invalid package name; it should start with a letter and contain only letters,\nnumbers, and underscores.\n";
+}
+
+print "\nWhat ORM (Object-Relational Mapper) do you want to use with this TurboGears\ninstance?  Select from the following list:\n";
+print "1. SQLAlchemy Elixir\n";
+print "2. SQLAlchemy\n";
+print "3. SQLObject\n";
+my $orm;
+while (1) {
+    print "ORM [1]: ";
+    my $ormnum=<STDIN>;
+    chomp($ormnum);
+    if ((!$ormnum) || $ormnum == 1) {
+	$orm = "elixir";
+	last;
+    } elsif ($ormnum == 2) {
+	$orm = "sqlalchemy";
+	last;
+    } elsif ($ormnum == 3) {
+	$orm = "sqlobject";
+	last;
+    }
+    print "Please choose 1, 2, or 3.\n";
+}
+
+print "\nWhat template do you want to use with this TurboGears instance?  Select from\nthe following list:\n";
+print "1. turbogears: normal template, recommended for most projects\n";
+print "2. tgbig:  a more complex directory structure for big projects\n";
+my $templ;
+while (1) {
+    print "Template [1]: ";
+    my $templnum=<STDIN>;
+    chomp($templnum);
+    if ((!$templnum) || $templnum == 1) {
+	$templ = "turbogears";
+	last;
+    } elsif ($templnum == 2) {
+	$templ = "tgbig";
+	last;
+    }
+    print "Please choose 1, 2, or 3.\n";
+}
+
+print "\nDo you want to use Identity (usernames/passwords) in this project?\n(These would be separate from Athena usernames/passwords.)\n";
+print "1. no identity: no logins, everyone sees the same pages\n";
+print "2. standard identity: users log in with site-specific usernames and passwords\n";
+#print "3. certificates: users are identified by their MIT certificates\n";
+my $ident;
+my $certpatch=0;
+while (1) {
+    print "Identity [1]: ";
+    my $identnum=<STDIN>;
+    chomp($identnum);
+    if ((!$identnum) || $identnum == 1) {
+	$ident = "no";
+	last;
+    } elsif ($identnum == 2) {
+	$ident = "yes";
+	last;
+    } elsif ($identnum == 3) {
+	$ident = "yes";
+	$certpatch = 1;
+	last;
+    }
+}
+
+open (FLUPCONF, ">flupconfig.py");
+print FLUPCONF <<EOF;
+code_dir = "/mit/$USER/Scripts/turbogears/$name/"
+project_name = "$name"
+package_name = "$pack"
+EOF
+close (FLUPCONF);
+
+system("ln","-s","/mit/$USER/Scripts/turbogears/$name/$pack","./$pack");
+system("ln","-s","/mit/$USER/Scripts/turbogears/$name/$pack/static",
+    "./static");
+
+chdir("/mit/$USER/Scripts/turbogears/");
+print "\nRunning tg-admin quickstart...\n";
+open(QS, "|/usr/bin/tg-admin quickstart $name --package=$pack --$orm --templates=$templ")
+    or die("tg-admin quickstart failed open!");
+QS->autoflush(1);
+print QS "$ident\n" or die("tg-admin quickstart failed specify ident!");
+close(QS) or die("tg-admin quickstart failed close!");
+
+# Put in the sqldb
+system(qw(sed -ri),'s/^sql(alchemy|object)\.dburi(.*)$/#sql\1.dburi\2\nsqlalchemy.dburi="mysql:\/\/' . uri_escape($sqluser) . ":" . uri_escape($sqlpass) . "\@$sqlhost\\/$sqldb\"/","$name/dev.cfg", "$name/sample-prod.cfg") == 0 or die "sed db failed!";
+system(qw(sed -ri),'s/^#? *autoreload\.on.*$/autoreload.on = False # breaks the scripts flup setup/',"$name/dev.cfg") == 0 or die "sed autoreload failed!";
+my $addrendescsl = $addrend;
+$addrendescsl =~ s|/|\\/|g;
+# Obviated by a TurboGears upgrade
+#system(qw(sed -ri),'s/^(\[global\] *)$/\1\nserver.webpath = "\/'."$addrendescsl".'"/',"$name/dev.cfg") == 0 or die "sed webpath failed!";
+if ($orm eq "elixir" or $orm eq "sqlalchemy") {
+    system(qw(sed -ri),'s/^(\[global\] *)$/\1\nsqlalchemy.pool_recycle = 30 # Need a short timeout for sql.mit.edu/',"$name/$pack/config/app.cfg") == 0 or die "sed pool_recycle failed!";
+}
+
+# Make logdir
+system('mkdir','-p',"$name/log");
+
+# Cert patch
+if ($certpatch) {
+    # comment out the password = line in model
+    system(qw(sed -ri),
+	   's/^(.*password.*)$/#\1 -- we use certs, not passwords/',
+	   "$name/$pack/model.py") == 0 or die "sed model for certs failed!";
+    
+    # Stick cert.py in
+    system('cp',"/mit/scripts/deploy$scriptsdev/turbogears-certs/certs.py",
+	   "$name/$pack/") == 0 or die "cp certs.py failed!";
+    
+    # Add the certness to controllers.py
+    system(qw(sed -ri),
+	   's/^(from cherrypy.*)$/\1\nfrom '."$pack".'.certs import with_mit_certs/',
+	   "$name/$pack/controllers.py") == 0 or die "sed controllers import for certs failed!";
+    system(qw(sed -ri),
+	   's/^(\s+)(def login.*)$/\1@with_mit_certs\n\1\2',
+	   "$name/$pack/model.py") == 0 or die "sed model for certs failed!";
+    #-! replace login body
+    #-! replace logout body
+    #-! replace login.kid
+}
+
+exit 0;
Index: /trunk/locker/sbin/get-ldap-admins
===================================================================
--- /trunk/locker/sbin/get-ldap-admins	(revision 1422)
+++ /trunk/locker/sbin/get-ldap-admins	(revision 1422)
@@ -0,0 +1,3 @@
+#!/bin/sh
+# This script can be run on or off of scripts
+ldapsearch -x -h scripts.mit.edu -b dc=scripts,dc=mit,dc=edu -LLL 'cn=Directory Administrators' uniqueMember
Index: /trunk/locker/sbin/vhostadd
===================================================================
--- /trunk/locker/sbin/vhostadd	(revision 1422)
+++ /trunk/locker/sbin/vhostadd	(revision 1422)
@@ -0,0 +1,74 @@
+#!/bin/bash
+set -e
+
+printf "Host name: " >&2
+if [ "$1" ]; then
+    host="$1"; shift
+    echo "$host"
+else
+    read host
+fi
+
+if ! grep -Fq "." <<< "$host"; then host=$host.mit.edu; fi
+
+printf "User: " >&2
+if [ "$1" ]; then
+    user="$1"; shift
+    echo "$user"
+else
+    read user
+fi
+
+while read attr value; do
+    echo "$attr" "$value"
+    case "$attr" in
+	dn:) user_dn=$value;;
+	uid:) user=$value;;
+	uidNumber:) uid=$value;;
+	gidNumber:) gid=$value;;
+	homeDirectory:) home=$value;;
+    esac
+done < <(ldapsearch -LLL -x -h scripts.mit.edu -b ou=People,dc=scripts,dc=mit,dc=edu "(uid=$user)" dn uid uidNumber gidNumber homeDirectory | perl -0pe 's/\n //g;')
+
+printf "Docroot: $home/web_scripts" >&2
+read subdir
+
+tmpfile=$(mktemp -t vhostadd.XXXXXX) || exit $?
+trap 'rm -f "$tmpfile"' EXIT
+
+cat <<EOF > "$tmpfile"
+dn: apacheServerName=$host,ou=VirtualHosts,dc=scripts,dc=mit,dc=edu
+objectClass: apacheConfig
+objectClass: top
+apacheServerName: $host
+EOF
+
+if [ "${host%mit.edu}" != "$host" ]; then
+    cat <<EOF >> "$tmpfile"
+apacheServerAlias: ${host%.mit.edu}
+EOF
+fi
+
+cat <<EOF >> "$tmpfile"
+apacheDocumentRoot: $home/web_scripts$subdir
+apacheSuexecUid: $uid
+apacheSuexecGid: $gid
+
+dn: scriptsVhostName=$host,ou=VirtualHosts,dc=scripts,dc=mit,dc=edu
+objectClass: scriptsVhost
+objectClass: top
+scriptsVhostName: $host
+EOF
+
+if [ "${host%mit.edu}" != "$host" ]; then
+    cat <<EOF >> "$tmpfile"
+scriptsVhostAlias: ${host%.mit.edu}
+EOF
+fi
+
+cat <<EOF >> "$tmpfile"
+scriptsVhostAccount: $user_dn
+scriptsVhostDirectory: ${subdir#/}
+EOF
+
+exec ldapvi --bind sasl -Y GSSAPI -h scripts4.mit.edu -b dc=scripts,dc=mit,dc=edu --add --in "$tmpfile"
Index: /trunk/locker/sbin/vhostedit
===================================================================
--- /trunk/locker/sbin/vhostedit	(revision 1422)
+++ /trunk/locker/sbin/vhostedit	(revision 1422)
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+if [ ! "$1" ]; then
+    echo "Usage: $0 <vhost>"
+    exit 2
+fi
+
+exec ldapvi --bind sasl -Y GSSAPI -h scripts4.mit.edu -b dc=scripts,dc=mit,dc=edu \
+       "(|(&(objectClass=apacheConfig)(|(apacheServerName=$1)(apacheServerAlias=$1)))(&(objectClass=scriptsVhost)(|(scriptsVhostName=$1)(scriptsVhostAlias=$1))))"
