r3078 - addPortInterfaceCompat(): new function
[racktables] / inc / ophandlers.php
index 1e3e4d1..fc7fd90 100644 (file)
@@ -5,82 +5,51 @@
 *
 */
 
-// This function assures that specified argument was passed
-// and is a number greater than zero.
-function assertUIntArg ($argname, $caller = 'N/A', $allow_zero = FALSE)
-{
-       if (!isset ($_REQUEST[$argname]))
-       {
-               showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
-       if (!is_numeric ($_REQUEST[$argname]))
-       {
-               showError ("Parameter '${argname}' is not a number (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
-       if ($_REQUEST[$argname] < 0)
-       {
-               showError ("Parameter '${argname}' is less than zero (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
-       if (!$allow_zero and $_REQUEST[$argname] == 0)
-       {
-               showError ("Parameter '${argname}' is equal to zero (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
-}
+$msgcode = array();
 
-// This function assures that specified argument was passed
-// and is a non-empty string.
-function assertStringArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
+function buildWideRedirectURL ($log, $nextpage = NULL, $nexttab = NULL, $moreArgs = array())
 {
-       if (!isset ($_REQUEST[$argname]))
-       {
-               showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
-       if (!is_string ($_REQUEST[$argname]))
-       {
-               showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
-       if (!$ok_if_empty and empty ($_REQUEST[$argname]))
-       {
-               showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
-}
+       global $root, $page, $pageno, $tabno;
+       if ($nextpage === NULL)
+               $nextpage = $pageno;
+       if ($nexttab === NULL)
+               $nexttab = $tabno;
+       $url = "${root}?page=${nextpage}&tab=${nexttab}";
+       if (isset ($page[$nextpage]['bypass']))
+               $url .= '&' . $page[$nextpage]['bypass'] . '=' . $_REQUEST[$page[$nextpage]['bypass']];
 
-function assertBoolArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
-{
-       if (!isset ($_REQUEST[$argname]))
-       {
-               showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
-       if (!is_string ($_REQUEST[$argname]) or $_REQUEST[$argname] != 'on')
-       {
-               showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
-       if (!$ok_if_empty and empty ($_REQUEST[$argname]))
+       if (count($moreArgs)>0)
        {
-               showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__);
-               die();
+               foreach($moreArgs as $arg=>$value)
+               {
+                       if (gettype($value) == 'array')
+                       {
+                               foreach ($value as $v)
+                               {
+                                       $url .= '&'.urlencode($arg.'[]').'='.urlencode($v);
+                               }
+                       }
+                       else
+                               $url .= '&'.urlencode($arg).'='.urlencode($value);
+               }
        }
+
+       $_SESSION['log'] = $log;
+       return $url;
 }
 
-function assertIPv4Arg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
+function buildRedirectURL ($callfunc, $status, $args = array(), $nextpage = NULL, $nexttab = NULL)
 {
-       assertStringArg ($argname, $caller, $ok_if_empty);
-       if (!empty ($_REQUEST[$argname]) and long2ip (ip2long ($_REQUEST[$argname])) !== $_REQUEST[$argname])
-       {
-               showError ("IPv4 address validation failed for value '" . $_REQUEST[$argname] . "' (calling function is [${caller}]).", __FUNCTION__);
-               die();
-       }
+       global $pageno, $tabno, $msgcode;
+       if ($nextpage === NULL)
+               $nextpage = $pageno;
+       if ($nexttab === NULL)
+               $nexttab = $tabno;
+       return buildWideRedirectURL (oneLiner ($msgcode[$callfunc][$status], $args), $nextpage, $nexttab);
 }
 
+$msgcode['addPortForwarding']['OK'] = 2;
+$msgcode['addPortForwarding']['ERR'] = 100;
 function addPortForwarding ()
 {
        assertUIntArg ('object_id', __FUNCTION__);
@@ -90,7 +59,7 @@ function addPortForwarding ()
        assertStringArg ('proto', __FUNCTION__);
        assertStringArg ('description', __FUNCTION__, TRUE);
        $remoteport = isset ($_REQUEST['remoteport']) ? $_REQUEST['remoteport'] : '';
-       if (empty ($remoteport))
+       if (!strlen ($remoteport))
                $remoteport = $_REQUEST['localport'];
 
        $error = newPortForwarding
@@ -105,11 +74,13 @@ function addPortForwarding ()
        );
 
        if ($error == '')
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
 }
 
+$msgcode['delPortForwarding']['OK'] = 3;
+$msgcode['delPortForwarding']['ERR'] = 100;
 function delPortForwarding ()
 {
        assertUIntArg ('object_id', __FUNCTION__);
@@ -129,11 +100,13 @@ function delPortForwarding ()
                $_REQUEST['proto']
        );
        if ($error == '')
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
 }
 
+$msgcode['updPortForwarding']['OK'] = 4;
+$msgcode['updPortForwarding']['ERR'] = 100;
 function updPortForwarding ()
 {
        assertUIntArg ('object_id', __FUNCTION__);
@@ -155,55 +128,66 @@ function updPortForwarding ()
                $_REQUEST['description']
        );
        if ($error == '')
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
 }
 
+$msgcode['addPortForObject']['OK'] = 5;
+$msgcode['addPortForObject']['ERR1'] = 101;
+$msgcode['addPortForObject']['ERR2'] = 100;
 function addPortForObject ()
 {
        assertUIntArg ('object_id', __FUNCTION__);
        assertStringArg ('port_name', __FUNCTION__, TRUE);
-       if (empty ($_REQUEST['port_name']))
-               return buildRedirectURL ('ERR1');
+       if (!strlen ($_REQUEST['port_name']))
+               return buildRedirectURL (__FUNCTION__, 'ERR1');
        $error = commitAddPort ($_REQUEST['object_id'], $_REQUEST['port_name'], $_REQUEST['port_type_id'], $_REQUEST['port_label'], $_REQUEST['port_l2address']);
        if ($error != '')
-               return buildRedirectURL ('ERR2', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR2', array ($error));
        else
-               return buildRedirectURL ('OK', array ($_REQUEST['port_name']));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['port_name']));
 }
 
+$msgcode['editPortForObject']['OK'] = 6;
+$msgcode['editPortForObject']['ERR1'] = 101;
+$msgcode['editPortForObject']['ERR2'] = 100;
 function editPortForObject ()
 {
+       assertUIntArg ('object_id', __FUNCTION__);
        assertUIntArg ('port_id', __FUNCTION__);
        assertUIntArg ('port_type_id', __FUNCTION__);
        // tolerate empty value now to produce custom informative message later
        assertStringArg ('name', __FUNCTION__, TRUE);
-       if (empty ($_REQUEST['name']))
-               return buildRedirectURL ('ERR1');
+       if (!strlen ($_REQUEST['name']))
+               return buildRedirectURL (__FUNCTION__, 'ERR1');
 
-       if (isset ($_REQUEST['reservation_comment']) and !empty ($_REQUEST['reservation_comment']))
+       if (isset ($_REQUEST['reservation_comment']) and strlen ($_REQUEST['reservation_comment']))
                $port_rc = '"' . $_REQUEST['reservation_comment'] . '"';
        else
                $port_rc = 'NULL';
-       $error = commitUpdatePort ($_REQUEST['port_id'], $_REQUEST['name'], $_REQUEST['port_type_id'], $_REQUEST['label'], $_REQUEST['l2address'], $port_rc);
+       $error = commitUpdatePort ($_REQUEST['object_id'], $_REQUEST['port_id'], $_REQUEST['name'], $_REQUEST['port_type_id'], $_REQUEST['label'], $_REQUEST['l2address'], $port_rc);
        if ($error != '')
-               return buildRedirectURL ('ERR2', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR2', array ($error));
        else
-               return buildRedirectURL ('OK', array ($_REQUEST['name']));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['name']));
 }
 
+$msgcode['delPortFromObject']['OK'] = 7;
+$msgcode['delPortFromObject']['ERR'] = 100;
 function delPortFromObject ()
 {
        assertUIntArg ('port_id', __FUNCTION__);
        $error = delObjectPort ($_REQUEST['port_id']);
 
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK', array ($_REQUEST['port_name']));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['port_name']));
 }
 
+$msgcode['linkPortForObject']['OK'] = 8;
+$msgcode['linkPortForObject']['ERR'] = 100;
 function linkPortForObject ()
 {
        assertUIntArg ('port_id', __FUNCTION__);
@@ -214,11 +198,13 @@ function linkPortForObject ()
 
        $error = linkPorts ($_REQUEST['port_id'], $_REQUEST['remote_port_id']);
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK', array ($_REQUEST['port_name'], $_REQUEST['remote_port_name'], $_REQUEST['remote_object_name']));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['port_name'], $_REQUEST['remote_port_name'], $_REQUEST['remote_object_name']));
 }
 
+$msgcode['unlinkPortForObject']['OK'] = 9;
+$msgcode['unlinkPortForObject']['ERR'] = 100;
 function unlinkPortForObject ()
 {
        assertUIntArg ('port_id', __FUNCTION__);
@@ -228,11 +214,13 @@ function unlinkPortForObject ()
 
        $error = unlinkPort ($_REQUEST['port_id']);
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK', array ($_REQUEST['port_name'], $_REQUEST['remote_port_name'], $_REQUEST['remote_object_name']));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['port_name'], $_REQUEST['remote_port_name'], $_REQUEST['remote_object_name']));
 }
 
+$msgcode['addMultiPorts']['OK'] = 10;
+$msgcode['addMultiPorts']['ERR'] = 123;
 function addMultiPorts ()
 {
        assertStringArg ('format', __FUNCTION__);
@@ -249,7 +237,7 @@ function addMultiPorts ()
        {
                $parts = explode ('\r', $line);
                reset ($parts);
-               if (empty ($parts[0]))
+               if (!strlen ($parts[0]))
                        continue;
                else
                        $lines2[] = rtrim ($parts[0]);
@@ -305,7 +293,7 @@ http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a008
                                break;
                        case 'ssv1':
                                $words = explode (' ', $line);
-                               if (empty ($words[0]) or empty ($words[1]))
+                               if (!strlen ($words[0]) or !strlen ($words[1]))
                                        continue;
                                $ports[] = array
                                (
@@ -315,7 +303,7 @@ http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a008
                                );
                                break;
                        default:
-                               return buildRedirectURL ('ERR');
+                               return buildRedirectURL (__FUNCTION__, 'ERR');
                                break;
                }
        }
@@ -334,16 +322,18 @@ http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a008
                }
                else
                {
-                       $result = commitUpdatePort ($port_id, $port['name'], $port_type, $port['label'], $port['l2address']);
+                       $result = commitUpdatePort ($object_id, $port_id, $port['name'], $port_type, $port['label'], $port['l2address']);
                        if ($result == '')
                                $updated_count++;
                        else
                                $error_count++;
                }
        }
-       return buildRedirectURL ('OK', array ($added_count, $updated_count, $error_count));
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($added_count, $updated_count, $error_count));
 }
 
+$msgcode['updIPv4Allocation']['OK'] = 12;
+$msgcode['updIPv4Allocation']['ERR'] = 100;
 function updIPv4Allocation ()
 {
        assertIPv4Arg ('ip', __FUNCTION__);
@@ -353,11 +343,13 @@ function updIPv4Allocation ()
 
        $error = updateBond ($_REQUEST['ip'], $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['delIPv4Allocation']['OK'] = 14;
+$msgcode['delIPv4Allocation']['ERR'] = 100;
 function delIPv4Allocation ()
 {
        assertIPv4Arg ('ip', __FUNCTION__);
@@ -365,11 +357,14 @@ function delIPv4Allocation ()
 
        $error = unbindIpFromObject ($_REQUEST['ip'], $_REQUEST['object_id']);
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['addIPv4Allocation']['OK'] = 13;
+$msgcode['addIPv4Allocation']['ERR1'] = 170;
+$msgcode['addIPv4Allocation']['ERR2'] = 100;
 function addIPv4Allocation ()
 {
        assertIPv4Arg ('ip', __FUNCTION__);
@@ -380,13 +375,13 @@ function addIPv4Allocation ()
        // Strip masklen.
        $ip = ereg_replace ('/[[:digit:]]+$', '', $_REQUEST['ip']);
        if  (getConfigVar ('IPV4_JAYWALK') != 'yes' and NULL === getIPv4AddressNetworkId ($ip))
-               return buildRedirectURL ('ERR1', array ($ip));
+               return buildRedirectURL (__FUNCTION__, 'ERR1', array ($ip));
        
        $error = bindIpToObject ($ip, $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
        if ($error != '')
-               return buildRedirectURL ('ERR2', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR2', array ($error));
        $address = getIPv4Address ($ip);
-       if ($address['reserved'] == 'yes' or !empty ($address['name']))
+       if ($address['reserved'] == 'yes' or strlen ($address['name']))
        {
                $release = getConfigVar ('IPV4_AUTO_RELEASE');
                if ($release >= 1)
@@ -395,9 +390,15 @@ function addIPv4Allocation ()
                        $address['name'] = '';
                updateAddress ($ip, $address['name'], $address['reserved']);
        }
-       return buildRedirectURL ('OK');
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['addIPv4Prefix']['OK'] = 23;
+$msgcode['addIPv4Prefix']['ERR'] = 100;
+$msgcode['addIPv4Prefix']['ERR1'] = 173;
+$msgcode['addIPv4Prefix']['ERR2'] = 174;
+$msgcode['addIPv4Prefix']['ERR3'] = 175;
+$msgcode['addIPv4Prefix']['ERR4'] = 176;
 function addIPv4Prefix ()
 {
        assertStringArg ('range', __FUNCTION__);
@@ -407,33 +408,39 @@ function addIPv4Prefix ()
        $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
        $error = createIPv4Prefix ($_REQUEST['range'], $_REQUEST['name'], $is_bcast == 'on', $taglist);
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['delIPv4Prefix']['OK'] = 24;
+$msgcode['delIPv4Prefix']['ERR'] = 100;
 function delIPv4Prefix ()
 {
        assertUIntArg ('id', __FUNCTION__);
        $error = destroyIPv4Prefix ($_REQUEST['id']);
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['updIPv4Prefix']['OK'] = 25;
+$msgcode['updIPv4Prefix']['ERR'] = 100;
 function updIPv4Prefix ()
 {
        assertUIntArg ('id', __FUNCTION__);
        assertStringArg ('name', __FUNCTION__, TRUE);
-
-       $error = updateRange ($_REQUEST['id'], $_REQUEST['name']);
-       if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+       assertStringArg ('comment', __FUNCTION__, TRUE);
+       global $sic;
+       if (strlen ($error = updateIPv4Network_real ($sic['id'], $sic['name'], $sic['comment'])))
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['editAddress']['OK'] = 27;
+$msgcode['editAddress']['ERR'] = 100;
 function editAddress ()
 {
        assertIPv4Arg ('ip', __FUNCTION__);
@@ -445,25 +452,31 @@ function editAddress ()
                $reserved = 'off';
        $error = updateAddress ($_REQUEST['ip'], $_REQUEST['name'], $reserved == 'on' ? 'yes' : 'no');
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['createUser']['OK'] = 40;
+$msgcode['createUser']['ERR'] = 102;
 function createUser ()
 {
        assertStringArg ('username', __FUNCTION__);
        assertStringArg ('realname', __FUNCTION__, TRUE);
        assertStringArg ('password', __FUNCTION__);
        $username = $_REQUEST['username'];
-       $password = hash (PASSWORD_HASH, $_REQUEST['password']);
+       $password = sha1 ($_REQUEST['password']);
        $result = commitCreateUserAccount ($username, $_REQUEST['realname'], $password);
-       if ($result == TRUE)
-               return buildRedirectURL ('OK', array ($username));
-       else
-               return buildRedirectURL ('ERR', array ($username));
+       if ($result != TRUE)
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($username));
+       if (isset ($_REQUEST['taglist']))
+               produceTagsForLastRecord ('user', $_REQUEST['taglist']);
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($username));
 }
 
+$msgcode['updateUser']['OK'] = 39;
+$msgcode['updateUser']['ERR1'] = 103;
+$msgcode['updateUser']['ERR1'] = 104;
 function updateUser ()
 {
        assertUIntArg ('user_id', __FUNCTION__);
@@ -472,44 +485,26 @@ function updateUser ()
        assertStringArg ('password', __FUNCTION__);
        $username = $_REQUEST['username'];
        $new_password = $_REQUEST['password'];
-       $old_hash = getHashByID ($_REQUEST['user_id']);
-       if ($old_hash == NULL)
-               return buildRedirectURL ('ERR1');
+       if (NULL == ($userinfo = spotEntity ('user', $_REQUEST['user_id'])))
+               return buildRedirectURL (__FUNCTION__, 'ERR1');
        // Update user password only if provided password is not the same as current password hash.
-       if ($new_password != $old_hash)
-               $new_password = hash (PASSWORD_HASH, $new_password);
+       if ($new_password != $userinfo['user_password_hash'])
+               $new_password = sha1 ($new_password);
        $result = commitUpdateUserAccount ($_REQUEST['user_id'], $username, $_REQUEST['realname'], $new_password);
        if ($result == TRUE)
-               return buildRedirectURL ('OK', array ($username));
-       else
-               return buildRedirectURL ('ERR2', array ($username));
-}
-
-function enableUser ()
-{
-       assertUIntArg ('user_id', __FUNCTION__);
-       if (commitEnableUserAccount ($_REQUEST['user_id'], 'yes') == TRUE)
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($username));
        else
-               return buildRedirectURL ('ERR');
-}
-
-function disableUser ()
-{
-       assertUIntArg ('user_id', __FUNCTION__);
-       if ($_REQUEST['user_id'] == 1)
-               return buildRedirectURL ('ERR1');
-       if (commitEnableUserAccount ($_REQUEST['user_id'], 'no'))
-               return buildRedirectURL ('OK');
-       else
-               return buildRedirectURL ('ERR2');
+               return buildRedirectURL (__FUNCTION__, 'ERR2', array ($username));
 }
 
+$msgcode['savePortMap']['OK'] = 44;
+$msgcode['savePortMap']['ERR'] = 108;
 // This function find differences in users's submit and PortCompat table
 // and modifies database accordingly.
 function savePortMap ()
 {
-       $ptlist = getPortTypes();
+       // values' format doesn't matter, only keys are used
+       $ptlist = readChapter (CHAP_PORTTYPE);
        $oldCompat = getPortCompat();
        $newCompat = array();
        foreach (array_keys ($ptlist) as $leftKey)
@@ -546,133 +541,241 @@ function savePortMap ()
                                                break;
                                }
        if ($error_count == 0)
-               return buildRedirectURL ('OK', array ($error_count, $success_count));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($error_count, $success_count));
        else
-               return buildRedirectURL ('ERR', array ($error_count, $success_count));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error_count, $success_count));
 }
 
+$msgcode['updateDictionary']['OK'] = 51;
+$msgcode['updateDictionary']['ERR'] = 109;
 function updateDictionary ()
 {
        assertUIntArg ('chapter_no', __FUNCTION__);
        assertUIntArg ('dict_key', __FUNCTION__);
        assertStringArg ('dict_value', __FUNCTION__);
        if (commitUpdateDictionary ($_REQUEST['chapter_no'], $_REQUEST['dict_key'], $_REQUEST['dict_value']) === TRUE)
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['supplementDictionary']['OK'] = 52;
+$msgcode['supplementDictionary']['ERR'] = 110;
 function supplementDictionary ()
 {
        assertUIntArg ('chapter_no', __FUNCTION__);
        assertStringArg ('dict_value', __FUNCTION__);
        if (commitSupplementDictionary ($_REQUEST['chapter_no'], $_REQUEST['dict_value']) === TRUE)
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['reduceDictionary']['OK'] = 50;
+$msgcode['reduceDictionary']['ERR'] = 111;
 function reduceDictionary ()
 {
        assertUIntArg ('chapter_no', __FUNCTION__);
        assertUIntArg ('dict_key', __FUNCTION__);
        if (commitReduceDictionary ($_REQUEST['chapter_no'], $_REQUEST['dict_key']) === TRUE)
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['addChapter']['OK'] = 55;
+$msgcode['addChapter']['ERR'] = 112;
 function addChapter ()
 {
        assertStringArg ('chapter_name', __FUNCTION__);
        if (commitAddChapter ($_REQUEST['chapter_name']) === TRUE)
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['updateChapter']['OK'] = 54;
+$msgcode['updateChapter']['ERR'] = 113;
 function updateChapter ()
 {
        assertUIntArg ('chapter_no', __FUNCTION__);
        assertStringArg ('chapter_name', __FUNCTION__);
        if (commitUpdateChapter ($_REQUEST['chapter_no'], $_REQUEST['chapter_name']) === TRUE)
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['delChapter']['OK'] = 53;
+$msgcode['delChapter']['ERR'] = 114;
 function delChapter ()
 {
        assertUIntArg ('chapter_no', __FUNCTION__);
        if (commitDeleteChapter ($_REQUEST['chapter_no']))
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['changeAttribute']['OK'] = 46;
+$msgcode['changeAttribute']['ERR'] = 115;
 function changeAttribute ()
 {
        assertUIntArg ('attr_id', __FUNCTION__);
        assertStringArg ('attr_name', __FUNCTION__);
        if (commitUpdateAttribute ($_REQUEST['attr_id'], $_REQUEST['attr_name']))
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['createAttribute']['OK'] = 45;
+$msgcode['createAttribute']['ERR'] = 116;
 function createAttribute ()
 {
        assertStringArg ('attr_name', __FUNCTION__);
        assertStringArg ('attr_type', __FUNCTION__);
        if (commitAddAttribute ($_REQUEST['attr_name'], $_REQUEST['attr_type']))
-               return buildRedirectURL ('OK', array ($_REQUEST['attr_name']));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['attr_name']));
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['deleteAttribute']['OK'] = 47;
+$msgcode['deleteAttribute']['ERR'] = 117;
 function deleteAttribute ()
 {
        assertUIntArg ('attr_id', __FUNCTION__);
        if (commitDeleteAttribute ($_REQUEST['attr_id']))
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['supplementAttrMap']['OK'] = 48;
+$msgcode['supplementAttrMap']['ERR1'] = 154;
+$msgcode['supplementAttrMap']['ERR2'] = 118;
 function supplementAttrMap ()
 {
        assertUIntArg ('attr_id', __FUNCTION__);
        assertUIntArg ('objtype_id', __FUNCTION__);
-       assertUIntArg ('chapter_no', __FUNCTION__);
-       if (commitSupplementAttrMap ($_REQUEST['attr_id'], $_REQUEST['objtype_id'], $_REQUEST['chapter_no']) === TRUE)
-               return buildRedirectURL ('OK');
+       $attrMap = getAttrMap();
+       if ($attrMap[$_REQUEST['attr_id']]['type'] != 'dict')
+               $chapter_id = 'NULL';
        else
-               return buildRedirectURL ('ERR');
+       {
+               assertUIntArg ('chapter_no', __FUNCTION__); // FIXME: this doesn't fail on 0 (ticket:272)
+               if (0 == ($chapter_id = $_REQUEST['chapter_no']))
+                       return buildRedirectURL (__FUNCTION__, 'ERR1', array ('chapter not selected'));
+       }
+       if (commitSupplementAttrMap ($_REQUEST['attr_id'], $_REQUEST['objtype_id'], $chapter_id) === TRUE)
+               return buildRedirectURL (__FUNCTION__, 'OK');
+       else
+               return buildRedirectURL (__FUNCTION__, 'ERR2');
 }
 
+$msgcode['reduceAttrMap']['OK'] = 49;
+$msgcode['reduceAttrMap']['ERR'] = 119;
 function reduceAttrMap ()
 {
        assertUIntArg ('attr_id', __FUNCTION__);
        assertUIntArg ('objtype_id', __FUNCTION__);
        if (commitReduceAttrMap ($_REQUEST['attr_id'], $_REQUEST['objtype_id']) === TRUE)
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['clearSticker']['OK'] = 15;
+$msgcode['clearSticker']['ERR'] = 120;
 function clearSticker ()
 {
        assertUIntArg ('attr_id', __FUNCTION__);
        assertUIntArg ('object_id', __FUNCTION__);
        if (commitResetAttrValue ($_REQUEST['object_id'], $_REQUEST['attr_id']) === TRUE)
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
+       else
+               return buildRedirectURL (__FUNCTION__, 'ERR');
+}
+
+$msgcode['updateObjectAllocation']['OK'] = 63;
+function updateObjectAllocation ()
+{
+       assertUIntArg ('object_id', __FUNCTION__);
+
+       if (!isset ($_REQUEST['got_atoms']))
+       {
+               unset($_GET['page']);
+               unset($_GET['tab']);
+               unset($_GET['op']);
+               unset($_POST['page']);
+               unset($_POST['tab']);
+               unset($_POST['op']);
+               return buildWideRedirectURL (array(), NULL, NULL, array_merge ($_GET, $_POST));
+       }
+       $object_id = $_REQUEST['object_id'];
+       $workingRacksData = array();
+       foreach ($_REQUEST['rackmulti'] as $cand_id)
+       {
+               if (!isset ($workingRacksData[$cand_id]))
+               {
+                       $rackData = spotEntity ('rack', $cand_id);
+                       if ($rackData == NULL)
+                       {
+                               showError ('rack not found', __FUNCTION__);
+                               return;
+                       }
+                       amplifyCell ($rackData);
+                       $workingRacksData[$cand_id] = $rackData;
+               }
+       }
+
+       foreach ($workingRacksData as &$rd)
+               applyObjectMountMask ($rd, $object_id);
+
+       $oldMolecule = getMoleculeForObject ($object_id);
+       $changecnt = 0;
+       $log = array();
+       foreach ($workingRacksData as $rack_id => $rackData)
+       {
+               $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
+               $log[] = $logrecord;
+               if ($logrecord['code'] == 300)
+                       continue;
+               $changecnt++;
+               // Reload our working copy after form processing.
+               $rackData = spotEntity ('rack', $cand_id);
+               amplifyCell ($rackData);
+               applyObjectMountMask ($rackData, $object_id);
+               $workingRacksData[$rack_id] = $rackData;
+       }
+       if (!$changecnt)
+               return buildRedirectURL (__FUNCTION__, 'OK', $changecnt);
+       // Log a record.
+       $newMolecule = getMoleculeForObject ($object_id);
+       $oc = count ($oldMolecule);
+       $nc = count ($newMolecule);
+       $omid = $oc ? createMolecule ($oldMolecule) : 'NULL';
+       $nmid = $nc ? createMolecule ($newMolecule) : 'NULL';
+       global $remote_username;
+       $comment = empty ($_REQUEST['comment']) ? 'NULL' : "'${_REQUEST['comment']}'";
+       $query =
+               "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
+               "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
+       global $dbxlink;
+       $result = $dbxlink->query ($query);
+       if ($result == NULL)
+               $log[] = array ('code' => 500, 'message' => 'SQL query failed during history logging.');
        else
-               return buildRedirectURL ('ERR');
+               $log[] = array ('code' => 200, 'message' => 'History logged.');
+       return buildWideRedirectURL ($log);
 }
 
+$msgcode['updateObject']['OK'] = 16;
+$msgcode['updateObject']['ERR'] = 121;
 function updateObject ()
 {
-       assertUIntArg ('num_attrs', __FUNCTION__);
+       assertUIntArg ('num_attrs', __FUNCTION__, TRUE);
        assertUIntArg ('object_id', __FUNCTION__);
        assertUIntArg ('object_type_id', __FUNCTION__);
        assertStringArg ('object_name', __FUNCTION__, TRUE);
@@ -694,18 +797,19 @@ function updateObject ()
                $_REQUEST['object_asset_no'],
                $_REQUEST['object_comment']
        ) !== TRUE)
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 
        // Update optional attributes
        $oldvalues = getAttrValues ($_REQUEST['object_id']);
        $result = array();
-       for ($i = 0; $i < $_REQUEST['num_attrs']; $i++)
+       $num_attrs = isset ($_REQUEST['num_attrs']) ? $_REQUEST['num_attrs'] : 0;
+       for ($i = 0; $i < $num_attrs; $i++)
        {
                assertUIntArg ("${i}_attr_id", __FUNCTION__);
                $attr_id = $_REQUEST["${i}_attr_id"];
 
                // Field is empty, delete attribute and move on.
-               if (empty($_REQUEST["${i}_value"]))
+               if (!strlen ($_REQUEST["${i}_value"]))
                {
                        commitResetAttrValue ($_REQUEST['object_id'], $attr_id);
                        continue;
@@ -729,35 +833,128 @@ function updateObject ()
                                showError ('Internal structure error', __FUNCTION__);
                                die;
                }
-               if ($value == $oldvalue)
+               if ($value === $oldvalue) // ('' == 0), but ('' !== 0)
                        continue;
 
                // Note if the queries succeed or not, it determines which page they see.
                $result[] = commitUpdateAttrValue ($_REQUEST['object_id'], $attr_id, $value);
        }
        if (in_array (FALSE, $result))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 
        // Invalidate thumb cache of all racks objects could occupy.
        foreach (getResidentRacksData ($_REQUEST['object_id'], FALSE) as $rack_id)
                resetThumbCache ($rack_id);
 
-       return buildRedirectURL ('OK');
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+
+function addMultipleObjects()
+{
+       $log = emptyLog();
+       $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
+       $max = getConfigVar ('MASSCOUNT');
+       for ($i = 0; $i < $max; $i++)
+       {
+               if (!isset ($_REQUEST["${i}_object_type_id"]))
+               {
+                       $log = mergeLogs ($log, oneLiner (184, array ($i + 1)));
+                       break;
+               }
+               assertUIntArg ("${i}_object_type_id", __FUNCTION__, TRUE);
+               assertStringArg ("${i}_object_name", __FUNCTION__, TRUE);
+               assertStringArg ("${i}_object_label", __FUNCTION__, TRUE);
+               assertStringArg ("${i}_object_asset_no", __FUNCTION__, TRUE);
+               assertStringArg ("${i}_object_barcode", __FUNCTION__, TRUE);
+               $name = $_REQUEST["${i}_object_name"];
+
+               // It's better to skip silently, than to print a notice.
+               if ($_REQUEST["${i}_object_type_id"] == 0)
+                       continue;
+               if (commitAddObject
+               (
+                       $name,
+                       $_REQUEST["${i}_object_label"],
+                       $_REQUEST["${i}_object_barcode"],
+                       $_REQUEST["${i}_object_type_id"],
+                       $_REQUEST["${i}_object_asset_no"],
+                       $taglist
+               ) === TRUE)
+                       $log = mergeLogs ($log, oneLiner (80, array ($name)));
+               else
+                       $log = mergeLogs ($log, oneLiner (185, array ($name)));
+       }
+       return buildWideRedirectURL ($log);
+}
+
+function addLotOfObjects()
+{
+       $log = emptyLog();
+       $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
+       assertUIntArg ('global_type_id', __FUNCTION__, TRUE);
+       assertStringArg ('namelist', __FUNCTION__, TRUE);
+       $global_type_id = $_REQUEST['global_type_id'];
+       if ($global_type_id == 0 or !strlen ($_REQUEST['namelist']))
+               $log = mergeLogs ($log, oneLiner (186));
+       else
+       {
+               // The name extractor below was stolen from ophandlers.php:addMultiPorts()
+               $names1 = explode ('\n', $_REQUEST['namelist']);
+               $names2 = array();
+               foreach ($names1 as $line)
+               {
+                       $parts = explode ('\r', $line);
+                       reset ($parts);
+                       if (!strlen ($parts[0]))
+                               continue;
+                       else
+                               $names2[] = rtrim ($parts[0]);
+               }
+               foreach ($names2 as $name)
+                       if (commitAddObject ($name, '', '', $global_type_id, '', $taglist) === TRUE)
+                               $log = mergeLogs ($log, oneLiner (80, array ($name)));
+                       else
+                               $log = mergeLogs ($log, oneLiner (185, array ($name)));
+       }
+       return buildWideRedirectURL ($log);
+}
+
+$msgcode['deleteObject']['OK'] = 76;
+$msgcode['deleteObject']['ERR'] = 100;
+function deleteObject ()
+{
+       assertUIntArg ('object_id', __FUNCTION__);
+       if (NULL === ($oinfo = spotEntity ('object', $_REQUEST['object_id'])))
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ('object not found'));
+
+       $racklist = getResidentRacksData ($_REQUEST['object_id'], FALSE);
+       $error = commitDeleteObject ($_REQUEST['object_id']);
+       foreach ($racklist as $rack_id)
+               resetThumbCache ($rack_id);
+
+       if ($error != '')
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
+
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($oinfo['dname']));
+}
+
+$msgcode['useupPort']['OK'] = 11;
+$msgcode['useupPort']['ERR'] = 124;
 function useupPort ()
 {
        assertUIntArg ('port_id', __FUNCTION__);
        if (commitUseupPort ($_REQUEST['port_id']) === TRUE)
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['updateUI']['OK'] = 56;
+$msgcode['updateUI']['ERR'] = 125;
 function updateUI ()
 {
        assertUIntArg ('num_vars', __FUNCTION__);
-       $error = '';
 
        for ($i = 0; $i < $_REQUEST['num_vars']; $i++)
        {
@@ -767,37 +964,29 @@ function updateUI ()
                $varvalue = $_REQUEST["${i}_varvalue"];
 
                // If form value = value in DB, don't bother updating DB
-               if ($varvalue == getConfigVar ($varname))
+               if ($varvalue === getConfigVar ($varname))
                        continue;
 
                // Note if the queries succeed or not, it determines which page they see.
                $error = setConfigVar ($varname, $varvalue, TRUE);
-               if (!empty ($error))
-                       break;
+               if (strlen ($error))
+                       return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        }
-
-       if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
-
-       return buildRedirectURL ('OK');
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['resetUIConfig']['OK'] = 57;
 function resetUIConfig()
 {
        setConfigVar ('default_port_type','24');
        setConfigVar ('MASSCOUNT','15');
        setConfigVar ('MAXSELSIZE','30');
-       setConfigVar ('NAMEFUL_OBJTYPES','4,7,8');
        setConfigVar ('ROW_SCALE','2');
        setConfigVar ('PORTS_PER_ROW','12');
        setConfigVar ('IPV4_ADDRS_PER_PAGE','256');
        setConfigVar ('DEFAULT_RACK_HEIGHT','42');
-       setConfigVar ('REQUIRE_ASSET_TAG_FOR','4,7,8');
-       setConfigVar ('USER_AUTH_SRC','database');
        setConfigVar ('DEFAULT_SLB_VS_PORT','');
        setConfigVar ('DEFAULT_SLB_RS_PORT','');
-       setConfigVar ('IPV4_PERFORMERS','1,4,7,8,12,14,445,447');
-       setConfigVar ('NATV4_PERFORMERS','4,7,8');
        setConfigVar ('DETECT_URLS','no');
        setConfigVar ('RACK_PRESELECT_THRESHOLD','1');
        setConfigVar ('DEFAULT_IPV4_RS_INSERVICE','no');
@@ -808,14 +997,39 @@ function resetUIConfig()
        setConfigVar ('DEFAULT_OBJECT_TYPE','4');
        setConfigVar ('IPV4_AUTO_RELEASE','1');
        setConfigVar ('SHOW_LAST_TAB', 'no');
-       setConfigVar ('COOKIE_TTL', '1209600');
        setConfigVar ('EXT_IPV4_VIEW', 'yes');
        setConfigVar ('TREE_THRESHOLD', '25');
        setConfigVar ('IPV4_JAYWALK', 'no');
        setConfigVar ('ADDNEW_AT_TOP', 'yes');
-       return buildRedirectURL ('OK');
-}
-
+       setConfigVar ('IPV4_TREE_SHOW_USAGE', 'yes');
+       setConfigVar ('PREVIEW_TEXT_MAXCHARS', '10240');
+       setConfigVar ('PREVIEW_TEXT_ROWS', '25');
+       setConfigVar ('PREVIEW_TEXT_COLS', '80');
+       setConfigVar ('PREVIEW_IMAGE_MAXPXS', '320');
+       setConfigVar ('VENDOR_SIEVE', '');
+       setConfigVar ('IPV4LB_LISTSRC', '{$typeid_4}');
+       setConfigVar ('IPV4OBJ_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8} or {$typeid_12} or {$typeid_445} or {$typeid_447}');
+       setConfigVar ('IPV4NAT_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
+       setConfigVar ('ASSETWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
+       setConfigVar ('NAMEWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
+       setConfigVar ('RACKS_PER_ROW','12');
+       setConfigVar ('FILTER_PREDICATE_SIEVE','');
+       setConfigVar ('FILTER_DEFAULT_ANDOR','or');
+       setConfigVar ('FILTER_SUGGEST_ANDOR','yes');
+       setConfigVar ('FILTER_SUGGEST_TAGS','yes');
+       setConfigVar ('FILTER_SUGGEST_PREDICATES','yes');
+       setConfigVar ('FILTER_SUGGEST_EXTRA','no');
+        setConfigVar ('DEFAULT_SNMP_COMMUNITY','public');
+       setConfigVar ('IPV4_ENABLE_KNIGHT','yes');
+       setConfigVar ('TAGS_TOPLIST_SIZE','50');
+       setConfigVar ('TAGS_QUICKLIST_SIZE','20');
+       setConfigVar ('TAGS_QUICKLIST_THRESHOLD','50');
+       setConfigVar ('ENABLE_MULTIPORT_FORM', 'no');
+       return buildRedirectURL (__FUNCTION__, 'OK');
+}
+
+$msgcode['addRealServer']['OK'] = 34;
+$msgcode['addRealServer']['ERR'] = 126;
 // Add single record.
 function addRealServer ()
 {
@@ -830,11 +1044,14 @@ function addRealServer ()
                getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'),
                $_REQUEST['rsconfig']
        ))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['addRealServers']['OK'] = 37;
+$msgcode['addRealServers']['ERR1'] = 131;
+$msgcode['addRealServers']['ERR2'] = 127;
 // Parse textarea submitted and try adding a real server for each line.
 function addRealServers ()
 {
@@ -847,7 +1064,7 @@ function addRealServers ()
        // Keep in mind, that the text will have HTML entities (namely '>') escaped.
        foreach (explode ('\n', $rawtext) as $line)
        {
-               if (empty ($line))
+               if (!strlen ($line))
                        continue;
                $match = array ();
                switch ($_REQUEST['format'])
@@ -885,23 +1102,26 @@ function addRealServers ()
                                        $nbad++;
                                break;
                        default:
-                               return buildRedirectURL ('ERR1');
+                               return buildRedirectURL (__FUNCTION__, 'ERR1');
                                break;
                }
        }
        if ($nbad == 0 and $ngood > 0)
-               return buildRedirectURL ('OK', array ($ngood));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($ngood));
        else
-               return buildRedirectURL ('ERR2', array ($ngood, $nbad));
+               return buildRedirectURL (__FUNCTION__, 'ERR2', array ($ngood, $nbad));
 }
 
+$msgcode['addVService']['OK'] = 28;
+$msgcode['addVService']['ERR1'] = 132;
+$msgcode['addVService']['ERR2'] = 100;
 function addVService ()
 {
        assertIPv4Arg ('vip', __FUNCTION__);
        assertUIntArg ('vport', __FUNCTION__);
        assertStringArg ('proto', __FUNCTION__);
        if ($_REQUEST['proto'] != 'TCP' and $_REQUEST['proto'] != 'UDP')
-               return buildRedirectURL ('ERR1');
+               return buildRedirectURL (__FUNCTION__, 'ERR1');
        assertStringArg ('name', __FUNCTION__, TRUE);
        assertStringArg ('vsconfig', __FUNCTION__, TRUE);
        assertStringArg ('rsconfig', __FUNCTION__, TRUE);
@@ -916,20 +1136,24 @@ function addVService ()
                isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array()
        );
        if ($error != '')
-               return buildRedirectURL ('ERR2', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR2', array ($error));
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['deleteRealServer']['OK'] = 35;
+$msgcode['deleteRealServer']['ERR'] = 128;
 function deleteRealServer ()
 {
        assertUIntArg ('id', __FUNCTION__);
        if (!commitDeleteRS ($_REQUEST['id']))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['deleteLoadBalancer']['OK'] = 19;
+$msgcode['deleteLoadBalancer']['ERR'] = 129;
 function deleteLoadBalancer ()
 {
        assertUIntArg ('object_id', __FUNCTION__);
@@ -940,20 +1164,24 @@ function deleteLoadBalancer ()
                $_REQUEST['pool_id'],
                $_REQUEST['vs_id']
        ))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['deleteVService']['OK'] = 29;
+$msgcode['deleteVService']['ERR'] = 130;
 function deleteVService ()
 {
        assertUIntArg ('vs_id', __FUNCTION__);
        if (!commitDeleteVS ($_REQUEST['vs_id']))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['updateRealServer']['OK'] = 36;
+$msgcode['updateRealServer']['ERR'] = 133;
 function updateRealServer ()
 {
        assertUIntArg ('rs_id', __FUNCTION__);
@@ -966,11 +1194,13 @@ function updateRealServer ()
                $_REQUEST['rsport'],
                $_REQUEST['rsconfig']
        ))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['updateLoadBalancer']['OK'] = 20;
+$msgcode['updateLoadBalancer']['ERR'] = 134;
 function updateLoadBalancer ()
 {
        assertUIntArg ('object_id', __FUNCTION__);
@@ -985,11 +1215,13 @@ function updateLoadBalancer ()
                $_REQUEST['vsconfig'],
                $_REQUEST['rsconfig']
        ))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['updateVService']['OK'] = 30;
+$msgcode['updateVService']['ERR'] = 135;
 function updateVService ()
 {
        assertUIntArg ('vs_id', __FUNCTION__);
@@ -1008,11 +1240,13 @@ function updateVService ()
                $_REQUEST['vsconfig'],
                $_REQUEST['rsconfig']
        ))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['addLoadBalancer']['OK'] = 18;
+$msgcode['addLoadBalancer']['ERR'] = 137;
 function addLoadBalancer ()
 {
        assertUIntArg ('pool_id', __FUNCTION__);
@@ -1027,11 +1261,13 @@ function addLoadBalancer ()
                $_REQUEST['vsconfig'],
                $_REQUEST['rsconfig']
        ))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['addRSPool']['OK'] = 31;
+$msgcode['addRSPool']['ERR'] = 100;
 function addRSPool ()
 {
        assertStringArg ('name', __FUNCTION__, TRUE);
@@ -1045,20 +1281,24 @@ function addRSPool ()
                isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array()
        );
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['deleteRSPool']['OK'] = 32;
+$msgcode['deleteRSPool']['ERR'] = 138;
 function deleteRSPool ()
 {
        assertUIntArg ('pool_id', __FUNCTION__);
        if (!commitDeleteRSPool ($_REQUEST['pool_id']))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['updateRSPool']['OK'] = 33;
+$msgcode['updateRSPool']['ERR'] = 139;
 function updateRSPool ()
 {
        assertUIntArg ('pool_id', __FUNCTION__);
@@ -1066,16 +1306,19 @@ function updateRSPool ()
        assertStringArg ('vsconfig', __FUNCTION__, TRUE);
        assertStringArg ('rsconfig', __FUNCTION__, TRUE);
        if (!commitUpdateRSPool ($_REQUEST['pool_id'], $_REQUEST['name'], $_REQUEST['vsconfig'], $_REQUEST['rsconfig']))
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        else
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['updateRSInService']['OK'] = 38;
+$msgcode['updateRSInService']['ERR'] = 140;
 function updateRSInService ()
 {
        assertUIntArg ('rscount', __FUNCTION__);
        $pool_id = $_REQUEST['pool_id'];
-       $orig = getRSPoolInfo ($pool_id);
+       $orig = spotEntity ('ipv4rspool', $pool_id);
+       amplifyCell ($orig);
        $nbad = $ngood = 0;
        for ($i = 1; $i <= $_REQUEST['rscount']; $i++)
        {
@@ -1093,11 +1336,13 @@ function updateRSInService ()
                }
        }
        if (!$nbad)
-               return buildRedirectURL ('OK', array ($ngood));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($ngood));
        else
-               return buildRedirectURL ('ERR', array ($nbad, $ngood));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($nbad, $ngood));
 }
 
+$msgcode['importPTRData']['OK'] = 26;
+$msgcode['importPTRData']['ERR'] = 141;
 // FIXME: check, that each submitted address belongs to the prefix we
 // are operating on.
 function importPTRData ()
@@ -1122,43 +1367,35 @@ function importPTRData ()
                        $nbad++;
        }
        if (!$nbad)
-               return buildRedirectURL ('OK', array ($ngood));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($ngood));
        else
-               return buildRedirectURL ('ERR', array ($nbad, $ngood));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($nbad, $ngood));
 }
 
+$msgcode['generateAutoPorts']['OK'] = 21;
+$msgcode['generateAutoPorts']['ERR'] = 142;
 function generateAutoPorts ()
 {
        global $pageno;
        assertUIntArg ('object_id', __FUNCTION__);
-       $info = getObjectInfo ($_REQUEST['object_id']);
+       $info = spotEntity ('object', $_REQUEST['object_id']);
        // Navigate away in case of success, stay at the place otherwise.
        if (executeAutoPorts ($_REQUEST['object_id'], $info['objtype_id']))
-               return buildRedirectURL ('OK', array(), $pageno, 'ports');
+               return buildRedirectURL (__FUNCTION__, 'OK', array(), $pageno, 'ports');
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
+$msgcode['saveEntityTags']['OK'] = 22;
+$msgcode['saveEntityTags']['ERR1'] = 143;
+$msgcode['saveEntityTags']['ERR2'] = 187;
 // Filter out implicit tags before storing the new tag set.
 function saveEntityTags ()
 {
-       $page2realm = array
-       (
-               'file' => 'file',
-               'ipv4net' => 'ipv4net',
-               'ipv4rspool' => 'ipv4rspool',
-               'ipv4vs' => 'ipv4vs',
-               'object' => 'object',
-               'rack' => 'rack',
-               'user' => 'user'
-       );
-       global $explicit_tags, $implicit_tags, $page, $pageno;
-       if (!isset ($page2realm[$pageno]) or !isset ($page[$pageno]['bypass']))
-       {
-               showError ('Internal error', __FUNCTION__);
-               die;
-       }
-       $realm = $page2realm[$pageno];
+       global $page, $pageno, $etype_by_pageno;
+       if (!isset ($etype_by_pageno[$pageno]) or !isset ($page[$pageno]['bypass']))
+               return buildRedirectURL (__FUNCTION__, 'ERR2', array (__FUNCTION__));
+       $realm = $etype_by_pageno[$pageno];
        $bypass = $page[$pageno]['bypass'];
        assertUIntArg ($bypass, __FUNCTION__);
        $entity_id = $_REQUEST[$bypass];
@@ -1166,6 +1403,8 @@ function saveEntityTags ()
        // Build a chain from the submitted data, minimize it,
        // then wipe existing records and store the new set instead.
        destroyTagsForEntity ($realm, $entity_id);
+       // TODO: these actions are very close to what rebuildTagChainForEntity() does,
+       // so why not use it?
        $newchain = getExplicitTagsOnly (buildTagChainFromIds ($taglist));
        $n_succeeds = $n_errors = 0;
        foreach ($newchain as $taginfo)
@@ -1174,37 +1413,47 @@ function saveEntityTags ()
                else
                        $n_errors++;
        if ($n_errors)
-               return buildRedirectURL ('ERR', array ($n_succeeds, $n_errors));
+               return buildRedirectURL (__FUNCTION__, 'ERR1', array ($n_succeeds, $n_errors));
        else
-               return buildRedirectURL ('OK', array ($n_succeeds));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($n_succeeds));
 }
 
+$msgcode['destroyTag']['OK'] = 58;
+$msgcode['destroyTag']['ERR1'] = 183;
+$msgcode['destroyTag']['ERR2'] = 144;
 function destroyTag ()
 {
        assertUIntArg ('tag_id', __FUNCTION__);
+       global $taglist;
+       if (!isset ($taglist[$_REQUEST['tag_id']]))
+               return buildRedirectURL (__FUNCTION__, 'ERR1', array ($_REQUEST['tag_id']));
        if (($ret = commitDestroyTag ($_REQUEST['tag_id'])) == '')
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($taglist[$_REQUEST['tag_id']]['tag']));
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR2');
 }
 
+$msgcode['createTag']['OK'] = 59;
+$msgcode['createTag']['ERR1'] = 145;
+$msgcode['createTag']['ERR3'] = 147;
 function createTag ()
 {
        assertStringArg ('tag_name', __FUNCTION__);
        assertUIntArg ('parent_id', __FUNCTION__, TRUE);
        $tagname = trim ($_REQUEST['tag_name']);
        if (!validTagName ($tagname))
-               return buildRedirectURL ('ERR1', array ($tagname));
-       if (tagExistsInDatabase ($tagname))
-               return buildRedirectURL ('ERR2', array ($tagname));
+               return buildRedirectURL (__FUNCTION__, 'ERR1', array ($tagname));
        if (($parent_id = $_REQUEST['parent_id']) <= 0)
                $parent_id = 'NULL';
        if (($ret = commitCreateTag ($tagname, $parent_id)) == '')
-               return buildRedirectURL ('OK', array ($tagname));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($tagname));
        else
-               return buildRedirectURL ('ERR3', array ($tagname, $ret));
+               return buildRedirectURL (__FUNCTION__, 'ERR3', array ($tagname, $ret));
 }
 
+$msgcode['updateTag']['OK'] = 60;
+$msgcode['updateTag']['ERR1'] = 145;
+$msgcode['updateTag']['ERR2'] = 148;
 function updateTag ()
 {
        assertUIntArg ('tag_id', __FUNCTION__);
@@ -1212,22 +1461,25 @@ function updateTag ()
        assertStringArg ('tag_name', __FUNCTION__);
        $tagname = trim ($_REQUEST['tag_name']);
        if (!validTagName ($tagname))
-               return buildRedirectURL ('ERR1', array ($tagname));
+               return buildRedirectURL (__FUNCTION__, 'ERR1', array ($tagname));
        if (($parent_id = $_REQUEST['parent_id']) <= 0)
                $parent_id = 'NULL';
        if (($ret = commitUpdateTag ($_REQUEST['tag_id'], $tagname, $parent_id)) == '')
-               return buildRedirectURL ('OK', array ($tagname));
-       else
-               return buildRedirectURL ('ERR2', array ($tagname, $ret));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($tagname));
+       // Use old name in the message, cause update failed.
+       global $taglist;
+       return buildRedirectURL (__FUNCTION__, 'ERR2', array ($taglist[$_REQUEST['tag_id']]['tag'], $ret));
 }
 
+$msgcode['rollTags']['OK'] = 67;
+$msgcode['rollTags']['ERR'] = 149;
 function rollTags ()
 {
        assertUIntArg ('row_id', __FUNCTION__);
        assertStringArg ('sum', __FUNCTION__, TRUE);
        assertUIntArg ('realsum', __FUNCTION__);
        if ($_REQUEST['sum'] != $_REQUEST['realsum'])
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
        // Even if the user requested an empty tag list, don't bail out, but process existing
        // tag chains with "zero" extra. This will make sure, that the stuff processed will
        // have its chains refined to "normal" form.
@@ -1236,35 +1488,46 @@ function rollTags ()
        // Minimizing the extra chain early, so that tag rebuilder doesn't have to
        // filter out the same tag again and again. It will have own noise to cancel.
        $extrachain = getExplicitTagsOnly (buildTagChainFromIds ($extratags));
-       foreach (getRacksForRow ($_REQUEST['row_id']) as $rackInfo)
+       foreach (listCells ('rack', $_REQUEST['row_id']) as $rack)
        {
-               if (rebuildTagChainForEntity ('rack', $rackInfo['id'], $extrachain))
+               if (rebuildTagChainForEntity ('rack', $rack['id'], $extrachain))
                        $n_ok++;
-               foreach (stuffInRackspace (getRackData ($rackInfo['id'])) as $object_id)
+               amplifyCell ($rack);
+               foreach ($rack['mountedObjects'] as $object_id)
                        if (rebuildTagChainForEntity ('object', $object_id, $extrachain))
                                $n_ok++;
        }
-       return buildRedirectURL ('OK', array ($n_ok));
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($n_ok));
 }
 
