]> andersk Git - sql-web.git/commitdiff
move SQL to use external joe libraries
authorJoe Presbrey <presbrey@mit.edu>
Thu, 2 Nov 2006 18:08:56 +0000 (18:08 +0000)
committerJoe Presbrey <presbrey@mit.edu>
Thu, 2 Nov 2006 18:08:56 +0000 (18:08 +0000)
git-svn-id: svn://presbrey.mit.edu/sql/web/dev@120 a142d4bd-2cfb-0310-9673-cb33a7e74f58

52 files changed:
.htaccess.dev [new file with mode: 0644]
.htaccess.main [new file with mode: 0755]
admin/main.php [new file with mode: 0755]
admin/php.ini [new symlink]
batch/batch.inc.php [new file with mode: 0644]
batch/create_db.php [new file with mode: 0755]
batch/signup.php [new file with mode: 0755]
batch/status.php [new file with mode: 0755]
bin/root_install_signup.sh [new file with mode: 0644]
bin/signup.c [new file with mode: 0644]
bin/updateMain.sh [new file with mode: 0755]
contact.php [new file with mode: 0644]
contrib/.forceauth [new file with mode: 0755]
contrib/deleteuser.sql [new file with mode: 0644]
contrib/mitsql.sql [new file with mode: 0644]
contrib/reset.sql [new file with mode: 0644]
contrib/server.cfg.php [new file with mode: 0755]
cron/checkProcesses.php [new file with mode: 0755]
cron/checkQuotas.php [new file with mode: 0644]
defaults.cfg.php [new file with mode: 0644]
error.php [new file with mode: 0755]
global.act.php [new file with mode: 0644]
global.done.php [new file with mode: 0644]
index.php [new file with mode: 0755]
lib/dbaccess.lib.php [new file with mode: 0644]
lib/display.lib.php [new file with mode: 0644]
lib/errorhandler.lib.php [new file with mode: 0644]
lib/joe.lib.php [new file with mode: 0755]
lib/mitsql.lib.php [new file with mode: 0755]
lib/proc.lib.php [new file with mode: 0644]
lib/security.lib.php [new file with mode: 0644]
login.php [new file with mode: 0644]
logout.php [new file with mode: 0644]
main.php [new file with mode: 0644]
mitsql.cfg.php [new file with mode: 0755]
mitsql.css [new file with mode: 0644]
offline.php [new file with mode: 0755]
php.ini [new file with mode: 0755]
setup.php [new file with mode: 0755]
signup.php [new file with mode: 0644]
test.php [new file with mode: 0755]
tpl/contact.php [new file with mode: 0755]
tpl/error.php [new file with mode: 0755]
tpl/foot.php [new file with mode: 0644]
tpl/head.php [new file with mode: 0644]
tpl/index.php [new file with mode: 0644]
tpl/login.php [new file with mode: 0644]
tpl/main.php [new file with mode: 0644]
tpl/menu.php [new file with mode: 0644]
tpl/offline.php [new file with mode: 0755]
tpl/setup.php [new file with mode: 0755]
tpl/signup.php [new file with mode: 0644]

