This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
phptsmadmin/lib/ds_tsm.php

713 lines
23 KiB
PHP
Raw Normal View History

2011-01-13 14:45:19 +00:00
<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/ds_tsm.php,v 1.8 2009/04/19 04:03:05 wurley Exp $
/**
* @package phpTSMadmin
* @author Deon George (c) 2006
*/
class tsm extends DS {
public function __construct($index) {
$this->index = $index;
$this->type = 'tsm';
# Additional values that can go in our config.php
$this->custom = new StdClass;
$this->default = new StdClass;
# TSM Server Stanza Name
$this->default->server['stanza'] = array(
'desc'=>'TSM Server Stanza Name',
'default'=>null);
$this->default->system['dsmadmc'] = array(
'desc'=>'Path to dsmadmc command.',
'default'=>'/opt/tivoli/tsm/client/ba/bin/dsmadmc');
$this->default->system['errorlog'] = array(
'desc'=>'Set errorlog filename',
'default'=>'/tmp/pta-tsm-errorlog.log');
$this->default->system['tapeage'] = array(
'desc'=>'Age of tapes to alert for rotation',
'default'=>180);
# TSM Parameters
$this->default->tsmparm['msgFormat'] = array(
'desc'=>'Format of TSM message codes.',
'default'=>'[A-Z]{3}[0-9]{4}[I|E|W|S]');
$this->default->tsmparm['queryStartMsg'] = array(
'desc'=>'TSM code depicting START of queries results.',
'default'=>'ANS8000I');
$this->default->tsmparm['queryEndMsg'] = array(
'desc'=>'TSM code depicting END of queries results.',
'default'=>'ANS8002I');
$this->default->tsmparm['loginFail'] = array(
'desc'=>'Known TSM "failed login" message codes.',
'default'=>array(
'ANS8023E', //
'ANS1017E', // TCP/IP connection rejected.
'ANS1217E', // Server name not found in System Options File
'ANS1355E', // Sessions disabled.
'ANS8034E' // Your administrator ID is not recognized by this server.
));
$this->default->tsmparm['loginFailIgnore'] = array(
'desc'=>'Known TSM "ignore" message codes during login.',
'default'=>array(
'ANS0110E', // LogMsg: Unable to open error log file '%s' for output.
'ANS8002I' // Highest return code was %s.
));
$this->default->tsmparm['ignoremsg'] = array(
'desc'=>'Known TSM "ignore" message codes.',
'default'=>array(
'ANS8001I', // Return code %s.
'ANS0102W' // Unable to open the message repository %s. The American English repository will be used instead.
));
$this->default->tsmparm['nodatamsg'] = array(
'desc'=>'Known TSM "select returned no data" message codes.',
'default'=>array(
'ANR2034E' // SELECT: No match found using this criteria.
));
}
/**
* Required ABSTRACT functions
*/
/**
* Connect and Bind to the Database
*
* @param method This enables to have multiple different types of connects, ie: read only, readwrite, etc
* @return resource|null Connection resource if successful, null if not.
*/
protected function connect($method,$debug=false) {
$method = $this->getMethod($method);
if (! $this->isLoggedIn($method))
system_message(array('title'=>'Not Logged In',
'body'=>sprintf('You are not logged into server %s',$this->getValue('server','name')),
'type'=>'warn'),'index.php');
if (! file_exists($this->getValue('system','dsmadmc'))) {
system_message(array('title'=>'Cant find DSMADMC',
'body'=>sprintf('Unable to find the dsmadmc at <b>%s</b>',$this->getValue('system','dsmadmc')),
'type'=>'error'));
return false;
}
if ($this->getValue('system','errorlog'))
$errorlog = sprintf('-errorlogname=%s',$this->getValue('system','errorlog'));
if (is_null($this->getValue('server','stanza')) || ! trim($this->getValue('server','stanza')))
$TSMcmd = sprintf('%s -id=%s -password=%s -displ=list %s',
$this->getValue('system','dsmadmc'),$this->getLogin($method),$this->getPassword($method),
isset($errorlog) ? $errorlog : '');
else
$TSMcmd = sprintf('%s -se=%s -id=%s -password=%s -displ=list %s',
$this->getValue('system','dsmadmc'),
$this->getValue('server','stanza'),$this->getLogin($method),$this->getPassword($method),
isset($errorlog) ? $errorlog : '');
return $TSMcmd;
}
/**
* Login to the database with the application user/password
*
* @param method This enables to have multiple different types of connects, ie: read only, readwrite, etc
* @return boolean true|false for successful login.
*/
public function login($user=null,$pass=null,$method=null) {
# Set our user and password.
$this->setLogin($user,$pass,$method);
# Test that it works.
$result = $this->query('SELECT platform,version,release,level,sublevel FROM status',$method);
if (! $result)
$this->logout($method);
else
return true;
return false;
}
/**
* Perform a query to the Database
*
* @param string SQL query to perform
* @param string Index items according to this key
* @return array|null Results of query.
*/
public function query($query,$method,$index=null,$debug=false) {
$TSMcmd = sprintf('%s "%s"',$this->connect($method,$debug),$query);
$TSMcmdOutput = exec($TSMcmd,$OutputLines,$return);
if ($debug)
debug_dump(array('cmd'=>$TSMcmd,'TSMcmdOutput'=>$TSMcmdOutput,'return'=>$return));
# Parse the ouput for key:value pairs.
$outindex = 0;
$isQueryResult = 0;
$isKeyValue = 0;
$haveHelp = false;
$QueryResult = false;
$tsmCommands = array();
foreach ($OutputLines as $OutputLine ) {
$OutputLine = preg_replace('/\s+$/','',$OutputLine);
if ($debug)
debug_dump("($isQueryResult/$isKeyValue): WORKING line [$OutputLine]");
# See if we got a message number.
if (preg_match("/^(".$this->getValue('tsmparm','msgFormat').")\s+/",$OutputLine,$matches)) {
$msgnum = $matches[1];
if ($debug)
debug_dump("($isQueryResult/$isKeyValue): Got SYSTEM Msg [$OutputLine]");
# Filter through the output and check if we got our start message.
if (preg_match("/^".$this->getValue('tsmparm','queryStartMsg')."\s+/",$OutputLine)) {
if ($debug)
debug_dump("($isQueryResult/$isKeyValue): Got START Msg [$OutputLine]");
$isQueryResult = 1;
continue;
# Break out of loop when we get our end message.
} elseif (preg_match("/^".$this->getValue('tsmparm','queryEndMsg')."\s+/",$OutputLine)) {
if ($debug)
debug_dump("($isQueryResult/$isKeyValue): Got END Msg [$OutputLine]");
break;
}
if (in_array($msgnum,$this->getValue('tsmparm','nodatamsg')))
continue;
if (! in_array($msgnum,$this->getValue('tsmparm','ignoremsg')))
system_message(array('title'=>'TSM Message','body'=>$OutputLine));
}
# If we the line is a queryResult line
if ($isQueryResult) {
# See if we got a key:value pair, otherwise go to next line.
if (preg_match('/:/',$OutputLine) && ! (preg_match('/^help/',$query))) {
$OutputLine = preg_replace('/\s*:\s+/',':',$OutputLine);
list($key,$value) = explode(':',$OutputLine,2);
$isKeyValue = 1;
# Not key:value, so check if we need to increase the index.
} else {
# Is this a show slots command, so there is more info
if (preg_match('/^show slots/',$query)) {
if (preg_match('/^Slot /',$OutputLine)) {
foreach ((preg_split('/,\s*/',$OutputLine,-1)) as $slotkey => $val) {
if (preg_match('/^element number\s+/',$val)) {
$key = preg_replace('/^element number\s+/','',$val);
} elseif (preg_match('/^Slot\s+/',$val)) {
$slots['slot'] = preg_replace('/^Slot\s+/','',$val);
} elseif (preg_match('/^status\s+/',$val)) {
$slots['status'] = preg_replace('/^status\s+/','',$val);
} elseif (preg_match('/^barcode value </',$val)) {
$slots['barcodelabel'] = preg_replace('/^barcode value <(.*)>/',"$1",$val);
} elseif (preg_match('/^barcode\s+/',$val)) {
$slots['barcode'] = preg_replace('/^barcode /','',$val);
}
}
$QueryResult[$outindex]['SlotUsage'][$key] = $slots;
} elseif (preg_match('/busy.$/',$OutputLine)) {
system_message(array('title'=>'Library is Busy',
'body'=>sprintf('The library appears busy at the moment.<br />%s',$OutputLine),
'type'=>'info'),
sprintf('index.php',get_request('cmd','REQUEST') ? sprintf('cmd=%s',get_request('cmd','REQUEST')) : ''));
}
# Is this a help command, so there is more info
} elseif (preg_match('/^help$/',$query)) {
if (preg_match('/^\s*([0-9]+) - Commands /',$OutputLine)) {
$helpnum = preg_replace('/^\s*([0-9]+) - Commands .*/','$1',$OutputLine);
$tsmCommands = array_unique(array_merge($tsmCommands,$this->query("help $helpnum",null)));
}
} elseif (preg_match('/^help\s+[0-9]+/',$query)) {
if (! $OutputLine)
continue;
if (! $haveHelp && preg_match('/^\s*Command Name/',$OutputLine)) {
$haveHelp = true;
$helpCommands = array();
continue;
}
if ($haveHelp) {
# Filter out the beginning spaces.
$OutputLine = preg_replace('/^\s*/','',$OutputLine);
# Filter out the "(See Note)" messages.
$OutputLine = preg_replace('/\s\(.*\)/','',$OutputLine);
# Join the two columns together
$OutputLine = preg_replace('/\ \s+/','|',$OutputLine);
# We should now just have commands and they should be in uppercase.
if (preg_match('/[a-z0-9]/',$OutputLine))
continue;
#debug_dump("Im finally here with [$OutputLine].");
foreach (explode('|',$OutputLine) as $helpCMD)
array_push($helpCommands,$helpCMD);
}
} elseif (preg_match('/^help\s+[A-Z]+/',$query)) {
# Sometimes QueryResult gets data because of colons - we need to capture that.
if (isset($QueryResult) && is_array($QueryResult)) {
foreach ($QueryResult as $lineDetail)
foreach ($lineDetail as $key => $ldindex)
$helpText[] = $key.$ldindex;
$QueryResult = array();
}
$helpText[] = $OutputLine;
//debug_dump(array("Im finally here with [$OutputLine]."=>$QueryResult));
# If this is a blank line
} elseif (!$OutputLine) {
# Only increment index if the previous iteration was a key/value pair.
# Reset isKeyValue so we dont increase index for 2 non key:value lines in a row.
if ($isKeyValue) {
if (!preg_match('/^show/',$query))
$outindex++;
$isKeyValue = 0;
}
} // if
continue;
} // if
$key = preg_replace('/^\s+/','',$key);
$value = preg_replace('/^\s+/','',$value);
$QueryResult[$outindex][$key] = $value;
} // if
} // foreach
if (is_array($tsmCommands) && preg_match('/^help$/',$query)) {
asort($tsmCommands);
$QueryResult = $tsmCommands;
}
if (isset($helpCommands) && preg_match('/^help\s+[0-9]+/',$query))
$QueryResult = $helpCommands;
if (isset($helpText) && preg_match('/^help\s+[A-Z]+/',$query))
$QueryResult = $helpText;
if ($debug)
debug_dump($QueryResult,0);
if (! $isQueryResult && $debug)
Error(sprintf('The query <BR>%s<BR>didnt return anything [%s]',preg_replace('/-password=(.*)\ -/','-password=x -',$TSMcmd),serialize($OutputLines)));
if ($index && is_array($QueryResult)) {
foreach ($QueryResult as $result => $val) {
if (isset($val[$index]))
$IndexQueryResult[$val[$index]] = $QueryResult[$result];
}
return (isset($IndexQueryResult) ? $IndexQueryResult : false);
} elseif (is_array($QueryResult)) {
return $QueryResult;
}
return array();
}
/**
* Get the last error string
*/
protected function getErrorMessage() {
return null;
}
/**
* Get the last error number
*/
protected function getErrorNum() {
return null;
}
/**
* Return if anonymous bind is allowed in the configuration
*/
public function isAnonBindAllowed() {
return false;
}
/**
* Query the database for particular attributes values.
*/
public function queryAttr($table,$attrs,$key,$where=null,$orderby=null) {
return array();
}
/**
* Register user to the application
*/
public function register($user,$pass,$other=array()) {
return null;
}
/**
* Query TSM and get Database information
*/
function QueryDBDetail() {
$query = $this->query('select * from DB',null);
$this->CACHE['db'] = $query[0];
$this->CACHE['db']['dbvols'] = $this->query('select * from DBVOLUMES',null);
$this->CACHE['cache']['db'] = time();
$this->CACHE['cache']['log'] = time();
$query = $this->query('select * from LOG',null);
$this->CACHE['log'] = $query[0];
$this->CACHE['log']['logvols'] = $this->query('select * from LOGVOLUMES',null);
$_SESSION['tsm'][$this->index] = $this->CACHE;
}
/**
* Return the DB information.
* @param string attribute
* @return string value for attribute
*/
function GetDBDetail($attribute) {
if (! isset($this->CACHE['db'][$attribute]))
$this->QueryDBDetail();
if (! isset($this->CACHE['db'][$attribute]))
Error(sprintf(_('ERROR: A request to get DB attribute "%" didnt return a value'),$attribute));
return $this->CACHE['db'][$attribute];
}
/**
* Return the LOG information.
* @param string attribute
* @return string value for attribute
*/
function GetLogDetail($attribute) {
if (! isset($this->CACHE['log'][$attribute]))
$this->QueryDBDetail();
if (! isset($this->CACHE['log'][$attribute]))
Error(sprintf(_('ERROR: A request to get LOG attribute "%" didnt return a value'),$attribute));
return $this->CACHE['log'][$attribute];
}
/**
* Return the VOLUMES information
* @return array
*/
function GetVolumes() {
if (isset($this->CACHE['volumes']))
return $this->CACHE['volumes'];
$this->CACHE['volumes'] = $this->query('select * from VOLUMES',null,'VOLUME_NAME');
$this->CACHE['cache']['volumes'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['volumes'];
}
/**
* Return the LIBVOLUMES information
* @return array
*/
function GetLibVolumes() {
if (isset($this->CACHE['libvols']))
return $this->CACHE['libvols'];
$this->CACHE['libvols'] = $this->query('select * from LIBVOLUMES',null,'HOME_ELEMENT');
$this->CACHE['cache']['libvols'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['libvols'];
}
/**
* Return the DB Backup Volumes
* @return array
*/
function GetDBBackupInfo() {
if (isset($this->CACHE['dbbackup']))
return $this->CACHE['dbbackup'];
$this->CACHE['dbbackup']['vols'] = $this->query("select * from VOLHISTORY where TYPE in ('BACKUPFULL','BACKUPINCR','DBSNAPSHOT') order by BACKUP_SERIES,BACKUP_OPERATION,VOLUME_SEQ",
null,'VOLUME_NAME');
# Now check that a backup series is valid - since it should be in order.
$lastSeries = -1;
$backupfirst = '';
$backuplast = '';
$backupcount = 0;
if (is_array($this->CACHE['dbbackup']['vols'])) {
foreach ($this->CACHE['dbbackup']['vols'] as $volume => $voldetails) {
if ($lastSeries != $voldetails['BACKUP_SERIES']) {
$lastSeries = $voldetails['BACKUP_SERIES'];
$lastOperation = -1;
$lastSeq = 0;
if (! $backupfirst | $voldetails['DATE_TIME'] < $backupfirst)
$backupfirst = $voldetails['DATE_TIME'];
if (! $backuplast | $voldetails['DATE_TIME'] > $backuplast)
$backuplast = $voldetails['DATE_TIME'];
$backupcount++;
}
# No point trying this series if it is invalid.
if (isset($status[$voldetails['BACKUP_SERIES']]['status']) &&
($status[$voldetails['BACKUP_SERIES']]['status'] == 'InValid'))
continue;
$this->CACHE['dbbackup']['vols'][$volume]['STATUS'] = 'Valid';
if (($voldetails['BACKUP_OPERATION'] == $lastOperation) || ($voldetails['BACKUP_OPERATION']-1 == $lastOperation)) {
$status[$voldetails['BACKUP_SERIES']]['status'] = 'Valid';
$lastOperation = $voldetails['BACKUP_OPERATION'];
} else {
$status[$voldetails['BACKUP_SERIES']]['status'] = 'InValid';
$status[$voldetails['BACKUP_SERIES']]['statusreason'] = sprintf(_('Missing SERIES volumes, expected [%s], found [%s].'),
$lastOperation+1,$voldetails['BACKUP_OPERATION']);
continue;
}
if (($voldetails['VOLUME_SEQ'] == $lastSeq) || $voldetails['VOLUME_SEQ']-1 == $lastSeq) {
$status[$voldetails['BACKUP_SERIES']]['status'] = 'Valid';
$lastSeq = $voldetails['VOLUME_SEQ'];
} else {
$status[$voldetails['BACKUP_SERIES']]['status'] = 'InValid';
$status[$voldetails['BACKUP_SERIES']]['statusreason'] = sprintf(_('Missing SERIES volumes, expected [%s], found [%s].'),$lastSeq+1,$voldetails['VOLUME_SEQ']);
}
$lastSeq = $voldetails['VOLUME_SEQ'];
}
# Now we know which series are invalid, mark all the volumes.
foreach ($this->CACHE['dbbackup']['vols'] as $volume => $voldetails) {
$this->CACHE['dbbackup']['vols'][$volume]['STATUS'] = $status[$voldetails['BACKUP_SERIES']]['status'];
if (isset($status[$voldetails['BACKUP_SERIES']]['statusreason']))
$this->CACHE['dbbackup']['vols'][$volume]['STATUSREASON'] = $status[$voldetails['BACKUP_SERIES']]['statusreason'];
}
}
# Grab backup information
$history = $this->query('select DATE_TIME,MSGNO,MESSAGE from ACTLOG where MSGNO in (4550,4551) order by DATE_TIME',null);
if (! isset($history[0]['ANR2034E SELECT']))
foreach ($history as $index => $historydetail) {
$this->CACHE['dbbackup']['history'][$index]['date'] = $historydetail['DATE_TIME'];
switch ($historydetail['MSGNO']) {
case 4550:
if (preg_match('/([0-9]+) pages copied./',$historydetail['MESSAGE'],$matchall)) {
$this->CACHE['dbbackup']['history'][$index]['size'] = $matchall[1];
$this->CACHE['dbbackup']['history'][$index]['type'] = 'FULL';
}
break;
case 4551:
if (preg_match('/([0-9]+) pages copied./',$historydetail['MESSAGE'],$matchall)) {
$this->CACHE['dbbackup']['history'][$index]['size'] = $matchall[1];
$this->CACHE['dbbackup']['history'][$index]['type'] = 'INCR';
}
break;
default:
printf('Message %s not catered for [%s]...',$historydetail['MSGNO'],$historydetail['MESSAGE']);
die();
}
}
# Get DBBackup Trigger information.
$select = $this->query('select * from DBBACKUPTRIGGER',null);
$result = array_shift($select);
if (isset($result['ANR2034E SELECT']))
$this->CACHE['dbbackup']['trigger'] = false;
else
$this->CACHE['dbbackup']['trigger'] = $result;
$this->CACHE['dbbackup']['first'] = $backupfirst;
$this->CACHE['dbbackup']['last'] = $backuplast;
$this->CACHE['dbbackup']['count'] = $backupcount;
$this->CACHE['cache']['dbbackup'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['dbbackup'];
}
function GetDBBackupDetail($detail) {
if (isset($this->CACHE['dbbackup'][$detail]))
return $this->CACHE['dbbackup'][$detail];
$this->GetDBBackupInfo();
if (isset($this->CACHE['dbbackup'][$detail]))
return $this->CACHE['dbbackup'][$detail];
else
return null;
}
/**
* Return the Status Information
* @return array
*/
function GetStatus() {
if (isset($this->CACHE['status']))
return $this->CACHE['status'];
$select = $this->query('select * from STATUS',null);
$this->CACHE['status'] = array_shift($select);
$this->CACHE['cache']['status'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['status'];
}
function GetStatusDetail($detail) {
if (isset($this->CACHE['status'][$detail]))
return $this->CACHE['status'][$detail];
$this->GetStatus();
if (isset($this->CACHE['status'][$detail]))
return $this->CACHE['status'][$detail];
else
return null;
}
/**
* Get TSM event information
* @param string Start date for report
* @param string End date for report
* @param string order by key.
* @return array Query result
*/
function GetEvents($reportStart='',$reportEnd='',$orderby='SCHEDULED_START') {
if (isset($this->CACHE['events']) && $reportStart == $this->CACHE['events']['start'] &&
$reportEnd == $this->CACHE['events']['end'] && $orderby == $this->CACHE['events']['orderby'])
return $this->CACHE['events'];
$TSMQuery = 'select * from EVENTS where DOMAIN_NAME is not null';
if (($reportStart) && ($reportEnd))
$TSMQuery .= sprintf(" and (SCHEDULED_START between '%s' and '%s')",$reportStart,$reportEnd);
else if ($reportStart)
$TSMQuery .= sprintf(" and SCHEDULED_START \> '%s'",$reportStart);
else if ($reportEnd)
$TSMQuery .= sprintf(" and SCHEDULED_START <= '%s'",$reportEnd);
$TSMQuery .= sprintf(' order by %s',$orderby);
$result = $this->query($TSMQuery,null);
if (isset($result[0]['ANR2034E SELECT'])) {
$this->CACHE['events'] = false;
} else {
$this->CACHE['events']['detail'] = $result;
$this->CACHE['events']['start'] = $reportStart;
$this->CACHE['events']['end'] = $reportEnd;
$this->CACHE['events']['orderby'] = $orderby;
}
$this->CACHE['cache']['events'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['events'];
}
/**
* Get TSM Activity Log Client backup information.
* @param string Start date for report
* @param string End date for report
* @return array Query result
*/
function GetActlogBackupSummary($reportStart='',$reportEnd='') {
if (isset($this->CACHE['actlogbackup']) && $reportStart == $this->CACHE['actlogbackup']['start'] &&
$reportEnd == $this->CACHE['actlogbackup']['end'])
return $this->CACHE['actlogbackup'];
$tsmMSG['4952'] = 'Inspected';
$tsmMSG['4954'] = 'Backup';
$tsmMSG['4958'] = 'Update';
$tsmMSG['4957'] = 'Delete';
$tsmMSG['4959'] = 'Failed';
$tsmMSG['4960'] = 'Rebound';
$tsmMSG['4961'] = 'Transfer';
$tsmMSG['4964'] = 'ProcTime';
$tsmMSG['4967'] = 'AggRate';
$tsmMSG['4968'] = 'Compress';
$tsmMSG['4970'] = 'Expire';
$TSMQuery = sprintf('select MSGNO,NODENAME,SESSID,MESSAGE,SCHEDNAME,DOMAINNAME from ACTLOG where MSGNO in (%s)',
implode(',',array_keys($tsmMSG)));
if (($reportStart) && ($reportEnd))
$TSMQuery .= sprintf(" and (DATE_TIME between '%s' and '%s')",$reportStart,$reportEnd);
else if ($reportStart)
$TSMQuery .= sprintf(" and DATE_TIME \> '%s'",$reportStart);
else if ($reportEnd)
$TSMQuery .= sprintf(" and DATE_TIME <= '%s'",$reportEnd);
$TSMQuery .= ' order by sessid';
foreach ($this->query($TSMQuery,null) as $tsmBackup => $tsmSession) {
# TSM on AIX adds a "SESSION" at the end of each line - maybe others do as well.
if (isset($tsmSession['MESSAGE']))
$tsmSession['MESSAGE'] = preg_replace('/\(SESSION:.*\)/','',$tsmSession['MESSAGE']);
$tsmBackupSummary['detail'][$tsmSession['NODENAME']][$tsmSession['SESSID']][$tsmMSG[$tsmSession['MSGNO']]] = preg_replace('/^.*:\s*/U','',$tsmSession['MESSAGE']);
}
$tsmBackupSummary['start'] = $reportStart;
$tsmBackupSummary['end'] = $reportEnd;
$this->CACHE['actlogbackup'] = $tsmBackupSummary;
$this->CACHE['cache']['actlogbackup'] = time();
$_SESSION['tsm'][$this->index] = $this->CACHE;
return $this->CACHE['actlogbackup'];
}
function GetVolLocation($vol) {
$volumes = $this->GetVolumes();
if ($this->GetLibVolumes())
foreach ($this->GetLibVolumes() as $slot => $details) {
if ($details['VOLUME_NAME'] == $vol)
return sprintf('**%s %s**',_('LIBRARY'),$details['LIBRARY_NAME']);
}
if (isset($volumes[$vol]))
return $volumes[$vol]['LOCATION'];
# If we get here, we dont know where the volume is.
return null;
}
}
?>