+$msgcode['changeMyPassword']['OK'] = 61;
+$msgcode['changeMyPassword']['ERR1'] = 150;
+$msgcode['changeMyPassword']['ERR2'] = 151;
+$msgcode['changeMyPassword']['ERR3'] = 152;
+$msgcode['changeMyPassword']['ERR4'] = 153;
 function changeMyPassword ()
 {
-       global $accounts, $remote_username;
-       if (getConfigVar ('USER_AUTH_SRC') != 'database')
-               return buildRedirectURL ('ERR1');
+       global $remote_username, $user_auth_src;
+       if ($user_auth_src != 'database')
+               return buildRedirectURL (__FUNCTION__, 'ERR1');
        assertStringArg ('oldpassword', __FUNCTION__);
        assertStringArg ('newpassword1', __FUNCTION__);
        assertStringArg ('newpassword2', __FUNCTION__);
-       if ($accounts[$remote_username]['user_password_hash'] != hash (PASSWORD_HASH, $_REQUEST['oldpassword']))
-               return buildRedirectURL ('ERR2');
+       $remote_userid = getUserIDByUsername ($remote_username);
+       $userinfo = spotEntity ('user', $remote_userid);
+       if ($userinfo['user_password_hash'] != sha1 ($_REQUEST['oldpassword']))
+               return buildRedirectURL (__FUNCTION__, 'ERR2');
        if ($_REQUEST['newpassword1'] != $_REQUEST['newpassword2'])
-               return buildRedirectURL ('ERR3');
-       if (commitUpdateUserAccount ($accounts[$remote_username]['user_id'], $accounts[$remote_username]['user_name'], $accounts[$remote_username]['user_realname'], hash (PASSWORD_HASH, $_REQUEST['newpassword1'])))
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'ERR3');
+       if (commitUpdateUserAccount ($remote_userid, $userinfo['user_name'], $userinfo['user_realname'], sha1 ($_REQUEST['newpassword1'])))
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR4');
+               return buildRedirectURL (__FUNCTION__, 'ERR4');
 }
 
