You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2008/12/12 19:20:18 UTC

svn commit: r726079 [26/32] - in /incubator/vcl/tags/import: ./ managementnode/ managementnode/bin/ managementnode/etc/ managementnode/etc/vcl/ managementnode/legacy_vcl_vbs_scripts/ managementnode/lib/ managementnode/lib/VCL/ managementnode/lib/VCL/Mo...

Added: incubator/vcl/tags/import/web/.ht-inc/requests.php
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/web/.ht-inc/requests.php?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/web/.ht-inc/requests.php (added)
+++ incubator/vcl/tags/import/web/.ht-inc/requests.php Fri Dec 12 10:20:10 2008
@@ -0,0 +1,4071 @@
+<?php
+/*
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+*/
+
+/**
+ * \file
+ */
+/// signifies an error with the submitted start date
+define("STARTDAYERR", 1);
+/// signifies an error with the submitted start hour
+define("STARTHOURERR", 1 << 1);
+/// signifies an error with the submitted end date
+define("ENDDAYERR", 1 << 2);
+/// signifies an error with the submitted end hour
+define("ENDHOURERR", 1 << 3);
+/// signifies an error with the submitted starting date
+define("STARTDATEERR", 1 << 4);
+/// signifies an error with the submitted endding date and time
+define("ENDDATEERR", 1 << 5);
+/// signifies an error with the selected imageid
+define("IMAGEIDERR", 1 << 6);
+/// signifies an error with the number of block machines
+define("BLOCKCNTERR", 1 << 7);
+/// signifies an error with the selected groupid
+define("USERGROUPIDERR", 1 << 8);
+/// signifies an error with the selected availibility time
+define("AVAILABLEERR", 1 << 9);
+/// signifies an error with the selected week number
+define("WEEKNUMERR", 1 << 10);
+/// signifies an error with the selected day of the week
+define("DAYERR", 1 << 11);
+/// signifies an error with the specified name
+define("BLOCKNAMEERR", 1 << 12);
+/// signifies an error with the selected admin groupid
+define("ADMINGROUPIDERR", 1 << 13);
+
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn newReservation()
+///
+/// \brief prints form for submitting a new reservation
+///
+////////////////////////////////////////////////////////////////////////////////
+function newReservation() {
+	global $submitErr, $user;
+	$timestamp = processInputVar("stamp", ARG_NUMERIC);
+	$imageid = processInputVar("imageid", ARG_STRING, getUsersLastImage($user['id']));
+	$length = processInputVar("length", ARG_NUMERIC);
+	$day = processInputVar("day", ARG_STRING);
+	$hour = processInputVar("hour", ARG_NUMERIC);
+	$minute = processInputVar("minute", ARG_NUMERIC);
+	$meridian = processInputVar("meridian", ARG_STRING);
+
+	if(! $submitErr)
+		print "<H2>New Reservation</H2><br>\n";
+
+	$resources = getUserResources(array("imageAdmin", "imageCheckOut"));
+	$resources["image"] = removeNoCheckout($resources["image"]);
+
+	if((! in_array("imageCheckOut", $user["privileges"]) &&
+	   ! in_array("imageAdmin", $user["privileges"])) ||
+	   empty($resources['image'])) {
+		print "You don't have access to any environments and, therefore, cannot ";
+		print "make any reservations.<br>\n";
+		return;
+	}
+	print "Please select the environment you want to use from the list:<br>\n";
+
+	$OSs = getOSList();
+
+	$images = getImages();
+	$maxTimes = getUserMaxTimes();
+	print "<script language=javascript>\n";
+	print "var defaultMaxTime = {$maxTimes['initial']};\n";
+	print "var maxTimes = {\n";
+	foreach(array_keys($resources['image']) as $imgid) {
+		if(array_key_exists($imgid, $images))
+			print "   $imgid: {$images[$imgid]['maxinitialtime']},\n";
+	}
+	print "   0: 0\n"; // this is because IE doesn't like the last item having a ',' after it
+	print "};\n";
+	print "</script>\n";
+
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	// list of images
+	uasort($resources["image"], "sortKeepIndex");
+	printSelectInput("imageid", $resources["image"], $imageid, 1, 0, 'imagesel', "onChange=\"selectEnvironment();\" tabIndex=1");
+	print "<br><br>\n";
+
+	$imagenotes = getImageNotes($imageid);
+	$desc = '';
+	if(preg_match('/\w/', $imagenotes['description'])) {
+		$desc = preg_replace("/\n/", '<br>', $imagenotes['description']);
+		$desc = preg_replace("/\r/", '', $desc);
+		$desc = "<strong>Image Description</strong>:<br>\n$desc<br><br>\n";
+	}
+	print "<div id=imgdesc>$desc</div>\n";
+
+	print "<fieldset id=whenuse class=whenusefieldset>\n";
+	print "<legend>When would you like to use the application?</legend>\n";
+	print "&nbsp;&nbsp;&nbsp;<INPUT type=radio name=time id=timenow ";
+	print "onclick='updateWaitTime(0);' value=now>Now<br>\n";
+	print "&nbsp;&nbsp;&nbsp;<INPUT type=radio name=time value=future ";
+	print "onclick='updateWaitTime(0);' checked>Later:\n";
+	if($submitErr) {
+		$hour24 = $hour;
+		if($hour24 == 12) {
+			if($meridian == "am") {
+				$hour24 = 0;
+			}
+		}
+		elseif($meridian == "pm") {
+			$hour24 += 12;
+		}
+		list($month, $day, $year) = explode('/', $day);
+		$stamp = datetimeToUnix("$year-$month-$day $hour24:$minute:00");
+		$day = date('l', $stamp);
+		printReserveItems(1, $day, $hour, $minute, $meridian, $length);
+	}
+	elseif(empty($timestamp)) {
+		printReserveItems();
+	}
+	else {
+		$timeArr = explode(',', date('l,g,i,a', $timestamp));
+		printReserveItems(1, $timeArr[0], $timeArr[1], $timeArr[2], $timeArr[3], $length);
+	}
+	print "</fieldset>\n";
+
+	print "<div id=waittime class=hidden></div><br>\n";
+	$cont = addContinuationsEntry('submitRequest');
+	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "<INPUT id=newsubmit type=submit value=\"Create Reservation\">\n";
+	print "<INPUT type=hidden id=testjavascript value=0>\n";
+	print "</FORM>\n";
+	$cont = addContinuationsEntry('AJupdateWaitTime');
+	print "<INPUT type=hidden name=waitcontinuation id=waitcontinuation value=\"$cont\">\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn AJupdateWaitTime()
+///
+/// \brief generates html update for ajax call to display estimated wait time
+/// for current selection on new reservation page
+///
+////////////////////////////////////////////////////////////////////////////////
+function AJupdateWaitTime() {
+	global $user, $requestInfo;
+	# proccess length
+	$length = processInputVar('length', ARG_NUMERIC);
+	$times = getUserMaxTimes();
+	if(empty($length) || $length > $times['initial']) {
+		dbDisconnect();
+		exit;
+	}
+	# process imageid
+	$imageid = processInputVar('imageid', ARG_NUMERIC);
+	$resources = getUserResources(array("imageAdmin", "imageCheckOut"));
+	$validImageids = array_keys($resources['image']);
+	if(! in_array($imageid, $validImageids)) {
+		dbDisconnect();
+		exit;
+	}
+
+	$desconly = processInputVar('desconly', ARG_NUMERIC, 1);
+
+	$imagenotes = getImageNotes($imageid);
+	if(preg_match('/\w/', $imagenotes['description'])) {
+		$desc = preg_replace("/\n/", '<br>', $imagenotes['description']);
+		$desc = preg_replace("/\r/", '', $desc);
+		print "dojo.byId('imgdesc').innerHTML = '<strong>Image Description</strong>:<br>";
+		print "$desc<br><br>'; ";
+	}
+
+	if($desconly)
+		return;
+
+	$images = getImages();
+	$now = time();
+	$start = unixFloor15($now);
+	$end = $start + $length * 60;
+	if($start < $now)
+		$end += 15 * 60;
+	$rc = isAvailable($images, $imageid, $start, $end, '');
+	semUnlock();
+	print "dojo.byId('waittime').innerHTML = ";
+	if($rc < 1) {
+		print "'<font color=red>Selection not currently available</font>'; ";
+		print "if(dojo.byId('newsubmit')) dojo.byId('newsubmit').value = 'View Time Table';";
+	}
+	elseif(array_key_exists(0, $requestInfo['loaded']) &&
+		   $requestInfo['loaded'][0]) {
+			print "'Estimated load time: &lt; 1 minute';";
+	}
+	else {
+		$loadtime = (int)(getImageLoadEstimate($imageid) / 60);
+		if($loadtime == 0)
+			print "'Estimated load time: &lt; {$images[$imageid]['reloadtime']} minutes';";
+		else
+			printf("'Estimated load time: &lt; %2.0f minutes';", $loadtime + 1);
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitRequest()
+///
+/// \brief checks to see if the request can fit in the schedule; adds it if
+/// it fits; notifies the user either way
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitRequest() {
+	global $submitErr, $user, $viewmode, $HTMLheader, $mode, $printedHTMLheader;
+
+	if($mode == 'submitTestProd') {
+		$data = getContinuationVar();
+		$data["revisionid"] = processInputVar("revisionid", ARG_MULTINUMERIC);
+		# TODO check for valid revisionids for each image
+		if(! empty($data["revisionid"])) {
+			foreach($data['revisionid'] as $key => $val) {
+				if(! is_numeric($val) || $val < 0)
+					unset($data['revisionid']);
+			}
+		}
+	}
+	else
+		$data = processRequestInput(1);
+	if($submitErr) {
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		print "<H2>New Reservation</H2>\n";
+		newReservation();
+		return;
+	}
+	// FIXME hack to make sure user didn't submit a request for an image he 
+	// doesn't have access to
+	$resources = getUserResources(array("imageAdmin", "imageCheckOut"));
+	$validImageids = array_keys($resources['image']);
+	if(! in_array($data['imageid'], $validImageids))
+		$data['imageid'] = array_shift($validImageids);
+
+	$showrevisions = 0;
+	$subimages = 0;
+	$images = getImages();
+	$revcount = count($images[$data['imageid']]['imagerevision']);
+	if($revcount > 1)
+		$showrevisions = 1;
+	if($images[$data['imageid']]['imagemetaid'] != NULL &&
+	   count($images[$data['imageid']]['subimages'])) {
+		$subimages = 1;
+		foreach($images[$data['imageid']]['subimages'] as $subimage) {
+			$revcount = count($images[$subimage]['imagerevision']);
+			if($revcount > 1)
+				$showrevisions = 1;
+		}
+	}
+
+	if($data["time"] == "now") {
+		$nowArr = getdate();
+		if($nowArr["minutes"] == 0) {
+			$subtract = 0;
+			$add = 0;
+		}
+		elseif($nowArr["minutes"] < 15) {
+			$subtract = $nowArr["minutes"] * 60;
+			$add = 900;
+		}
+		elseif($nowArr["minutes"] < 30) {
+			$subtract = ($nowArr["minutes"] - 15) * 60;
+			$add = 900;
+		}
+		elseif($nowArr["minutes"] < 45) {
+			$subtract = ($nowArr["minutes"] - 30) * 60;
+			$add = 900;
+		}
+		elseif($nowArr["minutes"] < 60) {
+			$subtract = ($nowArr["minutes"] - 45) * 60;
+			$add = 900;
+		}
+		$start = time() - $subtract;
+		$start -= $start % 60;
+		$nowfuture = "now";
+	}
+	else {
+		$add = 0;
+		$hour = $data["hour"];
+		if($data["hour"] == 12) {
+			if($data["meridian"] == "am") {
+				$hour = 0;
+			}
+		}
+		elseif($data["meridian"] == "pm") {
+			$hour = $data["hour"] + 12;
+		}
+
+		$tmp = explode('/', $data["day"]);
+		$start = mktime($hour, $data["minute"], "0", $tmp[0], $tmp[1], $tmp[2]);
+		if($start < time()) {
+			$printedHTMLheader = 1;
+			print $HTMLheader;
+			print "<H2>New Reservation</H2>\n";
+			print "<font color=\"#ff0000\">The time you requested is in the past.";
+			print " Please select \"Now\" or use a time in the future.</font><br>\n";
+			$submitErr = 1;
+			newReservation();
+			return;
+		}
+		$nowfuture = "future";
+	}
+	if($data["ending"] == "length")
+		$end = $start + $data["length"] * 60 + $add;
+	else {
+		$end = datetimeToUnix($data["enddate"]);
+		if($end % (15 * 60))
+			$end = unixFloor15($end) + (15 * 60);
+	}
+
+	// get semaphore lock
+	if(! semLock())
+		abort(3);
+
+	$max = getMaxOverlap($user['id']);
+	if(checkOverlap($start, $end, $max)) {
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		print "<H2>New Reservation</H2>\n";
+		if($max == 0) {
+			print "<font color=\"#ff0000\">The time you requested overlaps with ";
+			print "another reservation you currently have.  You are only allowed ";
+			print "to have a single reservation at any given time. Please select ";
+			print "another time to use the application. If you are finished with ";
+			print "an active reservation, click \"Current Reservations\", ";
+			print "then click the \"End\" button of your active reservation.";
+			print "</font><br><br>\n";
+		}
+		else {
+			print "<font color=\"#ff0000\">The time you requested overlaps with ";
+			print "another reservation you currently have.  You are allowed ";
+			print "to have $max overlapping reservations at any given time. ";
+			print "Please select another time to use the application. If you are ";
+			print "finished with an active reservation, click \"Current ";
+			print "Reservations\", then click the \"End\" button of your active ";
+			print "reservation.</font><br><br>\n";
+		}
+		$submitErr = 1;
+		newReservation();
+		return;
+	}
+	// if user is owner of the image and there is a test version of the image
+	#   available, ask user if production or test image desired
+	if($mode != "submitTestProd" && $showrevisions &&
+	   $images[$data["imageid"]]["ownerid"] == $user["id"]) {
+		#unset($data["testprod"]);
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		print "<H2>New Reservation</H2>\n";
+		if($subimages) {
+			print "This is a cluster environment. At least one image in the ";
+			print "cluster has more than one version available. Please select ";
+			print "the version you desire for each image listed below:<br>\n";
+		}
+		else {
+			print "There are multiple versions of this environment available.  Please ";
+			print "select the version you would like to check out:<br>\n";
+		}
+		print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post><br>\n";
+		if(! array_key_exists('subimages', $images[$data['imageid']]))
+			$images[$data['imageid']]['subimages'] = array();
+		array_unshift($images[$data['imageid']]['subimages'], $data['imageid']);
+		foreach($images[$data['imageid']]['subimages'] as $subimage) {
+			print "{$images[$subimage]['prettyname']}:<br>\n";
+			print "<table summary=\"lists versions of the selected environment, one must be selected to continue\">\n";
+			print "  <TR>\n";
+			print "    <TD></TD>\n";
+			print "    <TH>Version</TH>\n";
+			print "    <TH>Creator</TH>\n";
+			print "    <TH>Created</TH>\n";
+			print "    <TH>Currently in Production</TH>\n";
+			print "  </TR>\n";
+			foreach($images[$subimage]['imagerevision'] as $revision) {
+				print "  <TR>\n";
+				if(array_key_exists($subimage, $data['revisionid']) && 
+				   $data['revisionid'][$subimage] == $revision['id'])
+					print "    <TD align=center><INPUT type=radio name=revisionid[$subimage] value={$revision['id']} checked></TD>\n";
+				elseif($revision['production'])
+					print "    <TD align=center><INPUT type=radio name=revisionid[$subimage] value={$revision['id']} checked></TD>\n";
+				else
+					print "    <TD align=center><INPUT type=radio name=revisionid[$subimage] value={$revision['id']}></TD>\n";
+				print "    <TD align=center>{$revision['revision']}</TD>\n";
+				print "    <TD align=center>{$revision['user']}</TD>\n";
+				print "    <TD align=center>{$revision['prettydate']}</TD>\n";
+				if($revision['production'])
+					print "    <TD align=center>Yes</TD>\n";
+				else
+					print "    <TD align=center>No</TD>\n";
+				print "  </TR>\n";
+			}
+			print "</table>\n";
+		}
+		$cont = addContinuationsEntry('submitTestProd', $data);
+		print "<br><INPUT type=hidden name=continuation value=\"$cont\">\n";
+		print "<INPUT type=submit value=\"Create Reservation\">\n";
+		print "</FORM>\n";
+		return;
+	}
+	$rc = isAvailable($images, $data["imageid"], $start, $end, $data["os"]);
+	if($rc == -1) {
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		print "<H2>New Reservation</H2>\n";
+		print "You have requested an environment that is limited in the number ";
+		print "of concurrent reservations that can be made. No further ";
+		print "reservations for the environment can be made for the time you ";
+		print "have selected. Please select another time to use the ";
+		print "environment.<br>";
+		addLogEntry($nowfuture, unixToDatetime($start), 
+		            unixToDatetime($end), 0, $data["imageid"]);
+	}
+	elseif($rc > 0) {
+		$requestid = addRequest(0, $data["revisionid"]);
+		$time = prettyLength($data["length"]);
+		if($data["time"] == "now") {
+			$cdata = array('lengthchanged' => $data['lengthchanged']);
+			$cont = addContinuationsEntry('viewRequests', $cdata);
+			header("Location: " . BASEURL . SCRIPT . "?continuation=$cont");
+			dbDisconnect();
+			exit;
+		}
+		else {
+			if($data["minute"] == 0) {
+				$data["minute"] = "00";
+			}
+			$printedHTMLheader = 1;
+			print $HTMLheader;
+			print "<H2>New Reservation</H2>\n";
+			if($data["ending"] == "length") {
+				if($data['testjavascript'] == 0 && $data['lengthchanged']) {
+					print "<font color=red>NOTE: The maximum allowed reservation ";
+					print "length for this environment is $time, and the length of ";
+					print "this reservation has been adjusted accordingly.</font>\n";
+					print "<br><br>\n";
+				}
+				print "Your request to use <b>" . $images[$data["imageid"]]["prettyname"];
+				print "</b> on " . prettyDatetime($start) . " for $time has been ";
+				print "accepted.<br><br>\n";
+			}
+			else {
+				print "Your request to use <b>" . $images[$data["imageid"]]["prettyname"];
+				print "</b> starting " . prettyDatetime($start) . " and ending ";
+				print prettyDatetime($end) . " has been accepted.<br><br>\n";
+			}
+			print "When your reservation time has been reached, the <strong>";
+			print "Current Reservations</strong> page will have further ";
+			print "instructions on connecting to the reserved computer.  If you ";
+			print "would like to modify your reservation, you can do that from ";
+			print "the <b>Current Reservations</b> page as well.<br>\n";
+		}
+	}
+	else {
+		$cdata = array('imageid' => $data['imageid'],
+		               'length' => $data['length'],
+		               'showmessage' => 1);
+		$cont = addContinuationsEntry('selectTimeTable', $cdata);
+		addLogEntry($nowfuture, unixToDatetime($start), 
+		            unixToDatetime($end), 0, $data["imageid"]);
+		header("Location: " . BASEURL . SCRIPT . "?continuation=$cont");
+		/*print "<H2>New Reservation</H2>\n";
+		print "The reservation you have requested is not available. You may ";
+		print "<a href=\"" . BASEURL . SCRIPT . "?continuation=$cont\">";
+		print "view a timetable</a> of free and reserved times to find ";
+		print "a time that will work for you.<br>\n";*/
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn blockRequest()
+///
+/// \brief prints a page for selecting block request stuff
+///
+////////////////////////////////////////////////////////////////////////////////
+function blockRequest() {
+	print "<H2>Block Reservation</H2>\n";
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cont = addContinuationsEntry('newBlockRequest');
+	print "<INPUT type=radio id=newblock name=continuation value=\"$cont\">\n";
+	print "<label for=newblock>New Block Reservation</label><br>\n";
+	$cont = addContinuationsEntry('selectEditBlockRequest');
+	print "<INPUT type=radio id=editblock name=continuation value=\"$cont\" checked>\n";
+	print "<label for=editblock>Edit/Delete Block Reservation</label><br>\n";
+	print "<INPUT type=submit value=Submit>\n";
+	print "</FORM>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn newBlockRequest()
+///
+/// \brief prints form for submitting a new block request
+///
+////////////////////////////////////////////////////////////////////////////////
+function newBlockRequest() {
+	global $submitErr, $user, $days;
+	$data = processBlockRequestInput(0);
+
+	if(! $submitErr) {
+		if($data['state'])
+			print "<H2>Edit Block Reservation</H2>\n";
+		else {
+			print "<H2>New Block Reservation</H2>\n";
+			$data['machinecnt'] = '';
+		}
+	}
+	else {
+		foreach($days as $day) {
+			if(in_array($day, $data['wdays']))
+				$data['wdayschecked'][$day] = 'checked';
+		}
+	}
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "Enter a name for the Block Reservation:<br>\n";
+	print "<INPUT type=text name=blockname size=30 value=\"{$data['blockname']}\">";
+	printSubmitErr(BLOCKNAMEERR);
+	print "<br><br>\n";
+	print "Select an environment from the list:<br>\n";
+	printSubmitErr(IMAGEIDERR);
+
+	$resources = getUserResources(array("imageAdmin", "imageCheckOut"));
+	$resources["image"] = removeNoCheckout($resources["image"]);
+	$OSs = getOSList();
+
+	// list of images
+	uasort($resources["image"], "sortKeepIndex");
+	printSelectInput("imageid", $resources["image"], $data['imageid'], 1);
+	print "<br><br>\n";
+
+	print "How many machines do you need for the block request?<br>\n";
+	print "<INPUT type=text name=machinecnt size=3 value={$data['machinecnt']}>";
+	printSubmitErr(BLOCKCNTERR);
+	print "<br><br>\n";
+
+	print "What user group should be allowed to check out machines in this ";
+	print "block request?<br>\n";
+	// FIXME should we limit the course groups that show up?
+	$groups = getUserGroups(0, $user['affiliationid']);
+	if(array_key_exists(82, $groups))
+		unset($groups[82]); # remove None group
+	if(! empty($data['usergroupid']) &&
+	   ! array_key_exists($data['usergroupid'], $groups)) {
+		$groups[$data['usergroupid']] =
+		      array('name' => getUserGroupName($data['usergroupid'], 1));
+		uasort($groups, "sortKeepIndex");
+	}
+	printSelectInput('usergroupid', $groups, $data['usergroupid']);
+	printSubmitErr(USERGROUPIDERR);
+	print "<br><br>\n";
+
+	print "What user group should be allowed to manage (administer) this ";
+	print "block request?<br>\n";
+	if(! empty($data['admingroupid']) &&
+	   ! array_key_exists($data['admingroupid'], $groups)) {
+		$groups[$data['admingroupid']] =
+		      array('name' => getUserGroupName($data['admingroupid'], 1));
+		uasort($groups, "sortKeepIndex");
+	}
+	$nonegroups = array_reverse($groups, TRUE);
+	$nonegroups[0] = array('name' => 'None (owner only)');
+	$nonegroups = array_reverse($nonegroups, TRUE);
+	printSelectInput('admingroupid', $nonegroups, $data['admingroupid']);
+	printSubmitErr(ADMINGROUPIDERR);
+	print "<br><br>\n";
+
+	$checked = array('weekly' => '',
+	                 'monthly' => '',
+	                 'list' => '');
+	if($data['available'] == "weekly")
+		$checked['weekly'] = 'checked';
+	elseif($data['available'] == 'monthly')
+		$checked['monthly'] = 'checked';
+	elseif($data['available'] == 'list')
+		$checked['list'] = 'checked';
+	print "When do you need the block of machines to be available?<br>\n";
+	print "<INPUT type=radio name=available id=rweekly value=\"weekly\"";
+	print "{$checked['weekly']} onclick=javascript:show('weekly');>";
+	print "<label for=rweekly>Repeating Weekly</label>\n";
+	print "<INPUT type=radio name=available id=rmonthly value=\"monthly\"";
+	print "{$checked['monthly']} onclick=javascript:show('monthly');>";
+	print "<label for=rmonthly>Repeating Monthly</label>\n";
+	print "<INPUT type=radio name=available id=rlist value=\"list\"";
+	print "{$checked['list']} onclick=javascript:show('list');>";
+	print "<label for=rlist>List of dates/times</label><br>\n";
+
+	print "<fieldset id=weekly class=shown>\n";
+	print "<legend>Repeating Weekly</legend>\n";
+	print "<table summary=\"\">\n";
+	print "  <TR>\n";
+	print "    <TH>Day</TH>\n";
+	print "    <TH>Time</TH>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TD>\n";
+	foreach($days as $day) {
+		print "      <INPUT type=checkbox name=wdays[] value=$day {$data['wdayschecked'][$day]}>$day<br>\n";
+	}
+	printSubmitErr(STARTDAYERR);
+	print "    </TD>\n";
+	print "    <TD valign=top>\n";
+	print "    <table summary=\"\">\n";
+	print "      <TR>\n";
+	print "        <TH>Start</TH>\n";
+	print "        <TD></TD>\n";
+	print "        <TH>End</TH>\n";
+	print "      </TR>\n";
+	for($i = 0; $i < 4; $i++) {
+		if(count($data['swhour']) < 4) {
+			$data['swhour'][$i] = 1;
+			$data['swminute'][$i] = "zero";
+			$data['swmeridian'][$i] = "am";
+			$data['ewhour'][$i] = 1;
+			$data['ewminute'][$i] = "zero";
+			$data['ewmeridian'][$i] = "am";
+		}
+		print "      <TR>\n";
+		print "        <TD nowrap>\n";
+		print "          Slot" . ($i + 1) . ":\n";
+		printBlockStartEnd($i, 'w', $data['swhour'],
+		                   $data['swminute'],
+		                   $data['swmeridian'],
+		                   $data['ewhour'],
+		                   $data['ewminute'],
+		                   $data['ewmeridian']);
+		print "        </TD>\n";
+		print "        <TD>\n";
+		if($data['available'] == 'weekly') {
+			printSubmitErr(STARTHOURERR, $i);
+			printSubmitErr(ENDHOURERR, $i);
+		}
+		print "        </TD>\n";
+		print "      </TR>\n";
+	}
+	print "    </table>\n";
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</table>\n";
+	print "<table summary=\"\">\n";
+	print "  <TR>\n";
+	print "    <TH>Starting date:</TH>\n";
+	print "    <TD><INPUT type=text name=swdate size=10 maxlength=8 value=\"{$data['swdate']}\"></TD>\n";
+	print "    <TD><small>(mm/dd/yy) </small>";
+	if($data['available'] == 'weekly')
+		printSubmitErr(STARTDATEERR);
+	print "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH>Ending date:</TH>\n";
+	print "    <TD><INPUT type=text name=ewdate size=10 maxlength=8 value=\"{$data['ewdate']}\"></TD>\n";
+	print "    <TD><small>(mm/dd/yy) </small>";
+	if($data['available'] == 'weekly')
+		printSubmitErr(ENDDATEERR);
+	print "</TD>\n";
+	print "  </TR>\n";
+	print "</table>\n";
+	print "</fieldset>\n";
+
+	print "<fieldset id=monthly class=shown>\n";
+	print "<legend>Repeating Monthly</legend>\n";
+	$weeknumArr = array(1 => "1st",
+	                    2 => "2nd",
+	                    3 => "3rd",
+	                    4 => "4th",
+	                    5 => "5th");
+	$dayArr = array(1 => "Sunday",
+	                2 => "Monday",
+	                3 => "Tuesday",
+	                4 => "Wednesday",
+	                5 => "Thursday",
+	                6 => "Friday",
+	                7 => "Saturday");
+	printSelectInput('weeknum', $weeknumArr, $data['weeknum']);
+	printSelectInput('day', $dayArr, $data['day']);
+	print " of every month<br>\n";
+	print "<table summary=\"\">\n";
+	print "  <TR>\n";
+	print "    <TH>Start</TH>\n";
+	print "    <TD></TD>\n";
+	print "    <TH>End</TH>\n";
+	print "  </TR>\n";
+	for($i = 0; $i < 4; $i++) {
+		if(count($data['smhour']) < 4) {
+			$data['smhour'][$i] = 1;
+			$data['smminute'][$i] = "zero";
+			$data['smmeridian'][$i] = "am";
+			$data['emhour'][$i] = 1;
+			$data['emminute'][$i] = "zero";
+			$data['emmeridian'][$i] = "am";
+		}
+		print "  <TR>\n";
+		print "    <TD nowrap>\n";
+		print "      Slot" . ($i + 1) . ":\n";
+		printBlockStartEnd($i, 'm', $data['smhour'],
+		                   $data['smminute'],
+		                   $data['smmeridian'],
+		                   $data['emhour'],
+		                   $data['emmeridian'],
+		                   $data['emmeridian']);
+		print "    </TD>\n";
+		print "    <TD>\n";
+		if($data['available'] == 'monthly') {
+			printSubmitErr(STARTHOURERR, $i);
+			printSubmitErr(ENDHOURERR, $i);
+		}
+		print "    </TD>\n";
+		print "  </TR>\n";
+	}
+	print "</table>\n";
+	print "<table summary=\"\">\n";
+	print "  <TR>\n";
+	print "    <TH>Starting date:</TH>\n";
+	print "    <TD><INPUT type=text name=smdate size=10 value=\"{$data['smdate']}\"></TD>\n";
+	print "    <TD><small>(mm/dd/yy) </small>";
+	if($data['available'] == 'monthly')
+		printSubmitErr(STARTDATEERR);
+	print "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH>Ending date:</TH>\n";
+	print "    <TD><INPUT type=text name=emdate size=10 value=\"{$data['emdate']}\"></TD>\n";
+	print "    <TD><small>(mm/dd/yy) </small>\n";
+	if($data['available'] == 'monthly')
+		printSubmitErr(ENDDATEERR);
+	print "</TD>\n";
+	print "  </TR>\n";
+	print "</table>\n";
+	print "</fieldset>\n";
+
+	print "<fieldset id=list class=shown>\n";
+	print "<legend>List of dates/times</legend>\n";
+	print "<table summary=\"\">\n";
+	print "  <TR>\n";
+	print "    <TH nowrap>Date <small>(mm/dd/yy)</small></TH>\n";
+	print "    <TH>Start</TH>\n";
+	print "    <TD></TD>\n";
+	print "    <TH>End</TH>\n";
+	print "  </TR>\n";
+	for($i = 0; $i < 4; $i++) {
+		if(count($data['slhour']) < 4) {
+			$data['slhour'][$i] = 1;
+			$data['slminute'][$i] = "zero";
+			$data['slmeridian'][$i] = "am";
+			$data['elhour'][$i] = 1;
+			$data['elminute'][$i] = "zero";
+			$data['elmeridian'][$i] = "am";
+			$data['date'][$i] = "";
+		}
+		print "  <TR>\n";
+		$slot = $i + 1;
+		print "    <TD nowrap>Slot $slot:<INPUT type=text name=date[] size=10 value={$data['date'][$i]}></TD>\n";
+		print "    <TD nowrap>\n";
+		printBlockStartEnd($i, 'l', $data['slhour'],
+		                   $data['slminute'],
+		                   $data['slmeridian'],
+		                   $data['elhour'],
+		                   $data['elminute'],
+		                   $data['elmeridian']);
+		print "    </TD>\n";
+		print "    <TD>\n";
+		if($data['available'] == 'list') {
+			printSubmitErr(STARTDATEERR, $i);
+			printSubmitErr(STARTHOURERR, $i);
+			printSubmitErr(ENDHOURERR, $i);
+		}
+		print "    </TD>\n";
+		print "  </TR>\n";
+	}
+	print "</table>\n";
+	print "</fieldset>\n";
+
+	$cdata = array('state' => $data['state'],
+	               'blockRequestid' => $data['blockRequestid']);
+	$cont = addContinuationsEntry('confirmBlockRequest', $cdata, SECINDAY, 0, 1, 1);
+	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "<INPUT type=submit value=Confirm>\n";
+	print "</FORM>\n";
+	printBlockRequestJavascript($data['available']);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn selectEditBlockRequest()
+///
+/// \brief prints a page with summary info on each block request allowing one
+/// to be select for editing
+///
+////////////////////////////////////////////////////////////////////////////////
+function selectEditBlockRequest() {
+	global $user, $days;
+	$groups = getUserEditGroups($user['id']);
+	$groupids = implode(',', array_keys($groups));
+	$query = "SELECT b.id, "
+	       .        "b.name AS blockname, "
+	       .        "b.imageid, "
+	       .        "i.prettyname AS image, "
+	       .        "b.numMachines AS machinecnt, "
+	       .        "b.groupid as usergroupid, "
+	       .        "CONCAT(g.name, '@', a.name) AS `group`, "
+	       .        "b.admingroupid as admingroupid, "
+	       .        "CONCAT(ga.name, '@', aa.name) AS `admingroup`, "
+	       .        "b.repeating AS available "
+	       . "FROM image i, "
+	       .      "usergroup g, "
+	       .      "affiliation a, "
+	       .      "blockRequest b "
+	       . "LEFT JOIN usergroup ga ON (b.admingroupid = ga.id) "
+	       . "LEFT JOIN affiliation aa ON (ga.affiliationid = aa.id) "
+	       . "WHERE (b.ownerid = {$user['id']} ";
+	if(! empty($groupids))
+		$query .=   "OR b.admingroupid IN ($groupids) ";
+	$query .=      ") AND b.imageid = i.id AND "
+	       .       "b.groupid = g.id AND "
+	       .       "g.affiliationid = a.id "
+	       . "ORDER BY b.name";
+	$qh = doQuery($query, 101);
+	while($row = mysql_fetch_assoc($qh)) {
+		$blockrequest[$row['id']] = $row;
+		$query2 = "SELECT DATE_FORMAT(start, '%c/%e/%y<br>%l:%i %p') AS start1 "
+		        . "FROM blockTimes "
+		        . "WHERE blockRequestid = {$row['id']} "
+		        . "ORDER BY start "
+		        . "LIMIT 1";
+		$qh2 = doQuery($query2, 101);
+		if($row2 = mysql_fetch_assoc($qh2))
+			$blockrequest[$row['id']]['nextstart'] = $row2['start1'];
+		else
+			$blockrequest[$row['id']]['nextstart'] = "none found";
+	}
+	print "<h2>Edit Block Reservation</h2>\n";
+	if(empty($blockrequest)) {
+		print "There are currently no block reservations.<br>\n";
+		return;
+	}
+	foreach($blockrequest as $id => $request) {
+		if($request['available'] == 'weekly') {
+			$query = "SELECT DATE_FORMAT(start, '%m/%d/%y') AS swdate, "
+			       .        "DATE_FORMAT(end, '%m/%d/%y')AS ewdate, " 
+			       .        "days "
+			       . "FROM blockWebDate "
+			       . "WHERE blockRequestid = $id";
+			$qh = doQuery($query, 101);
+			if(! $row = mysql_fetch_assoc($qh))
+				abort(101);
+			$blockrequest[$id] = array_merge($request, $row);
+			$wdays = array();
+			for($i = 0; $i < 7; $i++) {
+				if($row['days'] & (1 << $i))
+					array_push($wdays, $days[$i]);
+			}
+			unset($blockrequest[$id]['days']);
+			$blockrequest[$id]['wdays'] = $wdays;
+			$query = "SELECT starthour, "
+			       .        "startminute, "
+			       .        "startmeridian, "
+			       .        "endhour, "
+			       .        "endminute, "
+			       .        "endmeridian, "
+			       .        "`order` "
+			       . "FROM blockWebTime "
+			       . "WHERE blockRequestid = {$request['id']}";
+			$qh = doQuery($query, 101);
+			while($row = mysql_fetch_assoc($qh)) {
+				$blockrequest[$id]['swhour'][$row['order']] = $row['starthour'];
+				$blockrequest[$id]['swminute'][$row['order']] = $row['startminute'];
+				$blockrequest[$id]['swmeridian'][$row['order']] = $row['startmeridian'];
+				$blockrequest[$id]['ewhour'][$row['order']] = $row['endhour'];
+				$blockrequest[$id]['ewminute'][$row['order']] = $row['endminute'];
+				$blockrequest[$id]['ewmeridian'][$row['order']] = $row['endmeridian'];
+			}
+		}
+		elseif($request['available'] == 'monthly') {
+			$query = "SELECT DATE_FORMAT(start, '%m/%d/%y') AS smdate, "
+			       .        "DATE_FORMAT(end, '%m/%d/%y')AS emdate, " 
+			       .        "days AS day, "
+			       .        "weeknum "
+			       . "FROM blockWebDate "
+			       . "WHERE blockRequestid = $id";
+			$qh = doQuery($query, 101);
+			if(! $row = mysql_fetch_assoc($qh))
+				abort(101);
+			$blockrequest[$id] = array_merge($request, $row);
+			$query = "SELECT starthour, "
+			       .        "startminute, "
+			       .        "startmeridian, "
+			       .        "endhour, "
+			       .        "endminute, "
+			       .        "endmeridian, "
+			       .        "`order` "
+			       . "FROM blockWebTime "
+			       . "WHERE blockRequestid = {$request['id']}";
+			$qh = doQuery($query, 101);
+			while($row = mysql_fetch_assoc($qh)) {
+				$blockrequest[$id]['smhour'][$row['order']] = $row['starthour'];
+				$blockrequest[$id]['smminute'][$row['order']] = $row['startminute'];
+				$blockrequest[$id]['smmeridian'][$row['order']] = $row['startmeridian'];
+				$blockrequest[$id]['emhour'][$row['order']] = $row['endhour'];
+				$blockrequest[$id]['emminute'][$row['order']] = $row['endminute'];
+				$blockrequest[$id]['emmeridian'][$row['order']] = $row['endmeridian'];
+			}
+		}
+		elseif($request['available'] == 'list') {
+			$query = "SELECT DATE_FORMAT(start, '%m/%d/%y') AS date, "
+			       #.        "DATE_FORMAT(end, '%m/%d/%y')AS ewdate, " 
+			       .        "days AS `order` "
+			       . "FROM blockWebDate "
+			       . "WHERE blockRequestid = $id";
+			$qh = doQuery($query, 101);
+			while($row = mysql_fetch_assoc($qh)) {
+				if($row['date'] == '00/00/00')
+					$blockrequest[$id]['date'][$row['order']] = '';
+				else
+					$blockrequest[$id]['date'][$row['order']] = $row['date'];
+			}
+			$query = "SELECT starthour, "
+			       .        "startminute, "
+			       .        "startmeridian, "
+			       .        "endhour, "
+			       .        "endminute, "
+			       .        "endmeridian, "
+			       .        "`order` "
+			       . "FROM blockWebTime "
+			       . "WHERE blockRequestid = {$request['id']}";
+			$qh = doQuery($query, 101);
+			while($row = mysql_fetch_assoc($qh)) {
+				$blockrequest[$id]['slhour'][$row['order']] = $row['starthour'];
+				$blockrequest[$id]['slminute'][$row['order']] = $row['startminute'];
+				$blockrequest[$id]['slmeridian'][$row['order']] = $row['startmeridian'];
+				$blockrequest[$id]['elhour'][$row['order']] = $row['endhour'];
+				$blockrequest[$id]['elminute'][$row['order']] = $row['endminute'];
+				$blockrequest[$id]['elmeridian'][$row['order']] = $row['endmeridian'];
+			}
+		}
+	}
+	print "Select a block reservation to edit:<br>\n";
+	print "<table summary=\"lists current block reservations\">\n";
+	print "  <TR align=center>\n";
+	print "    <TD colspan=2></TD>\n";
+	print "    <TH>Name</TH>\n";
+	print "    <TH>Image</TH>\n";
+	print "    <TH>Reserved<br>Machines</TH>\n";
+	print "    <TH>Reserved<br>For</TH>\n";
+	print "    <TH>Manageable<br>By</TH>\n";
+	print "    <TH>Repeating</TH>\n";
+	print "    <TH>Next Start Time</TH>\n";
+	print "  </TR>\n";
+	foreach($blockrequest as $request) {
+		print "  <TR align=center>\n";
+		print "    <TD>\n";
+		print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+		print "      <INPUT type=submit value=Edit>\n";
+		$cdata = $request;
+		$cdata['state'] = 1; # 1 = edit
+		$cdata['blockRequestid'] = $request['id'];
+		$cont = addContinuationsEntry('newBlockRequest', $cdata);
+		print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+		print "      </FORM>\n";
+		print "    </TD>\n";
+		print "    <TD>\n";
+		print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+		print "      <INPUT type=submit value=Delete>\n";
+		$cdata = $request;
+		$cdata['state'] = 2; # 2 = delete
+		$cdata['blockRequestid'] = $request['id'];
+		$cont = addContinuationsEntry('confirmBlockRequest', $cdata);
+		print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+		print "      </FORM>\n";
+		print "    </TD>\n";
+		print "    <TD>{$request['blockname']}</TD>\n";
+		print "    <TD>{$request['image']}</TD>\n";
+		print "    <TD>{$request['machinecnt']}</TD>\n";
+		print "    <TD>{$request['group']}</TD>\n";
+		if(empty($request['admingroup']))
+			print "    <TD>None (owner only)</TD>\n";
+		else
+			print "    <TD>{$request['admingroup']}</TD>\n";
+		print "    <TD>{$request['available']}</TD>\n";
+		print "    <TD>{$request['nextstart']}</TD>\n";
+		print "  </TR>\n";
+	}
+	print "</table>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn confirmBlockRequest()
+///
+/// \brief prints a confirmation page displaying information on submitted block
+/// request
+///
+////////////////////////////////////////////////////////////////////////////////
+function confirmBlockRequest() {
+	global $submitErr, $user, $days, $mode;
+	$data = processBlockRequestInput();
+	if($submitErr) {
+		newBlockRequest();
+		return;
+	}
+	$images = getImages();
+	// FIXME should we limit the course groups that show up?
+	$groups = getUserGroups(0, $user['affiliationid']);
+	if(! array_key_exists($data['usergroupid'], $groups))
+		$groups[$data['usergroupid']] =
+		      array('name' => getUserGroupName($data['usergroupid'], 1));
+	if(! array_key_exists($data['admingroupid'], $groups))
+		$groups[$data['admingroupid']] =
+		      array('name' => getUserGroupName($data['admingroupid'], 1));
+	$groups[0] = array('name' => 'None (owner only)');
+	if($data['state'] == 2) {
+		print "<H2>Delete Block Reservation</H2>\n";
+		print "Delete the following block reservation?<br>\n";
+	}
+	elseif($data['state'] == 1) {
+		print "<H2>Edit Block Reservation</H2>\n";
+		print "Modify the following block reservation?<br>\n";
+	}
+	else {
+		print "<H2>New Block Reservation</H2>\n";
+		print "Create the following block reservation?<br>\n";
+	}
+	print "<table summary=\"\">\n";
+	print "  <TR>\n";
+	print "    <TH align=right nowrap>Name:</TH>\n";
+	print "    <TD>{$data['blockname']}</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right nowrap>Image:</TH>\n";
+	print "    <TD>{$images[$data['imageid']]['prettyname']}</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right nowrap>Reserved Machines:</TH>\n";
+	print "    <TD>{$data['machinecnt']}</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right nowrap>Reserved for:</TH>\n";
+	print "    <TD>{$groups[$data['usergroupid']]['name']}</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right nowrap>Manageable by:</TH>\n";
+	print "    <TD>{$groups[$data['admingroupid']]['name']}</TD>\n";
+	print "  </TR>\n";
+	if($data['available'] == 'weekly') {
+		print "  <TR>\n";
+		print "    <TH align=right nowrap>Repeating:</TH>\n";
+		print "    <TD>Weekly</TD>\n";
+		print "  </TR>\n";
+		print "  <TR valign='top'>\n";
+		print "    <TH valign='top' align=right nowrap>On these days:</TH>\n";
+		print "    <TD>";
+		foreach($data['wdays'] as $day) {
+			print "$day<br>";
+		}
+		print "</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>For these timeslots on<br>each of the above days:</TH>\n";
+		print "    <TD>";
+		for($i = 0; $i < 4; $i++) {
+			if($data['stime'][$i] == $data['etime'][$i])
+				continue;
+			if($data['swminute'][$i] == 0)
+				$data['swminute'][$i] = "00";
+			if($data['ewminute'][$i] == 0)
+				$data['ewminute'][$i] = "00";
+			print "{$data['swhour'][$i]}:{$data['swminute'][$i]} {$data['swmeridian'][$i]} - ";
+			print "{$data['ewhour'][$i]}:{$data['ewminute'][$i]} {$data['ewmeridian'][$i]}<br>\n";
+		}
+		print "</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right nowrap>Starting:</TH>\n";
+		print "    <TD>{$data['swdate']}</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right nowrap>Ending:</TH>\n";
+		print "    <TD>{$data['ewdate']}</TD>\n";
+		print "  </TR>\n";
+	}
+	elseif($data['available'] == 'monthly') {
+		$weeknumArr = array(1 => "1st",
+		                    2 => "2nd",
+		                    3 => "3rd",
+		                    4 => "4th",
+		                    5 => "5th");
+		print "  <TR>\n";
+		print "    <TH align=right nowrap>Repeating:</TH>\n";
+		print "    <TD>The {$weeknumArr[$data['weeknum']]} {$days[$data['day'] - 1]} of each month</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>For these timeslots on<br>the above day of the month:</TH>\n";
+		print "    <TD>";
+		for($i = 0; $i < 4; $i++) {
+			if($data['stime'][$i] == $data['etime'][$i])
+				continue;
+			if($data['smminute'][$i] == 0)
+				$data['smminute'][$i] = "00";
+			if($data['emminute'][$i] == 0)
+				$data['emminute'][$i] = "00";
+			print "{$data['smhour'][$i]}:{$data['smminute'][$i]} {$data['smmeridian'][$i]} - ";
+			print "{$data['emhour'][$i]}:{$data['emminute'][$i]} {$data['emmeridian'][$i]}<br>\n";
+		}
+		print "</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right nowrap>Starting:</TH>\n";
+		print "    <TD>{$data['smdate']}</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right nowrap>Ending:</TH>\n";
+		print "    <TD>{$data['emdate']}</TD>\n";
+		print "  </TR>\n";
+	}
+	elseif($data['available'] == 'list') {
+		print "  <TR valign=top>\n";
+		print "    <TH align=right>For the following dates and times:</TH>\n";
+		print "    <TD>\n";
+		for($i = 0; $i < 4; $i++) {
+			if($data['slhour'][$i] == $data['elhour'][$i] &&
+			   $data['slminute'][$i] == $data['elminute'][$i] &&
+			   $data['slmeridian'][$i] == $data['elmeridian'][$i])
+				continue;
+			if($data['slminute'][$i] == 0)
+				$data['slminute'][$i] = '00';
+			if($data['elminute'][$i] == 0)
+				$data['elminute'][$i] = '00';
+			print "{$data['date'][$i]} {$data['slhour'][$i]}:{$data['slminute'][$i]} {$data['slmeridian'][$i]} to {$data['elhour'][$i]}:{$data['elminute'][$i]} {$data['elmeridian'][$i]}<br>\n";
+		}
+		print "    </TD>\n";
+		print "  </TR>\n";
+	}
+	print "</table>\n";
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	if($data['state'] == 2) {
+		print "<INPUT type=submit value=Delete>\n";
+		$cont = addContinuationsEntry('submitDeleteBlockRequest', $data, SECINDAY, 0, 0);
+	}
+	else {
+		print "<INPUT type=submit value=Submit>\n";
+		$cont = addContinuationsEntry('submitBlockRequest', $data, SECINDAY, 0, 0);
+	}
+	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "</FORM>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitBlockRequest()
+///
+/// \brief processes submitted block request information
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitBlockRequest() {
+	global $submitErr, $user, $days;
+	$data = processBlockRequestInput();
+	if($submitErr) {
+		newBlockRequest();
+		return;
+	}
+
+	# FIXME need to handle creation of a block time that we're currently in the
+	#    middle of if there wasn't already on we're in the middle of
+	if($data['state'] == 1) {
+		# get blockTime entry for this request if we're in the middle of one
+		$checkCurBlockTime = 0;
+		$query = "SELECT id, "
+		       .        "start, "
+		       .        "end "
+		       . "FROM blockTimes "
+		       . "WHERE start <= NOW() AND "
+		       .       "end > NOW() AND "
+		       .       "blockRequestid = {$data['blockRequestid']}";
+		$qh = doQuery($query, 101);
+		if($row = mysql_fetch_assoc($qh)) {
+			$checkCurBlockTime = 1;
+			$curBlockTime = $row;
+		}
+		# delete entries from blockTimes that start later than now
+		$query = "DELETE FROM blockTimes "
+		       . "WHERE blockRequestid = {$data['blockRequestid']} AND "
+		       .       "start > NOW()";
+		doQuery($query, 101);
+		# delete entries from blockWebDate and blockWebTime
+		$query = "DELETE FROM blockWebDate WHERE blockRequestid = {$data['blockRequestid']}";
+		doQuery($query, 101);
+		$query = "DELETE FROM blockWebTime WHERE blockRequestid = {$data['blockRequestid']}";
+		doQuery($query, 101);
+	}
+
+	if($data['available'] == 'weekly') {
+		$daymask = 0;
+		$startarr = split('/', $data['swdate']);
+		$startdate = "20{$startarr[2]}-{$startarr[0]}-{$startarr[1]}";
+		$startts = datetimeToUnix("20{$startarr[2]}-{$startarr[0]}-{$startarr[1]} 00:00:00");
+		$endarr = split('/', $data['ewdate']);
+		$enddt = "20{$endarr[2]}-{$endarr[0]}-{$endarr[1]} 23:59:59";
+		$enddate = "20{$endarr[2]}-{$endarr[0]}-{$endarr[1]}";
+		$endts = datetimeToUnix($enddt);
+		foreach($data['wdays'] as $day) {
+			$key = array_search($day, $days);
+			$daymask |= (1 << $key);
+		}
+	}
+	elseif($data['available'] == 'monthly') {
+		$startarr = split('/', $data['smdate']);
+		$startdate = "20{$startarr[2]}-{$startarr[0]}-{$startarr[1]}";
+		$startts = datetimeToUnix("20{$startarr[2]}-{$startarr[0]}-{$startarr[1]} 00:00:00");
+		$endarr = split('/', $data['emdate']);
+		$enddt = "20{$endarr[2]}-{$endarr[0]}-{$endarr[1]} 23:59:59";
+		$enddate = "20{$endarr[2]}-{$endarr[0]}-{$endarr[1]}";
+		$endts = datetimeToUnix($enddt);
+		$selectedday = $data['day'];
+	}
+	elseif($data['available'] == 'list') {
+		$last = -1;
+		$enddtArr[-1] = '1970-01-01 00:00:00';
+		for($i = 0; $i < 4; $i++) {
+			$data['slhour24'][$i] = hour12to24($data['slhour'][$i], $data['slmeridian'][$i]);
+			$data['elhour24'][$i] = hour12to24($data['elhour'][$i], $data['elmeridian'][$i]);
+			if(empty($data['date'][$i])) {
+				$startdtArr[$i] = "0000-00-00 00:00:00";
+				$enddtArr[$i] = "0000-00-00 00:00:00";
+			}
+			else {
+				$datearr = explode('/', $data['date'][$i]);
+				$startdtArr[$i] = "20{$datearr[2]}-{$datearr[0]}-{$datearr[1]} {$data['slhour24'][$i]}:{$data['slminute'][$i]}:00";
+				$enddtArr[$i] = "20{$datearr[2]}-{$datearr[0]}-{$datearr[1]} {$data['elhour24'][$i]}:{$data['elminute'][$i]}:00";
+			}
+			if($data['stime'][$i] == $data['etime'][$i])
+				continue;
+			if($startdtArr[$i] != $enddtArr[$i] &&
+			   datetimeToUnix($enddtArr[$last]) < datetimeToUnix($enddtArr[$i])) {
+				$last = $i;
+			}
+		}
+		unset($enddtArr[-1]);
+		$endts = datetimeToUnix($enddtArr[$last]);
+		$enddt = $enddtArr[$last];
+	}
+
+	if($data['state'] == 1) {
+		$query = "UPDATE blockRequest "
+		       . "SET name = '{$data['blockname']}', " 
+		       .     "imageid = {$data['imageid']}, "
+		       .     "numMachines = {$data['machinecnt']}, "
+		       .     "groupid = {$data['usergroupid']}, "
+		       .     "admingroupid = {$data['admingroupid']}, "
+		       .     "repeating = '{$data['available']}', "
+		       .     "expireTime = '$enddt' "
+		       . "WHERE  id = {$data['blockRequestid']}";
+		doQuery($query, 101);
+		$blockreqid = $data['blockRequestid'];
+	}
+	else {
+		$managementnodes = getManagementNodes('future');
+		if(empty($managementnodes))
+			abort(40);
+		$mnid = array_rand($managementnodes);
+		$query = "INSERT INTO blockRequest "
+		       .        "(name, "
+		       .        "imageid, "
+		       .        "numMachines, "
+		       .        "groupid, "
+		       .        "repeating, "
+		       .        "ownerid, "
+		       .        "admingroupid, "
+		       .        "managementnodeid, "
+		       .        "expireTime) "
+		       . "VALUES "
+		       .        "('{$data['blockname']}', "
+		       .        "{$data['imageid']}, "
+		       .        "{$data['machinecnt']}, "
+		       .        "{$data['usergroupid']}, "
+		       .        "'{$data['available']}', "
+		       .        "{$user['id']}, "
+		       .        "{$data['admingroupid']}, "
+		       .        "$mnid, "
+		       .        "'$enddt')";
+		doQuery($query, 101);
+		$qh = doQuery("SELECT LAST_INSERT_ID() FROM blockRequest", 101);
+		if(! $row = mysql_fetch_row($qh)) {
+			abort(380);
+		}
+		$blockreqid = $row[0];
+	}
+
+	if($data['available'] == 'weekly') {
+		$query = "INSERT INTO blockWebDate "
+		       .        "(blockRequestid, "
+		       .        "start, "
+		       .        "end, "
+		       .        "days) "
+		       . "VALUES "
+		       .        "($blockreqid, "
+		       .        "'$startdate', "
+		       .        "'$enddate', "
+		       .        "$daymask)";
+		doQuery($query, 101);
+		for($i = 0; $i < 4; $i++) {
+			$query = "INSERT INTO blockWebTime "
+			       .        "(blockRequestid, "
+			       .        "starthour, "
+			       .        "startminute, "
+			       .        "startmeridian, "
+			       .        "endhour, "
+			       .        "endminute, "
+			       .        "endmeridian, "
+			       .        "`order`) "
+			       . "VALUES "
+			       .        "($blockreqid, "
+			       .        "'{$data['swhour'][$i]}', "
+			       .        "'{$data['swminute'][$i]}', "
+			       .        "'{$data['swmeridian'][$i]}', "
+			       .        "'{$data['ewhour'][$i]}', "
+			       .        "'{$data['ewminute'][$i]}', "
+			       .        "'{$data['ewmeridian'][$i]}', "
+			       .        "$i)";
+			doQuery($query, 101);
+		}
+		for($day = $startts; $day <= $endts; $day += SECINDAY) {
+			if(! in_array(date('l', $day), $data['wdays']))
+				continue;
+			for($i = 0; $i < 4; $i++) {
+				if($data['stime'][$i] == $data['etime'][$i])
+					continue;
+				$data['swhour'][$i] = hour12to24($data['swhour'][$i], $data['swmeridian'][$i]);
+				$data['ewhour'][$i] = hour12to24($data['ewhour'][$i], $data['ewmeridian'][$i]);
+				$start = date("Y-m-d", $day) . " {$data['swhour'][$i]}:{$data['swminute'][$i]}:00";
+				$end = date("Y-m-d", $day) . " {$data['ewhour'][$i]}:{$data['ewminute'][$i]}:00";
+				$query = "INSERT INTO blockTimes "
+				       .        "(blockRequestid, "
+				       .        "start, "
+				       .        "end) "
+				       . "VALUES "
+				       .        "($blockreqid, "
+				       .        "'$start', "
+				       .        "'$end')";
+				doQuery($query, 101);
+			}
+		}
+	}
+	elseif($data['available'] == 'monthly') {
+		$query = "INSERT INTO blockWebDate "
+		       .        "(blockRequestid, "
+		       .        "start, "
+		       .        "end, "
+		       .        "days, "
+		       .        "weeknum) "
+		       . "VALUES "
+		       .        "($blockreqid, "
+		       .        "'$startdate', "
+		       .        "'$enddate', "
+		       .        "$selectedday, "
+		       .        "{$data['weeknum']})";
+		doQuery($query, 101);
+		for($i = 0; $i < 4; $i++) {
+			$query = "INSERT INTO blockWebTime "
+			       .        "(blockRequestid, "
+			       .        "starthour, "
+			       .        "startminute, "
+			       .        "startmeridian, "
+			       .        "endhour, "
+			       .        "endminute, "
+			       .        "endmeridian, "
+			       .        "`order`) "
+			       . "VALUES "
+			       .        "($blockreqid, "
+			       .        "'{$data['smhour'][$i]}', "
+			       .        "'{$data['smminute'][$i]}', "
+			       .        "'{$data['smmeridian'][$i]}', "
+			       .        "'{$data['emhour'][$i]}', "
+			       .        "'{$data['emminute'][$i]}', "
+			       .        "'{$data['emmeridian'][$i]}', "
+			       .        "$i)";
+			doQuery($query, 101);
+		}
+		for($day = $startts; $day <= $endts; $day += SECINDAY) {
+			if((date('w', $day) + 1) != $data['day'])
+				continue;
+			$dayofmon = date('j', $day);
+			if(($data['weeknum'] == 1 && ($dayofmon < 8)) ||
+			   ($data['weeknum'] == 2 && (7 < $dayofmon) && ($dayofmon < 15)) ||
+			   ($data['weeknum'] == 3 && (14 < $dayofmon) && ($dayofmon < 22)) ||
+			   ($data['weeknum'] == 4 && (21 < $dayofmon) && ($dayofmon < 29)) ||
+			   ($data['weeknum'] == 5 && (28 < $dayofmon) && ($dayofmon < 32))) {
+				$thedate = date("Y-m-d", $day);
+				for($i = 0; $i < 4; $i++) {
+					if($data['stime'][$i] == $data['etime'][$i])
+						continue;
+					$data['smhour'][$i] = hour12to24($data['smhour'][$i], $data['smmeridian'][$i]);
+					$data['emhour'][$i] = hour12to24($data['emhour'][$i], $data['emmeridian'][$i]);
+					$start = "$thedate {$data['smhour'][$i]}:{$data['smminute'][$i]}:00";
+					$end = "$thedate {$data['emhour'][$i]}:{$data['emminute'][$i]}:00";
+					$query = "INSERT INTO blockTimes "
+							 .        "(blockRequestid, "
+							 .        "start, "
+							 .        "end) "
+							 . "VALUES "
+							 .        "($blockreqid, "
+							 .        "'$start', "
+							 .        "'$end')";
+					doQuery($query, 101);
+				}
+			}
+		}
+	}
+	elseif($data['available'] == 'list') {
+		for($i = 0; $i < 4; $i++) {
+			$query = "INSERT INTO blockWebDate "
+			       .        "(blockRequestid, "
+			       .        "start, "
+			       .        "end, "
+			       .        "days) "
+			       . "VALUES "
+			       .        "($blockreqid, "
+					 .        "'{$startdtArr[$i]}', "
+					 .        "'{$enddtArr[$i]}', "
+			       .        "$i)";
+			doQuery($query, 101);
+			$query = "INSERT INTO blockWebTime "
+			       .        "(blockRequestid, "
+			       .        "starthour, "
+			       .        "startminute, "
+			       .        "startmeridian, "
+			       .        "endhour, "
+			       .        "endminute, "
+			       .        "endmeridian, "
+			       .        "`order`) "
+			       . "VALUES "
+			       .        "($blockreqid, "
+			       .        "'{$data['slhour'][$i]}', "
+			       .        "'{$data['slminute'][$i]}', "
+			       .        "'{$data['slmeridian'][$i]}', "
+			       .        "'{$data['elhour'][$i]}', "
+			       .        "'{$data['elminute'][$i]}', "
+			       .        "'{$data['elmeridian'][$i]}', "
+			       .        "$i)";
+			doQuery($query, 101);
+			if($data['stime'][$i] == $data['etime'][$i])
+				continue;
+			$query = "INSERT INTO blockTimes "
+					 .        "(blockRequestid, "
+					 .        "start, "
+					 .        "end) "
+					 . "VALUES "
+					 .        "($blockreqid, "
+					 .        "'{$startdtArr[$i]}', "
+					 .        "'{$enddtArr[$i]}')";
+			doQuery($query, 101);
+		}
+	}
+	if($data['state'] == 1) {
+		if($checkCurBlockTime) {
+			$query = "SELECT id, "
+			       .        "start, "
+			       .        "end "
+			       . "FROM blockTimes "
+			       . "WHERE start <= NOW() AND "
+			       .       "end > NOW() AND "
+			       .       "blockRequestid = {$data['blockRequestid']} AND "
+			       .       "id != {$curBlockTime['id']}";
+			$qh = doQuery($query, 101);
+			if($row = mysql_fetch_assoc($qh)) {
+				if($curBlockTime['end'] != $row['end']) {
+					# update old end time
+					$query = "UPDATE blockTimes "
+					       . "SET end = '{$row['end']}' " 
+					       . "WHERE id = {$curBlockTime['id']}";
+					doQuery($query, 101);
+				}
+				# delete $row entry
+				doQuery("DELETE FROM blockTimes WHERE id = {$row['id']}", 101);
+			}
+			else {
+				# the blockTime we were in the middle of was not recreated, so
+				#    delete the old one
+				doQuery("DELETE FROM blockTimes WHERE id = {$curBlockTime['id']}", 101);
+			}
+		}
+		print "<H2>Edit Block Reservation</H2>\n";
+		print "Block request has been updated<br>\n";
+	}
+	else {
+		print "<H2>New Block Reservation</H2>\n";
+		print "Block request added to database<br>\n";
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitDeleteBlockRequest()
+///
+/// \brief delete a block request
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitDeleteBlockRequest() {
+	$data = processBlockRequestInput();
+	$query = "DELETE FROM blockRequest WHERE id = {$data['blockRequestid']}";
+	doQuery($query, 101);
+	print "<H2>Delete Block Reservation</H2>\n";
+	print "Block reservation <strong>{$data['blockname']}</strong> has been deleted.<br>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn printBlockStartEnd($cnt, $type, $shour, $sminute, $smeridian, $ehour,
+///                        $eminute, $emeridian)
+///
+/// \param $cnt - index number for row
+/// \param $type - 'w', 'm', or 'l' to signify week, month, or list
+/// \param $shour - array of input data
+/// \param $sminute - array of input data
+/// \param $smeridian - array of input data
+/// \param $ehour - array of input data
+/// \param $eminute - array of input data
+/// \param $emeridian - array of input data
+///
+/// \brief prints 4 rows of select boxes for start and end times
+///
+////////////////////////////////////////////////////////////////////////////////
+function printBlockStartEnd($cnt, $type, $shour, $sminute, $smeridian, $ehour, $eminute, $emeridian) {
+	$hrArr = array();
+	for($i = 1; $i < 13; $i++) {
+		$hrArr[$i] = $i;
+	}
+	$minutes = array("zero" => "00",
+	                 "15" => "15",
+	                 "30" => "30", 
+	                 "45" => "45");
+	$t_shour = 's' . $type . 'hour[]';
+	$t_sminute = 's' . $type . 'minute[]';
+	$t_smeridian = 's' . $type . 'meridian[]';
+	$t_ehour = 'e' . $type . 'hour[]';
+	$t_eminute = 'e' . $type . 'minute[]';
+	$t_emeridian = 'e' . $type . 'meridian[]';
+	printSelectInput($t_shour, $hrArr, $shour[$cnt]);
+	printSelectInput($t_sminute, $minutes, $sminute[$cnt]);
+	printSelectInput($t_smeridian, array("am" => "am", "pm" => "pm"), $smeridian[$cnt]);
+	print "        </TD>\n";
+	print "        <TD nowrap width=5px></TD>\n";
+	print "        <TD nowrap>\n";
+	printSelectInput($t_ehour, $hrArr, $ehour[$cnt]);
+	printSelectInput($t_eminute, $minutes, $eminute[$cnt]);
+	printSelectInput($t_emeridian, array("am" => "am", "pm" => "pm"), $emeridian[$cnt]);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn printBlockRequestJavascript($show)
+///
+/// \param $show - 'weekly', 'monthly', or 'list'
+///
+/// \brief prints javascript to display the right frameset
+///
+////////////////////////////////////////////////////////////////////////////////
+function printBlockRequestJavascript($show) {
+	print <<<HTMLdone
+<script language="Javascript">
+function show(id) {
+	document.getElementById("weekly").className = "hidden";
+	document.getElementById("monthly").className = "hidden";
+	document.getElementById("list").className = "hidden";
+	document.getElementById(id).className = "shown";
+}
+HTMLdone;
+print "show(\"$show\")\n";
+print "</script>\n";
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn viewRequests
+///
+/// \brief prints user's reservations
+///
+////////////////////////////////////////////////////////////////////////////////
+function viewRequests() {
+	global $user, $viewmode, $inContinuation, $mode;
+	if($inContinuation)
+		$lengthchanged = getContinuationVar('lengthchanged', 0);
+	else
+		$lengthchanged = processInputVar('lengthchanged', ARG_NUMERIC, 0);
+	$incPaneDetails = processInputVar('incdetails', ARG_NUMERIC, 0);
+	$refreqid = processInputVar('reqid', ARG_NUMERIC, 0);
+	$requests = getUserRequests("all");
+	$images = getImages();
+	$computers = getComputers();
+
+	if($mode != 'AJviewRequests')
+		print "<div id=subcontent>\n";
+
+	$refresh = 0;
+	$failed = 0;
+	$connect = 0;
+
+	$normal = '';
+	$imaging = '';
+	$long = '';
+	if($count = count($requests)) {
+		$now = time();
+		for($i = 0, $noedit = 0, $text = '';
+		   $i < $count;
+		   $i++, $noedit = 0, $text = '') {
+			$imageid = $requests[$i]["imageid"];
+			$text .= "  <TR valign=top id=reqrow{$requests[$i]['id']}>\n";
+			if(requestIsReady($requests[$i])) {
+				$connect = 1;
+				# request is ready, print Connect! and End buttons
+				$cdata = array('requestid' => $requests[$i]['id']);
+				$text .= "    <TD>\n";
+				$text .= "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+				$cont = addContinuationsEntry('connectRequest', $cdata, SECINDAY);
+				$text .= "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+				$text .= "      <INPUT type=submit value=\"Connect!\">\n";
+				$text .= "      </FORM>\n";
+				$text .= "    </TD>\n";
+				if($requests[$i]['forimaging']) {
+					$noedit = 1;
+					$text .= "    <TD>\n";
+					$text .= "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+					$cont = addContinuationsEntry('startImage', $cdata);
+					$text .= "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+					$text .= "      <INPUT type=submit value=\"Create\nImage\">\n";
+					$text .= "      </FORM>\n";
+					$text .= "    </TD>\n";
+					$text .= "    <TD>\n";
+					$text .= "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+					$cdata = array('requestid' => $requests[$i]['id']);
+					$cont = addContinuationsEntry('confirmDeleteRequest', $cdata, SECINDAY);
+					$text .= "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+					$text .= "      <INPUT type=submit value=Cancel>\n";
+					$text .= "      </FORM>\n";
+					$text .= "    </TD>\n";
+				}
+				else {
+					$text .= "    <TD>\n";
+					$text .= "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+					$cont = addContinuationsEntry('confirmDeleteRequest', $cdata, SECINDAY);
+					$text .= "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+					$text .= "      <INPUT type=submit value=End>\n";
+					$text .= "      </FORM>\n";
+					$text .= "    </TD>\n";
+				}
+				$startstamp = datetimeToUnix($requests[$i]["start"]);
+			}
+			elseif($requests[$i]["currstateid"] == 5) {
+				# request has failed
+				$cdata = array('requestid' => $requests[$i]['id']);
+				$text .= "    <TD colspan=2 nowrap>\n";
+				$text .= "      <span class=scriptonly>\n";
+				$text .= "      <span class=compstatelink>";
+				$text .= "<a onClick=\"showResStatusPane({$requests[$i]['id']}); ";
+				$text .= "return false;\" href=\"#\">Reservation failed</a></span>\n";
+				$text .= "      </span>\n";
+				$text .= "      <noscript>\n";
+				$text .= "      <span class=scriptoff>\n";
+				$text .= "      <span class=compstatelink>";
+				$text .= "Reservation failed</span>\n";
+				$text .= "      </span>\n";
+				$text .= "      </noscript>\n";
+				$text .= "    </TD>\n";
+				$failed = 1;
+				$noedit = 1;
+			}
+			elseif(datetimeToUnix($requests[$i]["start"]) < $now) {
+				# other cases where the reservation start time has been reached
+				if(($requests[$i]["currstateid"] == 12 &&
+				   $requests[$i]['laststateid'] == 11) ||
+					$requests[$i]["currstateid"] == 11 ||
+					($requests[$i]["currstateid"] == 14 &&
+					$requests[$i]["laststateid"] == 11)) {
+					# request has timed out
+					if($requests[$i]['forimaging'])
+						$text .= "    <TD colspan=3>\n";
+					else
+						$text .= "    <TD colspan=2>\n";
+					$text .= "      <span class=compstatelink>Reservation has ";
+					$text .= "timed out</span>\n";
+					$noedit = 1;
+					$text .= "    </TD>\n";
+				}
+				else {
+					# computer is loading, print Pending... and Delete button
+					$remaining = 1;
+					if($requests[$i]['forimaging'])
+						$noedit = 1;
+					if(isComputerLoading($requests[$i], $computers)) {
+						if(datetimeToUnix($requests[$i]["daterequested"]) >=
+						   datetimeToUnix($requests[$i]["start"])) {
+							$startload = datetimeToUnix($requests[$i]["daterequested"]);
+						}
+						else {
+							$startload = datetimeToUnix($requests[$i]["start"]);
+						}
+						$imgLoadTime = getImageLoadEstimate($imageid);
+						if($imgLoadTime == 0)
+							$imgLoadTime = $images[$imageid]['reloadtime'] * 60;
+						$tmp = ($imgLoadTime - ($now - $startload)) / 60;
+						$remaining = sprintf("%d", $tmp) + 1;
+						if($remaining < 1) {
+							$remaining = 1;
+						}
+					}
+					# computer is loading, print Pending... and Delete button
+					if($requests[$i]['forimaging'])
+						$text .= "    <TD colspan=2>\n";
+					else
+						$text .= "    <TD>\n";
+					$text .= "      <span class=scriptonly>\n";
+					$text .= "      <span class=compstatelink><i>";
+					$text .= "<a onClick=\"showResStatusPane({$requests[$i]['id']}); ";
+					$text .= "return false;\" href=\"#\">Pending...</a></i></span>";
+					$text .= "      </span>\n";
+					$text .= "      <noscript>\n";
+					$text .= "      <span class=scriptoff>\n";
+					$text .= "      <span class=compstatelink>";
+					$text .= "<i>Pending...</i></span>\n";
+					$text .= "      </span>\n";
+					$text .= "      </noscript>\n";
+					$text .= "<br>Est:&nbsp;$remaining&nbsp;min remaining\n";
+					$refresh = 1;
+					$text .= "    </TD>\n";
+					$text .= "    <TD>\n";
+					$text .= "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+					$cdata = array('requestid' => $requests[$i]['id']);
+					$cont = addContinuationsEntry('confirmDeleteRequest', $cdata, SECINDAY);
+					$text .= "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+					$text .= "      <INPUT type=submit value=Delete>\n";
+					$text .= "      </FORM>\n";
+					$text .= "    </TD>\n";
+				}
+			}
+			else {
+				# reservation is in the future
+				$text .= "    <TD></TD>\n";
+				$text .= "    <TD>\n";
+				$text .= "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+				$cdata = array('requestid' => $requests[$i]['id']);
+				$cont = addContinuationsEntry('confirmDeleteRequest', $cdata, SECINDAY);
+				$text .= "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+				$text .= "      <INPUT type=submit value=Delete>\n";
+				$text .= "      </FORM>\n";
+				$text .= "    </TD>\n";
+			}
+			if(! $noedit) {
+				# print edit button
+				$text .= "    <TD align=right>\n";
+				$text .= "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+				$cdata = array('requestid' => $requests[$i]['id']);
+				$cont = addContinuationsEntry('editRequest', $cdata);
+				$text .= "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+				$text .= "      <INPUT type=submit value=Edit>\n";
+				$text .= "      </FORM>\n";
+				$text .= "    </TD>\n";
+			}
+			elseif($requests[$i]['forimaging'] == 0)
+				$text .= "    <TD></TD>\n";
+
+			# print name of image, add (Testing) if it is the test version of an image
+			$text .= "    <TD>" . str_replace("'", "&#39;", $requests[$i]["prettyimage"]);
+			if($requests[$i]["test"])
+				$text .= " (Testing)";
+			$text .= "</TD>\n";
+
+			# print start time
+			if(datetimeToUnix($requests[$i]["start"]) < 
+			   datetimeToUnix($requests[$i]["daterequested"])) {
+				$text .= "    <TD>" . prettyDatetime($requests[$i]["daterequested"]) . "</TD>\n";
+			}
+			else {
+				$text .= "    <TD>" . prettyDatetime($requests[$i]["start"]) . "</TD>\n";
+			}
+
+			# print end time
+			$text .= "    <TD>" . prettyDatetime($requests[$i]["end"]) . "</TD>\n";
+
+			# print date requested
+			$text .= "    <TD>" . prettyDatetime($requests[$i]["daterequested"]) . "</TD>\n";
+
+			if($viewmode == ADMIN_DEVELOPER) {
+				$text .= "    <TD align=center>" . $requests[$i]["id"] . "</TD>\n";
+				$text .= "    <TD align=center>" . $requests[$i]["computerid"] . "</TD>\n";
+				$text .= "    <TD>" . $requests[$i]["IPaddress"] . "</TD>\n";
+				$text .= "    <TD align=center>" . $requests[$i]["currstateid"];
+				$text .= "</TD>\n";
+				$text .= "    <TD align=center>" . $requests[$i]["laststateid"];
+				$text .= "</TD>\n";
+				$text .= "    <TD align=center>";
+				$text .= $computers[$requests[$i]["computerid"]]["stateid"] . "</TD>\n";
+			}
+			$text .= "  </TR>\n";
+			if($requests[$i]['forimaging'])
+				$imaging .= $text;
+			elseif($requests[$i]['longterm'])
+				$long .= $text;
+			else
+				$normal .= $text;
+		}
+	}
+
+	$text = "<H2>Current Reservations</H2>\n";
+	if(! empty($normal)) {
+		if(! empty($imaging) || ! empty($long))
+			$text .= "You currently have the following <strong>normal</strong> reservations:<br>\n";
+		else
+			$text .= "You currently have the following normal reservations:<br>\n";
+		if($lengthchanged) {
+			$text .= "<font color=red>NOTE: The maximum allowed reservation ";
+			$text .= "length for one of these reservations was less than the ";
+			$text .= "length you submitted, and the length of that reservation ";
+			$text .= "has been adjusted accordingly.</font>\n";
+		}
+		$text .= "<table id=reslisttable summary=\"lists reservations you currently have\" cellpadding=5>\n";
+		$text .= "  <TR>\n";
+		$text .= "    <TD colspan=3></TD>\n";
+		$text .= "    <TH>Environment</TH>\n";
+		$text .= "    <TH>Starting</TH>\n";
+		$text .= "    <TH>Ending</TH>\n";
+		$text .= "    <TH>Initially requested</TH>\n";
+		if($viewmode == ADMIN_DEVELOPER) {
+			$text .= "    <TH>Req ID</TH>\n";
+			$text .= "    <TH>Comp ID</TH>\n";
+			$text .= "    <TH>IP address</TH>\n";
+			$text .= "    <TH>Current State</TH>\n";
+			$text .= "    <TH>Last State</TH>\n";
+			$text .= "    <TH>Computer State</TH>\n";
+		}
+		$text .= "  </TR>\n";
+		$text .= $normal;
+		$text .= "</table>\n";
+	}
+	if(! empty($imaging)) {
+		if(! empty($normal))
+			$text .= "<hr>\n";
+		$text .= "You currently have the following <strong>imaging</strong> reservations:<br>\n";
+		$text .= "<table id=imgreslisttable summary=\"lists imaging reservations you currently have\" cellpadding=5>\n";
+		$text .= "  <TR>\n";
+		$text .= "    <TD colspan=3></TD>\n";
+		$text .= "    <TH>Environment</TH>\n";
+		$text .= "    <TH>Starting</TH>\n";
+		$text .= "    <TH>Ending</TH>\n";
+		$text .= "    <TH>Initially requested</TH>\n";
+		$computers = getComputers();
+		if($viewmode == ADMIN_DEVELOPER) {
+			$text .= "    <TH>Req ID</TH>\n";
+			$text .= "    <TH>Comp ID</TH>\n";
+			$text .= "    <TH>IP address</TH>\n";
+			$text .= "    <TH>Current State</TH>\n";
+			$text .= "    <TH>Last State</TH>\n";
+			$text .= "    <TH>Computer State</TH>\n";
+		}
+		$text .= "  </TR>\n";
+		$text .= $imaging;
+		$text .= "</table>\n";
+	}
+	if(! empty($long)) {
+		if(! empty($normal) || ! empty($imaging))
+			$text .= "<hr>\n";
+		$text .= "You currently have the following <strong>long term</strong> reservations:<br>\n";
+		$text .= "<table id=\"longreslisttable\" summary=\"lists long term reservations you currently have\" cellpadding=5>\n";
+		$text .= "  <TR>\n";
+		$text .= "    <TD colspan=3></TD>\n";
+		$text .= "    <TH>Environment</TH>\n";
+		$text .= "    <TH>Starting</TH>\n";
+		$text .= "    <TH>Ending</TH>\n";
+		$text .= "    <TH>Initially requested</TH>\n";
+		$computers = getComputers();
+		if($viewmode == ADMIN_DEVELOPER) {
+			$text .= "    <TH>Req ID</TH>\n";
+			$text .= "    <TH>Comp ID</TH>\n";
+			$text .= "    <TH>IP address</TH>\n";
+			$text .= "    <TH>Current State</TH>\n";
+			$text .= "    <TH>Last State</TH>\n";
+			$text .= "    <TH>Computer State</TH>\n";
+		}
+		$text .= "  </TR>\n";
+		$text .= $long;
+		$text .= "</table>\n";
+	}
+
+	# connect div
+	if($connect) {
+		$text .= "<br><br>Click the <strong>";
+		$text .= "Connect!</strong> button to get further ";
+		$text .= "information about connecting to the reserved system. You must ";
+		$text .= "click the button from a web browser running on the same computer ";
+		$text .= "from which you will be connecting to the remote computer; ";
+		$text .= "otherwise, you may be denied access to the machine.\n";
+	}
+
+	if($refresh) {
+		$text .= "<br><br>This page will automatically update ";
+		$text .= "every 20 seconds until the <font color=red><i>Pending...</i>";
+		#$text .= "</font> reservation is ready.<br></div>\n";
+		$text .= "</font> reservation is ready.\n";
+		$cont = addContinuationsEntry('AJviewRequests', $cdata, SECINDAY);
+		$text .= "<INPUT type=hidden id=resRefreshCont value=\"$cont\">\n";
+	}
+
+	if($failed) {
+		$text .= "<br><br>An error has occurred that has kept one of your reservations ";
+		$text .= "from being processed. We apologize for any inconvenience ";
+		$text .= "this may have caused.\n";
+		if(! $refresh) {
+			$cont = addContinuationsEntry('AJviewRequests', $cdata, SECINDAY);
+			$text .= "<INPUT type=hidden id=resRefreshCont value=\"$cont\">\n";
+		}
+	}
+
+	if(empty($normal) && empty($imaging) && empty($long))
+		$text .= "You have no current reservations.<br>\n";
+
+	$text .= "</div>\n";
+	if($mode != 'AJviewRequests') {
+		if($refresh || $failed) {
+			$text .= "<div dojoType=FloatingPane\n";
+			$text .= "      id=resStatusPane\n";
+			$text .= "      constrainToContainer=false\n";
+			$text .= "      hasShadow=true\n";
+			$text .= "      resizable=true\n";
+			$text .= "      windowState=minimized\n";
+			$text .= "      displayMinimizeAction=true\n";
+			$text .= "      style=\"width: 350px; height: 280px; position: absolute; left: 130; top: 0px;\"\n";
+			$text .= ">\n";
+			$text .= "<div id=resStatusText></div>\n";
+			$text .= "<input type=hidden id=detailreqid value=0>\n";
+			$text .= "</div>\n";
+			$text .= "<script type=\"text/javascript\">\n";
+			$text .= "dojo.addOnLoad(showScriptOnly);\n";
+			$text .= "dojo.byId('resStatusPane').title = \"Detailed Reservation Status\";\n";
+			$text .= "</script>\n";
+		}
+		print $text;
+	}
+	else {
+		$text = str_replace("\n", ' ', $text);
+		if($refresh)
+			print "refresh_timer = setTimeout(resRefresh, 20000);\n";
+		print(setAttribute('subcontent', 'innerHTML', $text));
+		print "AJdojoCreate('subcontent');";
+		if($incPaneDetails) {
+			$text = detailStatusHTML($refreqid);
+			print(setAttribute('resStatusText', 'innerHTML', $text));
+		}
+		dbDisconnect();
+		exit;
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn detailStatusHTML($reqid)
+///
+/// \param $reqid - a request id
+///
+/// \return html text showing detailed status from computerloadlog for specified
+/// request
+///
+/// \brief gathers information about the state flow for $reqid and formats it
+/// nicely for a user to view
+///
+////////////////////////////////////////////////////////////////////////////////
+function detailStatusHTML($reqid) {
+	$requests = getUserRequests("all");
+	$found = 0;
+	foreach($requests as $request) {
+		if($request['id'] == $reqid) {
+			$found = 1;
+			break;
+		}
+	}
+	if(! $found) {
+		$text  = "The selected reservation is no longer available.  Go to ";
+		$text .= "<a href=" . BASEURL . SCRIPT . "?mode=newRequest>New ";
+		$text .= "Reservations</a> to request a new reservation or ";
+		$text .= "select another one that is available.";
+		return $text;
+	}
+	if($request['imageid'] == $request['compimageid'])
+		$nowreq = 1;
+	else
+		$nowreq = 0;
+	$flow = getCompStateFlow($request['computerid']);
+
+	# cluster reservations not supported here yet
+	if(empty($flow) || count($request['reservations']) > 0) {
+		$noinfo =  "No detailed loading information is available for this ";
+		$noinfo .= "reservation.";
+		return $noinfo;
+	}
+
+	$logdata = getCompLoadLog($request['resid']);
+
+	# determine an estimated load time for the image
+	$imgLoadTime = getImageLoadEstimate($request['imageid']);
+	if($imgLoadTime == 0) {
+		$images = getImages(0, $request['imageid']);
+		$imgLoadTime = $images[$request['imageid']]['reloadtime'] * 60;
+	}
+	$time = 0;
+	$now = time();
+	$text = "<table summary=\"displays a list of states the reservation must "
+	      . "go through to become ready and how long each state will take or "
+			. "has already taken\">";
+	$text .= "<tr>";
+	$text .= "<th align=right><br>State</th>";
+	$text .= "<th>Est/Act<br>Time</th>";
+	$text .= "<th>Total<br>Time</th>";
+	$text .= "</tr>";
+
+	$slash = "<font color=black>/</font>";
+	$total = 0;
+	$id = "";
+	$last = array();
+	$logstateids = array();
+	$skippedstates = array();
+	# loop through all states in the log data
+	foreach($logdata as $data) {
+		# keep track of the states in the log data
+		array_push($logstateids, $data['loadstateid']);
+		# keep track of any skipped states
+		if(! empty($last) &&
+			$last['loadstateid'] != $flow['repeatid'] &&
+		   $data['loadstateid'] != $flow['data'][$last['loadstateid']]['nextstateid']) {
+			array_push($skippedstates, $flow['data'][$last['loadstateid']]['nextstateid']);
+		}
+		// if we reach a repeat state, include a message about having to go back
+		if($data['loadstateid'] == $flow['repeatid']) {
+			if(empty($id))
+				return $noinfo;
+			$text .= "<tr>";
+			$text .= "<td colspan=3><hr>problem at state ";
+			$text .= "\"{$flow['data'][$id]['nextstate']}\"";
+			$query = "SELECT additionalinfo "
+			       . "FROM computerloadlog "
+			       . "WHERE loadstateid = {$flow['repeatid']} AND "
+			       .       "reservationid = {$request['resid']} AND "
+			       .       "timestamp = '" . unixToDatetime($data['ts']) . "'";
+			$qh = doQuery($query, 101);
+			if($row = mysql_fetch_assoc($qh)) {
+				$reason = $row['additionalinfo'];
+				$text .= "<br>retrying at state \"$reason\"";
+			}
+			$text .= "<hr></td></tr>";
+			$total += $data['time'];
+			$last = $data;
+			continue;
+		}
+		$id = $data['loadstateid'];
+		// if in post config state, compute estimated time for the state
+		if($flow['data'][$id]['statename'] == 'loadimagecomplete') {
+			$addtime = 0;
+			foreach($skippedstates as $stateid)
+				$addtime += $flow['data'][$stateid]['statetime'];
+			# this state's time is (avg image load time - all other states time +
+			#                       state time for any skipped states)
+			$tmp = $imgLoadTime - $flow['totaltime'] + $addtime;
+			if($tmp < 0)
+				$flow['data'][$id]['statetime'] = 0;
+			else
+				$flow['data'][$id]['statetime'] = $tmp;
+		}
+		$total += $data['time'];
+		$text .= "<tr>";
+		$text .= "<td nowrap align=right><font color=green>";
+		$text .= "{$flow['data'][$id]['state']}($id)</font></td>";
+		$text .= "<td nowrap align=center><font color=green>";
+		$text .= secToMinSec($flow['data'][$id]['statetime']) . $slash;
+		$text .= secToMinSec($data['time']) . "</font></td>";
+		$text .= "<td nowrap align=center><font color=green>";
+		$text .= secToMinSec($total) . "</font></td>";
+		$text .= "</tr>";
+		$last = $data;
+	}
+	# $id will be set if there was log data, use the first state in the flow
+	#    if it isn't set
+	if(! empty($id))
+		$id = $flow['nextstates'][$id];
+	else
+		$id = $flow['stateids'][0];
+
+	# determine any skipped states
+	$matchingstates = array();
+	foreach($flow['stateids'] as $stateid) {
+		if($stateid == $id)
+			break;
+		array_push($matchingstates, $stateid);
+	}
+	$skippedstates = array_diff($matchingstates, $logstateids);
+	$addtime = 0;
+	foreach($skippedstates as $stateid)
+		$addtime += $flow['data'][$stateid]['statetime'];
+
+	$first = 1;
+	$count = 0;
+	# loop through the states in the flow that haven't been reached yet
+	# $count is included to protect against an infinite loop
+	while(! is_null($id) && $count < 100) {
+		$count++;
+		// if in post config state, compute estimated time for the state
+		if($flow['data'][$id]['statename'] == 'loadimagecomplete') {
+			# this state's time is (avg image load time - all other states time +
+			#                       state time for any skipped states)
+			$tmp = $imgLoadTime - $flow['totaltime'] + $addtime;
+			if($tmp < 0)
+				$flow['data'][$id]['statetime'] = 0;
+			else
+				$flow['data'][$id]['statetime'] = $tmp;
+		}
+		// if first time through this loop, this is the current state
+		if($first) {
+			// if request has failed, it was during this state, get reason
+			if($request['currstateid'] == 5) {
+				$query = "SELECT additionalInfo, "
+				       .        "UNIX_TIMESTAMP(timestamp) AS ts "
+				       . "FROM computerloadlog "
+				       . "WHERE loadstateid = (SELECT id "
+				       .                      "FROM computerloadstate "
+				       .                      "WHERE loadstatename = 'failed') AND "
+				       . "reservationid = {$request['resid']} "
+				       . "ORDER BY id "
+				       . "LIMIT 1";
+				$qh = doQuery($query, 101);
+				if($row = mysql_fetch_assoc($qh)) {
+					$reason = $row['additionalInfo'];
+					if(! empty($data))
+						$currtime = $row['ts'] - $data['ts'];
+					else
+						$currtime = $row['ts'] -
+						            datetimeToUnix($request['daterequested']);
+				}
+				else {
+					$text  = "No detailed information is available for this ";
+					$text .= "reservation.";
+					return $text;
+				}
+				$text .= "<tr>";
+				$text .= "<td nowrap align=right><font color=red>";
+				$text .= "{$flow['data'][$id]['state']}($id)</font></td>";
+				$text .= "<td nowrap align=center><font color=red>";
+				$text .= secToMinSec($flow['data'][$id]['statetime']);
+				$text .= $slash . secToMinSec($currtime) . "</font></td>";
+				$text .= "<td nowrap align=center><font color=red>";
+				$text .= secToMinSec($total + $currtime) . "</font></td>";
+				$text .= "</tr>";
+				$text .= "</table>";
+				if(strlen($reason))
+					$text .= "<br><font color=red>failed: $reason</font>";
+				return $text;
+			}
+			# otherwise add text about current state
+			else {
+				if(! empty($data))
+					$currtime = $now - $data['ts'];
+				else
+					$currtime = $now - datetimeToUnix($request['daterequested']);
+				$text .= "<td nowrap align=right><font color=#CC8500>";
+				$text .= "{$flow['data'][$id]['state']}($id)</font></td>";
+				$text .= "<td nowrap align=center><font color=#CC8500>";
+				$text .= secToMinSec($flow['data'][$id]['statetime']);
+				$text .= $slash . secToMinSec($currtime) . "</font></td>";
+				$text .= "<td nowrap align=center><font color=#CC8500>";
+				$text .= secToMinSec($total + $currtime) . "</font></td>";
+				$text .= "</tr>";
+				$first = 0;
+			}
+		}
+		# add text about future states
+		else {
+			$text .= "<td nowrap align=right>{$flow['data'][$id]['state']}($id)";
+			$text .= "</td>";
+			$text .= "<td nowrap align=center>";
+			$text .= secToMinSec($flow['data'][$id]['statetime']) . "</td>";
+			$text .= "<td></td>";
+			$text .= "</tr>";
+		}
+		$id = $flow['nextstates'][$id];
+	}
+	$text .= "</table>";
+	return $text;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn viewRequestInfo()
+///
+/// \brief prints a page with information about a specific request
+///
+////////////////////////////////////////////////////////////////////////////////
+function viewRequestInfo() {
+	$requestid = processInputVar("requestid", ARG_NUMERIC);
+	$request = getRequestInfo($requestid);
+	foreach($request["reservations"] as $res) {
+		if($res["forcheckout"]) {
+			$prettyimage = $res["prettyimage"];
+			break;
+		}
+	}
+	$states = getStates();
+	$userinfo = getUserInfo($request["userid"]);
+	print "<DIV align=center>\n";
+	print "<H2>View Reservation</H2>\n";
+	print "<table summary=\"\">\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Unity&nbsp;ID:</TH>\n";
+	print "    <TD>" . $userinfo["unityid"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Requested&nbsp;Image:</TH>\n";
+	print "    <TD>$prettyimage</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Start&nbsp;Time:</TH>\n";
+	if(datetimeToUnix($request["start"]) < 
+	   datetimeToUnix($request["daterequested"])) {
+		print "    <TD>" . prettyDatetime($request["daterequested"]) . "</TD>\n";
+	}
+	else {
+		print "    <TD>" . prettyDatetime($request["start"]) . "</TD>\n";
+	}
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>End&nbsp;Time:</TH>\n";
+	print "    <TD>" . prettyDatetime($request["end"]) . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Current&nbsp;State:</TH>\n";
+	print "    <TD>" . $states[$request["stateid"]] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Last&nbsp;State:</TH>\n";
+	print "    <TD>";
+	if($request["laststateid"]) {
+		print $states[$request["laststateid"]];
+	}
+	else {
+		print "None";
+	}
+	print "</TD>\n";
+	print "  </TR>\n";
+	foreach($request["reservations"] as $res) {
+		print "  <TR>\n";
+		print "    <TH align=right>Computer&nbsp;ID:</TH>\n";
+		print "    <TD>" . $res["computerid"] . "</TD>\n";
+		print "  </TR>\n";
+	}
+	print "  <TR>\n";
+	print "    <TH align=right>Request&nbsp;Time:</TH>\n";
+	print "    <TD>" . prettyDatetime($request["daterequested"]) . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Last&nbsp;Modified:</TH>\n";
+	if(! empty($request["datemodified"])) {
+		print "    <TD>" . prettyDatetime($request["datemodified"]) . "</TD>\n";
+	}
+	else {
+		print "    <TD>Never Modified</TD>\n";
+	}
+	print "  </TR>\n";
+	print "</table>\n";
+	print "<table summary=\"\">\n";
+	print "  <TR>\n";
+	/*print "    <TD>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "      <INPUT type=hidden name=mode value=adminEditRequest>\n";
+	print "      <INPUT type=hidden name=requestid value=$requestid>\n";
+	print "      <INPUT type=submit value=Modify>\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";*/
+	print "    <TD>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cdata = array('requestid' => $requestid);
+	$cont = addContinuationsEntry('confirmDeleteRequest', $cdata, SECINDAY);
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=\"Delete Reservation\">\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</table>\n";
+	print "</DIV>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn editRequest()
+///
+/// \brief prints a page for a user to edit a previous request
+///
+////////////////////////////////////////////////////////////////////////////////
+function editRequest() {
+	global $submitErr, $user;
+	$requestid = getContinuationVar('requestid', 0);
+	$request = getRequestInfo($requestid);
+	if(! array_key_exists("stateid", $request)) {
+		viewRequests();
+		return;
+	}
+	foreach($request["reservations"] as $res) {
+		if($res["forcheckout"]) {
+			$reservation = $res;
+			break;
+		}
+	}
+	if($submitErr) {
+		$data = processRequestInput(0);
+	}
+	// NCSU code
+	$groupid = getUserGroupID('Specify End Time', 1);
+	$members = getUserGroupMembers($groupid);
+	if(array_key_exists($user['id'], $members))
+		$openend = 1;
+	else
+		$openend = 0;
+	// end NCSU code
+	$unixstart = datetimeToUnix($request["start"]);
+	$unixend = datetimeToUnix($request["end"]);
+	$maxtimes = getUserMaxTimes("initialmaxtime");
+	$timeToNext = timeToNextReservation($request);
+
+	print "<H2>Modify Reservation</H2>\n";
+	$now = time();
+	if($unixstart > $now)
+		$started = 0;
+	else {
+		# \todo if $timeToNext is anything < 30, try moving reservations off until it is >= 30
+		if($timeToNext == 0) {
+			$movedall = 1;
+			foreach($request["reservations"] as $res) {
+				if(! moveReservationsOffComputer($res["computerid"], 1)) {
+					$movedall = 0;
+					break;
+				}
+			}
+			if(! $movedall) {
+				// cannot extend the reservation unless we move the next one to another computer
+				print "The computer you are using has another reservation ";
+				print "immediately following yours. Therefore, you cannot extend ";
+				print "your reservation because it would overlap with the next ";
+				print "one.<br>\n";
+				return;
+			}
+			$timeToNext = timeToNextReservation($request);
+		}
+		$started = 1;
+		print "Because this reservation has already started, you can only ";
+		print "extend the length of the reservation. ";
+		if(! $openend) {
+			print "If there are no reservations following yours, ";
+			print "you can extend your reservation ";
+			print "by up to " . minToHourMin($maxtimes["extend"]) . ", but not ";
+			print "exceeding " . minToHourMin($maxtimes["total"]) . " for your ";
+			print "total reservation time.<br><br>\n";
+		}
+	}
+	print "Modify reservation for <b>" . $reservation["prettyimage"];
+	print "</b> starting ";
+	if(datetimeToUnix($request["start"]) <
+	   datetimeToUnix($request["daterequested"])) {
+		print prettyDatetime($request["daterequested"]);
+	}
+	else {
+		print prettyDatetime($request["start"]);
+	}
+	print ":<br><br>\n";
+	$start = date('l,g,i,a', datetimeToUnix($request["start"]));
+	$startArr = explode(',', $start);
+	$len = ($unixend - $unixstart) / 60;
+	$cdata = array();

[... 1683 lines stripped ...]