config = $config;
$this->ui = $ui;
// Set storage points
$tD = $this->getObjectDefinitions();
$sP = array();
foreach($tD as $entry){
if(!empty($entry['ou']))
$sP[] = $entry['ou'];
}
$this->storagePoints = array_unique($sP);
// Build filter
# if (session::global_is_set(get_class($this)."_filter")){
# $filter= session::global_get(get_class($this)."_filter");
# } else {
$filter = new filter(get_template_path("system-filter.xml", true));
$filter->setObjectStorage($this->storagePoints);
# }
$this->setFilter($filter);
// Build headpage
$headpage = new listing(get_template_path("system-list.xml", true));
$headpage->setFilter($filter);
$filter->setConverter('INCOMING', 'systemManagement::incomingFilterConverter');
// Register Daemon Events
if(class_available("DaemonEvent") && class_available("gosaSupportDaemon")){
$events = DaemonEvent::get_event_types(SYSTEM_EVENT | HIDDEN_EVENT);
foreach($events['TRIGGERED'] as $name => $data){
$this->registerAction("T_".$name,"handleEvent");
$this->registerAction("S_".$name,"handleEvent");
}
$this->registerAction("activateMultiple","activateMultiple");
}
$this->registerAction("saveEvent","saveEventDialog");
$this->registerAction("createISO","createISO");
$this->registerAction("initiateISOcreation","initiateISOcreation");
$this->registerAction("performIsoCreation","performIsoCreation");
$this->registerAction("systemTypeChosen","systemTypeChosen");
$this->registerAction("handleActivationQueue","handleActivationQueue");
// Add copy&paste and snapshot handler.
if ($this->config->boolValueIsTrue("main", "copyPaste")){
$this->cpHandler = new CopyPasteHandler($this->config);
}
if($this->config->get_cfg_value("enableSnapshots") == "true"){
$this->snapHandler = new SnapshotHandler($this->config);
}
// Check if we are able to communicate with the GOsa supprot daemon
if(class_available("gosaSupportDaemon")){
$o = new gosaSupportDaemon();
$this->si_active = $o->connect() && class_available("DaemonEvent");
}
// Check if we are able to communicate with the GOsa supprot daemon
if(class_available("opsi")){
$this->opsi = new opsi($this->config);
}
parent::__construct($config, $ui, "systems", $headpage);
}
function createISO($action,$target)
{
if(count($target) == 1){
$smarty = get_smarty();
$this->dn= array_pop($target);
set_object_info($this->dn);
return ($smarty->fetch(get_template_path('goto/gencd.tpl', TRUE)));
}
}
function initiateISOcreation()
{
$smarty = get_smarty();
$smarty->assign("src", "?plug=".$_GET['plug']."&PerformIsoCreation");
return ($smarty->fetch(get_template_path('goto/gencd_frame.tpl', TRUE)));
}
function performIsoCreation()
{
$return_button = "
";
$dsc = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
/* Get and check command */
$command= $this->config->search("workgeneric", "SYSTEMISOHOOK",array('tabs'));
if (check_command($command)){
@DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execute");
/* Print out html introduction */
echo '
';
/* Open process handle and check if it is a valid process */
$process= proc_open($command." '".$this->dn."'", $dsc, $pipes);
if (is_resource($process)) {
fclose($pipes[0]);
/* Print out returned lines && write JS to scroll down each line */
while (!feof($pipes[1])){
$cur_dat = fgets($pipes[1], 1024);
echo $cur_dat;
echo '' ;
flush();
}
}
/* Get error string && close streams */
$buffer= stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
echo "
";
/* Check return code */
$ret= proc_close($process);
if ($ret != 0){
echo ""._("Creating the image failed. Please see the report below.")."
";
echo "$buffer
";
}
echo $return_button."
";
} else {
$tmp= "".sprintf(_("Command '%s', specified for ISO creation doesn't seem to exist."), $command)."
";
echo $tmp;
echo $return_button."
";
}
/* Scroll down completly */
echo '' ;
echo '';
flush();
exit;
}
/*! \brief Handle GOsa-si events
* All events are handled here.
*/
function handleEvent($action="",$target=array(),$all=array())
{
// Detect whether this event is scheduled or triggered.
$triggered = TRUE;
if(preg_match("/^S_/",$action)){
$triggered = FALSE;
}
// Detect triggere or scheduled actions
$headpage = $this->getHeadpage();
if(preg_match("/^[TS]_/", $action)){
// Send special reinstall action for opsi hosts
$event = preg_replace("/^[TS]_/","",$action);
if($event == "DaemonEvent_reinstall" && $this->si_active && $this->opsi){
foreach($target as $key => $dn){
$type = $headpage->getType($dn);
// Send Reinstall event for opsi hosts
if($type == "FAKE_OC_OpsiHost"){
$obj = $headpage->getEntry($dn);
$this->opsi->job_opsi_install_client($obj['cn'][0],$obj['macAddress'][0]);
unset($target[$key]);
}
}
}
}
// Now send remaining FAI/GOsa-si events here.
if(count($target) && $this->si_active){
$mac= array();
// Collect target mac addresses
$ldap = $this->config->get_ldap_link();
$tD = $this->getObjectDefinitions();
$events = DaemonEvent::get_event_types(SYSTEM_EVENT);
$o_queue = new gosaSupportDaemon();
foreach($target as $dn){
$type = $headpage->getType($dn);
if($tD[$type]['sendEvents']){
$obj = $headpage->getEntry($dn);
if(isset($obj['macAddress'][0])){
$mac[] = $obj['macAddress'][0];
}
}
}
/* Skip installation or update trigerred events,
* if this entry is currently processing.
*/
if($triggered && in_array($event,array("DaemonEvent_reinstall","DaemonEvent_update"))){
foreach($mac as $key => $mac_address){
foreach($o_queue->get_entries_by_mac(array($mac_address)) as $entry){
$entry['STATUS'] = strtoupper($entry['STATUS']);
if($entry['STATUS'] == "PROCESSING" &&
isset($events['QUEUED'][$entry['HEADERTAG']]) &&
in_array($events['QUEUED'][$entry['HEADERTAG']],array("DaemonEvent_reinstall","DaemonEvent_update"))){
unset($mac[$key]);
new log("security","systems/".get_class($this),"",array(),"Skip adding 'DaemonEvent::".$type."' for mac '".$mac_address."', there is already a job in progress.");
break;
}
}
}
}
// Prepare event to be added
if(count($mac) && isset($events['BY_CLASS'][$event]) && $this->si_active){
$event = $events['BY_CLASS'][$event];
$this->dialogObject = new $event['CLASS_NAME']($this->config);
$this->dialogObject->add_targets($mac);
if($triggered){
$this->dialogObject->set_type(TRIGGERED_EVENT);
$o_queue->append($this->dialogObject);
if($o_queue->is_error()){
msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
}else{
$this->closeDialogs();
}
}else{
$this->dialogObject->set_type(SCHEDULED_EVENT);
}
}
}
}
function cancelEdit()
{
management::cancelEdit();
$this->activationQueue = array();
}
function saveEventDialog()
{
$o_queue = new gosaSupportDaemon();
$o_queue->append($this->dialogObject);
if($o_queue->is_error()){
msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
}else{
$this->closeDialogs();
}
}
/*! \brief Update filter part for INCOMING.
* Allows us to search for "systemIncomingRDN".
*/
static function incomingFilterConverter($filter)
{
$rdn = preg_replace("/^[^=]*=/", "", get_ou('systemIncomingRDN'));
$rdn = preg_replace("/,.*$/","",$rdn);
return(preg_replace("/%systemIncomingRDN/", $rdn,$filter));
}
/*! \brief Queue selected objects to be removed.
* Checks ACLs, Locks and ask for confirmation.
*/
protected function removeEntryRequested($action="",$target=array(),$all=array())
{
$disallowed = array();
$this->dns = array();
@DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$target,"Entry removel requested!");
// Check permissons for each target
$tInfo = $this->getObjectDefinitions();
$headpage = $this->getHeadpage();
foreach($target as $dn){
$type = $headpage->getType($dn);
if(!isset($tInfo[$type])){
trigger_error("Unknown object type received '".$type."' please update systemManagement::getObjectDefinitions()!");
}else{
$info = $tInfo[$type];
$acl = $this->ui->get_permissions($dn, $info['aclCategory']."/".$info['aclClass']);
if(preg_match("/d/",$acl)){
$this->dns[] = $dn;
}else{
$disallowed[] = $dn;
}
}
}
if(count($disallowed)){
msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
}
// We've at least one entry to delete.
if(count($this->dns)){
// check locks
if ($user= get_multiple_locks($this->dns)){
return(gen_locked_message($user,$this->dns));
}
// Add locks
$dns_names = array();
foreach($this->dns as $dn){
$dns_names[] =LDAP::fix($dn);
}
add_lock ($this->dns, $this->ui->dn);
// Display confirmation dialog.
$smarty = get_smarty();
$smarty->assign("info", msgPool::deleteInfo($dns_names,_($this->objectName)));
$smarty->assign("multiple", true);
return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
}
}
/*! \brief Object removal was confirmed, now remove the requested entries.
*
* @param String 'action' The name of the action which was the used as trigger.
* @param Array 'target' A list of object dns, which should be affected by this method.
* @param Array 'all' A combination of both 'action' and 'target'.
*/
function removeEntryConfirmed($action="",$target=array(),$all=array(),
$altTabClass="",$altTabType="",$altAclCategory="")
{
@DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$target,"Entry removel confirmed!");
// Check permissons for each target
$tInfo = $this->getObjectDefinitions();
$headpage = $this->getHeadpage();
$disallowed = array();
foreach($this->dns as $key => $dn){
$type = $headpage->getType($dn);
if(!isset($tInfo[$type])){
trigger_error("Unknown object type received '".$type."' please update systemManagement::getObjectDefinitions()!");
}else{
$info = $tInfo[$type];
$acl = $this->ui->get_permissions($dn, $info['aclCategory']."/".$info['aclClass']);
if(preg_match("/d/",$acl)){
// Delete the object
$this->dn = $dn;
$this->tabObject= new $info['tabClass']($this->config,$this->config->data['TABS'][$info['tabDesc']],
$this->dn, $info['aclCategory'], true, true);
$this->tabObject->set_acl_base($this->dn);
$this->tabObject->parent = &$this;
$this->tabObject->delete ();
// Remove the lock for the current object.
del_lock($this->dn);
}else{
$disallowed[] = $dn;
new log("security","groups/".get_class($this),$dn,array(),"Tried to trick deletion.");
}
}
}
if(count($disallowed)){
msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
}
// Cleanup
$this->remove_lock();
$this->closeDialogs();
}
/*! \brief Edit the selected system type.
*
* @param String 'action' The name of the action which was the used as trigger.
* @param Array 'target' A list of object dns, which should be affected by this method.
* @param Array 'all' A combination of both 'action' and 'target'.
*/
function editEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
{
if(count($target) == 1){
$tInfo = $this->getObjectDefinitions();
$headpage = $this->getHeadpage();
$dn = $target[0];
$type =$headpage->getType($dn);
$tData = $tInfo[$type];
if($type == "FAKE_OC_ArpNewDevice"){
if(!class_available("ArpNewDeviceTabs")){
msg_dialog::display(_("Error"), msgPool::class_not_found("ArpNewDevice"), ERROR_DIALOG);
}else{
$this->system_activation_object= array($dn);
return(management::editEntry($action,$target,$all,"ArpNewDeviceTabs","ARPNEWDEVICETABS","incoming"));
}
}elseif($type == "FAKE_OC_NewDevice"){
if(!class_available("SelectDeviceType")){
msg_dialog::display(_("Error"), msgPool::class_not_found("SelectDeviceType"), ERROR_DIALOG);
}else{
$this->system_activation_object= array($dn);
$this->dialogObject = new SelectDeviceType($this->config,$dn);
$this->skipFooter = TRUE;
$this->displayApplyBtn = FALSE;
// see condition -$s_action == "::systemTypeChosen"- for further handling
}
}else{
return(management::editEntry($action,$target,$all,$tData['tabClass'],$tData['tabDesc'],$tData['aclCategory']));
}
}
}
function activateMultiple($action,$target)
{
$headpage = $this->getHeadpage();
foreach($target as $dn) {
if($headpage->getType($dn) == "FAKE_OC_NewDevice"){
$this->activationQueue[$dn] = array();
}
}
if(count($this->activationQueue)){
$this->dialogObject = new SelectDeviceType($this->config, array_keys($this->activationQueue));
$this->skipFooter = TRUE;
}
}
function systemTypeChosen()
{
// Detect the systems target type
$tInfo = $this->getObjectDefinitions();
$selected_group = "none";
if(isset($_POST['ObjectGroup'])){
$selected_group = $_POST['ObjectGroup'];
}
$selected_system = $_POST['SystemType'];
$tmp = array();
foreach($this->activationQueue as $dn => $data){
$tmp[$dn]['OG'] = $selected_group;
$tmp[$dn]['SS'] = $selected_system;
}
$this->closeDialogs();
$this->activationQueue = $tmp;
return($this->handleActivationQueue());
}
function handleActivationQueue()
{
if(!count($this->activationQueue)) return("");
$ldap = $this->config->get_ldap_link();
$pInfo = $this->getObjectDefinitions();
$ui = get_userinfo();
$headpage = $this->getHeadpage();
$ldap->cd($this->config->current['BASE']);
// Walk through systems to activate
while(count($this->activationQueue)){
// Get next entry
reset($this->activationQueue);
$dn = key($this->activationQueue);
$data= $this->activationQueue[$dn];
unset($this->activationQueue[$dn]);
// Validate the given system type.
if(!isset($data['SS'])) continue;
$sysType = $data['SS'];
if(!isset($pInfo[$sysType])){
trigger_error('Unknown type \''.$sysType.'\'!');
continue;
}
$type = $pInfo[$sysType];
// Get target type definition
$plugClass = $type["plugClass"];
$tabClass = $type["tabClass"];
$aclCategory = $type["aclCategory"];
$tabDesc = $type["tabDesc"];
if(!class_available($tabClass)){
msg_dialog::display(_("Error"), msgPool::class_not_found($tabclass), ERROR_DIALOG);
}else{
// Load permissions for selected 'dn' and check if we're allowed to create this 'dn'
$this->dn = $dn;
$acls = $ui->get_permissions($this->dn,$aclCategory."/".$plugClass);
// Check permissions
if(!preg_match("/c/",$acls)){
unset($this->activationQueue[$dn]);
msg_dialog::display(_("Error"), msgPool::permCreate(), ERROR_DIALOG);
continue;
}else{
// Open object an preset some values like the objects base
del_lock($dn);
management::editEntry('editEntry',array($dn),array(),$tabClass,$tabDesc, $aclCategory);
$this->displayApplyBtn = FALSE;
$this->tabObject->set_acl_base($headpage->getBase());
if($data['OG'] != "none"){
$this->tabObject->base = preg_replace("/^[^,]+,".preg_quote(get_ou('ogroupRDN'), '/')."/i", "", $data['OG']);
$this->tabObject->by_object[$plugClass]->base = $this->tabObject->base;
} else {
$this->tabObject->by_object[$plugClass]->base = $headpage->getBase();
$this->tabObject->base = $headpage->getBase();
}
// Assign some default values for opsi hosts
if($this->tabObject instanceOf opsi_tabs){
$ldap = $this->config->get_ldap_link();
$ldap->cat($dn);
$source_attrs = $ldap->fetch();
foreach(array("macAddress" => "mac" ,"cn" => "hostId","description" => "description") as $src => $attr){
if(isset($source_attrs[$src][0])){
$this->tabObject->by_object['opsiGeneric']->$attr = $source_attrs[$src][0];
}
}
}
// Queue entry to be activated, when it is saved.
if($data['OG'] != "none"){
// Set gotoMode to active if there was an ogroup selected.
$found = false;
foreach(array("workgeneric"=>"active","servgeneric"=>"active","termgeneric"=>"active") as $tab => $value){
if(isset($this->tabObject->by_object[$tab]->gotoMode)) {
$found = true;
$this->tabObject->by_object[$tab]->gotoMode = $value;
}
}
if(!$found){
msg_dialog::display(_("Internal error"), _("Cannot set mode to 'active'!"), ERROR_DIALOG);
}
// Update object group membership
$og = new ogroup($this->config,$data['OG']);
if($og){
$og->AddDelMembership($this->tabObject->dn);
$og->save();
}
// Set default system specific attributes
foreach (array("workgeneric", "termgeneric") as $cls){
if (isset($this->tabObject->by_object[$cls])){
$this->tabObject->by_object[$cls]->set_everything_to_inherited();
}
}
// Enable activation
foreach (array("servgeneric", "workgeneric", "termgeneric") as $cls){
if (isset($this->tabObject->by_object[$cls])){
$this->tabObject->by_object[$cls]->auto_activate= TRUE;
}
}
// Enable sending of LDAP events
if (isset($this->tabObject->by_object["workstartup"])){
$this->tabObject->by_object["workstartup"]->gotoLdap_inherit= TRUE;
}
}
// Try to inherit everythin from the selected object group and then save
// the entry, normally this should work without any problems.
// But if there is any, then display the dialogs.
if($data['OG'] != "none"){
$str = $this->saveChanges();
// There was a problem, skip activation here and allow to fix the problems..
if(is_object($this->tabObject)){
return;
}
}else{
return;
}
}
}
}
}
protected function saveChanges()
{
// Handle 'New Unknown Devices' here.
if($this->tabObject instanceOf ArpNewDeviceTabs){
$this->tabObject->save_object();
if($this->tabObject->by_object['ArpNewDevice']->gotoIntegration){
$message = $this->tabObject->check();
if(count($message)){
msg_dialog::displayChecks($message);
}else{
$this->tabObject->save();
$this->activationQueue[$this->tabObject->dn]=array();
$this->closeDialogs();
$this->systemTypeChosen();
}
return;
}
}
//
$str = management::saveChanges();
if($this->tabObject) return("");
if(isset($this->activationQueue[$this->last_dn])){
$this->activate_new_device($this->last_dn);
unset($this->activationQueue[$this->last_dn]);
}
// Avoid using values from an older input dialog
$_POST = array();
$this->handleActivationQueue();
}
/*! \brief Sets FAIstate to "install" for "New Devices".
This function is some kind of "Post handler" for activated systems,
it is called directly after the object (workstabs,servtabs) gets saved.
@param String $dn The dn of the newly activated object.
@return Boolean TRUE if activated else FALSE
*/
function activate_new_device($dn)
{
$ldap = $this->config->get_ldap_link();
$ldap->cd($this->config->current['BASE']);
$ldap->cat($dn);
if($ldap->count()){
$attrs = $ldap->fetch();
if(count(array_intersect(array('goServer','gotoTerminal'), $attrs['objectClass']))){
$ocs = $attrs['objectClass'];
unset($ocs['count']);
$new_attrs = array();
if(!in_array("FAIobject",$ocs)){
$ocs[] = "FAIobject";
$new_attrs['objectClass'] = $ocs;
}
$new_attrs['FAIstate'] = "install";
$ldap->cd($dn);
$ldap->modify($new_attrs);
if (!$ldap->success()){
msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn,
LDAP_MOD, "activate_new_device($dn)"));
}else{
return(TRUE);
}
}
}
return(FALSE);
}
/*! \brief Detects actions/events send by the ui
* and the corresponding targets.
*/
function detectPostActions()
{
$action= management::detectPostActions();
if(isset($_POST['abort_event_dialog'])) $action['action'] = "cancel";
if(isset($_POST['save_event_dialog'])) $action['action'] = "saveEvent";
if(isset($_POST['cd_create'])) $action['action'] = "initiateISOcreation";
if(isset($_GET['PerformIsoCreation'])) $action['action'] = "performIsoCreation";
if(isset($_POST['SystemTypeAborted'])) $action['action'] = "cancel";
if(!is_object($this->tabObject) && !is_object($this->dialogObject)){
if(count($this->activationQueue)) $action['action'] = "handleActivationQueue";
}
if(isset($_POST['systemTypeChosen'])) $action['action'] = "systemTypeChosen";
return($action);
}
/*! \brief Overridden render method of class management.
* this allows us to add a release selection box.
*/
function renderList()
{
$headpage = $this->getHeadpage();
$headpage->update();
$tD = $this->getObjectDefinitions();
$smarty = get_smarty();
foreach($tD as $name => $obj){
$smarty->assign("USE_".$name, (empty($obj['TABNAME']) || class_available($obj['TABNAME'])));
}
$display = $headpage->render();
return($this->getHeader().$display);
}
public function getObjectDefinitions()
{
$tabs = array(
"FAKE_OC_OpsiHost" => array(
"ou" => "",
"plugClass" => "opsiGeneric",
"tabClass" => "opsi_tabs",
"tabDesc" => "OPSITABS",
"aclClass" => "opsiGeneric",
"sendEvents" => TRUE,
"aclCategory" => "opsi"),
"goServer" => array(
"ou" => get_ou('serverRDN'),
"plugClass" => "servgeneric",
"tabClass" => "servtabs",
"tabDesc" => "SERVTABS",
"aclClass" => "servgeneric",
"sendEvents" => TRUE,
"aclCategory" => "server"),
"gotoWorkstation" => array(
"ou" => get_ou('workstationRDN'),
"plugClass" => "workgeneric",
"tabClass" => "worktabs",
"tabDesc" => "WORKTABS",
"aclClass" => "workstation",
"sendEvents" => TRUE,
"aclCategory" => "workgeneric"),
"gotoTerminal" => array(
"ou" => get_ou('terminalRDN'),
"plugClass" => "termgeneric",
"tabClass" => "termtabs",
"sendEvents" => TRUE,
"tabDesc" => "TERMTABS",
"aclClass" => "terminal",
"aclCategory" => "termgeneric"),
"gotoPrinter" => array(
"ou" => get_ou('printerRDN'),
"plugClass" => "printgeneric",
"tabClass" => "printtabs",
"tabDesc" => "PRINTTABS",
"aclClass" => "printer",
"sendEvents" => FALSE,
"aclCategory" => "printgeneric"),
"FAKE_OC_NewDevice" => array(
"ou" => get_ou('systemIncomingRDN'),
"plugClass" => "termgeneric",
"tabClass" => "termtabs",
"sendEvents" => TRUE,
"tabDesc" => "TERMTABS",
"aclClass" => "terminal",
"aclCategory" => "termgeneric"),
"goFonHardware" => array(
"ou" => get_ou('phoneRDN'),
"plugClass" => "phoneGeneric",
"tabClass" => "phonetabs",
"tabDesc" => "PHONETABS",
"sendEvents" => FALSE,
"aclClass" => "phone",
"aclCategory" => "phoneGeneric"),
"FAKE_OC_winstation" => array(
"ou" => get_winstations_ou(),
"plugClass" => "wingeneric",
"sendEvents" => TRUE,
"tabClass" => "wintabs",
"tabDesc" => "WINTABS",
"aclClass" => "wingeneric",
"aclCategory" => "winworkstation"),
"ieee802Device" => array(
"ou" => get_ou('componentRDN'),
"plugClass" => "componentGeneric",
"sendEvents" => FALSE,
"tabClass" => "componenttabs",
"tabDesc" => "COMPONENTTABS",
"aclClass" => "componentGeneric",
"aclCategory" => "component"),
);
// Now map some special types
$tabs['FAKE_OC_NewWorkstation'] = &$tabs['gotoWorkstation'];
$tabs['FAKE_OC_NewTerminal'] = &$tabs['gotoTerminal'];
$tabs['FAKE_OC_NewServer'] = &$tabs['gotoWorkstation'];
$tabs['gotoWorkstation__IS_BUSY'] = &$tabs['gotoWorkstation'];
$tabs['gotoWorkstation__IS_ERROR'] = &$tabs['gotoWorkstation'];
$tabs['gotoWorkstation__IS_LOCKED'] = &$tabs['gotoWorkstation'];
$tabs['gotoTerminal__IS_BUSY'] = &$tabs['gotoTerminal'];
$tabs['gotoTerminal__IS_ERROR'] = &$tabs['gotoTerminal'];
$tabs['gotoTerminal__IS_LOCKED'] = &$tabs['gotoTerminal'];
$tabs['goServer__IS_BUSY'] = &$tabs['goServer'];
$tabs['goServer__IS_ERROR'] = &$tabs['goServer'];
$tabs['goServer__IS_LOCKED'] = &$tabs['goServer'];
$tabs['FAKE_OC_ArpNewDevice'] = &$tabs['FAKE_OC_NewDevice'];
return($tabs);
}
}
// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
?>