+$msgcode['saveRackCode']['OK'] = 43;
+$msgcode['saveRackCode']['ERR1'] = 154;
+$msgcode['saveRackCode']['ERR2'] = 155;
 function saveRackCode ()
 {
        assertStringArg ('rackcode');
@@ -1272,14 +1535,15 @@ function saveRackCode ()
        $newcode = str_replace ('\r', '', str_replace ('\n', "\n", $_REQUEST['rackcode']));
        $parseTree = getRackCode ($newcode);
        if ($parseTree['result'] != 'ACK')
-               return buildRedirectURL ('ERR1', array ($parseTree['load']));
+               return buildRedirectURL (__FUNCTION__, 'ERR1', array ($parseTree['load']));
        saveScript ('RackCodeCache', '');
        if (saveScript ('RackCode', $newcode))
-               return buildRedirectURL ('OK');
+               return buildRedirectURL (__FUNCTION__, 'OK');
        else
-               return buildRedirectURL ('ERR2');
+               return buildRedirectURL (__FUNCTION__, 'ERR2');
 }
 
+$msgcode['setPortVLAN']['ERR1'] = 156;
 // This handler's context is pre-built, but not authorized. It is assumed, that the
 // handler will take existing context and before each commit check authorization
 // on the base chain plus necessary context added.
