This is an automated email from the ASF dual-hosted git repository.

jfthomps pushed a commit to branch VCL-1114_misc_small_web_updates
in repository https://gitbox.apache.org/repos/asf/vcl.git

commit 48065f2ebb4154288e6f2e0c7150d79b84058899
Author: Josh Thompson <[email protected]>
AuthorDate: Tue May 7 10:24:13 2019 -0400

    VCL-1114 - miscellaneous small web updates
    
    code.js: cleaned up whitespace
    
    dashboard.js: modified updateNewReservations: added VM Host to displayed 
data
    
    requests.js: cleaned up whitespace
    
    computer.js:
    -added Computer.prototype.ipsort: correctly sorts IP addresses
    -modified initPage: set resourcestore.comparatorMap for IPaddress and 
privateIPaddress to ipsort
    -modified refreshcompdata: set resourcestore.comparatorMap for IPaddress 
and privateIPaddress to ipsort
    
    image.js:
    -added initAddDialog: sets adauthenable checkbox to be disabled if user has 
no access to AD Domains
    -modified submitCreateUpdateImage: added call to initAddDialog when adding 
a new image
    
    vm.js:
    -modified VMtoHostCB, vmFromHostCB, and reloadVMhostCB to check for 
data.items.failed being 'invaliddata'
    -modified vmFromHost: cleaned up whitespace
    
    index.php: cleaned up initialization of $user, $mysqli_link_vcl, and 
$mysqli_link_acct
    
    blockallocations.php:
    -modified getCurrentBlockHTML: increased width of viewtimesDialog DataGrid
    -modified getUserCurrentBlockHTML: increased width of viewtimesDialog 
DataGrid and Date, Start, and End inputs
    -modified processBlockAllocationInput: added regular expression match for 
$slots
    
    computer.php:
    -modified AJsubmitCompProvisioningChange: updated query to ignore 
reservations in 'complete' state; added check for $nowids being empty; 
initialized $msg before conditionals
    -modified AJshowReservationHistory: added Request ID and IP Address to 
returned data
    
    conf-default.php: changed calls to create_function to use function() instead
    
    dashboard.php:
    -modified dashboard: added 3rd argument for call to addWidget for status to 
alert users to hover over items for a description
    -modified getStatusData: added 'Active Short Reservations'; added tooltip 
for 'Active Reservations'; added queries to get count of active reservations 
less than 24 hours in duration
    -modified getNewReservationData: added vmhost to returned data
    
    doxyfile.xmlrpc: removed Doxygen generated comments (there was some 
discussion on one of the ASF lists that including the comments was a license 
violation since Doxygen is GPL licensed)
    
    help.php:
    -modified submitHelpForm:
      -updated NAMEERR message to state that both first and last names need to 
be specified
      -updated calls to prettyDatetime to remove 2nd and 3rd arguments
      -added login history to email message
      -added call to getHelpEmail to get email address to send message to
    -added getHelpEmail: gets help email address for specified affiliation
    
    image.php:
    -modified addEditDialogHTML: removed width specifications for description, 
usage, and imgcomments textareas and advancedoptions TitlePane; added "(MB)" 
after "Required RAM" so users know correct units
    -modified validateResourceData: added default value of 0 for 
maxinitialtime; changed check of $return['addomainid'] not matching 
$extraaddomainid from != to !==
    
    privileges.php:
    -modified viewNodes: cleaned up old code at top of function
    -modified userLookup: added Max Overlapping Reservations and owned images 
to displayed user data
    
    requests.php:
    -modified viewRequests: added checks to prevent image capture options from 
being displayed for images with OSinstalltype 'none'
    -moved AJfetchRouterDNS from serverprofiles.php to here
    -modified AJnewRequest and AJsubmitEditRequest: removed MAC address 
references from error message returned when $availablerc == -3 since MAC 
address cannot be specified
    -modified AJsetImageProduction and AJsubmitSetImageProduction: set 
$prettyimage based on the first entry in $data['reservations'] when processing 
an imaging reservation
    
    resource.php: modified AJstartImage: added addomainvals to returned data
    
    serverprofiles.php: moved AJfetchRouterDNS from here to requests.php
    
    states.php:
    -uncommented AJfetchRouterDNS from $noHTMLwrappers
    -moved AJfetchRouterDNS $action array entries from serverProfiles to 
reservations
    
    statistics.php: modified viewStatistics: added OS type to statistics of 
each image
    
    utils.php:
    -modified initGlobals:
      -removed global references to $semid, $AUTHERROR
      -added global reference to $submitErr and $submitErrMsg
      -corrected typo: changed $crytpkey -> $cryptkey
      -changed calls to create_function to use function() instead
    -modified checkAccess
      -removed global references to $noHTMLwrappers, $docreaders
      -added check for HTTP_X_USER not being submitted for xmlrpccall
    -modified maintenanceCheck: changed call to fgetss to fgets and added 
separate call to strip_tags
    -modified main: removed global reference to $mode
    -modified abort: changed font tag setting color to red to use span with 
class of rederrormsg
    -modified getUserResources: removed initialization of $return to array()
    -modified encryptSecretKey and decryptSecretKey: changed calls to 
create_function to use function() instead
    -modified getUserInfo: removed initialization of $user to array()
    -modified updateUserData: removed $type as it wasn't used
    -modified isAvailable: added additional return when check for enough RAM on 
hosts results in no VMs available; changed debug reference number for case of 
IP address already being in use as 18 was already used elsewhere
    -modified debugIsAvailable: removed global reference to $user; changed case 
id for IP address already being in use from 18 to 24; added case 23
    -modified allocComputer: removed global reference to $requestInfo
    -modified checkOverlap: removed global reference to $user
    -modified addRequest: removed setting $qh from call to doQuery when doing 
insert
    -modified findManagementNode: removed global reference to $HTMLheader
    -modified deleteRequest: removed setting $qh from call to doQuery when 
doing update
    -modified moveReservationsOffComputer: removed global reference to $user
    -removed getDepartmentName
    -modified getMnsFromImage: removed outer foreach when getting mapped 
managementnode groups as the data from it wasn't used and just caused the 3 
lines in it to be run multiple times with the same data
    -modified findAvailableTimes: modified query finding slots available after 
reservations over to ignore reservations in failed, complete, or reload
    -modified sendHeaders: removed global reference to $oldmode
    -modified printHTMLHeader: removed global references to $oldmode, 
$docreaders, and $actions
    -modified getDojoHTML: removed commented out case for serverProfiles; 
removed commented out call to populateProfileStore for viewRequests case
    
    vm.php:
    -modified vmhostdata: removed continuation for AJchangeVMprofile from 
returned data since it is not used
    -modified AJvmToHost, AJvmFromHost, AJcancelVMmove, and AJnewProfile: 
cleaned up old code at top of each function
    
    xmlrpcWrappers.php: cleaned up whitespace
    
    ldapauth.php: changed call to create_function to use function() instead
---
 web/.ht-inc/authmethods/ldapauth.php |   2 +-
 web/.ht-inc/blockallocations.php     |  66 ++++++++++---------
 web/.ht-inc/computer.php             |  28 +++++---
 web/.ht-inc/conf-default.php         |   6 +-
 web/.ht-inc/dashboard.php            |  47 +++++++++++---
 web/.ht-inc/doxyfile.xmlrpc          |  54 ----------------
 web/.ht-inc/help.php                 |  97 ++++++++++++++++++++++++++--
 web/.ht-inc/image.php                |  20 +++---
 web/.ht-inc/privileges.php           |  37 ++++++++++-
 web/.ht-inc/requests.php             |  74 +++++++++++++++++----
 web/.ht-inc/resource.php             |   5 ++
 web/.ht-inc/serverprofiles.php       |  39 -----------
 web/.ht-inc/states.php               |  10 +--
 web/.ht-inc/statistics.php           |  11 +++-
 web/.ht-inc/utils.php                | 122 ++++++++++++-----------------------
 web/.ht-inc/vm.php                   |  19 ++++--
 web/.ht-inc/xmlrpcWrappers.php       |  62 +++++++++---------
 web/index.php                        |   4 +-
 web/js/code.js                       |   2 +-
 web/js/dashboard.js                  |   3 +
 web/js/requests.js                   |   8 +--
 web/js/resources/computer.js         |  32 ++++++++-
 web/js/resources/image.js            |   7 ++
 web/js/vm.js                         |  16 +++--
 24 files changed, 464 insertions(+), 307 deletions(-)