diff --git a/.htaccess.dev b/.htaccess.dev
new file mode 100644 (file)
index 0000000..a438060
--- /dev/null
@@ -0,0 +1,71 @@
+#php_value auto_append_file "global.done.php"
+#php_value auto_prepend_file "prepend.php"
+#php_flag xdebug.remote_enable on
+#php_flag xdebug.remote_autostart on
+#php_value xdebug.remote_host "localhost"
+#php_value xdebug.remote_port "9000"
+
+RewriteEngine On
+RewriteBase /~sql/dev/
+#RewriteBase http://sql.mit.edu/
+#RewriteBase /
+
+#RewriteOptions MaxRedirects=1
+
+#RewriteCond %{REQUEST_FILENAME}.php -f
+#RewriteRule ^.* do/%{REQUEST_FILENAME}
+#RewriteCond %{REQUEST_URI} !^/~administrator/mitsql/go/.+
+
+##RewriteCond %{REQUEST_URI} 
+##RewriteCond %{REQUEST_FILENAME} !-s
+#RewriteRule ^do/.+$ - [L]
+
+#RewriteCond %{IS_SUBREQ} !="true"
+#RewriteRule ^.*$ do/index [R,L]
+
+##RewriteCond %{REQUEST_URI} ^.*/do/.+$
+##RewriteRule ^do/.+$ - [C]
+#RewriteRule ^do/(.+)$ $1.php [PT,L]
+
+#RewriteRule ^do/(.+)$ $1.php [L]
+
+## attempt 2
+#RewriteCond %{REQUEST_URI} !^.*/do/.+$
+#RewriteRule ^.*$ do/index [R,L]
+#
+#RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /.+\.php\ HTTP
+#RewriteRule \.php$ - [F]
+#
+##RewriteCond do/%{REQUEST_FILENAME}.php -f
+#RewriteRule ^do/(.+)$ $1.php [L]
+
+# attempt 3
+
+#RewriteRule \.php$ - [F,C]
+
+#RewriteCond %{REQUEST_URI} !^.*/do/.+$
+#RewriteRule ^.*$ do/index [R,L]
+
+#RewriteCond do/%{REQUEST_FILENAME}.php -f
+#RewriteRule ^do/(.+)$ $1.php [L]
+
+#RewriteCond %{THE_REQUEST} !^(GET|HEAD)\ /.+\.php\ HTTP
+#RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /.+mitsql/do/.+\ HTTP
+
+## REVISION 4
+
+RewriteCond %{REQUEST_URI} ^.*/do/(.+)$
+RewriteRule ^do/(.+)$ $1.php [QSA]
+
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule .* do/index [R,L,QSA]
+
+# now redundant after following conditions
+#RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /.+\.php\ HTTP
+#RewriteRule .* do/index [R,L,QSA]
+
+RewriteCond %{THE_REQUEST} !^(GET|POST)\ /.+do/.+\ HTTP
+RewriteCond %{REQUEST_FILENAME} !\.html$
+RewriteCond %{REQUEST_FILENAME} !\.css$
+RewriteCond %{REQUEST_FILENAME} !\.jpg$
+RewriteRule .* do/index [R,L,QSA]
diff --git a/.htaccess.main b/.htaccess.main
new file mode 100755 (executable)
index 0000000..cddad44
--- /dev/null
@@ -0,0 +1,71 @@
+#php_value auto_append_file "global.done.php"
+#php_value auto_prepend_file "prepend.php"
+#php_flag xdebug.remote_enable on
+#php_flag xdebug.remote_autostart on
+#php_value xdebug.remote_host "localhost"
+#php_value xdebug.remote_port "9000"
+
+RewriteEngine On
+RewriteBase /~sql/main/
+#RewriteBase http://sql.mit.edu/
+#RewriteBase /
+
+#RewriteOptions MaxRedirects=1
+
+#RewriteCond %{REQUEST_FILENAME}.php -f
+#RewriteRule ^.* do/%{REQUEST_FILENAME}
+#RewriteCond %{REQUEST_URI} !^/~administrator/mitsql/go/.+
+
+##RewriteCond %{REQUEST_URI} 
+##RewriteCond %{REQUEST_FILENAME} !-s
+#RewriteRule ^do/.+$ - [L]
+
+#RewriteCond %{IS_SUBREQ} !="true"
+#RewriteRule ^.*$ do/index [R,L]
+
+##RewriteCond %{REQUEST_URI} ^.*/do/.+$
+##RewriteRule ^do/.+$ - [C]
+#RewriteRule ^do/(.+)$ $1.php [PT,L]
+
+#RewriteRule ^do/(.+)$ $1.php [L]
+
+## attempt 2
+#RewriteCond %{REQUEST_URI} !^.*/do/.+$
+#RewriteRule ^.*$ do/index [R,L]
+#
+#RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /.+\.php\ HTTP
+#RewriteRule \.php$ - [F]
+#
+##RewriteCond do/%{REQUEST_FILENAME}.php -f
+#RewriteRule ^do/(.+)$ $1.php [L]
+
+# attempt 3
+
+#RewriteRule \.php$ - [F,C]
+
+#RewriteCond %{REQUEST_URI} !^.*/do/.+$
+#RewriteRule ^.*$ do/index [R,L]
+
+#RewriteCond do/%{REQUEST_FILENAME}.php -f
+#RewriteRule ^do/(.+)$ $1.php [L]
+
+#RewriteCond %{THE_REQUEST} !^(GET|HEAD)\ /.+\.php\ HTTP
+#RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /.+mitsql/do/.+\ HTTP
+
+## REVISION 4
+
+RewriteCond %{REQUEST_URI} ^.*/do/(.+)$
+RewriteRule ^do/(.+)$ $1.php [L,QSA]
+
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule .* do/index [R,L,QSA]
+
+# now redundant after following conditions
+#RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /.+\.php\ HTTP
+#RewriteRule .* do/index [R,L,QSA]
+
+RewriteCond %{THE_REQUEST} !^(GET|POST)\ /.+do/.+\ HTTP
+RewriteCond %{REQUEST_FILENAME} !\.html$
+RewriteCond %{REQUEST_FILENAME} !\.css$
+RewriteCond %{REQUEST_FILENAME} !\.jpg$
+RewriteRule .* do/index [R,L,QSA]
diff --git a/admin/main.php b/admin/main.php
new file mode 100755 (executable)
index 0000000..c4bea86
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+
+require_once('../mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+if ((isAdmin() || isImpersonating()) && isset($i_impersonate)) {
+       impersonate($i_impersonate);
+       redirectStart();
+       exit;
+}
+
+if (!isAdmin()) redirectStart();
+
+empty($i_pagesize) && $i_pagesize=20;
+empty($i_page) && $i_page=1;
+empty($i_sortby) && $i_sortby='dSignup';
+empty($i_sortorder) && $i_sortorder=0;
+!isset($i_search) && $i_search='';
+
+if ($i_sortorder>0) $sortSQL = 'ASC'; else $sortSQL = 'DESC';
+
+$i_pagesize = mysql_escape_string($i_pagesize);
+$i_page = mysql_escape_string($i_page);
+$i_search = mysql_escape_string($i_search);
+$i_sortby = mysql_escape_string($i_sortby);
+
+$sql_search = empty($i_search)?'':" AND Username LIKE '%$i_search%' ";
+
+$columns = array('','Username','Name','nBytes','nBytesHard','nBytesOver','dSignup');
+
+$userCount = 0;
+$sqlc = "SELECT COUNT(*) as c FROM User WHERE bEnabled=1 $sql_search";
+$r = fetchRows(DBSelect($sqlc));
+$r = array_shift($r);
+count($r) && $userCount = array_shift($r);
+
+$sql = "SELECT User.UserId,Username,Name,dSignup,dLastCheck,nBytes,nBytesSoft,nBytesHard,
+                                       IF(nBytes>nBytesHard,nBytes-nBytesHard,0) as nBytesOver
+                               FROM User
+                               NATURAL JOIN UserStat
+                               NATURAL JOIN UserQuota
+                               WHERE bEnabled=1
+                               $sql_search
+                               ORDER BY $i_sortby $sortSQL";
+
+$sql .= ' LIMIT '.($i_page-1)*$i_pagesize.','.$i_pagesize;
+$pageArray = range(1,ceil($userCount/$i_pagesize));
+$pageCount = count($pageArray);
+
+$users = fetchRows(DBSelect($sql),'UserId');
+
+include 'tpl/head.php';
+
+?>
+<style>
+table.usertable td {
+       border: 1px solid black;
+       padding: 0px 2px 0px 2px;
+}
+</style>
+<?php
+
+echo '<em>',$userCount,' users</em> | ';
+if ($i_page > 1) $tPagePrev = ' <a href="'.$URI.newQS('page',$i_page-1).'">Prev</a>'; else $tPagePrev = 'First';
+if ($i_page < $pageCount) $tPageNext = ' <a href="'.$URI.newQS('page',$i_page+1).'">Next</a>'; else $tPageNext = 'Last';
+if (!empty($tPageNext) && empty($tPagePrev)) echo($tPageNext);
+elseif (empty($tPageNext) && !empty($tPagePrev)) echo($tPagePrev);
+else echo "$tPagePrev | $tPageNext";
+
+/*
+echo ' | Skip to: ';
+foreach($pageArray as $availablePage) {
+       echo ' <a href="'.$URI.newQS('page',$availablePage).'">'.$availablePage.'</a>';
+}
+*/
+
+echo ' | Page '.$i_page.' of '.$pageCount.' by '.$i_sortby;
+?>
+<span></span>
+<form method=get id=search name=search>
+<input type=text name=search value="<?=$i_search?>" />
+<input type=submit value="Search" />
+<input type=button value="Clear" onClick="document.forms['search']['search'].value = ''; document.forms['search'].submit();" />
+</form>
+<?php
+echo '<table cellspacing="0" cellpadding="0" class="usertable">';
+echo '<thead>';
+foreach($columns as $column) {
+       if (!empty($column)) {
+               $qsa = array('sortby'=>$column);
+               if ($column==$i_sortby)
+                       $qsa['sortorder']=abs($i_sortorder-1);
+               echo '<td><a href="'.$URI.newQSA($qsa).'">'.$column.'</a></td>';
+       } else echo '<td></td>';
+}
+echo '</thead>';
+foreach($users as $id=>$user) {
+       echo '<tr><td>',
+               $user['UserId'],
+               '</td><td>',
+               '<a href="do/admin/main',newQSA(array('impersonate'=>$id)),'">',
+               $user['Username'],
+               '</a></td><td><a href="http://web.mit.edu/bin/cgicso?query='.$user['Username'].'" target="_new">',
+               $user['Name'],
+               '</a></td><td>',
+               sprintSize($user['nBytes']),
+               '</td><td>',
+               sprintSize($user['nBytesHard']),
+               '</td><td>',
+               sprintSize($user['nBytesOver']),
+               '</td><td>',
+               $user['dSignup'],
+//             '</td><td>',
+//             $user['dLastCheck'],
+               '</td></tr>';
+}
+echo '</table>';
+
+include 'tpl/foot.php';
+
+?>
diff --git a/admin/php.ini b/admin/php.ini
new file mode 120000 (symlink)
index 0000000..9fc31db
--- /dev/null
@@ -0,0 +1 @@
+../php.ini
\ No newline at end of file
diff --git a/batch/batch.inc.php b/batch/batch.inc.php
new file mode 100644 (file)
index 0000000..8b65e29
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+isset($i_u) || $i_u = '';
+isset($i_p) || $i_p = '';
+isset($i_d) || $i_d = '';
+
+$i_d = str_replace(' ', '+', $i_d);
+
+?>
diff --git a/batch/create_db.php b/batch/create_db.php
new file mode 100755 (executable)
index 0000000..0f994d9
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+require_once('../mitsql.cfg.php');
+require_once('mitsql.lib.php');
+require_once('proc.lib.php');
+
+require_once('batch.inc.php');
+
+$Login = new Login($i_u, $i_p);
+if (!$Login->canLogin()) die('-1');
+
+$User = new User($Login->getUserID());
+$myUsername = $User->getUsername();
+
+if (substr($i_d,0,strlen($myUsername)+1) == $myUsername.DELIMETER) {
+       $i_d = explode(DELIMETER, $i_d);
+       array_shift($i_d);
+       $i_d = implode(DELIMETER, $i_d);
+}
+
+list($msg1, $err1) = proc::newdb($User, $i_d);
+if (!empty($err1)) die('-3,'.implode(' ',$err1));
+if (empty($err1)) die('0,'.$i_d);
+
+?>
diff --git a/batch/signup.php b/batch/signup.php
new file mode 100755 (executable)
index 0000000..65a81a8
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/php
+<?php
+
+require_once(dirname(__FILE__).'/../mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+require_once('batch.inc.php');
+
+$myUsername = $argv[1];
+$myUID = $argv[3];
+$hescmd = "hesinfo $myUsername passwd";
+$hesinfo = explode(':', trim(exec($hescmd)));
+if (count($hesinfo)>=4) {
+       $myName = explode(',', $hesinfo[4]);
+       $myName = array_shift($myName);
+} else {
+       $myName = $myUsername;
+}
+$myEmail = $myUsername.'@mit.edu';
+$myPassword = substr(md5(uniqid()),0,8);
+
+if ($myUID<1000) exit('bad UID');
+
+$Login = new Login($myUsername);
+if (!$Login->exists() && !empty($myUsername)) {
+       addUser(array('Name'=>$myName,'Username'=>$myUsername,'Email'=>$myEmail));
+       $Login->refresh();
+}
+if ($Login->canSignup()) {
+       $User = new User($Login->getUserId());
+       $User->signup($myPassword);
+       die($myPassword);
+}
+
+?>
diff --git a/batch/status.php b/batch/status.php
new file mode 100755 (executable)
index 0000000..072f064
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+
+require_once('../mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+require_once('batch.inc.php');
+
+$Login = new Login($i_u);
+// Previously "-1" -- verify consistency
+if (!$Login->canLogin()) die('1');
+
+die('0');
+
+?>
diff --git a/bin/root_install_signup.sh b/bin/root_install_signup.sh
new file mode 100644 (file)
index 0000000..84d250a
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+gcc signup.c -o /home/tools/bin/sql-signup
+chown sql /home/tools/bin/sql-signup
+chmod 4701 /home/tools/bin/sql-signup
diff --git a/bin/signup.c b/bin/signup.c
new file mode 100644 (file)
index 0000000..fe41149
--- /dev/null
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main() {
+       system("/usr/bin/php /home/sql/web_scripts/main/batch/signup.php");
+       return 0;
+}
diff --git a/bin/updateMain.sh b/bin/updateMain.sh
new file mode 100755 (executable)
index 0000000..cb5d738
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+pushd ~/web_scripts/main/ >/dev/null
+svn up
+sh ../perm.sh
+popd >/dev/null
diff --git a/contact.php b/contact.php
new file mode 100644 (file)
index 0000000..d0e68af
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+if (isOnline()) {
+       $User = new User($Login->getUserID());
+}
+
+include 'tpl/contact.php';
+
+?>
diff --git a/contrib/.forceauth b/contrib/.forceauth
new file mode 100755 (executable)
index 0000000..25dc570
--- /dev/null
@@ -0,0 +1 @@
+Test User|test@mit.edu
diff --git a/contrib/deleteuser.sql b/contrib/deleteuser.sql
new file mode 100644 (file)
index 0000000..2447df9
--- /dev/null
@@ -0,0 +1,11 @@
+
+SET @NAME=185;
+
+USE mitsql;
+DELETE FROM DBQuota WHERE DatabaseId IN (SELECT DatabaseId FROM DBOwner WHERE UserId = @NAME);
+DELETE FROM DB WHERE DatabaseId IN (SELECT DatabaseId FROM DBOwner WHERE UserId = @NAME);
+DELETE FROM DBOwner WHERE UserId = @NAME;
+DELETE FROM UserGroup WHERE UserId = @NAME;
+DELETE FROM UserQuota WHERE UserId = @NAME;
+DELETE FROM UserStat WHERE UserId = @NAME;
+DELETE FROM `User` WHERE UserId = @NAME;
diff --git a/contrib/mitsql.sql b/contrib/mitsql.sql
new file mode 100644 (file)
index 0000000..2a56522
--- /dev/null
@@ -0,0 +1,165 @@
+-- MySQL dump 10.9
+--
+-- Host: localhost    Database: mitsql
+-- ------------------------------------------------------
+-- Server version      4.1.12-nt
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `DB`
+--
+
+DROP TABLE IF EXISTS `DB`;
+CREATE TABLE `DB` (
+  `DatabaseId` int(10) unsigned NOT NULL auto_increment,
+  `Name` varchar(200) NOT NULL default '',
+  `nBytes` int(10) unsigned NOT NULL default '0',
+  `dLastCheck` datetime NOT NULL default '0000-00-00 00:00:00',
+  `dCreated` datetime NOT NULL default '0000-00-00 00:00:00',
+  `bEnabled` tinyint(3) unsigned NOT NULL default '1',
+  PRIMARY KEY  (`DatabaseId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `DBOwner`
+--
+
+DROP TABLE IF EXISTS `DBOwner`;
+CREATE TABLE `DBOwner` (
+  `DatabaseId` int(10) unsigned NOT NULL default '0',
+  `UserId` int(10) unsigned NOT NULL default '0',
+  `GroupId` int(10) unsigned NOT NULL default '0',
+  KEY `DatabaseId` (`DatabaseId`),
+  KEY `UserId` (`UserId`),
+  KEY `GroupId` (`GroupId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `DBQuota`
+--
+
+DROP TABLE IF EXISTS `DBQuota`;
+CREATE TABLE `DBQuota` (
+  `DatabaseId` int(10) unsigned NOT NULL default '0',
+  `nBytesSoft` int(10) unsigned NOT NULL default '0',
+  `nBytesHard` int(10) unsigned NOT NULL default '0',
+  `dCreated` datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY  (`DatabaseId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `Group`
+--
+
+DROP TABLE IF EXISTS `Group`;
+CREATE TABLE `Group` (
+  `GroupId` int(10) unsigned NOT NULL auto_increment,
+  `Username` varchar(200) NOT NULL default '',
+  `Password` varchar(200) NOT NULL default '',
+  `Name` text NOT NULL,
+  `Email` text NOT NULL,
+  `dCreated` datetime NOT NULL default '0000-00-00 00:00:00',
+  `bEnabled` tinyint(3) unsigned NOT NULL default '1',
+  PRIMARY KEY  (`GroupId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `GroupQuota`
+--
+
+DROP TABLE IF EXISTS `GroupQuota`;
+CREATE TABLE `GroupQuota` (
+  `GroupId` int(10) unsigned NOT NULL default '0',
+  `nDatabases` int(10) unsigned NOT NULL default '0',
+  `nBytesSoft` int(10) unsigned NOT NULL default '0',
+  `nBytesHard` int(10) unsigned NOT NULL default '0',
+  `dCreated` datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY  (`GroupId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `GroupStat`
+--
+
+DROP TABLE IF EXISTS `GroupStat`;
+CREATE TABLE `GroupStat` (
+  `GroupId` int(10) unsigned NOT NULL default '0',
+  `nDatabases` int(10) unsigned NOT NULL default '0',
+  `nBytes` int(10) unsigned NOT NULL default '0',
+  `dLastCheck` datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY  (`GroupId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `User`
+--
+
+DROP TABLE IF EXISTS `User`;
+CREATE TABLE `User` (
+  `UserId` int(10) unsigned NOT NULL auto_increment,
+  `Username` varchar(200) NOT NULL default '',
+  `Password` varchar(200) NOT NULL default '',
+  `Name` text NOT NULL,
+  `Email` text NOT NULL,
+  `UL` tinyint(3) unsigned NOT NULL default '1',
+  `dCreated` datetime NOT NULL default '0000-00-00 00:00:00',
+  `dSignup` datetime NOT NULL default '0000-00-00 00:00:00',
+  `bEnabled` tinyint(3) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`UserId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `UserGroup`
+--
+
+DROP TABLE IF EXISTS `UserGroup`;
+CREATE TABLE `UserGroup` (
+  `UserId` int(10) unsigned NOT NULL default '0',
+  `GroupId` int(10) unsigned NOT NULL default '0',
+  KEY `UserId` (`UserId`),
+  KEY `GroupId` (`GroupId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `UserQuota`
+--
+
+DROP TABLE IF EXISTS `UserQuota`;
+CREATE TABLE `UserQuota` (
+  `UserId` int(10) unsigned NOT NULL default '0',
+  `nDatabases` int(10) unsigned NOT NULL default '0',
+  `nBytesSoft` int(10) unsigned NOT NULL default '0',
+  `nBytesHard` int(10) unsigned NOT NULL default '0',
+  `dCreated` datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY  (`UserId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `UserStat`
+--
+
+DROP TABLE IF EXISTS `UserStat`;
+CREATE TABLE `UserStat` (
+  `UserId` int(10) unsigned NOT NULL default '0',
+  `nDatabases` int(10) unsigned NOT NULL default '0',
+  `nBytes` int(10) unsigned NOT NULL default '0',
+  `dLastCheck` datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY  (`UserId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
diff --git a/contrib/reset.sql b/contrib/reset.sql
new file mode 100644 (file)
index 0000000..84c5573
--- /dev/null
@@ -0,0 +1,10 @@
+TRUNCATE TABLE `DB`;
+TRUNCATE TABLE `DBOwner`;
+TRUNCATE TABLE `DBQuota`;
+TRUNCATE TABLE `Group`;
+TRUNCATE TABLE `GroupQuota`;
+TRUNCATE TABLE `GroupStat`;
+TRUNCATE TABLE `User`;
+TRUNCATE TABLE `UserGroup`;
+TRUNCATE TABLE `UserQuota`;
+TRUNCATE TABLE `UserStat`;
diff --git a/contrib/server.cfg.php b/contrib/server.cfg.php
new file mode 100755 (executable)
index 0000000..00ac13c
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+define('BASE_URL', '/~sql/dev/');
+define('DEVEL',1);
+define('DEBUG',0);
+
+function IPblockCalc($IP,$subnetMask) {
+  $IP = ip2long($IP);
+  $subnetMask = ip2long($subnetMask);
+  $revSub = ~$subnetMask;
+  $networkAddress = $IP & $subnetMask;
+  $broadcastAddress = $IP | $revSub;
+  return Array('networkAddress'=>$networkAddress,
+               'broadcastAddress'=>$broadcastAddress
+        );
+}
+
+$allowIP = array(
+       '204.9.221.18',
+       '18.237.0.77',
+       '18.237.0.90',
+       '18.237.0.225',
+       '18.237.0.227',
+       '18.237.0.228',
+       '18.239.1.6'
+       );
+
+$IP = $_SERVER['REMOTE_ADDR'];
+
+if (!empty($IP) && !in_array($IP, $allowIP)) {
+//     header('Location: http://scripts.mit.edu/~sql/');
+       header('');
+       exit('403 Access denied');
+}
diff --git a/cron/checkProcesses.php b/cron/checkProcesses.php
new file mode 100755 (executable)
index 0000000..a98a865
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+@chdir(dirname(__FILE__).'/../');
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+isOffline() && exit;
+
+define('MAX_PROC_TIME', 20);
+
+$baddbs = $badusers = $bad = array();
+$result = mysql_query('SHOW FULL PROCESSLIST');
+while ($row = mysql_fetch_assoc($result)){
+       if ($row['Time']>MAX_PROC_TIME && $row['Command']!='Sleep') {
+               $bad[] = $row;
+               $baddbs[] = $row['db'];
+               $badusers[] = $row['User'];
+       }
+}
+mysql_free_result($result);
+
+foreach($bad as $badproc) {
+       $mailtos = $mailnames = array();
+       $baddb = mysql_escape_string($badproc['db']);
+       $badtime = $badproc['Time'];
+       $badquery = $badproc['Info'];
+       if (empty($baddb)) continue;
+       $sql = "SELECT User.UserId,User.Name,User.Email
+                       FROM `User`
+                       NATURAL JOIN DBOwner
+                       NATURAL JOIN DB
+                       WHERE DB.Name = '$baddb'
+                         AND User.UL < 10";
+       $r = fetchRows(DBSelect($sql),'UserId');
+       foreach($r as $addy) {
+               $mailtos[] = $addy['Email'];
+               $mailnames[] = $addy['Name'];
+       }
+       if (empty($mailtos)) continue;
+       $mailto = implode(', ',$mailtos);
+       $mailname = implode(', ',$mailnames);
+       $mailsubj = "[sql] Slow Query on $baddb";
+       $mailbody = "Dear $mailname:
+
+A slow query was found on your database: $baddb
+It took $badtime seconds and has been aborted.
+
+We do not allow inefficient SQL queries to run this long. Your query has
+been appended to this message for your records. Please optimize your
+queries to avoid having your queries killed in the future. If you have any
+questions, please contact sql@mit.edu.
+
+This SQL Service is available at sql.mit.edu.
+
+---------------------------------------------------------------------------
+
+$badquery";
+
+       mysql_query('KILL '.$badproc['Id']);
+       mail($mailto,$mailsubj,$mailbody,"From: SQL Service <sql@mit.edu>\r\nBcc: sql@mit.edu\r\n");
+}
+
+?>
diff --git a/cron/checkQuotas.php b/cron/checkQuotas.php
new file mode 100644 (file)
index 0000000..e372390
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+
+@chdir(dirname(__FILE__).'/../');
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+isOffline() && exit;
+
+checkQuotas();
+
+?>
diff --git a/defaults.cfg.php b/defaults.cfg.php
new file mode 100644 (file)
index 0000000..10dceb3
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+$_NEW_DB['nBytes'] = 0;
+$_NEW_DB['dCreated'] = 'NOW()';
+$_NEW_DB['bEnabled'] = 0;
+
+$_NEW_DBOWNER = array();
+
+$_NEW_DBQUOTA['nBytesSoft'] = 0;
+$_NEW_DBQUOTA['nBytesHard'] = 0;
+$_NEW_DBQUOTA['dCreated'] = 'NOW()';
+
+$_NEW_USER['UserId'] = '';
+$_NEW_USER['UL'] = 1;
+$_NEW_USER['dCreated'] = 'NOW()';
+$_NEW_USER['bEnabled'] = 0;
+
+$_NEW_USERQUOTA['nDatabasesHard'] = 5;
+$_NEW_USERQUOTA['nBytesSoft'] = 94371840;
+$_NEW_USERQUOTA['nBytesHard'] = 104857600;
+$_NEW_USERQUOTA['dCreated'] = 'NOW()';
+
+$_NEW_USERSTAT['nDatabases'] = 0;
+$_NEW_USERSTAT['nBytes'] = 0;
+
+?>
diff --git a/error.php b/error.php
new file mode 100755 (executable)
index 0000000..6446c24
--- /dev/null
+++ b/error.php
@@ -0,0 +1,11 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+include 'tpl/error.php';
+
+?>
diff --git a/global.act.php b/global.act.php
new file mode 100644 (file)
index 0000000..724ab54
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+$msg = $err = $timings = array();
+
+## PROCESS CERTIFICATE
+
+$SSLCred = getSSLCert();
+$SSLName = '';
+$SSLEmail = '';
+$SSLUsername = '';
+
+if (isOnline()) {
+       
+## HANDLE SOME GLOBAL ACTIONS
+
+       if (isset($i_ssl)) {
+               if (isSSL() && $i_ssl==1) redirect(newQS('ssl'));
+               if (!isSSL() && $i_ssl==0) redirect(newQS('ssl'));
+               redirect2(flipSSL());
+       }
+       if (isset($i_reset)) { session_destroy(); session_start(); redirect(newQS('reset')); }
+
+## SETUP SESSION VARS
+
+       $UserId = sess('UserId');
+       $Login = new Login($UserId);
+
+       if (isSSL() || !isLoggedIn()) {
+               $SSLName = $SSLCred['Name'];
+               $SSLUsername = $SSLCred['Username'];
+               $SSLEmail = $SSLCred['Email'];
+
+               /*$LoginSSL = sess('LoginSSL');
+               if (!is_a($LoginSSL, 'Login')) { $LoginSSL = new Login($SSLUsername); }*/
+               $LoginSSL = new Login($SSLUsername);
+               $LoginSSL->update($SSLCred['Name'],$SSLCred['Email']);
+
+               if (!isLoggedIn() && !$LoginSSL->exists()) {
+                       if (!empty($SSLName))
+                               addUser($SSLCred);
+                       $LoginSSL->refresh();
+               }
+       } else {
+               unset($_SESSION['LoginSSL']);
+       }
+
+       /*
+       if (isPost() || isset($i_refresh)) {
+               if (!empty($UserId)) {
+                       checkQuotas($UserId);
+               }
+               isset($i_refresh) && redirect('main?r');
+       }
+       */
+
+} // isOnline()
+
+?>
diff --git a/global.done.php b/global.done.php
new file mode 100644 (file)
index 0000000..fcd343d
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+/*
+isset($Login) && sess('Login', $Login);
+isset($LoginSSL) && sess('LoginSSL', $LoginSSL);
+*/
+
+if (DEBUG) {
+       echo '<pre>';
+       print_r($_SESSION);
+       print_r($timings);
+       isset($Login) && print_r($Login);
+       isset($User) && print_r($User);
+}
+
+?>
diff --git a/index.php b/index.php
new file mode 100755 (executable)
index 0000000..e825968
--- /dev/null
+++ b/index.php
@@ -0,0 +1,20 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+
+       add switching of what owner to manage
+       - to support group sql "lockers"
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+isLoggedIn() && redirect('main');
+!DEBUG && $_SERVER['SERVER_NAME'] != 'sql.mit.edu' && redirect2('http://sql.mit.edu/');
+
+//$LoginSSL->canSignup() && redirect('signup');
+//redirect('login');
+
+include 'tpl/index.php';
+
+?>
diff --git a/lib/dbaccess.lib.php b/lib/dbaccess.lib.php
new file mode 100644 (file)
index 0000000..150aeab
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('joe.lib.php');
+
+function DBMaster($sql) {
+       sessTime($sql);
+       $res = mysql_query($sql);
+       sessTime();
+       return $res;
+}
+function DBSlave($sql) {
+       sessTime($sql);
+       $res = mysql_query($sql);
+       sessTime();
+       if (mysql_error()) trigger_error($sql."<br />\n".mysql_error(),E_USER_ERROR);
+       return $res;
+}
+
+function DBSelect($sql) { return DBSlave($sql); }
+function DBInsert($sql) {
+       DBMaster($sql);
+       if (mysql_error()) trigger_error($sql."<br />\n".mysql_error(),E_USER_ERROR);
+       return mysql_insert_id();
+}
+function DBUpdate($sql) { DBInsert($sql); }
+function DBDelete($sql) { DBInsert($sql); }
+function DBCreate($sql) { DBMaster($sql); }
+function DBDrop($sql) { DBMaster($sql); }
+function DBGrant($sql) { DBInsert($sql); }
+function DBRevoke($sql) { DBInsert($sql); }
+function DBSet($sql) { DBInsert($sql); }
+function DBShow($sql) { return DBSlave($sql); }
+
+function calcDBSize($tdb) {
+       $sql_result = "SHOW DATABASES LIKE '".mysql_escape_string($tdb)."'";
+       $result = DBShow($sql_result);
+       if (!mysql_num_rows($result)) return null;
+       
+   $sql_result = "SHOW TABLE STATUS FROM `" .mysql_escape_string($tdb)."`";
+   $result = DBShow($sql_result);
+
+   if($result) {
+       $size = 0;
+       while ($data = mysql_fetch_array($result)) {
+             $size += $data["Data_length"] + $data["Index_length"];
+       }
+       mysql_free_result($result);
+       return $size;
+   }
+   else {
+       return null;
+   }
+}
+
+function checkQuotas($userId=null) {
+       if (empty($userId)) {
+               $sql = 'SELECT DatabaseId,Name FROM DB WHERE bEnabled=1';
+       } else {
+               $sql = sprintf("SELECT DB.DatabaseId,Name FROM DB INNER JOIN DBOwner ON DB.DatabaseId = DBOwner.DatabaseId WHERE bEnabled=1 AND UserId = '%s'", mysql_escape_string($userId));
+       }
+       $databases = fetchRows(DBSelect($sql),'Name');
+       foreach($databases as $db) {
+               $DBId = $db['DatabaseId'];
+               $arr['dLastCheck'] = 'NOW()';
+               $arr['nBytes'] = calcDBSize($db['Name']);
+               $sql = sprintf("UPDATE DB %s WHERE DatabaseId = '%s'",
+                                               buildSQLSet($arr),
+                                               mysql_escape_string($DBId));
+               DBUpdate($sql);
+       }
+       $sql = "UPDATE UserStat SET nBytes = (
+                               SELECT SUM(nBytes)
+                               FROM DB
+                               INNER JOIN DBOwner ON DBOwner.DatabaseId = DB.DatabaseId
+                               WHERE DBOwner.UserId = UserStat.UserId
+                                 AND DB.bEnabled=1
+                               GROUP BY UserId
+                               ), dLastCheck = NOW()";
+       if (!empty($userId)) $sql .= sprintf(" WHERE UserId = '%s'", mysql_escape_string($userId));
+       DBUpdate($sql);
+       $sql = "UPDATE UserStat SET nDatabases = (
+                               SELECT COUNT(*)
+                               FROM DB
+                               INNER JOIN DBOwner ON DBOwner.DatabaseId = DB.DatabaseId
+                               WHERE DBOwner.UserId = UserStat.UserId
+                                 AND DB.bEnabled=1
+                               GROUP BY UserId
+                               ), dLastCheck = NOW()";
+       if (!empty($userId)) $sql .= sprintf(" WHERE UserId = '%s'", mysql_escape_string($userId));
+       DBUpdate($sql);
+}
+
+?>
diff --git a/lib/display.lib.php b/lib/display.lib.php
new file mode 100644 (file)
index 0000000..e33721d
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+## FORMATTING FUNCTIONS
+
+function sprintSize($bytes, $float=2) {
+       if (is_null($bytes)) return null;
+       $kb = round($bytes / 1024, $float);
+       $mb = round($bytes / 1024 / 1024, $float);
+       $gb = round($bytes / 1024 / 1024 / 1024, $float);
+       
+       return ($bytes<1||$kb<1?$bytes.' B':($mb<1?$kb.' KB':($gb<1?$mb.' MB':$gb.' GB')));
+}
+
+function sprintTS($timestamp) {        
+       return substr($timestamp,0,4).
+               '-'.substr($timestamp,4,2).
+               '-'.substr($timestamp,6,2).
+               ' '.substr($timestamp,8,2).
+               ':'.substr($timestamp,10,2).
+               ':'.substr($timestamp,12,2);
+}
+
+function printBar($percent, $txt1 = '', $txt2 = '') {
+       $color1 = 'black';
+       $color2 = 'white';
+       $color3 = 'white';
+       $color4 = 'black';
+       /* if ($percent>1) {
+               $percent = $percent/100;
+       }
+       } elseif (!is_integer($percent) && $percent<2) {
+               $percent = $percent*100;
+       } elseif ($percent == 1) {
+               $percent = 100;
+       } */
+       $per1 = $per2 = floor($percent*100);
+       if ($per1>100) {
+               $per1 = 100;
+               $per2 = 0;
+       } else {
+               $per2 = 100 - $per2;
+       }
+       $per1 .= "%";
+       $per2 .= "%";
+/*     return '<table cellpadding=0 cellspacing=0 width="100%" class="bargraph">
+                               <tr>
+                               <td class="bar" align="left" width="'.$per1.'"><div style="position: relative;"><div style="left: 0; display: inline; position: absolute;">&nbsp;'.$txt1.'&nbsp;</div>&nbsp;</div></td>
+                               <td class="fill" align="left" width="'.$per2.'"><div style="position: relative;">&nbsp;<div style="right: 0; display: inline; position: absolute;">'.$txt2.'&nbsp;<em>'.$per1.'</em></div></div></td>
+                               </tr></table>';*/
+       return '<table cellpadding=0 cellspacing=0 width="100%" class="bargraph">
+                               <tr>
+                               <td class="bar" align="left" width="'.$per1.'"><div style="position: relative;"></div></td>
+                               <td class="fill" align="right" width="'.$per2.'"><div style="position: relative;"></div></td>
+                               </tr>
+                       </table><table cellpadding=0 cellspacing=0 width="100%">
+                               <tr style="height: 1px;">
+                               <td class="bar" align="left" width="50%"><div style="position: relative;"><div style="bottom: 3px; left: 5px; position: absolute;">'.$txt1.'</div></div></td>
+                               <td class="fill" align="right" width="50%"><div style="position: relative;"><div style="bottom: 3px; right: 3px; position: absolute;">'.$txt2.'&nbsp;&nbsp;<em>'.$per1.'</em></div></div></td>
+                               </tr>
+                               </table>';
+}
+
+function chars_encode($string) {
+   $chars = array();
+   $ent = null;
+   $chars = preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY);
+   for ($i = 0; $i < count($chars); $i++)
+               $ent[$i] = '&#' . ord($chars[$i]) . ';';
+   if (sizeof($ent) < 1) return '';
+   return implode('',$ent);
+}
+
+?>
diff --git a/lib/errorhandler.lib.php b/lib/errorhandler.lib.php
new file mode 100644 (file)
index 0000000..647e40a
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+function ErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) {
+       $error_halt = true;
+       $error_type = 'Error';
+       $error_msg = " $errstr occured in $errfile on $errline at ".date("D M j G:i:s T Y");
+       $email_to = 'sql@mit.edu';
+       $email_from = 'sql@sql.mit.edu';
+       switch($errno) {
+               case E_USER_NOTICE:
+               case E_NOTICE:
+                       $type = 'Notice';
+                       $error_halt = false;
+                       break;
+               case E_USER_WARNING:
+               case E_COMPILE_WARNING:
+               case E_CORE_WARNING:
+               case E_WARNING:
+                       $type = 'Warning';
+                       $error_halt = false;
+                       break;
+               case E_USER_ERROR:
+               case E_COMPILE_ERROR:
+               case E_CORE_ERROR:
+               case E_ERROR:
+                       $type = 'Fatal Error';
+                       break;
+               case E_PARSE:
+                       $type = 'Parse Error';
+                       break;
+               default:
+                       $type = 'Unknown Error';
+                       break;
+       }
+       $error_bt = ErrorBacktrace(debug_backtrace());
+       $error_msg = $type . ':' . $error_msg . "\n" . $error_bt . "\n\n";
+       if (DEVEL) {
+               echo '<table width="100%" bgcolor="white"><tr><td><pre>'.$error_msg.'</pre></td></tr></table>';
+       } else {
+               $error_msg .= print_r(get_included_files(),1)."\n";
+               $error_msg .= print_r($errcontext,1);
+               error_log($error_msg, 1, $email_to);
+               if ($error_halt) {
+                       while(ob_get_level()) { ob_end_clean(); }
+                       require_once('security.lib.php');
+                       redirect('error');
+                       exit -1;
+               }
+       }
+}
+
+function ErrorBacktrace($debug_backtrace) {
+       array_shift($debug_backtrace);
+       $output = '';
+   foreach ($debug_backtrace as $bt) {
+       $args = '';
+       foreach ($bt['args'] as $a) {
+           if (!empty($args)) {
+               $args .= ', ';
+           }
+           switch (gettype($a)) {
+           case 'integer':
+           case 'double':
+               $args .= $a;
+               break;
+           case 'string':
+               $a = htmlspecialchars(substr($a, 0, 64)).((strlen($a) > 64) ? '...' : '');
+               $args .= "\"$a\"";
+               break;
+           case 'array':
+               //$args .= 'Array('.count($a).')';
+               $args .= print_r($a,1);
+               break;
+           case 'object':
+               $args .= 'Object('.get_class($a).')';
+               break;
+           case 'resource':
+               $args .= 'Resource('.strstr($a, '#').')';
+               break;
+           case 'boolean':
+               $args .= $a ? 'True' : 'False';
+               break;
+           case 'NULL':
+               $args .= 'Null';
+               break;
+           default:
+               $args .= 'Unknown';
+           }
+       }
+          empty($bt['class']) && $bt['class'] = '';
+          empty($bt['type']) && $bt['type'] = '';
+          empty($bt['function']) && $bt['function'] = '';
+          $output .= "\n";
+       $output .= "file: {$bt['line']} - {$bt['file']}\n";
+       $output .= "call: {$bt['class']}{$bt['type']}{$bt['function']}($args)\n";
+   }
+       return $output;
+}
+
+set_error_handler('ErrorHandler');
+
+?>
diff --git a/lib/joe.lib.php b/lib/joe.lib.php
new file mode 100755 (executable)
index 0000000..d36cef1
--- /dev/null
@@ -0,0 +1,211 @@
+<?php
+/*
+    (c) 2005 Joe Presbrey
+
+    ATTN:  This library was assembled and completed in its entirety independent of
+    any and all corporate projects and/or work environ.
+
+    You may NOT use this library elsewhere!
+
+*/
+
+function isPost() {
+  if($_SERVER['REQUEST_METHOD'] == 'POST') {
+    return true;
+  } else {
+    return false;
+  }
+}
+function isFormPost() { return isPost(); }
+
+function isSess($id) {
+  return isset($_SESSION[$id]);
+}
+
+function sess($id,$val=null) {
+  if (is_null($val)) {
+    return (isSess($id)?$_SESSION[$id]:null);
+  } elseif (empty($val)) {
+    unset($_SESSION[$id]);
+  } else {
+    $prev = sess($id);
+    $_SESSION[$id] = $val;
+    return $prev;
+  }
+}
+
+function stopSess() {
+  $sid[] = session_id();
+  @session_destroy();
+  session_start();
+  $sid[] = session_id();
+  session_regenerate_id();
+  $sid[] = session_id();
+  session_write_close();
+  @session_destroy();
+
+  foreach($sid as $id) {
+    @unlink(session_save_path().'/sess_'.$id);
+  }
+}
+
+function sessTime($query=null) {
+  global $timingc;
+  global $timings;
+
+  if(!isset($timings)) {
+    $timings = array();
+  }
+
+  if (!isset($timingc) || empty($timingc)) {
+       $timingc = 1;
+  } elseif (!is_null($query)) {
+    $current = $timingc;
+       $timingc = ++$current;
+  }
+  $key = $timingc;
+
+  if (is_null($query)) {
+    $timings[$key]['time'] = microtime(true)-$timings[$key]['time'];
+       if (mysql_error())
+               $timings[$key]['error'] = mysql_error();
+    return true;
+  } else {
+    $timings[$key] = array();
+    $timings[$key]['time'] = microtime(true);
+    $timings[$key]['query'] = $query;
+    return false;
+  }
+}
+
+function fetchRows($rs, $key = null) {
+    /* ask me how to use this if its not obvious ~ Joe */
+    if (!$rs) return array();
+    $kn = is_null($key);
+    $n = mysql_num_rows($rs);
+    if ($n > 0) {
+        $arr = array();
+        if (is_null($key)) {
+            while ($r = mysql_fetch_assoc($rs)) {
+                $arr[] = $r;
+            }
+        } elseif (is_numeric($key)) {
+            while ($r = mysql_fetch_row($rs)) {
+                $arr[$r[$key]] = $r;
+            }
+        } else {
+            while ($r = mysql_fetch_assoc($rs)) {
+                $arr[$r[$key]] = $r;
+            }
+        }
+        mysql_free_result($rs);
+        return $arr;
+    } else {
+        mysql_free_result($rs);
+        return array();
+    }
+}
+
+function printErrors($err) { printList('err', $err); }
+function printMsgs($err) { printList('msg', $err); }
+
+function printList($class,$err) {
+    if (is_array($err) && count($err)) {
+        echo '<div class="',$class,'">',(count($err)>1?'<ul>':'');
+        foreach($err as $e) {
+                       if (count($err)>1) {
+                               echo '<li><p>',$e,'</p></li>';
+                       } else {
+                               echo '<p>',$e,'</p>';
+                       }
+        }
+        echo (count($err)>1?'</ul>':''),'</div>';
+    }
+}
+
+function buildSQLSet($fields, $values=null) {
+    $ex = array('NOW()','NULL');
+    $sql = 'SET';
+    $c = 0;
+    if (!is_null($values)) {
+        foreach($fields as $field) {
+            if ($c++) $sql .= ',';
+            $sql .= " `$field`='".mysql_escape_string(array_shift($values))."'";
+        }
+    } else {
+        foreach($fields as $field=>$value) {
+            if ($c++) $sql .= ',';
+            if (in_array($value,$ex)) {
+                $sql .= " `$field`= $value";
+            } else {
+                $sql .= " `$field`='".mysql_escape_string($value)."'";
+            }
+        }
+    }
+    return $sql;
+}
+
+function buildSQLInsert($array, $table=null) {
+    $ex = array('NOW()','NULL');
+    $sql = '(';
+    $c = 0;
+    foreach($array as $field=>$value) {
+        if ($c++) $sql .= ',';
+        $sql .= " `$field` ";
+    }
+    $sql .= ') VALUES (';
+    $c = 0;
+       foreach($array as $field=>$value) {
+        $v = mysql_escape_string($value);
+        if ($c++) $sql .= ',';
+        if (in_array($v, $ex))
+            $sql .= " $v ";
+        else
+            $sql .= " '$v' ";
+    }
+    $sql .= ')';
+    return (is_null($table)?$sql:('INSERT INTO `'.$table.'` '.$table));
+}
+
+function build_str($query_array) {
+    $query_string = array();
+    foreach ($query_array as $k => $v) {
+        $new = $k;
+        if (strlen($v))
+            $new .= '='.$v;
+        $query_string[] = $new;
+    }
+    return join('&', $query_string);
+}
+
+function newQS($key, $val=null) {
+    /*
+    parse_str($_SERVER['QUERY_STRING'], $arr);
+    $arr[$key] = $val;
+    return '?'.build_str($arr);
+    */
+    return newQSA(array($key=>$val));
+}
+
+function newQSA($array=array()) {
+    parse_str($_SERVER['QUERY_STRING'], $arr);
+    $s = count($arr);
+    foreach($array as $key=>$val) {
+        $arr[$key] = $val;
+        if (is_null($val))
+            unset($arr[$key]);
+    }
+    return (count($arr)||$s)?'?'.build_str($arr):'';
+}
+
+function formQSA($array=array()) {
+    if (!count($array)) $array = $_SERVER['QUERY_STRING'];
+    parse_str($array, $arr);
+    $text = '';
+    foreach($arr as $key=>$val) {
+        $text .= sprintf('<input type="hidden" name="%s" value="%s">', $key, $val);
+    }
+    return $text;
+}
+
+?>
diff --git a/lib/mitsql.lib.php b/lib/mitsql.lib.php
new file mode 100755 (executable)
index 0000000..519e2d2
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/*
+       mitsql.lib.php
+       (c) 2005 Joe Presbrey
+       written for SIPB/MIT SQL service
+*/
+
+require_once('joe.lib.php');
+require_once('dbaccess.lib.php');
+
+require_once('mitsql.cfg.php');
+require_once('security.lib.php');
+require_once('errorhandler.lib.php');
+
+require_once('display.lib.php');
+
+if (isset($_SERVER['SERVER_NAME'])) {
+       $BASE_URL = 'http'.(isSSL()?'s':'').'://'.$_SERVER['SERVER_NAME'].BASE_URL;
+} else {
+       $BASE_URL = 'http://sql.mit.edu/';
+}
+
+if (isset($_SERVER['REQUEST_URI'])) {
+    //$thisPath=pathinfo($_SERVER['REQUEST_URI']);
+    //session_set_cookie_params(0, $thisPath['dirname']);
+       //$arr = explode('/', $_SERVER['SCRIPT_NAME']);
+    //session_set_cookie_params(0, '/'.$arr[1].'/');
+       session_name('SQLMITEDU');
+    session_set_cookie_params(0, BASE_URL);
+    session_start();
+    define('INTERACTIVE', 1);
+} else {
+    define('INTERACTIVE', 0);
+}
+
+INTERACTIVE && require_once('global.act.php');
+
+?>
diff --git a/lib/proc.lib.php b/lib/proc.lib.php
new file mode 100644 (file)
index 0000000..adf8252
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.lib.php');
+
+define('MAXDBS', 20);
+
+class proc {
+       static function newdb(&$User, &$i_newdb) {
+               // return through $i_newdb the full name of the created db
+               $msg1 = $err1 = array();
+               $uname = $User->getUsername();
+               $uname = str_replace('.','',$uname);
+               $dbname = $uname.DELIMETER.$i_newdb;
+               if ($User->isOverQuota() && !isAdmin()) {
+                       $err1[] = 'You are over your quota. You may not add more databases.';
+               } elseif (count($User->getDBList())>MAXDBS && !isAdmin()) {
+                       $err1[] = 'You have too many databases. You may not add more databases.';
+               } elseif (empty($i_newdb)) {
+                       $err1[] = 'Your database name may not be empty.';
+               } elseif (!$User->addDB($dbname)) {
+                       if (mysql_error()) {
+                               $err1[] = mysql_error();
+                       } else {
+                               $err1[] = 'Database already exists.';
+                       }
+               } else {
+                       $msg1[] = 'Database `'.$dbname.'` created.';
+               }
+               $i_newdb = $dbname;
+               return array($msg1, $err1);
+       }
+       static function drop(&$User, $i_drop) {
+               $msg1 = $err1 = array();
+               $dropdbs = array_keys($i_drop);
+               foreach($dropdbs as $dbname) {
+                       if ($User->delDB($dbname)) {
+                               $msg1[] = 'Database `'.$dbname.'` dropped.';
+                       } else {
+                               $err1[] = mysql_error();
+                       }
+               }
+               return array($msg1, $err1);
+       }
+}
+
+?>
diff --git a/lib/security.lib.php b/lib/security.lib.php
new file mode 100644 (file)
index 0000000..0b7c384
--- /dev/null
@@ -0,0 +1,400 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.lib.php');
+
+class Login {
+       private $id, $u, $p;
+    private $info;
+    function Login($u, $p=null) {
+               if (empty($u)) return;
+               $this->u = $u;
+               $this->p = $p;
+               if (is_numeric($u)) {
+                       $this->id = $u;
+                       $opt = sprintf(" Username = '%s' OR UserId = '%s'", mysql_escape_string($u), mysql_escape_string($u));
+               } else {
+                       $opt = sprintf(" Username = '%s'", mysql_escape_string($u));
+                       $opt .= (is_null($p)?'':sprintf(" AND Password='%s'", mysql_escape_string(base64_encode($p))));
+               }
+        $sql = sprintf("SELECT UserId, Username, Name, Email, UL, bEnabled
+                        FROM User
+                        WHERE %s", $opt);
+        $r = fetchRows(DBSelect($sql),'UserId');
+               $this->info = count($r)?array_shift($r):$r;
+       }
+    function exists() {
+        return count($this->info);
+    }
+       function isValid() {
+               return $this->getUL()>0;
+       }
+    function isEnabled() {
+        return $this->exists() && $this->info['bEnabled']==1;
+    }
+    function canLogin() {
+        return $this->isEnabled() && $this->isValid();
+    }
+    function canSignup() {
+        return !$this->isEnabled() && $this->isValid();
+    }
+    function getUserId() {
+        return $this->exists()?$this->info['UserId']:'';
+    }
+    function getUsername() {
+        return $this->exists()?$this->info['Username']:'';
+    }
+    function getName() {
+        return $this->exists()?$this->info['Name']:'';
+    }
+    function getEmail() {
+        return $this->exists()?$this->info['Email']:'';
+    }
+    function getUL() {
+        return $this->exists()?$this->info['UL']:'';
+    }
+    function expire() {
+        $this->info = null;
+    }
+    function refresh() {
+               if (!empty($this->id)) {
+                       $this->Login($this->id);
+               } else {
+                       $this->Login($this->u,$this->p);
+               }
+    }
+    function update($name=null,$email=null) {
+        if (!$this->exists()) return;
+        $arr = array();
+               if ($name == $this->getName()) $name = null;
+               if ($email == $this->getEmail()) $email = null;
+        is_null($name) || $arr['Name'] = $name;
+        is_null($email) || $arr['Email'] = $email;
+               $upd = buildSQLSet($arr);
+        $sql = sprintf("UPDATE User %s WHERE UserId = '%s'",
+                        $upd, mysql_escape_string($this->getUserId()));
+               if (!empty($upd) && $upd != 'SET')
+                       DBUpdate($sql);
+               if (isset($arr['Name']))
+                       $this->info['Name'] = $arr['Name'];
+               if (isset($arr['Email']))
+                       $this->info['Email'] = $arr['Email'];
+       }
+}
+
+class User {
+       private $userId;
+       private $info;
+       private $dblist;
+    function User($userId) {
+               $this->userId = $userId;
+        $sql = sprintf("SELECT User.UserId, Username, Name, Email, UL, bEnabled, nBytesSoft, nBytesHard, nBytes, nDatabases, nDatabasesHard, IF(nBytes>nBytesHard,1,0) AS bOverQuota
+                        FROM User
+                                               INNER JOIN UserQuota ON User.UserId = UserQuota.UserId
+                                               INNER JOIN UserStat ON User.UserId = UserStat.UserId
+                        WHERE User.UserId = '%s'",
+                        mysql_escape_string($userId));
+        $r = fetchRows(DBSelect($sql),'UserId');
+        $this->info = count($r)?array_shift($r):$r;
+               $this->dblist = $this->getDBList();
+    }
+       function refresh() {
+               unset($this->dblist);
+               $this->User($this->userId);
+               /*
+        $sql = sprintf("SELECT UserId, Username, Name, Email, UL, bEnabled
+                        FROM User
+                        WHERE UserId = '%s'",
+                        mysql_escape_string($this->userId));
+        $r = fetchRows(DBSelect($sql),'UserId');
+        $this->info = count($r)?array_shift($r):$r;
+               unset($this->dblist);
+               $this->getDBList();
+               */
+       }
+    function exists() {
+        return count($this->info);
+    }
+    function getUserId() {
+        return $this->exists()?$this->info['UserId']:'';
+    }
+    function getUsername() {
+        return $this->exists()?$this->info['Username']:'';
+    }
+    function isOverQuota() {
+        return $this->exists()?($this->info['bOverQuota']>0?true:false):'';
+    }
+    function getBytes() {
+        if($this->exists()) {
+                       $arr['nBytes'] = $this->info['nBytes'];
+                       $arr['nBytesSoft'] = $this->info['nBytesSoft'];
+                       $arr['nBytesHard'] = $this->info['nBytesHard'];
+                       return $arr;
+               }
+    }
+       function setPassword($pwd) {
+               $arr['Password'] = base64_encode($pwd);
+        $sql = sprintf("UPDATE User %s WHERE UserId = '%s'",
+                        buildSQLSet($arr), mysql_escape_string($this->getUserId()));
+        DBUpdate($sql);
+               $sql = sprintf('SET PASSWORD FOR \'%s\'@\'%%\'=PASSWORD(\'%s\')',
+                                               mysql_escape_string($this->getUsername()),
+                                               mysql_escape_string($pwd));
+               DBSet($sql);
+       }
+       function signup($pwd) {
+               $this->pass = $pwd;
+               $arr['Password'] = base64_encode($pwd);
+               $arr['bEnabled'] = 1;
+               $arr['dSignup'] = 'NOW()';
+        $sql = sprintf("UPDATE User %s WHERE UserId = '%s'",
+                        buildSQLSet($arr), mysql_escape_string($this->getUserId()));
+        DBUpdate($sql);
+
+               $this->setUsage();
+               $this->setAccess();
+       }
+       function setUsage($yes=true) {
+               $verb = $yes?'GRANT':'REVOKE';
+               $prep = $yes?'TO':'FROM';
+               $suffix = $yes?sprintf("IDENTIFIED BY '%s'",mysql_escape_string($this->pass)):'';
+               $sql = sprintf("%s USAGE ON * . * %s '%s'@'%s' %s",
+                                               mysql_escape_string($verb),
+                                               mysql_escape_string($prep),
+                                               mysql_escape_string($this->getUsername()),
+                                               '%',
+                                               $suffix);
+               DBGrant($sql);
+       }
+       function setAccess($db=null,$yes=true) {
+               $verb = $yes?'GRANT':'REVOKE';
+               $prep = $yes?'TO':'FROM';
+               if (is_null($db)) {
+                       $dbs = $this->getDBList();
+               } else {
+                       $dbs[] = array('Name'=>$db);
+               }
+               foreach($dbs as $db) {
+                       $name = $db['Name'];
+                       $sql = sprintf("%s ALL PRIVILEGES ON `%s` . * %s '%s'@'%s'",
+                                                       mysql_escape_string($verb),
+                                                       mysql_escape_string($name),
+                                                       mysql_escape_string($prep),
+                                                       mysql_escape_string($this->getUsername()),
+                                                       '%');
+                       DBGrant($sql);
+               }
+       }
+       function getDBList() {
+               if (isset($this->dblist)) {
+                       return $this->dblist;
+               } else {
+                       //                      LEFT JOIN DBQuota ON DBQuota.DatabaseId = DBOwner.DatabaseId
+                       $sql = sprintf("SELECT *
+                                               FROM DBOwner
+                                               INNER JOIN DB ON DB.DatabaseId = DBOwner.DatabaseId
+                                               INNER JOIN DBQuota ON DBQuota.DatabaseId = DBOwner.DatabaseId
+                                               WHERE DBOwner.UserId = '%s' AND DB.bEnabled=1",
+                                               mysql_escape_string($this->getUserId()));
+//                     $r = fetchRows(DBSelect($sql),'DatabaseId');
+                       $r = fetchRows(DBSelect($sql),'Name');
+                       ksort($r);
+                       return $r;
+               }
+       }
+       function addDB($name) {
+               if (in_array($name, array_keys($this->getDBList()))) return false;
+               if (!addDB($name, $this->getUserId())) return false;
+               $this->setAccess($name);
+               return true;
+       }
+       function delDB($name) {
+               if (!in_array($name, array_keys($this->getDBList()))) return false;
+               if (!delDB($name)) return false;//, $this->getUserId())) return false;
+               $this->setAccess($name,false);
+               return true;
+       }
+}
+
+
+function isLoggedIn($aLogin=null) {
+    if (is_null($aLogin)) {
+        global $Login;
+        $aLogin = $Login;
+    }
+    return !empty($aLogin) && ($aLogin instanceof Login) && $aLogin->canLogin();
+}
+
+function isAdmin($aLogin=null) {
+    if (is_null($aLogin)) {
+        global $Login;
+        $aLogin = $Login;
+    }
+    return !empty($aLogin) && ($aLogin instanceof Login) && $aLogin->getUL()>=100;
+}
+
+function isImpersonating() {
+       return isSess('_UserId') && isSess('UserId');
+}
+
+function isOffline() {
+       return (defined('OFFLINE') && OFFLINE);
+}
+
+function isOnline() {
+       return !isOffline();
+}
+
+function impersonate($userId=null) {
+       $wasImpersonating = isImpersonating();
+       if ($wasImpersonating) {
+               if (is_null($userId) || empty($userId)) {
+                       sess('UserId',sess('_UserId'));
+                       sess('_UserId','');
+               } elseif ($userId>0) {
+                       sess('UserId',$userId);
+               } else {
+                       return false;
+               }
+       } elseif (isLoggedIn()) {
+               sess('_UserId',sess('UserId'));
+               sess('UserId',$userId);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+function isSSL() {
+       return isset($_SERVER['SERVER_PORT'])?($_SERVER['SERVER_PORT'] == 443):false;
+}
+
+function getSSLCert() {
+    if (DEVEL && file_exists('.forceauth')) {
+        $fu = explode('|',file_get_contents('.forceauth'));
+        $name = trim($fu[0]);
+        $email = trim($fu[1]);
+    } else {
+        $name = isset($_SERVER['SSL_CLIENT_S_DN_CN'])?$_SERVER['SSL_CLIENT_S_DN_CN']:null;
+        $email = isset($_SERVER['SSL_CLIENT_S_DN_Email'])?$_SERVER['SSL_CLIENT_S_DN_Email']:null;
+    }
+    if (!is_null($email)) {
+        $user = explode('@',$email);
+               $user = $user[0];
+        return array('Username'=>$user, 'Name'=>$name, 'Email'=>$email);
+       } else {
+               return null;
+       }
+}
+
+## 302 REDIRECTS
+
+function redirect($target=null,$secure=null) {
+    $base = (is_null($target)||substr($target,0,1)=='?')?$_SERVER['REDIRECT_URL']:(dirname($_SERVER['REDIRECT_URL']).'/');
+    redirectFull(is_null($target)?$base:($base.$target),$secure);
+}
+function redirectStart() {
+       redirectFull(BASE_URL,null);
+}
+function redirectFull($target,$secure) {
+       //redirect2((((isSSL()&&is_null($secure))||$secure==true)?'https://':'http://').$_SERVER['SERVER_NAME'].$target);
+       redirect2((((isSSL()&&is_null($secure))||$secure==true)?'https://scripts-cert.mit.edu':'http://scripts.mit.edu').$target);
+}
+function redirect2($target) {
+       header('Location: '.$target);
+       exit;
+}
+function flipSSL() {
+       //return (isSSL()?'http://':'https://').$_SERVER['SERVER_NAME'].$_SERVER['REDIRECT_URL'];
+       return (isSSL()?'http://scripts.mit.edu':'https://scripts-cert.mit.edu').$_SERVER['REDIRECT_URL'];
+}
+
+## USER SCRIPTS
+
+function addUser($sslCredentials) {
+    global $_NEW_USER, $_NEW_USERQUOTA, $_NEW_USERSTAT;
+
+    $arr = array_merge($sslCredentials, $_NEW_USER);
+    $sql = sprintf("INSERT INTO User %s",
+                    buildSQLInsert($arr));
+    $UserId = DBInsert($sql);
+
+       $arr = $_NEW_USERQUOTA;
+       $arr['UserId'] = $UserId;
+    $sql = sprintf("INSERT INTO UserQuota %s",
+                    buildSQLInsert($arr));
+       DBInsert($sql);
+
+       $arr = $_NEW_USERSTAT;
+       $arr['UserId'] = $UserId;
+    $sql = sprintf("INSERT INTO UserStat %s",
+                    buildSQLInsert($arr));
+       DBInsert($sql);
+
+       return $UserId;
+}
+
+function addDB($dbname,$userid) {
+       global $_NEW_DB, $_NEW_DBQUOTA, $_NEW_DBOWNER;
+
+       DBCreate(sprintf('CREATE DATABASE `%s`', mysql_escape_string($dbname)));
+       if (mysql_error()) return false;
+
+       $newdb['Name'] = $dbname;
+       $arr = array_merge($newdb, $_NEW_DB);
+       $arr['bEnabled'] = 1;
+       $sql = sprintf("INSERT IGNORE INTO DB %s",
+                    buildSQLInsert($arr));
+       $DBId = DBInsert($sql);
+       if (empty($DBId)) {
+               $sql = sprintf("SELECT DatabaseId FROM DB WHERE Name = '%s'",
+                                               mysql_escape_string($dbname));
+               $r = fetchRows(DBSelect($sql), 'DatabaseId');
+               if (count($r)) {
+                       $r = array_shift($r);
+                       $DBId = $r['DatabaseId'];
+               } else {
+                       return false;
+               }
+               $sql = sprintf("UPDATE DB %s WHERE DB.DatabaseId = '%s'",
+                                               buildSQLSet($arr),
+                                               $DBId);
+               DBUpdate($sql);
+       }
+
+       DBDelete(sprintf("DELETE FROM DBOwner WHERE DatabaseId = '%s'", mysql_escape_string($DBId)));
+       DBDelete(sprintf("DELETE FROM DBQuota WHERE DatabaseId = '%s'", mysql_escape_string($DBId)));
+       
+       $arr = $_NEW_DBQUOTA;
+       $arr['DatabaseId'] = $DBId;
+       $sql = sprintf("INSERT IGNORE INTO DBQuota %s",
+                                       buildSQLInsert($arr));
+       DBInsert($sql);
+
+       $arr = $_NEW_DBOWNER;
+       $arr['DatabaseId'] = $DBId;
+       $arr['UserId'] = $userid;
+       $sql = sprintf("INSERT IGNORE INTO DBOwner %s",
+                                       buildSQLInsert($arr));
+       DBInsert($sql);
+
+       return $DBId;
+}
+
+function delDB($dbname) {
+       global $_NEW_DB, $_NEW_DBQUOTA, $_NEW_DBOWNER;
+
+       DBCreate(sprintf('DROP DATABASE `%s`', mysql_escape_string($dbname)));
+
+       $arr['bEnabled'] = 0;
+       $sql = sprintf("UPDATE DB %s WHERE DB.Name = '%s'",
+                                       buildSQLSet($arr),
+                                       $dbname);
+       DBUpdate($sql);
+
+       return true;
+}
+
+?>
diff --git a/login.php b/login.php
new file mode 100644 (file)
index 0000000..4858893
--- /dev/null
+++ b/login.php
@@ -0,0 +1,42 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+if (isSSL()) {
+       if (is_null($SSLCred)) {
+               $err[] = 'Please install a valid certificate.';
+       }
+}
+
+if (isPost() && empty($err)) {
+
+       if (isSSL()) {
+               $Login = $LoginSSL;
+       } else {
+               $Login = new Login($i_u, $i_p);
+       }
+       
+       if ($Login->exists() && !$Login->isEnabled()) {
+               $err[] = 'Account not active. <a href="do/signup">Did you signup yet?</a>.';
+       } elseif (!$Login->exists()) {
+               $err[] = 'Nonexistant account or invalid password.';
+       } elseif (!$Login->canLogin()) {
+               $err[] = 'That account is no longer valid. Please contact the staff (sql@mit.edu).';
+       }
+
+       if (empty($err)) {
+               sess('UserId', $Login->getUserId());
+               redirect('main?refresh');
+       }
+
+}
+
+isLoggedIn() && redirect('main');
+
+include 'tpl/login.php';
+
+?>
diff --git a/logout.php b/logout.php
new file mode 100644 (file)
index 0000000..1b8b5d5
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+session_destroy();
+
+redirect('index');
diff --git a/main.php b/main.php
new file mode 100644 (file)
index 0000000..4551be7
--- /dev/null
+++ b/main.php
@@ -0,0 +1,34 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+require_once('proc.lib.php');
+
+if (!isLoggedIn()) redirect('index');
+
+$err1 = $msg1 = array();
+
+$User = new User($Login->getUserID());
+
+if (isPost()) {
+       if (isset($i_newdb)) {
+               list($msg1, $err1) = proc::newdb($User, $i_newdb);
+       }
+       if (isset($i_drop)) {
+               list($msg1, $err1) = proc::drop($User, $i_drop);
+       }
+}
+
+if (!count($err1)) {//&& !isset($i_r))
+       checkQuotas($Login->getUserID());
+       $User->refresh();
+}
+
+$myDBs = $User->getDBList();
+
+include 'tpl/main.php';
+
+?>
diff --git a/mitsql.cfg.php b/mitsql.cfg.php
new file mode 100755 (executable)
index 0000000..6a5acfd
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+/*
+    mitsql.cfg.php
+       (c) 2005 Joe Presbrey
+*/
+
+$CWD = getcwd();
+chdir(dirname(__FILE__));
+
+file_exists('/etc/sql-mit-edu.cfg.php') && require('/etc/sql-mit-edu.cfg.php');
+file_exists('/usr/local/etc/sql-mit-edu.cfg.php') && require('/usr/local/etc/sql-mit-edu.cfg.php');
+file_exists('server.cfg.php') && require('server.cfg.php');
+defined('DEBUG') || define('DEBUG', 0);
+defined('DEVEL') || define('DEVEL', 0);
+defined('OFFLINE') || define('OFFLINE', 0);
+
+define('VER', '1.2');
+if (DEVEL) {
+       define('VERSION', VER.'-dev');
+       defined('BASE_URL') || define('BASE_URL', '/~sql/dev/');
+} else {
+       define('VERSION', VER);
+       defined('BASE_URL') || define('BASE_URL', '/~sql/main/');
+}
+
+define('DELIMETER', '+');
+defined('DBHOST') || define('DBHOST', 'sql.mit.edu');
+defined('ADMINUSER') || define('ADMINUSER', 'root');
+defined('ADMINPASS') || die('Please email sql@mit.edu');
+defined('ADMINDB') || define('ADMINDB', 'mitsql');
+
+$BASE_PATH = dirname(__FILE__).'/';
+define('BASE_PATH', $BASE_PATH);
+$URI = (isset($_SERVER["REDIRECT_URL"])?$_SERVER["REDIRECT_URL"]:'');
+$URI = ((empty($URI) && isset($_SERVER['REQUEST_URI']))?$_SERVER['REQUEST_URI']:$URI);
+define('URI', $URI);
+$THIS_PAGE = str_replace(BASE_URL, '', URI);
+define('THIS_PAGE', $THIS_PAGE);
+
+set_time_limit(0);
+ignore_user_abort(1);
+import_request_variables('cgp', 'i_');
+!DEVEL && ini_set('display_errors', 0);
+DEVEL && ini_set('display_errors', 1);
+error_reporting(E_ALL);
+set_include_path(get_include_path() . PATH_SEPARATOR . $BASE_PATH . 'lib/' . PATH_SEPARATOR . $BASE_PATH);
+
+require_once('defaults.cfg.php');
+
+if (!OFFLINE) {
+       $cxn = mysql_connect(DBHOST, ADMINUSER, ADMINPASS);
+       mysql_select_db(ADMINDB,$cxn);
+       if (mysql_error()) {
+               require_once('errorhandler.lib.php');
+               trigger_error(mysql_error(),E_USER_ERROR);
+       }
+}
+
+chdir($CWD);
+
+?>
diff --git a/mitsql.css b/mitsql.css
new file mode 100644 (file)
index 0000000..979deee
--- /dev/null
@@ -0,0 +1,57 @@
+#content_wide form {
+       margin: 0;
+       display: inline;
+}
+#content_wide p {
+       font-size: 10pt;
+       text-indent: 25px;
+}
+#content_wide h2 {
+       margin-top: 0;
+}
+#content_wide input {
+       font-size: 9pt;
+       border: 1px solid black;
+}
+#content_wide table,tr,td {
+       padding: 0;
+}
+td p {
+       padding-right: 10px;
+       padding-left: 10px;
+       border-left: 1px solid black;
+}
+div.msg {
+       padding: 0px 20px 0px 0px;
+       background-color: #ccc;
+       border: 1px solid black;
+       font-weight: bold;
+       position: relative;
+}
+div.msg li {
+       list-style-type: square;
+}
+div.err {
+       color: maroon;
+       padding: 0px 20px 0px 0px;
+       background-color: #ccc;
+       border: 1px dashed black;
+       font-variant: small-caps;
+       font-weight: bold;
+}
+div.err li {
+       list-style-type: square;
+}
+pre {
+       font-size: 10px;
+}
+table.bargraph {
+       border: 1px solid #ccc;
+}
+table.bargraph td.bar {
+       height: 18px;
+       background-color: #888;
+}
+table.bargraph td.fill {
+       background-color: #bbb;
+}
diff --git a/offline.php b/offline.php
new file mode 100755 (executable)
index 0000000..96e9641
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+isOnline() && redirect('index');
+
+include 'tpl/offline.php';
+
+?>
diff --git a/php.ini b/php.ini
new file mode 100755 (executable)
index 0000000..62a9be2
--- /dev/null
+++ b/php.ini
@@ -0,0 +1,4 @@
+extension = mysql.so
+auto_append_file = "global.done.php"
+session.save_path = "/afs/athena.mit.edu/contrib/sql/web_tmp"
+output_buffering = 4096
diff --git a/setup.php b/setup.php
new file mode 100755 (executable)
index 0000000..70e4e1e
--- /dev/null
+++ b/setup.php
@@ -0,0 +1,30 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+if (!isLoggedIn()) redirect('index');
+
+$User = new User($Login->getUserID());
+
+if (isPost()) {
+       if (isset($i_chgpw)) {
+               $p1 = (isset($i_p[1])?$i_p[1]:'');
+               $p2 = (isset($i_p[2])?$i_p[2]:'');
+               if (empty($p1)) {
+                       $err[] = 'You may not have a blank password.';
+               } elseif ($p1 != $p2) {
+                       $err[] = 'Your confirmation password does not match.';
+               } else {
+                       $User->setPassword($p1);
+                       $msg[] = 'Your password was changed.';
+               }
+       }
+}
+
+include 'tpl/setup.php';
+
+?>
diff --git a/signup.php b/signup.php
new file mode 100644 (file)
index 0000000..96aba8c
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+if (!isSSL())
+       redirect('signup',true);
+
+if (isLoggedIn()) {
+
+       redirect('index');
+
+} else {
+       
+       if (is_null($SSLCred)) {
+               $err[] = 'Please install a valid certificate.';
+       } else {
+               if (isPost() && $LoginSSL->canSignup()) {
+                       if (empty($i_p1)) {
+                               $err[] = 'Your password may not be blank.';
+                       } elseif ($i_p1 != $i_p2) {
+                               $err[] = 'Your confirmation password does not match.';
+                       } else {
+                               $u = new User($LoginSSL->getUserId());
+                               $u->signup($i_p1);
+                               $LoginSSL->refresh();
+                               redirect('login', true);
+                       }
+               } elseif (isPost()) {
+                       $err[] = 'You may not signup.';
+               }
+       }
+}
+
+include 'tpl/signup.php';
+
+?>
diff --git a/test.php b/test.php
new file mode 100755 (executable)
index 0000000..2c6210a
--- /dev/null
+++ b/test.php
@@ -0,0 +1,49 @@
+<?php
+/*
+       (c) 2005 Joe Presbrey
+*/
+
+require_once('mitsql.cfg.php');
+require_once('mitsql.lib.php');
+
+include 'tpl/head.php';
+
+function getManagedDBs($owner=null) {
+       $databases = array_keys(fetchRows(DBSelect('SELECT Name FROM DB WHERE bEnabled=1'),'Name'));
+       $owners = array();
+       foreach($databases as $database) {
+               if (stristr($database, DELIMETER)) {
+                       $exp = explode(DELIMETER, $database);
+                       $thisowner = array_shift($exp);
+                       if (!is_null($owner) && $thisowner!=$owner) { continue; }
+                       isset($owners[$thisowner]) || $owners[$thisowner] = array();
+                       $owners[$thisowner][] = $database;
+               }
+       }
+       return $owners;
+}
+
+/* //GET MANAGED DBs
+$g = getManagedDBs();
+print_r($g);
+*/
+
+/* //TEST A LOGIN
+$l = new Login('6.001');
+echo !$l->isEnabled();
+echo $l->isValid();
+print_r($GLOBALS);
+*/
+
+//phpinfo();
+
+//checkQuotas();
+
+printMsgs(array('this is a test msg: test 0'));
+printMsgs(array('this is a test msg: test 1', 'this is a test msg: test 2'));
+
+printErrors(array('this is a test error: test 0'));
+printErrors(array('this is a test error: test 1', 'this is a test error: test 2'));
+
+include 'tpl/foot.php';
+?>
diff --git a/tpl/contact.php b/tpl/contact.php
new file mode 100755 (executable)
index 0000000..3ab17f3
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+include 'head.php';
+?>
+
+<h3>Contact/Help</h3>
+
+<?php printErrors($err); ?>
+
+<p>
+We welcome all questions, comments, and suggestions.<br>
+</p>
+<p>
+Please direct inquiries to <strong>sql at mit.edu</strong>
+</p>
+
+<?php
+include 'foot.php';
+?>
diff --git a/tpl/error.php b/tpl/error.php
new file mode 100755 (executable)
index 0000000..873de8e
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+include 'head.php';
+?>
+
+<h3>Page Error</h3>
+
+<p>
+The page you were trying to view experienced an error while loading.
+An email reporting this error has been sent to the Support Team.
+</p>
+<p>
+Please accept our apologies for this inconvenience.
+</p>
+<p>
+Return <a href="do/main">Home</a>.
+</p>
+
+<?php
+include 'foot.php';
+?>
diff --git a/tpl/foot.php b/tpl/foot.php
new file mode 100644 (file)
index 0000000..4f46d85
--- /dev/null
@@ -0,0 +1,21 @@
+                               </div> <!-- end#content -->
+                       </div> <!-- end#main -->
+               </div>
+               <!-- end#rap -->
+               <!-- footer -->
+               <div id="foot">&nbsp;</div>
+               <!-- end#foot -->
+               <div id="clearer">&nbsp;</div>
+               <!-- end#clearer -->
+               <div id="footer">
+                       <p id="credit" style="text-align: right;">
+                               <strong><em>sql.mit.edu v<?php echo VERSION; ?></em></strong>&nbsp;
+                       </p>
+               </div>
+               <!-- end#footer -->
+       </div>
+       <!-- end#outer -->
+</div>
+<!-- end#farouter -->
+</body>
+</html>
diff --git a/tpl/head.php b/tpl/head.php
new file mode 100644 (file)
index 0000000..bffc1ed
--- /dev/null
@@ -0,0 +1,38 @@
+<?php\r
+\r
+if (isOffline()) {\r
+       switch(THIS_PAGE) {\r
+               case 'do/contact':\r
+               case 'do/offline':\r
+                       break;\r
+               default:\r
+                       redirect('offline');\r
+                       break;\r
+       }\r
+}\r
+\r
+?>\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\r
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\r
+<head>\r
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />\r
+    <title>MIT SIPB MySQL Service for Athena</title>\r
+       <link rel="stylesheet" href="/style.css" type="text/css" />\r
+    <link rel="stylesheet" href="<?=$BASE_URL?>mitsql.css" type="text/css" />\r
+       <base href="<?=$BASE_URL?>" />\r
+</head>\r
+<body>\r
+<div id="farouter">\r
+       <div id="outer">\r
+               <div id="rap">\r
+                       <div id="masthead">\r
+                               <h1 id="header"><a href="http://sql.mit.edu/" target="_top">sql.mit.edu</a></h1>\r
+                               <h2 id="tagline">MIT SIPB MySQL Service for Athena<br />\r
+                                       email: <?=chars_encode('sql@mit.edu')?></h2>\r
+                       </div>\r
+                       <div id="hmenu">\r
+                               <?php isOnline() && include('menu.php'); ?>\r
+                       </div>\r
+                       <div id="main">\r
+                               <div id="content_wide">\r
diff --git a/tpl/index.php b/tpl/index.php
new file mode 100644 (file)
index 0000000..9b940f1
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+include 'head.php';
+?>
+
+<p>
+This service provides <a target="_blank" href="http://dev.mysql.com/doc">MySQL</a> databases to <a target="_blank" href="http://ca.mit.edu/">MIT certificate</a> holders.
+You must choose a MySQL password (which should be different from your Athena account password) when you <a href="do/signup">sign up</a>, and
+then use this interface to create and drop databases.  All subsequent SQL commands can be issued from any host, client, and/or script of your choice;
+simply connect to the MySQL server at <b>sql.mit.edu</b> using your username and your new MySQL password.
+You may find it convenient to run scripts using the <a target="_blank" href="http://scripts.mit.edu/web">web script service</a> or
+<a target="_blank" href="http://scripts.mit.edu/cron">shortjobs service</a>.
+</p>
+
+<p>
+All uses of this service must comply with the <a target="_blank" href="http://web.mit.edu/olh/Welcome/rules.html">MITnet rules of use</a>.
+</p>
+
+<p>
+Although this service has been designed with reliability in mind, the SIPB MySQL service should not be used to host critical applications that cannot tolerate downtime.
+We perform no query logging, schema or data backups, or any other backups otherwise generally available. You are solely responsible for performing backups of your data.
+We maintain general usage statistics of this service by the MIT community at large.
+</p>
+
+<?php
+include 'foot.php';
+?>
diff --git a/tpl/login.php b/tpl/login.php
new file mode 100644 (file)
index 0000000..a9ce2b5
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+include 'head.php';
+
+$thisTxt = isSSL()?' using this Certificate':' using your MySQL Password';
+?>
+
+<h3>Login</h3>
+
+<?php printErrors($err); ?>
+
+<?php if (!isSSL()): ?>
+
+<form method=post action="<?=$URI?>">
+<p>Please enter your MySQL login information:</p>
+<p>username: <input type="text" name="u" value="<?=isset($i_u)?$i_u:''?>"></p>
+<p>password: <input type="password" name="p"></p>
+
+<?php elseif (isSSL() && !empty($SSLCred)): ?>
+
+<form method=post action="<?=$URI?>">
+<p>You are identified as: <?=$SSLUsername?></p>
+<p><?=$SSLName?></p>
+<p><?=$SSLEmail?></p>
+
+<?php endif; ?>
+
+<?php if (!isSSL() || $LoginSSL->canLogin()): ?>
+
+<input type=submit value="Login<?=$thisTxt?>">
+</form>
+
+<?php elseif (isSSL() && !is_null($SSLCred)): ?>
+
+<p><a href="do/signup">Sign up</a> to use this service.</p>
+
+<?php endif; ?>
+
+<?php
+include 'foot.php';
+?>
diff --git a/tpl/main.php b/tpl/main.php
new file mode 100644 (file)
index 0000000..d3744eb
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+include 'head.php';
+
+if (isset($i_dropask)) {
+       $dropdbs = array_keys($i_dropask);
+       echo '<form method="post" action="', $URI,'">';
+       foreach($dropdbs as $dbname) {
+               $msg1[] = 'Are you sure you want to drop `'.$dbname.'`? <input style="position:absolute; right:20px;" type="submit" name="drop['.$dbname.']" value="Yes">';
+       }
+       echo '</form>';
+}
+
+?>
+<h3>Databases</h3>
+
+<form method="post" action="<?=$URI?>">
+<?php printErrors($err1); ?>
+<?php printMsgs($msg1); ?>
+</form>
+
+<table width="100%">
+<form method="post" action="<?=$URI?>">
+<?php
+       $bytes = $User->getBytes();
+       $usage = $bytes['nBytes'];
+       $total = $bytes['nBytesHard'];
+       if (!count($myDBs)) {
+               echo '<tr><td width="100%"><em>You have no databases. Add one below.</em></td></tr>';
+       } else
+       foreach($myDBs as $db) {
+               echo '<tr><td width="100%">';
+               if ($total>0)
+                       $percentage = $db['nBytes']/$total;
+               else $percentage = 0;
+               echo printBar($percentage, $db['Name'], str_replace(' ', '&nbsp;', sprintSize($db['nBytes'])));
+               echo '</td><td>';
+               echo '<input type="submit" name="dropask[',$db['Name'],']" value="drop">';
+               echo '</td></tr>';
+       }
+       if ($total>0) {
+               $percentage = $usage/$total;
+       } else {
+               $percentage = 0;
+       }
+       echo '<tr><td colspan=2>';
+       echo '<hr />';
+       echo '</td></tr>';
+       echo '<tr><td colspan=2>';
+       echo printBar($percentage, '<b>TOTAL&nbsp;USED</b>', str_replace(' ', '&nbsp;', sprintSize($usage).' of '.sprintSize($total)));
+       echo '</td></tr>';
+?>
+</form>
+</table>
+
+<form method="post" action="<?=$URI?>">
+<p align="right"><span style="width: 150px;"><label for="p1">new database:</label></span> <input type="text" name="newdb">
+<input type=submit value="add"></p>
+</form>
+
+<h3>Manage Data</h3>
+<p>One interface we recommend for managing SQL data is <a href="https://scripts.mit.edu/~sql/phpMyAdmin/" target="_blank">phpMyAdmin</a>. Feel free to use it after you've created your databases.</p>
+
+<?php
+
+include 'foot.php';
+
+?>
diff --git a/tpl/menu.php b/tpl/menu.php
new file mode 100644 (file)
index 0000000..b96bb46
--- /dev/null
@@ -0,0 +1,36 @@
+                               <div id="hnav">
+                                       <ul id="navlist">
+<?php if (isLoggedIn()): ?>
+<div style="float:left;">
+<li><a href="do/main?refresh">Databases</a></li>
+<li><a href="do/setup">Account</a></li>
+<?php if (isAdmin()) { ?>
+<li><a href="do/admin/main">Admin</a></li>
+<?php } ?>
+<li><a href="do/logout">Logout</a></li>
+</div>
+<?php
+       $loggedInText = $Login->getUsername();
+       if (isImpersonating()) {
+               $loggedInText = '<li><a href="do/admin/main?impersonate">'.$loggedInText.'</a></li>';
+       }
+?>
+<div style="text-align: right;">
+Logged in: <em><?=$loggedInText?>@<?=DBHOST?></em>&nbsp;
+</div>
+<?php else: ?>
+<div style="float:left;">
+<li><a href="do/signup">Sign up</a></li>
+<li><a href="https://scripts.mit.edu/~sql/phpMyAdmin/" target="_blank">phpMyAdmin</a></li>
+<?php if (DEBUG) { ?>
+<li><a href="do/index">Home</a></li>
+<?php } else { ?>
+<li><a href="http://sql.mit.edu/">Home</a></li>
+<?php } ?>
+</div>
+<div style="text-align: right;">
+Login via: <li><a href="do/login?ssl=0">SQL Password</a></li><li><a href="do/login?ssl=1">MIT Certificate</a></li>
+</div>
+<?php endif; ?>
+                                       </ul>
+                               </div>
diff --git a/tpl/offline.php b/tpl/offline.php
new file mode 100755 (executable)
index 0000000..c330bc7
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+include 'head.php';
+?>
+
+<h3>System Maintenance</h3>
+
+<p>
+The MySQL Service interface is temporarily offline while we perform system maintenance.
+Please check back with us in a few minutes for interface access recommencement.
+We apologize for the delay in service and inconvenience.
+In the meantime, feel free to <a href="do/contact">Contact Us</a>.
+</p>
+
+<?php
+include 'foot.php';
+?>
diff --git a/tpl/setup.php b/tpl/setup.php
new file mode 100755 (executable)
index 0000000..284a69a
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+include 'head.php';
+?>
+
+<h3>Change MySQL Password</h3>
+
+Your MySQL password should be different from your Athena account password.<br>
+<br>
+
+<?php printErrors($err); ?>
+<?php printMsgs($msg); ?>
+
+<form method="post" action="<?=$URI?>">
+<table>
+<?/*
+<tr><td align="right">old password:</td><td><input type="password" name="p[0]"></td></tr>*/?>
+<tr><td align="right">new password:</td><td><input type="password" name="p[1]"></td></tr>
+<tr><td align="right">repeat new password:</td><td><input type="password" name="p[2]"></td></tr>
+<tr><td align="right" colspan=2><br /><input name="chgpw" type="submit" value="change password"></td></tr>
+</table>
+</form>
+
+<?php
+include 'foot.php';
+?>
diff --git a/tpl/signup.php b/tpl/signup.php
new file mode 100644 (file)
index 0000000..b980a4a
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+include 'head.php';
+
+$thisTxt = isSSL()?' with this Certificate':' via SQL';
+?>
+
+<h3>Signup</h3>
+
+<?php printErrors($err); ?>
+
+<?php if ($LoginSSL->canSignup()): ?>
+<p>You are registering as: <?=$LoginSSL->getUsername()?></p>
+<p><?=$LoginSSL->getName()?></p>
+<p><?=$LoginSSL->getEmail()?></p>
+
+Your MySQL password should be different from your Athena account password.
+
+<form method=post action="<?=$URI?>">
+<p><span style="width: 150px;"><label for="p1">password:</label></span> <input type="password" name="p1"></p>
+<p><span style="width: 150px;"><label for="p2">repeat password:</label></span> <input type="password" name="p2"></p>
+<input type=submit value="Confirm Registration">
+</form>
+
+<?php elseif ($LoginSSL->canLogin()): ?>
+
+<p>Your account [<?=$LoginSSL->getUsername()?>] is already signed up.</p>
+
+<?php else: ?>
+
+<?php endif; ?>
+
+<?php
+include 'foot.php';
+?>
This page took 0.15474 seconds and 5 git commands to generate.