@@ -1288,7 +1552,7 @@ function setPortVLAN ()
        assertUIntArg ('portcount', __FUNCTION__);
        $data = getSwitchVLANs ($_REQUEST['object_id']);
        if ($data === NULL)
-               return buildRedirectURL ('ERR1');
+               return buildRedirectURL (__FUNCTION__, 'ERR1');
        list ($vlanlist, $portlist) = $data;
        // Here we just build up 1 set command for the gateway with all of the ports
        // included. The gateway is expected to filter unnecessary changes silently
@@ -1296,7 +1560,7 @@ function setPortVLAN ()
        // for each of the rest.
        $nports = $_REQUEST['portcount'];
        $prefix = 'set ';
-       $log = array ('v' => 2, 'm' => array());
+       $log = emptyLog();
        $setcmd = '';
        for ($i = 0; $i < $nports; $i++)
                if
@@ -1341,31 +1605,51 @@ function submitSLBConfig ()
 {
        assertUIntArg ('object_id', __FUNCTION__);
        $newconfig = buildLVSConfig ($_REQUEST['object_id']);
-       $msglog = gwSendFile ($_REQUEST['object_id'], 'slbconfig', html_entity_decode ($newconfig, ENT_QUOTES, 'UTF-8'));
+       $msglog = gwSendFileToObject ($_REQUEST['object_id'], 'slbconfig', html_entity_decode ($newconfig, ENT_QUOTES, 'UTF-8'));
        return buildWideRedirectURL ($msglog);
 }
 