diff --git a/web/.ht-inc/authmethods/ldapauth.php 
b/web/.ht-inc/authmethods/ldapauth.php
index 1c2ee53..3848ebe 100644
--- a/web/.ht-inc/authmethods/ldapauth.php
+++ b/web/.ht-inc/authmethods/ldapauth.php
@@ -257,7 +257,7 @@ function addLDAPUser($authtype, $userid) {
 function validateLDAPUser($type, $loginid) {
        global $authMechs;
        $auth = $authMechs[$type];
-       $savehdlr = set_error_handler(create_function('', ''));
+       $savehdlr = set_error_handler(function() {});
        if(! ($fh = fsockopen($auth['server'], 636, $errno, $errstr, 5)))
                return -1;
        set_error_handler($savehdlr);
diff --git a/web/.ht-inc/blockallocations.php b/web/.ht-inc/blockallocations.php
index 9bf25e2..ed0fffa 100644
--- a/web/.ht-inc/blockallocations.php
+++ b/web/.ht-inc/blockallocations.php
@@ -1448,15 +1448,15 @@ function getCurrentBlockHTML($listonly=0) {
        $rt .= "title=\"" . i("Block Allocation Times") . "\">\n";
        $rt .= "<h2>" . i("Block Allocation Times") . "</h2>\n";
        $rt .= "<table dojoType=\"dojox.grid.DataGrid\" jsId=\"blockTimesGrid\" 
sortInfo=1 ";
-       $rt .= "style=\"width: 278px; height: 200px;\">\n";
+       $rt .= "style=\"width: 328px; height: 200px;\">\n";
        $rt .= "<script type=\"dojo/method\" event=\"onStyleRow\" 
args=\"row\">\n";
        $rt .= "blockTimeRowStyle(row);\n";
        $rt .= "</script>\n";
        $rt .= "<thead>\n";
        $rt .= "<tr>\n";
-       $rt .= "<th field=\"start\" width=\"65px\" 
formatter=\"blockTimesGridDate\">" . i("Date") . "</th>\n";
-       $rt .= "<th field=\"start\" width=\"54px\" 
formatter=\"blockTimesGridStart\">" . i("Start") . "</th>\n";
-       $rt .= "<th field=\"end\" width=\"54px\" 
formatter=\"blockTimesGridEnd\">" . i("End") . "</th>\n";
+       $rt .= "<th field=\"start\" width=\"70px\" 
formatter=\"blockTimesGridDate\">" . i("Date") . "</th>\n";
+       $rt .= "<th field=\"start\" width=\"85px\" 
formatter=\"blockTimesGridStart\">" . i("Start") . "</th>\n";
+       $rt .= "<th field=\"end\" width=\"85px\" 
formatter=\"blockTimesGridEnd\">" . i("End") . "</th>\n";
        $rt .= "<th field=\"delbtn\" width=\"60px\">" . i("Skip") . "</th>\n";
        $rt .= "</tr>\n";
        $rt .= "</thead>\n";
@@ -1741,17 +1741,17 @@ function getUserCurrentBlockHTML($listonly=0) {
        $rt .= i("Block Allocation Times") . "\">\n";
        $rt .= "<h2>" . i("Block Allocation Times") . "</h2>\n";
        $rt .= "<table dojoType=\"dojox.grid.DataGrid\" jsId=\"blockTimesGrid\" 
sortInfo=1 ";
-       $rt .= "style=\"width: 278px; height: 200px;\">\n";
+       $rt .= "style=\"width: 328px; height: 200px;\">\n";
        $rt .= "<script type=\"dojo/method\" event=\"onStyleRow\" 
args=\"row\">\n";
        $rt .= "blockTimeRowStyle(row);\n";
        $rt .= "</script>\n";
        $rt .= "<thead>\n";
        $rt .= "<tr>\n";
-       $rt .= "<th field=\"start\" width=\"60px\" 
formatter=\"blockTimesGridDate\">";
+       $rt .= "<th field=\"start\" width=\"70px\" 
formatter=\"blockTimesGridDate\">";
        $rt .= i("Date") . "</th>\n";
-       $rt .= "<th field=\"start\" width=\"54px\" 
formatter=\"blockTimesGridStart\">";
+       $rt .= "<th field=\"start\" width=\"85px\" 
formatter=\"blockTimesGridStart\">";
        $rt .= i("Start") . "</th>\n";
-       $rt .= "<th field=\"end\" width=\"54px\" 
formatter=\"blockTimesGridEnd\">";
+       $rt .= "<th field=\"end\" width=\"85px\" 
formatter=\"blockTimesGridEnd\">";
        $rt .= i("End") . "</th>\n";
        $rt .= "<th field=\"delbtn\" width=\"60px\">" . i("Skip") . "</th>\n";
        $rt .= "</tr>\n";
@@ -3133,35 +3133,41 @@ function processBlockAllocationInput() {
        if(! $err) {
                if($type == 'list') {
                        $slots = processInputVar('slots', ARG_STRING);
-                       $return['slots'] = explode(',', $slots);
+                       if(! 
preg_match('/^(\d{8}\|\d{2}:\d{2}\|\d{2}:\d{2})(,(\d{8}\|\d{2}:\d{2}\|\d{2}:\d{2}))*$/',
 $slots)) {
+                               $errmsg = i("Invalid time slot submitted.");
+                               $err = 1;
+                       }
                        $return['times'] = array();
-                       $lastdate = array('day' => '', 'ts' => 0);
-                       foreach($return['slots'] as $slot) {
-                               $tmp = explode('|', $slot);
-                               if(count($tmp) != 3) {
-                                       $errmsg = i("Invalid date/time 
submitted.");
-                                       $err = 1;
-                                       break;
-                               }
-                               $date = $tmp[0];
-                               if(! $err) {
-                                       $datets = strtotime($date);
-                                       if($method != 'edit' && $datets < 
(time() - SECINDAY)) {
-                                               $errmsg = i("The date must be 
today or later.");
+                       if(! $err) {
+                               $return['slots'] = explode(',', $slots);
+                               $lastdate = array('day' => '', 'ts' => 0);
+                               foreach($return['slots'] as $slot) {
+                                       $tmp = explode('|', $slot);
+                                       if(count($tmp) != 3) {
+                                               $errmsg = i("Invalid date/time 
submitted.");
                                                $err = 1;
                                                break;
                                        }
+                                       $date = $tmp[0];
+                                       if(! $err) {
+                                               $datets = strtotime($date);
+                                               if($method != 'edit' && $datets 
< (time() - SECINDAY)) {
+                                                       $errmsg = i("The date 
must be today or later.");
+                                                       $err = 1;
+                                                       break;
+                                               }
+                                       }
+                                       $return['times'][] = 
"{$tmp[1]}|{$tmp[2]}";
+                                       if($datets > $lastdate['ts']) {
+                                               $lastdate['ts'] = $datets;
+                                               $lastdate['day'] = $date;
+                                       }
                                }
-                               $return['times'][] = "{$tmp[1]}|{$tmp[2]}";
-                               if($datets > $lastdate['ts']) {
-                                       $lastdate['ts'] = $datets;
-                                       $lastdate['day'] = $date;
+                               if(! $err) {
+                                       $expirets = 
strtotime("{$lastdate['day']} 23:59:59");
+                                       $return['expiretime'] = 
unixToDatetime($expirets);
                                }
                        }
-                       if(! $err) {
-                               $expirets = strtotime("{$lastdate['day']} 
23:59:59");
-                               $return['expiretime'] = 
unixToDatetime($expirets);
-                       }
                }
                if($type == 'weekly' || $type == 'monthly') {
                        $return['startdate'] = processInputVar('startdate', 
ARG_NUMERIC);
diff --git a/web/.ht-inc/computer.php b/web/.ht-inc/computer.php
index 3a9e117..b67a75a 100644
--- a/web/.ht-inc/computer.php
+++ b/web/.ht-inc/computer.php
@@ -4280,27 +4280,33 @@ class Computer extends Resource {
 
                $query = "SELECT rs.computerid "
                       . "FROM request rq, "
-                      .      "reservation rs "
+                      .      "reservation rs, "
+                      .      "state s "
                       . "WHERE rs.requestid = rq.id AND "
+                      .       "rq.stateid = s.id AND "
                       .       "rs.computerid IN ($allids) AND "
                       .       "rq.start <= '$startcheckdt' AND "
-                      .       "rq.end > NOW()";
+                      .       "rq.end > NOW() AND "
+                      .       "s.name != 'complete'";
                $qh = doQuery($query);
                while($row = mysqli_fetch_assoc($qh))
                        $fails[] = $row['computerid'];
 
                $nowids = array_diff($compids, $fails);
-               $allids = implode(',', $nowids);
-               $query = "UPDATE computer "
-                      . "SET provisioningid = $provisioningid "
-                      . "WHERE id in ($allids)";
-               doQuery($query);
+               if(! empty($nowids)) {
+                       $allids = implode(',', $nowids);
+                       $query = "UPDATE computer "
+                              . "SET provisioningid = $provisioningid "
+                              . "WHERE id in ($allids)";
+                       doQuery($query);
+               }
 
                $resources = getUserResources(array($this->restype . "Admin"), 
array("administer"));
                $compdata = $resources[$this->restype];
 
+               $msg = '';
                if(count($nowids)) {
-                       $msg  = "The following computers had their Provisioning 
Engine set to $provname:<br><br>\n";
+                       $msg  .= "The following computers had their 
Provisioning Engine set to $provname:<br><br>\n";
                        foreach($nowids as $compid)
                                $msg .= "{$compdata[$compid]}<br>\n";
                        $msg .= "<br>";
@@ -4872,9 +4878,11 @@ class Computer extends Resource {
                       .        "i.prettyname AS image, "
                       .        "ir.revision, "
                       .        "c.hostname AS hostname, "
+                      .        "s.IPaddress, "
                       .        "mn.hostname AS managementnode, "
                       .        "l.ending, "
-                      .        "CONCAT(u.unityid, '@', a.name) AS username "
+                      .        "CONCAT(u.unityid, '@', a.name) AS username, "
+                      .        "l.requestid "
                       . "FROM computer c "
                       . "LEFT JOIN sublog s ON (c.id = s.computerid) "
                       . "LEFT JOIN image i ON (s.imageid = i.id) "
@@ -4907,6 +4915,8 @@ class Computer extends Resource {
                                $msg .= "End: " . prettyDatetime($row['end'], 
1) . "<br>";
                        $msg .= "Management Node: {$row['managementnode']}<br>";
                        $msg .= "Ending: {$row['ending']}<br>";
+                       $msg .= "Request ID: {$row['requestid']}<br>";
+                       $msg .= "IP Address: {$row['IPaddress']}<br>";
                        $msg .= "<hr>";
                        $data[] = array('name' => $row['hostname'], 'msg' => 
$msg);
                }
diff --git a/web/.ht-inc/conf-default.php b/web/.ht-inc/conf-default.php
index 50f204b..cff15a3 100644
--- a/web/.ht-inc/conf-default.php
+++ b/web/.ht-inc/conf-default.php
@@ -183,9 +183,9 @@ foreach($authMechs as $key => $item) {
                $updateUserFuncArgs[$item['affiliationid']] = $key;
        }
        elseif($item['type'] == 'local') {
-               $affilValFunc[$item['affiliationid']] = create_function('', 
'return 0;');
-               $addUserFunc[$item['affiliationid']] = create_function('', 
'return NULL;');
-               $updateUserFunc[$item['affiliationid']] = create_function('', 
'return NULL;');
+               $affilValFunc[$item['affiliationid']] = function() {return 0;};
+               $addUserFunc[$item['affiliationid']] = function() {return 
NULL;};
+               $updateUserFunc[$item['affiliationid']] = function() {return 
NULL;};
        }
 }
 
diff --git a/web/.ht-inc/dashboard.php b/web/.ht-inc/dashboard.php
index 3c2df3f..9018c20 100644
--- a/web/.ht-inc/dashboard.php
+++ b/web/.ht-inc/dashboard.php
@@ -42,7 +42,7 @@ function dashboard() {
 
        # -------- left column ---------
        print "<div id=\"dashleft\">\n";
-       print addWidget('status', 'Current Status');
+       print addWidget('status', 'Current Status', '(Hover for description)');
        print addWidget('topimages', 'Top 5 Images in Use', '(Reservations &lt; 
24 hours long)');
        print addWidget('toplongimages', 'Top 5 Long Term Images in Use', 
'(Reservations &gt; 24 hours long)');
        print addWidget('toppastimages', 'Top 5 Images From Past Day', 
'(Reservations with a start<br>time within past 24 hours)');
@@ -168,10 +168,11 @@ function addLineChart($id, $title) {
 function getStatusData() {
        $affilid = getDashboardAffilID();
        $data = array();
-       $data[] = array('key' => 'Active Reservations', 'val' => 0);
-       $data[] = array('key' => 'Online Computers', 'val' => 0, 'tooltip' => 
'Computers in states available, reserved,<br>reloading, inuse, or timeout');
-       $data[] = array('key' => 'In Use Computers', 'val' => 0, 'tooltip' => 
'Computers in inuse state');
-       $data[] = array('key' => 'Failed Computers', 'val' => 0);
+       $data[0] = array('key' => 'Active Reservations', 'val' => 0, 'tooltip' 
=> 'Reservations currently running');
+       $data[1] = array('key' => 'Active Short Reservations', 'val' => 0, 
'tooltip' => 'Reservations with a duration < 24 hours');
+       $data[2] = array('key' => 'Online Computers', 'val' => 0, 'tooltip' => 
'Computers in states available, reserved,<br>reloading, inuse, or timeout');
+       $data[3] = array('key' => 'In Use Computers', 'val' => 0, 'tooltip' => 
'Computers in inuse state');
+       $data[4] = array('key' => 'Failed Computers', 'val' => 0);
        $reloadid = getUserlistID('vclreload@Local');
        if($affilid == 0) {
                $query = "SELECT COUNT(id) "
@@ -196,20 +197,45 @@ function getStatusData() {
        if($row = mysqli_fetch_row($qh))
                $data[0]['val'] = $row[0];
 
-       $query = "SELECT COUNT(id) FROM computer WHERE stateid IN (2, 3, 6, 8, 
11)";
+       if($affilid == 0) {
+               $query = "SELECT COUNT(id) "
+                      . "FROM request "
+                      . "WHERE userid != $reloadid AND "
+                      .       "stateid NOT IN (1, 5, 10, 12) AND "
+                      .       "start < NOW() AND "
+                                .       "end > NOW() AND "
+                      .       "(UNIX_TIMESTAMP(end) - UNIX_TIMESTAMP(start)) < 
86400";
+       }
+       else {
+               $query = "SELECT COUNT(rq.id) "
+                      . "FROM request rq, "
+                      .      "user u "
+                      . "WHERE rq.userid != $reloadid AND "
+                      .       "rq.userid = u.id AND "
+                      .       "u.affiliationid = $affilid AND "
+                      .       "rq.stateid NOT IN (1, 5, 10, 12) AND "
+                      .       "rq.start < NOW() AND "
+                                .       "rq.end > NOW() AND "
+                      .       "(UNIX_TIMESTAMP(end) - UNIX_TIMESTAMP(start)) < 
86400";
+       }
        $qh = doQuery($query, 101);
        if($row = mysqli_fetch_row($qh))
                $data[1]['val'] = $row[0];
 
-       $query = "SELECT COUNT(id) FROM computer WHERE stateid = 8";
+       $query = "SELECT COUNT(id) FROM computer WHERE stateid IN (2, 3, 6, 8, 
11)";
        $qh = doQuery($query, 101);
        if($row = mysqli_fetch_row($qh))
                $data[2]['val'] = $row[0];
 
-       $query = "SELECT COUNT(id) FROM computer WHERE stateid = 5";
+       $query = "SELECT COUNT(id) FROM computer WHERE stateid = 8";
        $qh = doQuery($query, 101);
        if($row = mysqli_fetch_row($qh))
                $data[3]['val'] = $row[0];
+
+       $query = "SELECT COUNT(id) FROM computer WHERE stateid = 5";
+       $qh = doQuery($query, 101);
+       if($row = mysqli_fetch_row($qh))
+               $data[4]['val'] = $row[0];
        return $data;
 }
 
@@ -674,6 +700,7 @@ function getBlockAllocationData() {
 function getNewReservationData() {
        $affilid = getDashboardAffilID();
        $query = "SELECT c.hostname AS computer, "
+              .        "h.hostname AS vmhost, "
               .        "i.prettyname AS image, "
               .        "rq.id, "
               .        "UNIX_TIMESTAMP(rq.start) AS start, "
@@ -684,6 +711,8 @@ function getNewReservationData() {
               . "FROM request rq "
               . "LEFT JOIN reservation rs ON (rs.requestid = rq.id) "
               . "LEFT JOIN computer c ON (c.id = rs.computerid) "
+              . "LEFT JOIN vmhost vh ON (c.vmhostid = vh.id) "
+              . "LEFT JOIN computer h ON (h.id = vh.computerid) "
               . "LEFT JOIN image i ON (i.id = rs.imageid) "
               . "LEFT JOIN OS o ON (o.id = i.OSid) "
               . "LEFT JOIN state s1 ON (s1.id = rq.stateid) "
@@ -703,6 +732,8 @@ function getNewReservationData() {
        while($row = mysqli_fetch_assoc($qh)) {
                $tmp = explode('.', $row['computer']);
                $row['computer'] = $tmp[0];
+               $tmp = explode('.', $row['vmhost']);
+               $row['vmhost'] = $tmp[0];
                $row['start'] = date('D h:i', $row['start']);
                $tmp = explode('.', $row['managementnode']);
                $row['managementnode'] = $tmp[0];
diff --git a/web/.ht-inc/doxyfile.xmlrpc b/web/.ht-inc/doxyfile.xmlrpc
index 4880847..f8519e5 100644
--- a/web/.ht-inc/doxyfile.xmlrpc
+++ b/web/.ht-inc/doxyfile.xmlrpc
@@ -1,5 +1,3 @@
-# Doxyfile 1.4.7
-
 #  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.
@@ -14,10 +12,6 @@
 #  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.
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
 PROJECT_NAME           = "VCL XML RPC"
 PROJECT_NUMBER         = 
 OUTPUT_DIRECTORY       = xmlrpcdocs/
@@ -53,9 +47,6 @@ OPTIMIZE_OUTPUT_JAVA   = NO
 BUILTIN_STL_SUPPORT    = NO
 DISTRIBUTE_GROUP_DOC   = NO
 SUBGROUPING            = NO
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
 EXTRACT_ALL            = NO
 EXTRACT_PRIVATE        = NO
 EXTRACT_STATIC         = NO
@@ -81,9 +72,6 @@ ENABLED_SECTIONS       =
 MAX_INITIALIZER_LINES  = 30
 SHOW_USED_FILES        = NO
 FILE_VERSION_FILTER    = 
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
 QUIET                  = NO
 WARNINGS               = YES
 WARN_IF_UNDOCUMENTED   = YES
@@ -91,9 +79,6 @@ WARN_IF_DOC_ERROR      = YES
 WARN_NO_PARAMDOC       = NO
 WARN_FORMAT            = "$file:$line: $text"
 WARN_LOGFILE           = 
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
 INPUT                  = .
 FILE_PATTERNS          = xmlrpcWrappers.php
 RECURSIVE              = NO
@@ -107,9 +92,6 @@ IMAGE_PATH             =
 INPUT_FILTER           = 
 FILTER_PATTERNS        = 
 FILTER_SOURCE_FILES    = NO
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
 SOURCE_BROWSER         = NO
 INLINE_SOURCES         = NO
 STRIP_CODE_COMMENTS    = YES
@@ -118,15 +100,9 @@ REFERENCES_RELATION    = NO
 REFERENCES_LINK_SOURCE = YES
 USE_HTAGS              = NO
 VERBATIM_HEADERS       = NO
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
 ALPHABETICAL_INDEX     = NO
 COLS_IN_ALPHA_INDEX    = 5
 IGNORE_PREFIX          = 
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
 GENERATE_HTML          = YES
 HTML_OUTPUT            = .
 HTML_FILE_EXTENSION    = .html
@@ -143,9 +119,6 @@ DISABLE_INDEX          = YES
 ENUM_VALUES_PER_LINE   = 4
 GENERATE_TREEVIEW      = NO
 TREEVIEW_WIDTH         = 250
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
 GENERATE_LATEX         = NO
 LATEX_OUTPUT           = latex
 LATEX_CMD_NAME         = latex
@@ -158,44 +131,26 @@ PDF_HYPERLINKS         = NO
 USE_PDFLATEX           = NO
 LATEX_BATCHMODE        = NO
 LATEX_HIDE_INDICES     = NO
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
 GENERATE_RTF           = NO
 RTF_OUTPUT             = rtf
 COMPACT_RTF            = NO
 RTF_HYPERLINKS         = NO
 RTF_STYLESHEET_FILE    = 
 RTF_EXTENSIONS_FILE    = 
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
 GENERATE_MAN           = NO
 MAN_OUTPUT             = man
 MAN_EXTENSION          = .3
 MAN_LINKS              = NO
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
 GENERATE_XML           = NO
 XML_OUTPUT             = xml
 XML_SCHEMA             = 
 XML_DTD                = 
 XML_PROGRAMLISTING     = YES
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
 GENERATE_AUTOGEN_DEF   = NO
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
 GENERATE_PERLMOD       = NO
 PERLMOD_LATEX          = NO
 PERLMOD_PRETTY         = YES
 PERLMOD_MAKEVAR_PREFIX = 
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
 ENABLE_PREPROCESSING   = YES
 MACRO_EXPANSION        = NO
 EXPAND_ONLY_PREDEF     = NO
@@ -205,17 +160,11 @@ INCLUDE_FILE_PATTERNS  =
 PREDEFINED             = 
 EXPAND_AS_DEFINED      = 
 SKIP_FUNCTION_MACROS   = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
 TAGFILES               = 
 GENERATE_TAGFILE       = 
 ALLEXTERNALS           = NO
 EXTERNAL_GROUPS        = YES
 PERL_PATH              = /usr/bin/perl
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
 CLASS_DIAGRAMS         = YES
 HIDE_UNDOC_RELATIONS   = YES
 HAVE_DOT               = NO
@@ -238,7 +187,4 @@ DOT_TRANSPARENT        = NO
 DOT_MULTI_TARGETS      = NO
 GENERATE_LEGEND        = YES
 DOT_CLEANUP            = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
 SEARCHENGINE           = NO
diff --git a/web/.ht-inc/help.php b/web/.ht-inc/help.php
index f632f6b..149bca0 100644
--- a/web/.ht-inc/help.php
+++ b/web/.ht-inc/help.php
@@ -130,7 +130,7 @@ function submitHelpForm() {
                $testname = stripslashes($name);
        if(! preg_match('/^([-A-Za-z \']{1,} [-A-Za-z \']{2,})*$/', $testname)) 
{
                $submitErr |= NAMEERR;
-               $submitErrMsg[NAMEERR] = "Name can only contain letters, 
spaces, apostrophes ('), and dashes (-)";
+               $submitErrMsg[NAMEERR] = "Name can only contain letters, 
spaces, apostrophes ('), and dashes (-). Both first and last name must be 
specified.";
        }
        if(! 
preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i',
           $email)) {
@@ -186,9 +186,9 @@ function submitHelpForm() {
        $recentrequests = "";
        foreach($requests as $request) {
                $thisstart = str_replace('&nbsp;', ' ', 
-                               prettyDatetime($request["start"]));
+                               prettyDatetime($request["start"], 0, 1));
                $thisend = str_replace('&nbsp;', ' ', 
-                               prettyDatetime($request["end"]));
+                               prettyDatetime($request["end"], 0, 1));
                $recentrequests .= "Image: {$request["prettyimage"]}\n"
                                .  "Computer: 
{$computers[$request["computerid"]]["hostname"]}\n"
                                .  "Start: $thisstart\n"
@@ -202,16 +202,79 @@ function submitHelpForm() {
                $message .= "User has no recent reservations\n";
        }
 
+       # login history
+       $query = "SELECT authmech, "
+              .        "timestamp, "
+              .        "passfail, "
+              .        "remoteIP, "
+              .        "code "
+              . "FROM loginlog "
+              . "WHERE (user = '{$user['unityid']}' OR "
+              .       "user = '{$user['unityid']}@{$user['affiliation']}') AND 
"
+              .       "affiliationid = {$user['affiliationid']} "
+              . "ORDER BY timestamp DESC "
+              . "LIMIT 5";
+       $methodlen = strlen(i('Authentication Method'));
+       $timelen = strlen(i('Timestamp'));
+       $resultlen = strlen(i('Result'));
+       $remoteiplen = strlen(i('Remote IP'));
+       $extralen = strlen(i('Extra Info'));
+       if(strlen(i('Pass')) > $resultlen)
+               $resultlen = strlen(i('Pass'));
+       if(strlen(i('Fail')) > $resultlen)
+               $resultlen = strlen(i('Fail'));
+       $qh = doQuery($query);
+       $logins = array();
+       while($row = mysql_fetch_assoc($qh)) {
+               $tmp = prettyDatetime($row['timestamp'], 1, 1);
+               $row['timestamp'] = str_replace('&nbsp;', ' ', $tmp);
+               if($row['passfail'])
+                       $row['passfail'] = 'Pass';
+               else
+                       $row['passfail'] = 'Fail';
+               if(strlen($row['authmech']) > $methodlen)
+                       $methodlen = strlen($row['authmech']);
+               if(strlen($row['timestamp']) > $timelen)
+                       $timelen = strlen($row['timestamp']);
+               if(strlen($row['remoteIP']) > $remoteiplen)
+                       $remoteiplen = strlen($row['remoteIP']);
+               if(strlen($row['code']) > $extralen)
+                       $extralen = strlen($row['code']);
+               $logins[] = $row;
+       }
+       if(count($logins)) {
+               $logins = array_reverse($logins);
+               $message .= "-----------------------------------------------\n";
+               $message .= "User's Login History (up to last 5 attempts):\n\n";
+               $message .= sprintf("%-{$methodlen}s | ", i('Authentication 
Method'));
+               $message .= sprintf("%-{$timelen}s | ", i('Timestamp'));
+               $message .= sprintf("%-{$resultlen}s | ", i('Result'));
+               $message .= sprintf("%-{$remoteiplen}s | ", i('Remote IP'));
+               $message .= sprintf("%-{$extralen}s\n", i('Extra Info'));
+               foreach($logins as $login) {
+                       $message .= sprintf("%-{$methodlen}s | ", 
$login['authmech']);
+                       $message .= sprintf("%-{$timelen}s | ", 
$login['timestamp']);
+                       $message .= sprintf("%-{$resultlen}s | ", 
$login['passfail']);
+                       $message .= sprintf("%-{$remoteiplen}s | ", 
$login['remoteIP']);
+                       $message .= sprintf("%-{$extralen}s\n", $login['code']);
+               }
+       }
+       if(isset($_SERVER['HTTP_USER_AGENT'])) {
+               $message .= "-----------------------------------------------\n";
+               $message .= "User agent: {$_SERVER['HTTP_USER_AGENT']}\n";
+       }
+
        $indrupal = getContinuationVar('indrupal', 0);
        if(! $indrupal)
                print "<H2>VCL Help</H2>\n";
        $mailParams = "-f" . ENVELOPESENDER;
        if(get_magic_quotes_gpc())
                $summary = stripslashes($summary);
-       if(! mail(HELPEMAIL, "$summary", $message,
+       $helpemail = getHelpEmail($user['affiliationid']);
+       if(! mail($helpemail, "$summary", $message,
           "From: $from\r\nReply-To: $email\r\n", $mailParams)){
                print "The Server was unable to send mail at this time. Please 
e-mail ";
-               print "<a href=\"mailto:"; . HELPEMAIL . "\">" . HELPEMAIL . 
"</a> for ";
+               print "<a href=\"mailto:$helpemail\";>$helpemail</a> for ";
                print "help with your problem.";
        }
        else {
@@ -220,4 +283,28 @@ function submitHelpForm() {
        }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getHelpEmail
+///
+/// \param $affil - id or name of an affiliation
+///
+/// \return email address for $affil or HELPEMAIL from conf.php if $affil does
+/// not have a specific email address set
+///
+/// \brief gets the email address for support for a $affil
+///
+////////////////////////////////////////////////////////////////////////////////
+function getHelpEmail($affil) {
+       if(is_numeric($affil))
+               $field = 'id';
+       else
+               $field = 'name';
+       $query = "SELECT helpaddress FROM affiliation WHERE $field = '$affil'";
+       $qh = doQuery($query);
+       if($row = mysql_fetch_assoc($qh))
+               if($row['helpaddress'] != '')
+                       return $row['helpaddress'];
+       return HELPEMAIL;
+}
 ?>
diff --git a/web/.ht-inc/image.php b/web/.ht-inc/image.php
index 8f7bc88..329cec8 100644
--- a/web/.ht-inc/image.php
+++ b/web/.ht-inc/image.php
@@ -366,34 +366,34 @@ class Image extends Resource {
                $h .= "<legend>" . i("Image Description") . "</legend>\n";
                $h .= i("Description of image (required - users will see this 
on the <strong>New Reservations</strong> page):");
                $h .= "<br>\n";
-               $h .= "<textarea dojoType=\"dijit.form.Textarea\" 
id=\"description\" ";
-               $h .= "style=\"width: 400px; text-align: left;\"></textarea>\n";
+               $h .= "<textarea dojoType=\"dijit.form.Textarea\" 
id=\"description\">";
+               $h .= "</textarea>\n";
                $h .= "</fieldset>\n";
                # usage notes
                $h .= "<fieldset>\n";
                $h .= "<legend>" . i("Usage Notes") . "</legend>\n";
                $msg = i("Optional notes to the user explaining how to use the 
image (users will see this on the <strong>Connect!</strong> page):");
                $h .= preg_replace("/(.{1,100}([ \n]|$))/", '\1<br>', $msg);
-               $h .= "<textarea dojoType=\"dijit.form.Textarea\" id=\"usage\" 
";
-               $h .= "style=\"width: 400px; text-align: left;\"></textarea>\n";
+               $h .= "<textarea dojoType=\"dijit.form.Textarea\" 
id=\"usage\">";
+               $h .= "</textarea>\n";
                $h .= "</fieldset>\n";
                if($add) {
                        $h .= "<fieldset>\n";
                        $h .= "<legend>" . i("Revision Comments") . 
"</legend>\n";
                        $msg = i("Notes for yourself and other admins about how 
the image was setup/installed. These are optional and are not visible to end 
users.");
                        $h .= preg_replace("/(.{1,80}([ \n]|$))/", '\1<br>', 
$msg);
-                       $h .= "<textarea dojoType=\"dijit.form.Textarea\" 
id=\"imgcomments\" ";
-                       $h .= "style=\"width: 400px; text-align: 
left;\"></textarea>";
+                       $h .= "<textarea dojoType=\"dijit.form.Textarea\" 
id=\"imgcomments\">";
+                       $h .= "</textarea>";
                        $h .= "</fieldset>\n";
                }
                # advanced options
                $h .= "<div dojoType=\"dijit.TitlePane\" title=\"";
                $h .= i("Advanced Options - leave default values unless you 
really know what you are doing (click to expand)");
-               $h .= "\" open=\"false\" style=\"width: 460px\" 
id=\"advancedoptions\" ";
+               $h .= "\" open=\"false\" id=\"advancedoptions\" ";
                $h .= "onShow=\"delayedEditResize();\" 
onHide=\"delayedEditResize();\">\n";
                # RAM
                $extra = array('smallDelta' => 256, 'largeDelta' => 1024);
-               $h .= labeledFormItem('ram', i('Required RAM'), 'spinner', 
'{min:512, max:8388607}',
+               $h .= labeledFormItem('ram', i('Required RAM') . ' (MB)', 
'spinner', '{min:512, max:8388607}',
                                      1, 1024, '', '', $extra);
                # cores
                $extra = array('smallDelta' => 1, 'largeDelta' => 2);
@@ -1644,7 +1644,7 @@ class Image extends Resource {
                $return["checkuser"] = processInputVar("checkuser", 
ARG_NUMERIC);
                $return["rootaccess"] = processInputVar("rootaccess", 
ARG_NUMERIC);
                $return["sethostname"] = processInputVar("sethostname", 
ARG_NUMERIC);
-               $return["maxinitialtime"] = processInputVar("maxinitialtime", 
ARG_NUMERIC);
+               $return["maxinitialtime"] = processInputVar("maxinitialtime", 
ARG_NUMERIC, 0);
                $return["sysprep"] = processInputVar("sysprep", ARG_NUMERIC); # 
only in add
                $return["connectmethodids"] = 
processInputVar("connectmethodids", ARG_STRING); # only in add
                $return["adauthenabled"] = processInputVar("adauthenabled", 
ARG_NUMERIC);
@@ -1767,7 +1767,7 @@ class Image extends Resource {
                        $extraaddomainid = 
getContinuationVar('extraaddomainid', 0);
                        $extraaddomainou = 
getContinuationVar('extraaddomainou', '');
                        if(! array_key_exists($return['addomainid'], $vals) &&
-                          $return['addomainid'] != $extraaddomainid) {
+                          $return['addomainid'] !== $extraaddomainid) {
                                $return['error'] = 1;
                                $errormsg[] = i("Invalid AD Domain submitted");
                        }
diff --git a/web/.ht-inc/privileges.php b/web/.ht-inc/privileges.php
index 165e14b..714b910 100644
--- a/web/.ht-inc/privileges.php
+++ b/web/.ht-inc/privileges.php
@@ -36,8 +36,11 @@ define("ADDUSERNOPRIVS", 1 << 1);
 
////////////////////////////////////////////////////////////////////////////////
 function viewNodes() {
        global $user;
-       if(! empty($_COOKIE["VCLACTIVENODE"]) &&
-               nodeExists($_COOKIE['VCLACTIVENODE']))
+       if(isset($_COOKIE["VCLACTIVENODE"]) &&
+          is_numeric($_COOKIE['VCLACTIVENODE']) &&
+          $_COOKIE['VCLACTIVENODE'] > 0 &&
+          $_COOKIE['VCLACTIVENODE'] < 16777216 &&
+          nodeExists($_COOKIE['VCLACTIVENODE']))
                $activeNode = $_COOKIE["VCLACTIVENODE"];
        else {
                $topNodes = getChildNodes();
@@ -1629,6 +1632,12 @@ function userLookup() {
                print "      Total: {$times['total']}<br>\n";
                print "  </TR>\n";
 
+               $maxconcurrent = getMaxOverlap($userdata['id']);
+               print "  <TR>\n";
+               print "    <TH align=right>Max Overlapping 
Reservations:</TH>\n";
+               print "    <TD>$maxconcurrent</TD>\n";
+               print "  </TR>\n";
+
                print "  <TR>\n";
                print "    <TH align=right style=\"vertical-align: 
top\">Privileges (found somewhere in the tree):</TH>\n";
                print "    <TD>\n";
@@ -1724,6 +1733,30 @@ function userLookup() {
                }
                print "</div>\n";
 
+               # owned images
+               $ownedimages = array();
+               $query = "SELECT prettyname "
+                      . "FROM image "
+                      . "WHERE ownerid = {$userdata['id']} AND "
+                      .       "deleted = 0 "
+                      . "ORDER BY prettyname";
+               $qh = doQuery($query);
+               while($row = mysqli_fetch_row($qh))
+                       $ownedimages[] = $row[0];
+               print "<table>\n";
+               print "  <tr>\n";
+               print "    <th style=\"vertical-align: top;\">Images Owned by 
User:<th>\n";
+               print "    <td>\n";
+               if(count($ownedimages)) {
+                       foreach($ownedimages as $image)
+                               print "      $image<br>\n";
+               }
+               else
+                       print "      None\n";
+               print "    </td>\n";
+               print "  </tr>\n";
+               print "</table>\n";
+
                # image access
                print "<table>\n";
                print "  <tr>\n";
diff --git a/web/.ht-inc/requests.php b/web/.ht-inc/requests.php
index 565c53c..c836668 100644
--- a/web/.ht-inc/requests.php
+++ b/web/.ht-inc/requests.php
@@ -276,12 +276,14 @@ function viewRequests() {
                                        $text .= 
getViewRequestHTMLitem('openmoreoptions');
                                        $text .= 
getViewRequestHTMLitem('editoption', $editcont);
                                        if(array_key_exists($imageid, 
$resources['image']) && ! $cluster &&            # imageAdmin access, not a 
cluster,
+                                          $requests[$i]['OSinstalltype'] != 
'none' &&
                                           ($requests[$i]['currstateid'] == 8 
|| $requests[$i]['laststateid'] == 8)) { # reservation has been in inuse state
                                                $text .= 
getViewRequestHTMLitem('endcreateoption', $imgcont);
                                        }
                                        /*else
                                                $text .= 
getViewRequestHTMLitem('endcreateoptiondisable');*/
                                        if(array_key_exists($imageid, 
$resources['image']) && ! $cluster &&
+                                          $requests[$i]['OSinstalltype'] != 
'none' &&
                                           $requests[$i]['server'] && 
($requests[$i]['currstateid'] == 8 ||
                                                ($requests[$i]['currstateid'] 
== 14 && $requests[$i]['laststateid'] == 8))) {
                                                $chkcdata = $cdata;
@@ -291,7 +293,8 @@ function viewRequests() {
                                        }
                                        elseif($requests[$i]['server'] && 
$requests[$i]['currstateid'] == 24)
                                                $text .= 
getViewRequestHTMLitem('checkpointoptiondisable');
-                                       if($requests[$i]['currstateid'] == 8 ||
+                                       if((! $cluster && 
$requests[$i]['OSinstalltype'] != 'none' &&
+                                          $requests[$i]['currstateid'] == 8) ||
                                           (! $cluster &&
                                           $requests[$i]['OSinstalltype'] != 
'none' &&
                                           $requests[$i]['currstateid'] != 3 &&
@@ -2093,6 +2096,45 @@ function printImageDescription($imageid) {
 
 
////////////////////////////////////////////////////////////////////////////////
 ///
+/// \fn AJfetchRouterDNS()
+///
+/// \brief get router and dns information for a given IP address
+///
+////////////////////////////////////////////////////////////////////////////////
+function AJfetchRouterDNS() {
+       $data = array('status' => 'none');
+       $page = processInputVar('page', ARG_STRING);
+       if($page != 'deploy') {
+               sendJSON($data);
+               return;
+       }
+       $ipaddr = processInputVar('ipaddr', ARG_STRING);
+       # validate fixed IP address
+       if(! validateIPv4addr($ipaddr)) {
+               sendJSON($data);
+               return;
+       }
+       # validate netmask
+       $netmask = processInputVar('netmask', ARG_STRING);
+       $bnetmask = ip2long($netmask);
+       if(! preg_match('/^[1]+0[^1]+$/', sprintf('%032b', $bnetmask))) {
+               sendJSON($data);
+               return;
+       }
+       $network = ip2long($ipaddr) & $bnetmask;
+       $availnets = getVariable('fixedIPavailnetworks', array());
+       $key = long2ip($network) . "/$netmask";
+       if(array_key_exists($key, $availnets)) {
+               $data = array('status' => 'success',
+                             'page' => $page,
+                             'router' => $availnets[$key]['router'],
+                             'dns' => implode(',', $availnets[$key]['dns']));
+       }
+       sendJSON($data);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \fn AJshowRequestSuggestedTimes()
 ///
 /// \brief builds html to display list of available times the selected image
@@ -2359,7 +2401,8 @@ function AJnewRequest() {
                return;
        }
        elseif($availablerc == -3) {
-               $msg = i("The IP or MAC address you specified overlaps with 
another reservation using the same IP or MAC address you specified. Please use 
a different IP or MAC or select a different time to deploy the server.");
+               #$msg = i("The IP or MAC address you specified overlaps with 
another reservation using the same IP or MAC address you specified. Please use 
a different IP or MAC or select a different time to deploy the server.");
+               $msg = i("The IP address you specified overlaps with another 
reservation using the same IP address. Please use a different IP address or 
select a different time to deploy the server.");
                $data = array('err' => 1,
                              'errmsg' => $msg);
                sendJSON($data);
@@ -3859,7 +3902,8 @@ function AJsubmitEditRequest() {
                        $msgip = " ($ip)";
                if(! empty($mac))
                        $msgmac = " ($mac)";
-               $h .= sprintf(i("The reserved IP (%s) or MAC address (%s) 
conflicts with another reservation using the same IP or MAC address. Please 
select a different time to use the image."), $msgip, $msgmac);
+               #$h .= sprintf(i("The reserved IP (%s) or MAC address (%s) 
conflicts with another reservation using the same IP or MAC address. Please 
select a different time to use the image."), $msgip, $msgmac);
+               $h .= sprintf(i("The reserved IP address (%s) conflicts with 
another reservation using the same IP address. Please select a different time 
to use the image."), $msgip);
                $h = preg_replace("/(.{1,60}([ \n]|$))/", '\1<br>', $h);
                $cdata = getContinuationVar();
                $cont = addContinuationsEntry('AJsubmitEditRequest', $cdata, 
SECINDAY, 1, 0);
@@ -5040,10 +5084,14 @@ function getReserveDayData() {
 function AJsetImageProduction() {
        $requestid = getContinuationVar('requestid');
        $data = getRequestInfo($requestid);
-       foreach($data["reservations"] as $res) {
-               if($res["forcheckout"]) {
-                       $prettyimage = $res["prettyimage"];
-                       break;
+       if($data['forimaging'])
+               $prettyimage = $data['reservations'][0]['prettyimage'];
+       else {
+               foreach($data["reservations"] as $res) {
+                       if($res["forcheckout"]) {
+                               $prettyimage = $res["prettyimage"];
+                               break;
+                       }
                }
        }
        $title = "<big><strong>" . i("Change Test Image to Production") . 
"</strong></big><br><br>\n";
@@ -5068,10 +5116,14 @@ function AJsetImageProduction() {
 function AJsubmitSetImageProduction() {
        $requestid = getContinuationVar('requestid');
        $data = getRequestInfo($requestid);
-       foreach($data["reservations"] as $res) {
-               if($res["forcheckout"]) {
-                       $prettyimage = $res["prettyimage"];
-                       break;
+       if($data['forimaging'])
+               $prettyimage = $data['reservations'][0]['prettyimage'];
+       else {
+               foreach($data["reservations"] as $res) {
+                       if($res["forcheckout"]) {
+                               $prettyimage = $res["prettyimage"];
+                               break;
+                       }
                }
        }
        $query = "UPDATE request SET stateid = 17 WHERE id = $requestid";
diff --git a/web/.ht-inc/resource.php b/web/.ht-inc/resource.php
index cc55d09..04a5e10 100644
--- a/web/.ht-inc/resource.php
+++ b/web/.ht-inc/resource.php
@@ -1731,6 +1731,11 @@ function AJstartImage() {
                       'baserevisionid' => $revid,
                       'checkpoint' => $checkpoint,
                       'add' => 1);
+       $cdata['addomainvals'] = array();
+       if(in_array("addomainAdmin", $user["privileges"])) {
+               $vals = getUserResources(array('addomainAdmin'), 
array("manageGroup"));
+               $cdata['addomainvals'] = $vals['addomain'];
+       }
        $cont = addContinuationsEntry('AJsaveResource', $cdata, SECINDAY, 0);
        $arr = array('newcont' => $cont,
                     'enableupdate' => 0,
diff --git a/web/.ht-inc/serverprofiles.php b/web/.ht-inc/serverprofiles.php
index 2de4826..9d9ad37 100644
--- a/web/.ht-inc/serverprofiles.php
+++ b/web/.ht-inc/serverprofiles.php
@@ -1138,43 +1138,4 @@ function AJremProfileFromGroup() {
        sendJSON($arr);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \fn AJfetchRouterDNS()
-///
-/// \brief get router and dns information for a given IP address
-///
-////////////////////////////////////////////////////////////////////////////////
-function AJfetchRouterDNS() {
-       $data = array('status' => 'none');
-       $page = processInputVar('page', ARG_STRING);
-       if($page != 'deploy' && $page != 'profile') {
-               sendJSON($data);
-               return;
-       }
-       $ipaddr = processInputVar('ipaddr', ARG_STRING);
-       # validate fixed IP address
-       if(! validateIPv4addr($ipaddr)) {
-               sendJSON($data);
-               return;
-       }
-       # validate netmask
-       $netmask = processInputVar('netmask', ARG_STRING);
-       $bnetmask = ip2long($netmask);
-       if(! preg_match('/^[1]+0[^1]+$/', sprintf('%032b', $bnetmask))) {
-               sendJSON($data);
-               return;
-       }
-       $network = ip2long($ipaddr) & $bnetmask;
-       $availnets = getVariable('fixedIPavailnetworks', array());
-       $key = long2ip($network) . "/$netmask";
-       if(array_key_exists($key, $availnets)) {
-               $data = array('status' => 'success',
-                             'page' => $page,
-                             'router' => $availnets[$key]['router'],
-                             'dns' => implode(',', $availnets[$key]['dns']));
-       }
-       sendJSON($data);
-}
-
 ?>
diff --git a/web/.ht-inc/states.php b/web/.ht-inc/states.php
index ae4227c..2e7cb06 100644
--- a/web/.ht-inc/states.php
+++ b/web/.ht-inc/states.php
@@ -150,8 +150,8 @@ $noHTMLwrappers = array('sendRDPfile',
                         'AJremGroupFromProfile',
                         'AJaddProfileToGroup',
                         'AJremProfileFromGroup',
-                        'AJserverProfileStoreData',
-                        'AJfetchRouterDNS',*/
+                        'AJserverProfileStoreData',*/
+                        'AJfetchRouterDNS',
                         'AJconfirmDeleteRequest',
                         'AJsubmitDeleteRequest',
                         'AJconfirmRemoveRequest',
@@ -257,6 +257,7 @@ $actions['mode']['AJconnectRequest'] = "AJconnectRequest";
 $actions['mode']['sendRDPfile'] = "sendRDPfile";
 $actions['mode']['AJcheckConnectTimeout'] = "AJcheckConnectTimeout";
 $actions['mode']['AJpreviewClickThrough'] = "AJpreviewClickThrough";
+$actions['mode']['AJfetchRouterDNS'] = "AJfetchRouterDNS";
 #$actions['mode']['connectMindterm'] = "connectMindterm";
 #$actions['mode']['connectRDPapplet'] = "connectRDPapplet";
 $actions['pages']['AJnewRequest'] = "reservations";
@@ -281,6 +282,7 @@ $actions['pages']['AJconnectRequest'] = "reservations";
 $actions['pages']['sendRDPfile'] = "reservations";
 $actions['pages']['AJcheckConnectTimeout'] = "reservations";
 $actions['pages']['AJpreviewClickThrough'] = "reservations";
+$actions['pages']['AJfetchRouterDNS'] = "reservations";
 #$actions['pages']['connectMindterm'] = "currentReservations";
 #$actions['pages']['connectRDPapplet'] = "currentReservations";
 
@@ -386,7 +388,6 @@ $actions['mode']['AJremGroupFromProfile'] = 
"AJremGroupFromProfile";
 $actions['mode']['AJaddProfileToGroup'] = "AJaddProfileToGroup";
 $actions['mode']['AJremProfileFromGroup'] = "AJremProfileFromGroup";
 $actions['mode']['AJserverProfileStoreData'] = "AJserverProfileStoreData";
-$actions['mode']['AJfetchRouterDNS'] = "AJfetchRouterDNS";
 $actions['pages']['serverProfiles'] = "serverProfiles";
 $actions['pages']['AJsaveServerProfile'] = "serverProfiles";
 $actions['pages']['AJserverProfileData'] = "serverProfiles";
@@ -397,8 +398,7 @@ $actions['pages']['AJaddGroupToProfile'] = "serverProfiles";
 $actions['pages']['AJremGroupFromProfile'] = "serverProfiles";
 $actions['pages']['AJaddProfileToGroup'] = "serverProfiles";
 $actions['pages']['AJremProfileFromGroup'] = "serverProfiles";
-$actions['pages']['AJserverProfileStoreData'] = "serverProfiles";
-$actions['pages']['AJfetchRouterDNS'] = "serverProfiles";*/
+$actions['pages']['AJserverProfileStoreData'] = "serverProfiles";*/
 
 # time table
 # TODO a few of these belong to new reservation
diff --git a/web/.ht-inc/statistics.php b/web/.ht-inc/statistics.php
index f30998f..9d749fe 100644
--- a/web/.ht-inc/statistics.php
+++ b/web/.ht-inc/statistics.php
@@ -213,7 +213,8 @@ function viewStatistics() {
                       .        "l.wasavailable, "
                       .        "l.ending, "
                       .        "i.prettyname, "
-                      .        "o.prettyname AS OS "
+                      .        "o.prettyname AS OS, "
+                      .        "o.type AS OStype "
                       . "FROM log l, "
                       .      "image i, "
                       .      "user u, "
@@ -234,7 +235,8 @@ function viewStatistics() {
                       .        "l.wasavailable, "
                       .        "l.ending, "
                       .        "i.prettyname, "
-                      .        "o.prettyname AS OS "
+                      .        "o.prettyname AS OS, "
+                      .        "o.type AS OStype "
                       . "FROM image i, "
                       .      "user u, "
                       .      "OS o, "
@@ -282,6 +284,7 @@ function viewStatistics() {
        $imageload6to8 = array();
        $imageload8more = array();
        $imagefails = array();
+       $imageostype = array();
        $lengths = array("30min" => 0,
                         "1hour" => 0,
                         "2hours" => 0,
@@ -301,6 +304,8 @@ function viewStatistics() {
                        $imageload6to8[$row["prettyname"]] = 0;
                if(! array_key_exists($row["prettyname"], $imageload8more))
                        $imageload8more[$row["prettyname"]] = 0;
+               if(! isset($imageostype[$row["prettyname"]]))
+                       $imageostype[$row["prettyname"]] = 
ucfirst($row['OStype']);
 
                # notavailable
                if($row["wasavailable"] == 0) {
@@ -452,6 +457,7 @@ function viewStatistics() {
        print "    <TH>" . i("6-8 min wait") . "</TH>\n";
        print "    <TH>" . i("&gt;= 8 min wait") . "</TH>\n";
        print "    <TH>" . i("Failures") . "</TH>\n";
+       print "    <TH>" . i("OS Type") . "</TH>\n";
        print "  </TR>\n";
        foreach($imagecount as $key => $value) {
                print "  <TR>\n";
@@ -477,6 +483,7 @@ function viewStatistics() {
                }
                else
                        print "    <TD align=center>{$imagefails[$key]}</TD>\n";
+               print "    <TD align=center>{$imageostype[$key]}</TD>\n";
                print "  </TR>\n";
        }
        print "</TABLE>\n";
diff --git a/web/.ht-inc/utils.php b/web/.ht-inc/utils.php
index c13be06..71b9e3f 100644
--- a/web/.ht-inc/utils.php
+++ b/web/.ht-inc/utils.php
@@ -56,8 +56,8 @@ $printedHTMLheader = 0;
 ///
 
////////////////////////////////////////////////////////////////////////////////
 function initGlobals() {
-       global $mode, $user, $remoteIP, $authed, $oldmode, $semid;
-       global $days, $phpVer, $keys, $pemkey, $AUTHERROR;
+       global $mode, $user, $remoteIP, $authed, $oldmode;
+       global $days, $phpVer, $keys, $pemkey, $submitErr, $submitErrMsg;
        global $passwdArray, $skin, $contdata, $lastmode, $inContinuation;
        global $ERRORS, $actions;
        global $affilValFunc, $addUserFunc, $updateUserFunc, $addUserFuncArgs;
@@ -87,7 +87,7 @@ function initGlobals() {
 
        if(function_exists('openssl_encrypt')) {
                define('USE_PHPSECLIB', 0);
-               $crytpkey = base64_decode($cryptkey);
+               $cryptkey = base64_decode($cryptkey);
        }
        else {
                define('USE_PHPSECLIB', 1);
@@ -279,9 +279,9 @@ function initGlobals() {
                $id = $row['id'];
                if(! array_key_exists($id, $affilValFunc)) {
                        if(ALLOWADDSHIBUSERS)
-                               $affilValFunc[$id] = create_function('', 
'return 1;');
+                               $affilValFunc[$id] = function() {return 1;};
                        else
-                               $affilValFunc[$id] = create_function('', 
'return 0;');
+                               $affilValFunc[$id] = function() {return 0;};
                }
                if(! array_key_exists($id, $addUserFunc)) {
                        if(ALLOWADDSHIBUSERS) {
@@ -289,10 +289,10 @@ function initGlobals() {
                                $addUserFuncArgs[$id] = $id;
                        }
                        else
-                               $addUserFunc[$id] = create_function('', 'return 
0;');
+                               $addUserFunc[$id] = function() {return 0;};
                }
                if(! array_key_exists($id, $updateUserFunc))
-                       $updateUserFunc[$id] = create_function('', 'return 
NULL;');
+                       $updateUserFunc[$id] = function() {return NULL;};
        }
 
        # include appropriate files
@@ -382,8 +382,8 @@ function __autoload($class) {
 
////////////////////////////////////////////////////////////////////////////////
 function checkAccess() {
        global $mode, $user, $actionFunction, $authMechs;
-       global $itecsauthkey, $ENABLE_ITECSAUTH, $actions, $noHTMLwrappers;
-       global $inContinuation, $docreaders, $apiValidateFunc;
+       global $itecsauthkey, $ENABLE_ITECSAUTH, $actions;
+       global $inContinuation, $apiValidateFunc;
        if($mode == 'xmlrpccall') {
                // double check for SSL
                if(! isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") {
@@ -391,6 +391,11 @@ function checkAccess() {
                        dbDisconnect();
                        exit;
                }
+               if(! isset($_SERVER['HTTP_X_USER'])) {
+                       printXMLRPCerror(3);   # access denied
+                       dbDisconnect();
+                       exit;
+               }
                $xmluser = processInputData($_SERVER['HTTP_X_USER'], 
ARG_STRING, 1);
                if(! $user = getUserInfo($xmluser)) {
                        // if first call to getUserInfo fails, try calling with 
$noupdate set
@@ -769,7 +774,8 @@ function maintenanceCheck() {
                        # check to see if end time has been reached
                        $fh = fopen($file, 'r');
                        $msg = '';
-                       while($line = fgetss($fh)) {
+                       while($line = fgets($fh)) {
+                           $line = strip_tags($line);
                                
if(preg_match("/^END=([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/", 
$line, $matches)) {
                                        $tmp = 
"{$matches[1]}-{$matches[2]}-{$matches[3]} {$matches[4]}:{$matches[5]}:00";
                                        $end = datetimeToUnix($tmp);
@@ -969,7 +975,7 @@ function stopSession() {
 ///
 
////////////////////////////////////////////////////////////////////////////////
 function main() {
-       global $user, $authed, $mode;
+       global $user, $authed;
        print "<H2>" . i("Welcome to the Virtual Computing Lab") . "</H2>\n";
        if($authed) {
                if(! empty($user['lastname']) && ! 
empty($user['preferredname']))
@@ -1023,10 +1029,10 @@ function abort($errcode, $query="") {
                xmlRPCabort($errcode, $query);
        if(ONLINEDEBUG && checkUserHasPerm('View Debug Information')) {
                if($errcode >= 100 && $errcode < 400) {
-                       print "<font color=red>" . 
mysqli_error($mysqli_link_vcl) . "</font><br>\n";
+                       print "<span class=\"rederrormsg\">" . 
mysqli_error($mysqli_link_vcl) . "</span><br>\n";
                        error_log(mysqli_error($mysqli_link_vcl));
                        if($ENABLE_ITECSAUTH) {
-                               print "<font color=red>" . 
mysqli_error($mysqli_link_acct) . "</font><br>\n";
+                               print "<span class=\"rederrormsg\">" . 
mysqli_error($mysqli_link_acct) . "</span><br>\n";
                                error_log(mysqli_error($mysqli_link_acct));
                        }
                        print "$query<br>\n";
@@ -2099,7 +2105,6 @@ function getUserResources($userprivs, 
$resourceprivs=array("available"),
                $bygroup = 1;
        if(! $userid)
                $userid = $user["id"];
-       $return = array();
 
        $nodeprivs = array();
        $startnodes = array();
@@ -2861,7 +2866,7 @@ function encryptSecretKey($secret, $cryptkey) {
        }
        else
                $padding = constant('OPENSSL_PKCS1_OAEP_PADDING');
-       $savehdlr = set_error_handler(create_function('', ''));
+       $savehdlr = set_error_handler(function() {});
        if(@openssl_public_encrypt($secret, $encdata, $cryptkey, $padding)) {
                set_error_handler($savehdlr);
                $b64data = base64_encode($encdata);
@@ -2891,7 +2896,7 @@ function decryptSecretKey($encsecret) {
        $file .= "/.ht-inc/cryptkey/private.pem";
        $prikey = openssl_pkey_get_private("file://$file", $pemkey);
        # decrypt secret using private key
-       $savehdlr = set_error_handler(create_function('', ''));
+       $savehdlr = set_error_handler(function() {});
        if(ASYMOPT == 'OAEP')
                $padding = constant('OPENSSL_PKCS1_OAEP_PADDING');
        # OAEP currently only supported padding option
@@ -4258,7 +4263,6 @@ function getUserInfo($id, $noupdate=0, $numeric=0) {
                        return NULL;
        }
 
-       $user = array();
        $query = "SELECT u.unityid AS unityid, "
               .        "u.affiliationid, "
               .        "af.name AS affiliation, "
@@ -4496,7 +4500,6 @@ function updateUserData($id, $type="loginid", 
$affilid=DEFAULT_AFFILID) {
                $qh = doQuery($query, 101);
                if($row = mysqli_fetch_assoc($qh)) {
                        $id = $row['unityid'];
-                       $type = 'loginid';
                        $affilid = $row['affiliationid'];
                }
                else
@@ -5085,6 +5088,8 @@ function isAvailable($images, $imageid, $imagerevisionid, 
$start, $end,
                        while($row = mysqli_fetch_assoc($qh))
                                $newcompids[] = $row['id'];
                        $computerids = $newcompids;
+                       if(empty($computerids) && empty($blockids))
+                               return debugIsAvailable(0, 23, $start, $end, 
$imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual);
                }
 
                # check for use of specified IP address, have to wait until here
@@ -5106,7 +5111,7 @@ function isAvailable($images, $imageid, $imagerevisionid, 
$start, $end,
                        $qh = doQuery($query);
                        if(mysqli_num_rows($qh)) {
                                if($now)
-                                       return debugIsAvailable(-4, 18, $start, 
$end, $imagerevisionid, $computerids, $currentids, $blockids, array(), 
$virtual);
+                                       return debugIsAvailable(-4, 24, $start, 
$end, $imagerevisionid, $computerids, $currentids, $blockids, array(), 
$virtual);
                                $requestInfo['ipwarning'] = 1;
                        }
                        $query = "SELECT id "
@@ -5208,7 +5213,7 @@ function isAvailable($images, $imageid, $imagerevisionid, 
$start, $end,
 function debugIsAvailable($rc, $loc, $start, $end, $imagerevisionid,
                               $compids=array(), $currentids=array(),
                               $blockids=array(), $failedids=array(), 
$virtual='') {
-       global $user, $mode, $requestInfo;
+       global $mode, $requestInfo;
        $debug = getContinuationVar('debug', 0);
        if(! $debug ||
           $mode != 'AJupdateWaitTime' ||
@@ -5266,9 +5271,6 @@ function debugIsAvailable($rc, $loc, $start, $end, 
$imagerevisionid,
                case "13":
                        $msg = "no computers available (after virtual host 
resource checks/before performing overlapping IP address check)";
                        break;
-               case "18":
-                       $msg = "requested IP address in use by another 
computer";
-                       break;
                case "22":
                        $msg = "at least 2 computers have the requested IP 
address assigned to them";
                        break;
@@ -5278,6 +5280,12 @@ function debugIsAvailable($rc, $loc, $start, $end, 
$imagerevisionid,
                case "12":
                        $msg = "successfully found a computer (id: 
{$requestInfo['computers'][0]})";
                        break;
+               case "23":
+                       $msg = "no computers available after performing VM host 
check";
+                       break;
+               case "24":
+                       $msg = "requested IP address in use by another 
computer";
+                       break;
        }
        print "console.log('$msg');";
        return $rc;
@@ -5412,7 +5420,6 @@ function schCheckMaintenance($start, $end) {
 function allocComputer($blockids, $currentids, $computerids, $start, $end,
                        $nowfuture, $imageid, $imagerevisionid, $holdcomps,
                        $requestid) {
-       global $requestInfo;
        $ret = array();
        if(SCHEDULER_ALLOCATE_RANDOM_COMPUTER) {
                shuffle($blockids);
@@ -5696,7 +5703,6 @@ function getMappedResources($resourcesubid, 
$resourcetype1, $resourcetype2) {
 ///
 
////////////////////////////////////////////////////////////////////////////////
 function checkOverlap($start, $end, $max, $requestid=0) {
-       global $user;
        $requests = getUserRequests("all");
        $count = 0;
        if($max > 0)
@@ -5875,7 +5881,7 @@ function addRequest($forimaging=0, $revisionid=array(), 
$checkuser=1) {
               .       "'$endstamp', "
               .       "NOW(), "
               .       "$checkuser)";
-       $qh = doQuery($query, 136);
+       doQuery($query, 136);
 
        $qh = doQuery("SELECT LAST_INSERT_ID() FROM request", 134);
        if(! $row = mysqli_fetch_row($qh)) {
@@ -6037,7 +6043,6 @@ function simpleAddRequest($compid, $imageid, $revisionid, 
$start, $end,
 ///
 
////////////////////////////////////////////////////////////////////////////////
 function findManagementNode($compid, $start, $nowfuture) {
-       global $HTMLheader;
        $allmgmtnodes = array_keys(getManagementNodes($nowfuture));
        $mapped = getMappedResources($compid, "computer", "managementnode");
        $usablemgmtnodes = array_intersect($allmgmtnodes, $mapped);
@@ -6359,7 +6364,7 @@ function deleteRequest($request) {
                                       . "WHERE id = {$request['id']}";
                        }
                }
-               $qh = doQuery($query, 150);
+               doQuery($query, 150);
 
                addChangeLogEntry($request["logid"], NULL, 
unixToDatetime($now), NULL,
                                  NULL, "released");
@@ -6402,7 +6407,7 @@ function deleteRequest($request) {
 ///
 
////////////////////////////////////////////////////////////////////////////////
 function moveReservationsOffComputer($compid=0, $count=0) {
-       global $requestInfo, $user;
+       global $requestInfo;
        $resInfo = array();
        $checkstart = unixToDatetime(time() + 180);
        if($compid == 0) {
@@ -7183,29 +7188,6 @@ function hour24to12($hour) {
 
 
////////////////////////////////////////////////////////////////////////////////
 ///
-/// \fn getDepartmentName($id)
-///
-/// \param $id - id for a department in the department table
-///
-/// \return if found, department name; if not, 0
-///
-/// \brief looks up the name field corresponding to $id in the department table
-/// and returns it
-///
-////////////////////////////////////////////////////////////////////////////////
-function getDepartmentName($id) {
-       $query = "SELECT name FROM department WHERE id = '$id'";
-       $qh = doQuery($query, 101);
-       if($row = mysqli_fetch_row($qh)) {
-               return $row[0];
-       }
-       else {
-               return 0;
-       }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///
 /// \fn getImageId($image)
 ///
 /// \param $image - name of an image (must match name (not prettyname) in the
@@ -7580,11 +7562,9 @@ function getMnsFromImage($imageid) {
        while($row = mysqli_fetch_assoc($qh))
                $compgroups[] = $row['resourcegroupid'];
        $mngrps = array();
-       foreach($compgroups as $grpid) {
-               $mngrpset = getResourceMapping('managementnode', 'computer', 
'', implode(',', $compgroups));
-               foreach($mngrpset as $mngrpid => $compgrpset)
-                       $mngrps[$mngrpid] = 1;
-       }
+       $mngrpset = getResourceMapping('managementnode', 'computer', '', 
implode(',', $compgroups));
+       foreach($mngrpset as $mngrpid => $compgrpset)
+               $mngrps[$mngrpid] = 1;
        $mngrpnames = array();
        foreach(array_keys($mngrps) as $mnid) {
                $mngrpnames[] = getResourceGroupName($mnid);
@@ -8562,6 +8542,7 @@ function findAvailableTimes($start, $end, $imageid, 
$userid, $usedaysahead,
               .      "reservation rs, "
               .      "image i, "
               .      "state s, "
+              .      "state rqs, "
               .      "computer c, "
               .      "provisioningOSinstalltype poi, "
               .      "OSinstalltype oi, "
@@ -8569,6 +8550,8 @@ function findAvailableTimes($start, $end, $imageid, 
$userid, $usedaysahead,
               . "WHERE rs.requestid = rq.id AND "
               .       "(rq.start > '$startdt' OR "
               .        "(DATE_ADD(rq.end, INTERVAL 15 MINUTE) > '$startdt' AND 
rq.start <= '$startdt')) AND "
+              .       "rq.stateid = rqs.id AND "
+              .       "rqs.name NOT IN ('failed', 'complete', 'reload') AND "
               .       "rs.computerid IN ($incompids) AND "
               .       "i.id = $imageid AND "
               .       "c.id = rs.computerid AND "
@@ -13111,7 +13094,7 @@ function sendJSON($arr, $identifier='', $REST=0) {
 ///
 
////////////////////////////////////////////////////////////////////////////////
 function sendHeaders() {
-       global $mode, $user, $authed, $oldmode, $actionFunction;
+       global $mode, $user, $authed, $actionFunction;
        global $shibauthed, $authFuncs;
        if(! $authed && $mode == "auth") {
                header("Location: " . BASEURL . SCRIPT . "?mode=selectauth");
@@ -13206,8 +13189,8 @@ function sendHeaders() {
 ///
 
////////////////////////////////////////////////////////////////////////////////
 function printHTMLHeader() {
-       global $mode, $user, $authed, $oldmode, $HTMLheader, $contdata;
-       global $printedHTMLheader, $docreaders, $noHTMLwrappers, $actions;
+       global $mode, $user, $authed, $HTMLheader, $contdata;
+       global $printedHTMLheader, $noHTMLwrappers;
        if($printedHTMLheader)
                return;
        $refresh = 0;
@@ -13783,23 +13766,6 @@ function getDojoHTML($refresh) {
                                              'dijit.form.ValidationTextBox',
                                              'dijit.layout.TabContainer');
                        break;
-               # TODO clean up
-               /*case 'serverProfiles':
-                       $filename = 'vclServerProfiles.js';
-                       $dojoRequires = array('dojo.parser',
-                                             'dijit.Dialog',
-                                             'dijit.form.Button',
-                                             'dijit.form.FilteringSelect',
-                                             'dijit.form.Select',
-                                             'dijit.form.TextBox',
-                                             'dijit.form.ValidationTextBox',
-                                             'dijit.form.CheckBox',
-                                             'dijit.form.Textarea',
-                                             'dijit.layout.ContentPane',
-                                             'dijit.layout.TabContainer',
-                                             'dojox.string.sprintf',
-                                             'dojo.data.ItemFileWriteStore');
-                       break;*/
                /*case 'testDojoREST':
                        $filename = '';
                        $dojoRequires = array('dojo.parser',
@@ -13851,8 +13817,6 @@ function getDojoHTML($refresh) {
                        $rt .= "      testJS();\n";
                        $rt .= "      document.onmousemove = updateMouseXY;\n";
                        $rt .= "      showScriptOnly();\n";
-                       /*$cont = 
addContinuationsEntry('AJserverProfileStoreData', array(), 120, 1, 0);
-                       $rt .= "   populateProfileStore('$cont');\n";*/
                        $rt .= "   });\n";
                        if($refresh)
                                $rt .= "   refresh_timer = 
setTimeout(resRefresh, 12000);\n";
diff --git a/web/.ht-inc/vm.php b/web/.ht-inc/vm.php
index 90c96a5..df10b43 100644
--- a/web/.ht-inc/vm.php
+++ b/web/.ht-inc/vm.php
@@ -437,9 +437,7 @@ function vmhostdata() {
        $currvms = array_merge($currvms);
        $noaccess = array_merge($noaccess);
        $freevms = array_merge($freevms);
-       $cont = addContinuationsEntry('AJchangeVMprofile', array(), 3600, 1, 0);
        $arr = array('profile' => $data[$vmhostid]['vmprofiledata'],
-                    'continuation' => $cont,
                     'allvms' => $allvms,
                     'currvms' => $currvms,
                     'noaccess' => $noaccess,
@@ -516,6 +514,10 @@ function AJvmToHost() {
        $fails = array();
 
        $vmlistids = processInputVar('listids', ARG_STRING);
+       if(! preg_match('/^(\d+)(,\d+)*$/', $vmlistids)) {
+               sendJSON(array('failed' => 'invaliddata'));
+               return;
+       }
        $vmids = explode(',', $vmlistids);
 
        # get data about submitted vms to add
@@ -583,6 +585,10 @@ function AJvmFromHost() {
 
        $fails = array();
        $vmlistids = processInputVar('listids', ARG_STRING);
+       if(! preg_match('/^(\d+)(,\d+)*$/', $vmlistids)) {
+               sendJSON(array('failed' => 'invaliddata'));
+               return;
+       }
        $vmids = explode(',', $vmlistids);
        $rems = array();
        $checks = array();
@@ -718,6 +724,10 @@ function AJcancelVMmove() {
 
        $fails = array();
        $requestids = processInputVar('listids', ARG_STRING);
+       if(! preg_match('/^(\d+)(,\d+)*$/', $requestids)) {
+               sendJSON(array('failed' => 'invaliddata'));
+               return;
+       }
        $now = time();
        $msg = 'FAIL';
        foreach(explode(',', $requestids) AS $reqid) {
@@ -944,10 +954,9 @@ function AJupdateVMprofileItem() {
 
////////////////////////////////////////////////////////////////////////////////
 function AJnewProfile() {
        $newprofile = processInputVar('newname', ARG_STRING);
-       if(get_magic_quotes_gpc()) {
+       if(get_magic_quotes_gpc())
                $newprofile = stripslashes($newprofile);
-               $newprofile = vcl_mysql_escape_string($newprofile);
-       }
+       $newprofile = vcl_mysql_escape_string($newprofile);
        $query = "SELECT id FROM vmprofile WHERE profilename = '$newprofile'";
        $qh = doQuery($query, 101);
        if($row = mysqli_fetch_assoc($qh)) {
diff --git a/web/.ht-inc/xmlrpcWrappers.php b/web/.ht-inc/xmlrpcWrappers.php
index 33b1587..750000e 100644
--- a/web/.ht-inc/xmlrpcWrappers.php
+++ b/web/.ht-inc/xmlrpcWrappers.php
@@ -19,9 +19,9 @@
 /**
  * \file
  * The functions listed here are for making VCL requests from other 
applications.
- * They are implemented according to the XML RPC spec defined at 
+ * They are implemented according to the XML RPC spec defined at
  * http://www.xmlrpc.com/ \n
- * There is one function called \b XMLRPCtest() that can be used during 
+ * There is one function called \b XMLRPCtest() that can be used during
  * initial development to get started without actually making a request.\n
  * \n
  * The URL you will use to submit RPC calls is the URL for your VCL site
@@ -171,7 +171,7 @@ function XMLRPCaddRequest($imageid, $start, $length, 
$foruser='',
        $length = processInputData($length, ARG_NUMERIC);
        #$foruser = processInputData($foruser, ARG_STRING, 1);
 
-       // make sure user didn't submit a request for an image he 
+       // 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']);
@@ -233,7 +233,7 @@ function XMLRPCaddRequest($imageid, $start, $length, 
$foruser='',
        $revisionid = getProductionRevisionid($imageid);
        $rc = isAvailable($images, $imageid, $revisionid, $start, $end, 1);
        if($rc < 1) {
-               addLogEntry($nowfuture, unixToDatetime($start), 
+               addLogEntry($nowfuture, unixToDatetime($start),
                            unixToDatetime($end), 0, $imageid);
                return array('status' => 'notavailable');
        }
@@ -354,7 +354,7 @@ function XMLRPCaddRequestWithEnding($imageid, $start, $end, 
$foruser='',
        $revisionid = getProductionRevisionid($imageid);
        $rc = isAvailable($images, $imageid, $revisionid, $start, $end, 1);
        if($rc < 1) {
-               addLogEntry($nowfuture, unixToDatetime($start), 
+               addLogEntry($nowfuture, unixToDatetime($start),
                            unixToDatetime($end), 0, $imageid);
                return array('status' => 'notavailable');
        }
@@ -387,7 +387,7 @@ function XMLRPCaddRequestWithEnding($imageid, $start, $end, 
$foruser='',
 /// \param $foruser - (optional) login to be used when setting up the account
 /// on the reserved machine - CURRENTLY, THIS IS UNSUPPORTED
 /// \param $name - (optional) name for reservation
-/// \param $userdata - (optional) text that will be placed in 
+/// \param $userdata - (optional) text that will be placed in
 /// /root/.vclcontrol/post_reserve_userdata on the reserved node
 ///
 /// \return an array with at least one index named '\b status' which will have
@@ -562,7 +562,7 @@ function XMLRPCdeployServer($imageid, $start, $end, 
$admingroup='',
        $rc = isAvailable($images, $imageid, $revisionid, $start, $end,
                          1, 0, 0, 0, 0, $ipaddr, $macaddr);
        if($rc < 1) {
-               addLogEntry($nowfuture, unixToDatetime($start), 
+               addLogEntry($nowfuture, unixToDatetime($start),
                            unixToDatetime($end), 0, $imageid);
                return array('status' => 'notavailable');
        }
@@ -851,23 +851,23 @@ function XMLRPCgetRequestConnectData($requestid, 
$remoteIP) {
                $portdata = array();
                foreach($connectMethods as $key => $cm) {
                        $connecttext = $cm["connecttext"];
-                       $connecttext = preg_replace("/#userid#/", $thisuser, 
$connecttext); 
-                       $connecttext = preg_replace("/#password#/", $passwd, 
$connecttext); 
-                       $connecttext = preg_replace("/#connectIP#/", $serverIP, 
$connecttext); 
+                       $connecttext = preg_replace("/#userid#/", $thisuser, 
$connecttext);
+                       $connecttext = preg_replace("/#password#/", $passwd, 
$connecttext);
+                       $connecttext = preg_replace("/#connectIP#/", $serverIP, 
$connecttext);
                        foreach($cm['ports'] as $port) {
                                if(! empty($natports) && 
array_key_exists($port['key'], $natports[$key])) {
-                                       $connecttext = 
preg_replace("/{$port['key']}/", $natports[$key][$port['key']]['publicport'], 
$connecttext); 
+                                       $connecttext = 
preg_replace("/{$port['key']}/", $natports[$key][$port['key']]['publicport'], 
$connecttext);
                                        $connectMethods[$key]['connectports'][] 
= 
"{$port['protocol']}:{$port['port']}:{$natports[$key][$port['key']]['publicport']}";
                                }
                                else {
                                        if((preg_match('/remote desktop/i', 
$cm['description']) ||
-                                          preg_match('/RDP/i', 
$cm['description'])) && 
+                                          preg_match('/RDP/i', 
$cm['description'])) &&
                                           $port['key'] == '#Port-TCP-3389#') {
-                                               $connecttext = 
preg_replace("/{$port['key']}/", $user['rdpport'], $connecttext); 
+                                               $connecttext = 
preg_replace("/{$port['key']}/", $user['rdpport'], $connecttext);
                                                
$connectMethods[$key]['connectports'][] = 
"{$port['protocol']}:{$port['port']}:{$user['rdpport']}";
                                        }
                                        else {
-                                               $connecttext = 
preg_replace("/{$port['key']}/", $port['port'], $connecttext); 
+                                               $connecttext = 
preg_replace("/{$port['key']}/", $port['port'], $connecttext);
                                                
$connectMethods[$key]['connectports'][] = 
"{$port['protocol']}:{$port['port']}:{$port['port']}";
                                        }
                                }
@@ -880,7 +880,7 @@ function XMLRPCgetRequestConnectData($requestid, $remoteIP) 
{
                $cmid = $tmp[0];
                if(empty($natports))
                        if((preg_match('/remote desktop/i', 
$connectMethods[$cmid]['description']) ||
-                          preg_match('/RDP/i', 
$connectMethods[$cmid]['description'])) && 
+                          preg_match('/RDP/i', 
$connectMethods[$cmid]['description'])) &&
                                $portdata[$cmid][0]['port'] == 3389)
                                $connectport = $user['rdpport'];
                        else
@@ -1005,7 +1005,7 @@ function XMLRPCextendRequest($requestid, $extendtime) {
        if($timeToNext > -1) {
                $lockedall = 1;
                if(count($request['reservations']) > 1) {
-                       # get semaphore on each existing node in cluster so 
that nothing 
+                       # get semaphore on each existing node in cluster so 
that nothing
                        # can get moved to the nodes during this process
                        $checkend = unixToDatetime($endts + 900);
                        foreach($request["reservations"] as $res) {
@@ -1721,7 +1721,7 @@ function XMLRPCgetNodes($root=NULL) {
                        $node['id'] = $id;
                        array_push($nodes, $node);
                        array_push($stack, $node);
-               } 
+               }
                while(count($stack)) {
                        $item = array_shift($stack);
                        $children = getChildNodes($item['id']);
@@ -1962,7 +1962,7 @@ function XMLRPCgetUserGroupPrivs($name, $affiliation, 
$nodeid) {
 
        $privileges = array();
        $nodePrivileges = getNodePrivileges($nodeid, 'usergroups');
-       $cascadedNodePrivileges = getNodeCascadePrivileges($nodeid, 
'usergroups'); 
+       $cascadedNodePrivileges = getNodeCascadePrivileges($nodeid, 
'usergroups');
        $cngp = $cascadedNodePrivileges['usergroups'];
        $ngp = $nodePrivileges['usergroups'];
        if(array_key_exists($groupid, $cngp)) {
@@ -2180,7 +2180,7 @@ function XMLRPCgetResourceGroupPrivs($name, $type, 
$nodeid) {
                                     'errormsg' => 'resource group does not 
exist');
                }
                $np = getNodePrivileges($nodeid, 'resources');
-               $cnp = getNodeCascadePrivileges($nodeid, 'resources'); 
+               $cnp = getNodeCascadePrivileges($nodeid, 'resources');
                $key = "$type/$name/$groupid";
                if(isset($np['resources'][$key]['block']) || ! 
isset($cnp['resources'][$key]))
                        $privs = array_keys($np['resources'][$key]);
@@ -2399,9 +2399,9 @@ function XMLRPCgetUserGroups($groupType=0, 
$affiliationid=0) {
        // Filter out any groups to which the user does not have access.
        $usergroups = array();
        foreach($groups as $id => $group) {
-               if($group['ownerid'] == $user['id'] || 
+               if($group['ownerid'] == $user['id'] ||
                   (array_key_exists("editgroupid", $group) &&
-                  array_key_exists($group['editgroupid'], $user["groups"])) || 
+                  array_key_exists($group['editgroupid'], $user["groups"])) ||
                   (array_key_exists($id, $user["groups"]))) {
                        array_push($usergroups, $group);
                }
@@ -2476,7 +2476,7 @@ function XMLRPCgetUserGroupAttributes($name, 
$affiliation) {
                             'errormsg' => 'user group with submitted name and 
affiliation does not exist');
        }
        // if not owner and not member of managing group, no access
-       if($user['id'] != $row['ownerid'] && 
+       if($user['id'] != $row['ownerid'] &&
           ! array_key_exists($row['editgroupid'], $user['groups'])) {
                return array('status' => 'error',
                             'errorcode' => 69,
@@ -2854,7 +2854,7 @@ function XMLRPCgetUserGroupMembers($name, $affiliation) {
                             'errorcode' => 18,
                             'errormsg' => 'user group with submitted name and 
affiliation does not exist');
        }
-       // if custom and not owner and not member of managing group or 
+       // if custom and not owner and not member of managing group or
        //    custom/courseroll and no federated user group access, no access 
to delete group
        if(($row['custom'] == 1 && $user['id'] != $row['ownerid'] &&
           ! array_key_exists($row['editgroupid'], $user['groups'])) ||
@@ -2930,7 +2930,7 @@ function XMLRPCaddUsersToGroup($name, $affiliation, 
$users) {
                             'errormsg' => 'user group with submitted name and 
affiliation does not exist');
        }
        // if not owner and not member of managing group, no access
-       if($user['id'] != $row['ownerid'] && 
+       if($user['id'] != $row['ownerid'] &&
           ! array_key_exists($row['editgroupid'], $user['groups'])) {
                return array('status' => 'error',
                             'errorcode' => 28,
@@ -3012,7 +3012,7 @@ function XMLRPCremoveUsersFromGroup($name, $affiliation, 
$users) {
                             'errormsg' => 'user group with submitted name and 
affiliation does not exist');
        }
        // if not owner and not member of managing group, no access
-       if($user['id'] != $row['ownerid'] && 
+       if($user['id'] != $row['ownerid'] &&
           ! array_key_exists($row['editgroupid'], $user['groups'])) {
                return array('status' => 'error',
                             'errorcode' => 28,
@@ -3655,7 +3655,7 @@ function XMLRPCprocessBlockTime($blockTimesid, 
$ignoreprivileges=0) {
        $stagCnt = 0;
        $stagTime = 60;        # stagger reload reservations by 1 min
        if($imgLoadTime > 840) // if estimated load time is > 14 min
-               $stagTime = 120;    #    stagger reload reservations by 2 min 
+               $stagTime = 120;    #    stagger reload reservations by 2 min
        for($i = 0; $i < $reqToAlloc; $i++) {
                $stagunixstart = $unixstart - $loadtime - ($stagCnt * 
$stagTime);
                $stagstart = unixToDatetime($stagunixstart);
@@ -4003,8 +4003,8 @@ function XMLRPCgetOneClicks() {
                . "LEFT JOIN OS os ON (i.OSid = os.id) "
                . "LEFT JOIN ("
                .      "SELECT rs.imageid, "
-               .             "MAX(rq.id) AS requestid, " 
-               .             "COUNT(rq.id) AS reqcount " 
+               .             "MAX(rq.id) AS requestid, "
+               .             "COUNT(rq.id) AS reqcount "
                .      "FROM reservation rs, "
                .           "request rq "
                .      "WHERE rs.requestid = rq.id AND "
@@ -4200,7 +4200,7 @@ function XMLRPCeditOneClick($oneclickid, $name, $imageid, 
$duration, $autologin)
                             'errormsg' => "Specified duration is too long",
                             'maxduration' => $allowed);
        }
-       
+
        $query = "SELECT id "
               . "FROM oneclick "
               . "WHERE id = $oneclickid AND "
@@ -4218,7 +4218,7 @@ function XMLRPCeditOneClick($oneclickid, $name, $imageid, 
$duration, $autologin)
                             'errorcode' => 90,
                             'errormsg' => "The OneClick with ID $oneclickid 
does not belong to the user that requested it.");
        }*/
-       
+
        $query = "UPDATE oneclick "
               . "SET imageid = $imageid, "
               .     "name = '$name', "
@@ -4255,7 +4255,7 @@ function XMLRPCeditOneClick($oneclickid, $name, $imageid, 
$duration, $autologin)
 function XMLRPCdeleteOneClick($oneclickid) {
        global $user;
        $oneclickid = processInputData($oneclickid, ARG_NUMERIC);
-       
+
        $query = "SELECT id "
               . "FROM oneclick "
               . "WHERE id = $oneclickid AND "
diff --git a/web/index.php b/web/index.php
index 0d059c9..7a8e908 100644
--- a/web/index.php
+++ b/web/index.php
@@ -28,9 +28,7 @@ if (SSLOFFLOAD == 0) {
     }
 }
 
-$user = '';
-$mysqli_link_vcl = '';
-$mysqli_link_acct = '';
+$user = array();
 $mode = '';
 $oldmode = '';
 $submitErr = '';
diff --git a/web/js/code.js b/web/js/code.js
index 0b2c024..3391500 100644
--- a/web/js/code.js
+++ b/web/js/code.js
@@ -226,7 +226,7 @@ function showScriptOnly() {
        if(document.styleSheets[0].cssRules)  // Standards Compliant
                cssobj = document.styleSheets[0].cssRules;
        else
-               cssobj = document.styleSheets[0].rules;  // IE 
+               cssobj = document.styleSheets[0].rules;  // IE
        var stop = 0;
        for(var i = 0; i < cssobj.length; i++) {
                if(cssobj[i].selectorText) {
diff --git a/web/js/dashboard.js b/web/js/dashboard.js
index 59922f2..0591c5c 100644
--- a/web/js/dashboard.js
+++ b/web/js/dashboard.js
@@ -203,6 +203,7 @@ function updateNewReservations(data) {
            +  '<th>ReqID</th>'
            +  '<th>User</th>'
            +  '<th>Computer</th>'
+           +  '<th>VM Host</th>'
            +  '<th>States</th>'
            +  '<th>Image</th>'
            +  '<th>Install Type</th>'
@@ -222,6 +223,8 @@ function updateNewReservations(data) {
                    + '</td><td style=\"padding: 1px; border-right: 1px 
solid;\">'
                    + data[i].computer
                    + '</td><td style=\"padding: 1px; border-right: 1px 
solid;\">'
+                   + data[i].vmhost
+                   + '</td><td style=\"padding: 1px; border-right: 1px 
solid;\">'
                    + data[i].state
                    + '</td><td style=\"padding: 1px; border-right: 1px 
solid;\">'
                    + data[i].image
diff --git a/web/js/requests.js b/web/js/requests.js
index 4a28222..b8272f9 100644
--- a/web/js/requests.js
+++ b/web/js/requests.js
@@ -875,7 +875,7 @@ function configureSystemCB(data, ioArgs) {
        oldstore = dijit.byId('configvariables').store;
        dijit.byId('configvariables').setStore(newstore2, '', {query: {id: 
''}});
        delete oldstore;
-       
+
        // finishconfigs
        /*if(data.items.configs.length == 0)
                dijit.byId('newResDlgShowConfigBtn').set('disabled', true);
@@ -1388,7 +1388,7 @@ function endReservationCB(data, ioArgs) {
                dijit.byId('serverdeletedlg').show();
                return;
        }
-       if(dijit.byId('serverdeletedlg') && 
+       if(dijit.byId('serverdeletedlg') &&
           dijit.byId('serverdeletedlg').open) {
                dijit.byId('serverdeletedlg').hide();
                dijit.byId('serverDeleteDlgBtn').set('disabled', false);
@@ -1552,7 +1552,7 @@ function submitEditReservation() {
                data.day = dijit.byId('day').value;
        if(dijit.byId('editstarttime')) {
                var t = dijit.byId('editstarttime').value;
-               data.starttime = dojox.string.sprintf('%02d%02d', 
+               data.starttime = dojox.string.sprintf('%02d%02d',
                                                      t.getHours(),
                                                      t.getMinutes());
                var tmp = 
dijit.byId('day').value.match(/([0-9]{4})([0-9]{2})([0-9]{2})/);
@@ -1583,7 +1583,7 @@ function submitEditReservation() {
                data.endmode = 'length';
        }
        else if((dojo.byId('dateradio') && dojo.byId('dateradio').checked) ||
-               (dijit.byId('openenddate') && ! dojo.byId('indefiniteradio')) 
|| 
+               (dijit.byId('openenddate') && ! dojo.byId('indefiniteradio')) ||
                (dijit.byId('openenddate') && dojo.byId('indefiniteradio') && ! 
dojo.byId('indefiniteradio').checked)) {
                var d = dijit.byId('openenddate').value;
                var t = dijit.byId('openendtime').value;
diff --git a/web/js/resources/computer.js b/web/js/resources/computer.js
index 6e511ea..dd08e37 100644
--- a/web/js/resources/computer.js
+++ b/web/js/resources/computer.js
@@ -210,6 +210,32 @@ Computer.prototype.nocasesort = function(a, b) {
        return 0;
 }
 
+Computer.prototype.ipsort = function(a, b) {
+       var aparts = a.split('.');
+       var bparts = b.split('.');
+       for(var i = 0; i < 4; i++) {
+               aparts[i] = parseInt(aparts[i]);
+               bparts[i] = parseInt(bparts[i]);
+       }
+       if(aparts[0] < bparts[0])
+               return -1;
+       if(aparts[0] > bparts[0])
+               return 1;
+       if(aparts[1] < bparts[1])
+               return -1;
+       if(aparts[1] > bparts[1])
+               return 1;
+       if(aparts[2] < bparts[2])
+               return -1;
+       if(aparts[2] > bparts[2])
+               return 1;
+       if(aparts[3] < bparts[3])
+               return -1;
+       if(aparts[3] > bparts[3])
+               return 1;
+       return 0;
+}
+
 Computer.prototype.comparehostnames = function(a, b) {
        // get hostname
        var tmp = a.split('.');
@@ -291,6 +317,8 @@ function initPage() {
                resourcestore.comparatorMap['procnumber'] = resource.nocasesort;
                resourcestore.comparatorMap['procspeed'] = resource.nocasesort;
                resourcestore.comparatorMap['network'] = resource.nocasesort;
+               resourcestore.comparatorMap['IPaddress'] = resource.ipsort;
+               resourcestore.comparatorMap['privateIPaddress'] = 
resource.ipsort;
 
                dojo.connect(resourcegrid, '_onFetchComplete', function() 
{dojo.byId('computercount').innerHTML = 'Computers in table: ' + 
resourcegrid.rowCount;});
        }
@@ -1216,7 +1244,9 @@ function refreshcompdata(refreshcount) {
                                       procnumber: resource.nocasesort,
                                       procspeed: resource.nocasesort,
                                       network: resource.nocasesort,
-                                      ram: resource.nocasesort};
+                                      ram: resource.nocasesort,
+                                      IPaddress: resource.ipsort,
+                                      privateIPaddress: resource.ipsort};
        resourcestore.fetch();
        savescroll = resourcegrid.scrollTop;
        resourcegrid.setStore(resourcestore, resourcegrid.query);
diff --git a/web/js/resources/image.js b/web/js/resources/image.js
index b710c55..4ad565d 100644
--- a/web/js/resources/image.js
+++ b/web/js/resources/image.js
@@ -137,6 +137,12 @@ function inlineEditResourceCB(data, ioArgs) {
        }
 }
 
+function initAddDialog() {
+       if(dijit.byId('addomainid').options.length == 0) {
+               dijit.byId('adauthenable').set('disabled', true);
+       }
+}
+
 function delayedEditResize() {
        setTimeout(function() {resizeRecenterDijitDialog('addeditdlg');}, 300);
 }
@@ -781,6 +787,7 @@ function startImageCB(data, ioArgs) {
 function submitCreateUpdateImage() {
        if(dojo.byId('newimage').checked) {
                dijit.byId('addeditdlg').show();
+               initAddDialog();
                dijit.byId('startimagedlg').hide();
                return;
        }
diff --git a/web/js/vm.js b/web/js/vm.js
index 0864f9a..b56313b 100644
--- a/web/js/vm.js
+++ b/web/js/vm.js
@@ -183,6 +183,8 @@ function vmToHostCB(data, ioArgs) {
        if(data.items.failed) {
                if(data.items.failed == 'nohostaccess')
                        alert('You do not have access to manage this VM host.');
+               if(data.items.failed == 'invaliddata')
+                       alert('Invalid list of VMs submitted.');
                document.body.style.cursor = 'default';
                return;
        }
@@ -300,15 +302,18 @@ function vmFromHost(cont) {
                handleAs: "json",
                error: errorHandler,
                content: {continuation: cont,
-                                        listids: listids.join(','),
-                                        hostid: hostid},
+                         listids: listids.join(','),
+                         hostid: hostid},
                timeout: 15000
        });
 }
 
 function vmFromHostCB(data, ioArgs) {
        if(data.items.failed) {
-               alert('You do not have access to manage this VM host.');
+               if(data.items.failed == 'nohostaccess')
+                       alert('You do not have access to manage this VM host.');
+               if(data.items.failed == 'invaliddata')
+                       alert('Invalid list of VMs submitted.');
                document.body.style.cursor = 'default';
                return;
        }
@@ -412,7 +417,10 @@ function vmFromHostDelayed(cont) {
 
 function reloadVMhostCB(data, ioArgs) {
        if(data.items.failed) {
-               alert('You do not have access to manage this VM host.');
+               if(data.items.failed == 'nohostaccess')
+                       alert('You do not have access to manage this VM host.');
+               if(data.items.failed == 'invaliddata')
+                       alert('Invalid list of VMs submitted.');
                document.body.style.cursor = 'default';
                return;
        }

Reply via email to