+$msgcode['addRow']['OK'] = 74;
+$msgcode['addRow']['ERR'] = 100;
 function addRow ()
 {
        assertStringArg ('name', __FUNCTION__);
 
-       if (commitSupplementDictionary (3, $_REQUEST['name']) === TRUE)
-               return buildRedirectURL ('OK', array ($_REQUEST['name']));
+       if (commitAddRow ($_REQUEST['name']) === TRUE)
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['name']));
        else
-               return buildRedirectURL ('ERR', array ($_REQUEST['name']));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($_REQUEST['name']));
 }
 
+$msgcode['updateRow']['OK'] = 75;
+$msgcode['updateRow']['ERR'] = 100;
 function updateRow ()
 {
        assertUIntArg ('row_id', __FUNCTION__);
        assertStringArg ('name', __FUNCTION__);
 
-       if (TRUE === commitUpdateDictionary (3, $_REQUEST['row_id'], $_REQUEST['name']))
-               return buildRedirectURL ('OK', array ($_REQUEST['name']));
+       if (TRUE === commitUpdateRow ($_REQUEST['row_id'], $_REQUEST['name']))
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['name']));
+       else
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($_REQUEST['name']));
+}
+
+$msgcode['deleteRow']['OK'] = 77;
+$msgcode['deleteRow']['ERR'] = 100;
+function deleteRow ()
+{
+       assertUIntArg ('row_id', __FUNCTION__);
+       $rowinfo = getRackRowInfo ($_REQUEST['row_id']);
+
+       if (TRUE === commitDeleteRow ($_REQUEST['row_id']))
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($rowinfo['name']));
        else
-               return buildRedirectURL ('ERR', array ($_REQUEST['name']));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($rowinfo['name']));
 }
 
+$msgcode['addRack']['OK'] = 65;
+$msgcode['addRack']['ERR1'] = 171;
+$msgcode['addRack']['ERR2'] = 172;
 function addRack ()
 {
        assertUIntArg ('row_id', __FUNCTION__);
@@ -1377,15 +1661,15 @@ function addRack ()
                assertStringArg ('rack_comment', __FUNCTION__, TRUE);
 
                if (commitAddRack ($_REQUEST['rack_name'], $_REQUEST['rack_height1'], $_REQUEST['row_id'], $_REQUEST['rack_comment'], $taglist) === TRUE)
-                       return buildRedirectURL ('OK', array ($_REQUEST['rack_name']));
+                       return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['rack_name']));
                else
-                       return buildRedirectURL ('ERR1', array ($_REQUEST['rack_name']));
+                       return buildRedirectURL (__FUNCTION__, 'ERR1', array ($_REQUEST['rack_name']));
        }
        elseif (isset ($_REQUEST['got_mdata']))
        {
                assertUIntArg ('rack_height2', __FUNCTION__);
                assertStringArg ('rack_names', __FUNCTION__, TRUE);
-               $log = array ('v' => 2);
+               $log = emptyLog();
                // copy-and-paste from renderAddMultipleObjectsForm()
                $names1 = explode ('\n', $_REQUEST['rack_names']);
                $names2 = array();
@@ -1393,22 +1677,41 @@ function addRack ()
                {
                        $parts = explode ('\r', $line);
                        reset ($parts);
-                       if (empty ($parts[0]))
+                       if (!strlen ($parts[0]))
                                continue;
                        else
                                $names2[] = rtrim ($parts[0]);
                }
+               global $msgcode;
                foreach ($names2 as $cname)
                        if (commitAddRack ($cname, $_REQUEST['rack_height2'], $_REQUEST['row_id'], '', $taglist) === TRUE)
-                               $log['m'][] = array ('c' => getMessageCode ('OK'), 'a' => array ($cname));
+                               $log['m'][] = array ('c' => $msgcode[__FUNCTION__]['OK'], 'a' => array ($cname));
                        else
-                               $log['m'][] = array ('c' => getMessageCode ('ERR1'), 'a' => array ($cname));
+                               $log['m'][] = array ('c' => $msgcode[__FUNCTION__]['ERR1'], 'a' => array ($cname));
                return buildWideRedirectURL ($log);
        }
        else
-               return buildRedirectURL ('ERR2');
+               return buildRedirectURL (__FUNCTION__, 'ERR2');
 }
 
+$msgcode['deleteRack']['OK'] = 79;
+$msgcode['deleteRack']['ERR'] = 100;
+$msgcode['deleteRack']['ERR1'] = 206;
+function deleteRack ()
+{
+       assertUIntArg ('rack_id', __FUNCTION__);
+       if (NULL == ($rackData = spotEntity ('rack', $_REQUEST['rack_id'])))
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ('Rack not found'), 'rackspace', 'default');
+       amplifyCell ($rackData);
+       if (count ($rackData['mountedObjects']))
+               return buildRedirectURL (__FUNCTION__, 'ERR1');
+       if (TRUE !== commitDeleteRack ($_REQUEST['rack_id']))
+               return buildRedirectURL (__FUNCTION__, 'ERR', array(), 'rackspace', 'default');
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($rackData['name']), 'rackspace', 'default');
+}
+
+$msgcode['updateRack']['OK'] = 68;
+$msgcode['updateRack']['ERR'] = 177;
 function updateRack ()
 {
        assertUIntArg ('rack_id', __FUNCTION__);
@@ -1419,9 +1722,35 @@ function updateRack ()
 
        resetThumbCache ($_REQUEST['rack_id']);
        if (TRUE === commitUpdateRack ($_REQUEST['rack_id'], $_REQUEST['rack_name'], $_REQUEST['rack_height'], $_REQUEST['rack_row_id'], $_REQUEST['rack_comment']))
-               return buildRedirectURL ('OK', array ($_REQUEST['rack_name']));
+               return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['rack_name']));
        else
-               return buildRedirectURL ('ERR');
+               return buildRedirectURL (__FUNCTION__, 'ERR');
+}
+
+$msgcode['updateRackDesign']['ERR'] = 100;
+function updateRackDesign ()
+{
+       assertUIntArg ('rack_id', __FUNCTION__);
+       if (NULL == ($rackData = spotEntity ('rack', $_REQUEST['rack_id'])))
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ('Rack not found'), 'rackspace', 'default');
+       amplifyCell ($rackData);
+       applyRackDesignMask($rackData);
+       markupObjectProblems ($rackData);
+       $response = processGridForm ($rackData, 'A', 'F');
+       return buildWideRedirectURL (array($response));
+}
+
+$msgcode['updateRackProblems']['ERR'] = 100;
+function updateRackProblems ()
+{
+       assertUIntArg ('rack_id', __FUNCTION__);
+       if (NULL == ($rackData = spotEntity ('rack', $_REQUEST['rack_id'])))
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ('Rack not found'), 'rackspace', 'default');
+       amplifyCell ($rackData);
+       applyRackProblemMask($rackData);
+       markupObjectProblems ($rackData);
+       $response = processGridForm ($rackData, 'F', 'U');
+       return buildWideRedirectURL (array($response));
 }
 
 function querySNMPData ()
@@ -1431,6 +1760,8 @@ function querySNMPData ()
        return buildWideRedirectURL (doSNMPmining ($_REQUEST['object_id'], $_REQUEST['community']));
 }
 
+$msgcode['addFileWithoutLink']['OK'] = 69;
+$msgcode['addFileWithoutLink']['ERR'] = 100;
 // File-related functions
 function addFileWithoutLink ()
 {
@@ -1438,87 +1769,181 @@ function addFileWithoutLink ()
 
        // Make sure the file can be uploaded
        if (get_cfg_var('file_uploads') != 1)
-               return buildRedirectURL ('ERR', array ("file uploads not allowed, change 'file_uploads' parameter in php.ini"));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ("file uploads not allowed, change 'file_uploads' parameter in php.ini"));
 
        $fp = fopen($_FILES['file']['tmp_name'], 'rb');
-       $error = commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $_FILES['file']['size'], $fp, $_REQUEST['comment']);
+       global $sic;
+       // commitAddFile() uses prepared statements
+       $error = commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $_FILES['file']['size'], $fp, $sic['comment']);
+       if (isset ($_REQUEST['taglist']))
+               produceTagsForLastRecord ('file', $_REQUEST['taglist']);
 
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
 
-       return buildRedirectURL ('OK', array ($_FILES['file']['name']));
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($_FILES['file']['name']));
 }
 
+$msgcode['addFileToEntity']['OK'] = 69;
+$msgcode['addFileToEntity']['ERR1'] = 187;
+$msgcode['addFileToEntity']['ERR2'] = 181;
+$msgcode['addFileToEntity']['ERR3'] = 182;
 function addFileToEntity ()
 {
-       assertStringArg ('entity_type', __FUNCTION__);
-       assertUIntArg ('entity_id', __FUNCTION__);
+       global $page, $pageno, $etype_by_pageno;
+       if (!isset ($etype_by_pageno[$pageno]) or !isset ($page[$pageno]['bypass']))
+               return buildRedirectURL (__FUNCTION__, 'ERR1', array (__FUNCTION__));
+       $realm = $etype_by_pageno[$pageno];
+       $bypass = $page[$pageno]['bypass'];
+       assertUIntArg ($bypass, __FUNCTION__);
+       $entity_id = $_REQUEST[$bypass];
        assertStringArg ('comment', __FUNCTION__, TRUE);
-       if (empty ($_REQUEST['entity_type']) || empty ($_REQUEST['entity_id']))
-               return buildRedirectURL ('ERR');
 
        // Make sure the file can be uploaded
        if (get_cfg_var('file_uploads') != 1)
-               return buildRedirectURL ('ERR', array ("file uploads not allowed, change 'file_uploads' parameter in php.ini"));
+               return buildRedirectURL (__FUNCTION__, 'ERR2');
 
        $fp = fopen($_FILES['file']['tmp_name'], 'rb');
-       $error = commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $_FILES['file']['size'], $fp, $_REQUEST['comment']);
+       global $sic;
+       // commitAddFile() uses prepared statements
+       $error = commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $_FILES['file']['size'], $fp, $sic['comment']);
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR3', array ($error));
 
-       $file_id = lastInsertID();
-       $error = commitLinkFile ($file_id, $_REQUEST['entity_type'], $_REQUEST['entity_id']);   
+       $error = commitLinkFile (lastInsertID(), $realm, $entity_id);   
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR3', array ($error));
 
-       return buildRedirectURL ('OK', array ($_FILES['file']['name']));
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($_FILES['file']['name']));
 }
 
+$msgcode['linkFileToEntity']['OK'] = 71;
+$msgcode['linkFileToEntity']['ERR1'] = 178;
+$msgcode['linkFileToEntity']['ERR2'] = 100;
 function linkFileToEntity ()
 {
-       assertUIntArg ('entity_id', __FUNCTION__);
        assertUIntArg ('file_id', __FUNCTION__);
-       assertStringArg ('file_name', __FUNCTION__);
+       global $page, $pageno, $etype_by_pageno;
+       $entity_type = $etype_by_pageno[$pageno];
+       $bypass_name = $page[$pageno]['bypass'];
+       assertUIntArg ($bypass_name, __FUNCTION__);
+
+       $fi = spotEntity ('file', $_REQUEST['file_id']);
+       if ($fi === NULL)
+               return buildRedirectURL (__FUNCTION__, 'ERR1'); // file not found
+       $error = commitLinkFile ($_REQUEST['file_id'], $entity_type, $_REQUEST[$bypass_name]);
+       if ($error != '')
+               return buildRedirectURL (__FUNCTION__, 'ERR2', array ($error)); // linking failed
+
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($fi['name']));
+}
 
-       $error = commitLinkFile ($_REQUEST['file_id'], $_REQUEST['entity_type'], $_REQUEST['entity_id']);
+$msgcode['replaceFile']['OK'] = 70;
+$msgcode['replaceFile']['ERR1'] = 181;
+$msgcode['replaceFile']['ERR2'] = 207;
+$msgcode['replaceFile']['ERR3'] = 182;
+function replaceFile ()
+{
+       global $sic;
+       assertUIntArg ('file_id', __FUNCTION__);
+
+       // Make sure the file can be uploaded
+       if (get_cfg_var('file_uploads') != 1)
+               return buildRedirectURL (__FUNCTION__, 'ERR1');
+       $shortInfo = spotEntity ('file', $sic['file_id']);
+
+       $fp = fopen($_FILES['file']['tmp_name'], 'rb');
+       if ($fp === FALSE)
+               return buildRedirectURL (__FUNCTION__, 'ERR2');
+       $error = commitReplaceFile ($sic['file_id'], $fp);
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR3', array ($error));
 
-       return buildRedirectURL ('OK', array ($_REQUEST['file_name']));
+       return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
 }
 
+$msgcode['updateFile']['OK'] = 70;
+$msgcode['updateFile']['ERR'] = 100;
 function updateFile ()
 {
        assertUIntArg ('file_id', __FUNCTION__);
-       assertStringArg ('name', __FUNCTION__);
-       assertStringArg ('comment', __FUNCTION__, TRUE);
-       $error = commitUpdateFile ($_REQUEST['file_id'], $_REQUEST['comment']);
+       assertStringArg ('file_name', __FUNCTION__);
+       assertStringArg ('file_type', __FUNCTION__);
+       assertStringArg ('file_comment', __FUNCTION__, TRUE);
+       // prepared statement params below
+       global $sic;
+       $error = commitUpdateFile ($sic['file_id'], $sic['file_name'], $sic['file_type'], $sic['file_comment']);
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
 
-       return buildRedirectURL ('OK', array ($_REQUEST['name']));
+       return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['name']));
 }
 
+$msgcode['unlinkFile']['OK'] = 72;
+$msgcode['unlinkFile']['ERR'] = 182;
 function unlinkFile ()
 {
        assertUIntArg ('link_id', __FUNCTION__);
        $error = commitUnlinkFile ($_REQUEST['link_id']);
 
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
 
-       return buildRedirectURL ('OK', array ($_REQUEST['name']));
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
+$msgcode['deleteFile']['OK'] = 73;
+$msgcode['deleteFile']['ERR'] = 100;
 function deleteFile ()
 {
        assertUIntArg ('file_id', __FUNCTION__);
+       $shortInfo = spotEntity ('file', $_REQUEST['file_id']);
        $error = commitDeleteFile ($_REQUEST['file_id']);
 
        if ($error != '')
-               return buildRedirectURL ('ERR', array ($error));
+               return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
 
-       return buildRedirectURL ('OK', array ($_REQUEST['name']));
+       return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
+}
+
+$msgcode['updateFileText']['OK'] = 78;
+$msgcode['updateFileText']['ERR1'] = 179;
+$msgcode['updateFileText']['ERR2'] = 180;
+function updateFileText ()
+{
+       assertUIntArg ('file_id', __FUNCTION__);
+       assertStringArg ('mtime_copy', __FUNCTION__);
+       assertStringArg ('file_text', __FUNCTION__, TRUE); // it's Ok to save empty
+       $shortInfo = spotEntity ('file', $_REQUEST['file_id']);
+       if ($shortInfo['mtime'] != $_REQUEST['mtime_copy'])
+               return buildRedirectURL (__FUNCTION__, 'ERR1');
+       global $sic;
+       $error = commitReplaceFile ($sic['file_id'], $sic['file_text']);
+       if ($error == '')
+               return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
+       return buildRedirectURL (__FUNCTION__, 'ERR2');
+}
+
+$msgcode['addPortInterfaceCompat']['OK'] = 48;
+$msgcode['addPortInterfaceCompat']['ERR'] = 110;
+function addPortInterfaceCompat ()
+{
+       assertUIntArg ('iif_id', __FUNCTION__);
+       assertUIntArg ('oif_id', __FUNCTION__);
+       if (commitSupplementPIC ($_REQUEST['iif_id'], $_REQUEST['oif_id']))
+               return buildRedirectURL (__FUNCTION__, 'OK');
+       return buildRedirectURL (__FUNCTION__, 'ERR');
+}
+
+$msgcode['delPortInterfaceCompat']['OK'] = 49;
+$msgcode['delPortInterfaceCompat']['ERR'] = 111;
+function delPortInterfaceCompat ()
+{
+       assertUIntArg ('iif_id', __FUNCTION__);
+       assertUIntArg ('oif_id', __FUNCTION__);
+       if (commitReducePIC ($_REQUEST['iif_id'], $_REQUEST['oif_id']))
+               return buildRedirectURL (__FUNCTION__, 'OK');
+       return buildRedirectURL (__FUNCTION__, 'ERR');
 }
 
 ?>