<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/lib/tsm_classes.php,v 1.1 2009/04/19 04:04:29 wurley Exp $

abstract class base {
	function getName() {
		return $this->name;
	}
}

abstract class copyGroup extends base {
	function __construct($name) {
		$this->id = $name;
	}

	abstract public function setDetails($details);

	public function setDefaultMgmtClass() {
		$this->default = true;
	}

	public function isDefaultMgmtClass() {
		return $this->default;
	}

	public function getStoragePool() {
		$stgpools = objectCache('stgps');

		if ($stgpools->ifExist($this->stgpool))
			return $stgpools->getStoragePool($this->stgpool);
		else
			return null;
	}
}

class copyGroupArchive extends copyGroup {
	public function setDetails($details) {
		$this->domain = $details['DOMAIN_NAME'];
		#$this->xx = $details['SET_NAME'];
		$this->name = $details['CLASS_NAME'];
		#$this->xx = $details['COPYGROUP_NAME'];
		$this->retain['DAYS'] = $details['RETVER'];
		#$this->xx = $details['SERIALIZATION'];
		$this->stgpool = $details['DESTINATION'];
		#$this->xx = $details['CHG_TIME'];
		#$this->xx = $details['CHG_ADMIN'];
		#$this->xx = $details['PROFILE'];
		#$this->xx = $details['RETINIT'];
		#$this->xx = $details['RETMIN'];

		$this->default = false;
		$this->type = 'Arch';
	}
}

class copyGroupBackup extends copyGroup {
	public function setDetails($details) {
		$this->domain = $details['DOMAIN_NAME'];
		#$this->xx = $details['SET_NAME'];
		$this->name = $details['CLASS_NAME'];
		#$this->xx = $details['COPYGROUP_NAME'];
		$this->version['EXISTS'] = $details['VEREXISTS'];
		$this->version['DELETED'] = $details['VERDELETED'];
		$this->retain['EXTRA'] = $details['RETEXTRA'];
		$this->retain['ONLY'] = $details['RETONLY'];
		#$this->xx = $details['MODE'];
		#$this->xx = $details['SERIALIZATION'];
		$this->frequency = $details['FREQUENCY'];
		$this->stgpool = $details['DESTINATION'];
		#$this->xx = $details['TOC_DESTINATION'];
		#$this->xx = $details['CHG_TIME'];
		#$this->xx = $details['CHG_ADMIN'];
		#$this->xx = $details['PROFILE'];

		$this->default = false;
		$this->type = 'Bkup';
	}
}

class deviceClass extends base {
	function deviceClass($name) {
		$this->name = $name;
	}

	function setDetails($details) {
		$this->access = $details['ACCESS_STRATEGY'];
		#$this->xx = $details['STGPOOL_COUNT'];
		$this->type = $details['DEVTYPE'];
		#$this->xx = $details['FORMAT'];
		$this->capacity = $details['CAPACITY'];
		#$this->xx = $details['MOUNTLIMIT'];
		#$this->xx = $details['MOUNTWAIT'];
		#$this->xx = $details['MOUNTRETENTION'];
		#$this->xx = $details['PREFIX'];
		$this->library = $details['LIBRARY_NAME'];
		$this->dir = $details['DIRECTORY'];
		#$this->xx = $details['SERVERNAME'];
		#$this->xx = $details['RETRYPERIOD'];
		#$this->xx = $details['RETRYINTERVAL'];
		#$this->xx = $details['SHARED'];
		#$this->xx = $details['HLADDRESS'];
		#$this->xx = $details['MINCAPACITY'];
		#$this->xx = $details['WORM'];
		#$this->xx = $details['SCALECAPACITY'];
		#$this->xx = $details['LAST_UPDATE_BY'];
		#$this->xx = $details['LAST_UPDATE'];

		# DISK types have a blank type - we'll set it.
		if ($this->access == 'Random' && ! trim($this->type) && $this->name='DISK')
			$this->type = 'DISK';
	}

	function LibraryDevClass() {
		if (trim($this->library))
			return $this->library;
		else
			return false;
	}

	function isLibraryDevClass() {
		if (trim($this->library))
			return true;
		else
			return false;
	}
}

class drive extends base {
	function drive($name) {
		$this->name = $name;
	}

	function setDetails($details) {
		$this->library = $details['LIBRARY_NAME'];
		$this->type = $details['DEVICE_TYPE'];
		#$this->xx = $details['ONLINE'];
		#$this->xx = $details['READ_FORMATS'];
		#$this->xx = $details['WRITE_FORMATS'];
		#$this->xx = $details['ELEMENT'];
		#$this->xx = $details['ACS_DRIVE_ID'];
		$this->status = $details['DRIVE_STATE'];
		#$this->xx = $details['ALLOCATED_TO'];
		#$this->xx = $details['LAST_UPDATE_BY'];
		#$this->xx = $details['LAST_UPDATE'];
		#$this->xx = $details['CLEAN_FREQ'];
		#$this->xx = $details['DRIVE_SERIAL'];
		$this->volume = $details['VOLUME_NAME'];
	}

	function inLibraryName($library) {
		if ($this->library == $library)
			return true;
		else
			return false;
	}
}

class filesystem extends base {
	function filesystem($name) {
		$this->name = $name;
	}

	function setDetails($details) {
		#$this->xx = $details['NODE_NAME'];
		$this->id = $details['FILESPACE_ID'];
		$this->type = $details['FILESPACE_TYPE'];
		$this->capacity = $details['CAPACITY'];
		$this->util = $details['PCT_UTIL'];
		$this->backup['start'] = $details['BACKUP_START'];
		$this->backup['end'] = $details['BACKUP_END'];
		#$this->xx = $details['DELETE_OCCURRED'];
		#$this->xx = $details['UNICODE_FILESPACE'];
		#$this->xx = $details['FILESPACE_HEXNAME'];
	}

	function setOccupancy($details) {
		$this->occupancy[$details->type][$details->getStoragePool()] = $details->files;
	}

	function setVolumeUsage($details) {
		switch ($details['COPY_TYPE']) {
			case 'BACKUP' : $type = 'Bkup';
				break;
			case 'ARCHIVE' : $type = 'Arch';
				break;
			case 'SPACE MANAGED' : $type = 'HSM';
				break;

			default:
				debug_dump(sprintf('Unknown Copy Type: %s',$details['COPY_TYPE']),1);
		}
		#$this->xx = $details['NODE_NAME'];
		#$this->xx = $details['COPY_TYPE'];
		#$this->xx = $details['FILESPACE_NAME'];
		#$this->xx = $details['STGPOOL_NAME'];
		#$this->xx = $details['VOLUME_NAME'];
		$this->volume[$type][$details['STGPOOL_NAME']][$details['VOLUME_NAME']] = getVolume($details['VOLUME_NAME']);
		#$this->xx = $details['FILESPACE_ID'];
	}

	function getStoragePools() {
		$result = array();

		if (isset($this->occupancy))
			foreach ($this->occupancy as $type => $stgpools)
				foreach ($stgpools as $stgpool => $details)
					if (! in_array($stgpool,$result))
						$result[] = $stgpool;

		return $result;
	}

	/**
	 * Return a list of VOLUMES used by this FILE SYSTEM
	 * @input string (STORAGE POOL NAME|NULL [for all storage pools])
	 * @return array (VOLUME NAMES)
	 */
	function getVolumeUsage($stgp = null) {
		$result = array();

		if (isset($this->volume))
			foreach ($this->volume as $type => $stgpools)
				foreach ($stgpools as $stgpool => $volumes) {
					if ($stgp && $stgp != $stgpool)
						continue;
					foreach ($volumes as $volume => $details)
						if (! in_array($volume,$result))
							$result[] = $volume;
				}

		return $result;
	}

	function getOccupancy($type='Bkup') {
		if (isset($this->occupancy[$type]))
			return $this->occupancy[$type];
		else
			return null;
	}

	function getVolumes($type='Bkup') {
		if (isset($this->volume[$type]))
			return $this->volume[$type];
		else
			return array();
	}

	function getVolumesStgp($type,$stgp) {
		$return = array();

		foreach ($this->getVolumes($type) as $stgpool => $stgpdetails) {
			foreach ($stgpdetails as $volid => $volume) {
				if ($volume->getStoragePool() == $stgp)
					$return[] = $volume;
			}
		}

		return $return;
	}
}

class helpText {
	function helpText($command) {
		$this->command = $command;
		$this->description = '';
		$this->class = '';
		$this->example = '';
		$this->parameter = '';
		$this->related = '';
	}

	function addTitle($text) {
		$this->title = $text;
	}

	function addDescription($text) {
		if (trim($text) && (! preg_match('/^\s*\*\s+/',$text)))
			$this->description .= $text.' ';
		else
			if (trim($text))
				$this->description .= sprintf('<br />%s',$text);
			else
				$this->description .= '<br /><br />';
	}

	function addClass($text) {
		if (trim($text))
			$this->class .= $text.' ';
		else
			$this->class .= '<br /><br />';
	}

	function addParameter($text) {
		static $lastcommand;

		if (preg_match('/^\s+/',$text) && trim($lastcommand))
			$this->parameter[$lastcommand]['text'] .= $text.'<br />';

		else {
			if (trim($text)) {
				$lastcommand = preg_replace('/(.*)\s+\(Required\)/',"$1",$text);
				if ($lastcommand != $text)
					$this->parameter[$lastcommand]['required'] = true;
				$this->parameter[$lastcommand]['text'] = '';

			} else {
				$this->parameter[$lastcommand]['text'] .= '<br />';
			}
		}
	}

	function addSyntax($text) {
		$this->syntax .= $text.'<br />';
	}

	function addExample($text) {
		$this->example[] = $text;
	}

	function addRelated($text) {
		static $lastrelated;

		# If there are than 2 upper case chars together, assume a command.
		$text = preg_replace('/^\s*/','',$text);
		if (preg_match('/^\s*([A-Z]{2,}\s?)+/',$text,$matches)) {

			# $matches[0] has the command.
			$command = preg_replace('/\s*$/','',$matches[0]);
			$text = preg_replace("/${command}\s*/",'',$text);
			$lastrelated = $command;
		}

		if (! isset($this->related[$lastrelated]))
			$this->related[$lastrelated] = '';

		$this->related[$lastrelated] .= $text;
	}

	function getTitle() {
		return $this->title;
	}

	function getDescription() {
		global $app;
		$help = objectCache('help',1);

		# Find any commands and make them hotlinks
		foreach ($help->getCommands() as $command)
			$this->description = preg_replace("/$command/",
				sprintf('<a href="cmd.php?cmd=help&amp;index=%s&amp;command=%s">%s</a>',$app['server']->index,htmlspecialchars($command),$command),$this->description);
		return $this->description;
	}

	function getClass() {
		return $this->class;
	}

	function getSyntax() {
		foreach ($this->getParameterList() as $parm)
			$this->syntax = preg_replace("/-$parm-/",
				sprintf('-<a href="#%s">%s</a>-',$parm,$parm),$this->syntax);

		return "<pre>".$this->syntax."</pre>";
	}

	function getParameterList() {
		return array_keys($this->parameter);
	}

	function getParameters() {
		$return = '<table class="result" border=0>';
		foreach ($this->parameter as $parm => $text)
			$return .= sprintf('<tr class="list_item"><td class="heading"><a name="%s">%s</a></td><td class="value"><table class="result"><tr><td>%s</td></tr></table></td></tr>',
				$parm,
				isset($text['required']) ? "<b>$parm</b>" : $parm,$text['text']);
		$return .= '</table>';
		return $return;
	}

	function getRelated() {
		global $app;
		$help = objectCache('help',1);
		$commands = $help->getCommands();

		$return = '<table class="result" border=0>'."\n";
		# Find any commands and make them hotlinks
		foreach ($this->related as $command => $desc) {
			if (in_array($command,$commands))
				$return .= sprintf('<tr class="list_item"><td class="heading"><span style="white-space: nowrap;"><a href="cmd.php?cmd=help&amp;index=%s&amp;command=%s">%s</a></span></td><td class="value"><table class="result"><tr><td>%s</td></tr></table></td></tr>',
					$app['server']->index,htmlspecialchars($command),$command,$desc)."\n";
			else
				$return .= sprintf('<tr class="list_item"><td class="heading"><span style="white-space: nowrap;">%s</span></td><td class="value"><table class="result"><tr><td>%s</td></tr></table></td></tr>',
					$command,$desc)."\n";
		}
		$return .= '</table>'."\n";

		return $return;
	}
}

class library extends base {
	function library($name,$server) {
		$this->name = $name;
		$this->index = $server;
	}

	function setLibrary($details) {
		$this->type = $details['LIBRARY_TYPE'];
		#$this->xx = $details['ACS_ID'];
		#$this->xx = $details['PRIVATE_CATEGORY'];
		#$this->xx = $details['SCRATCH_CATEGORY'];
		#$this->xx = $details['EXTERNAL_MGR'];
		$this->shared = $details['SHARED'];
		#$this->xx = $details['LANFREE'];
		#$this->xx = $details['OBEYMOUNTRETENTION'];
		#$this->xx = $details['PRIMARY_LIB_MGR'];
		$this->autolabel = $details['AUTOLABEL'];
		#$this->xx = $details['LAST_UPDATE_BY'];
		#$this->xx = $details['LAST_UPDATE'];
		#$this->xx = $details['LIBRARY_SERIAL'];
		#$this->xx = $details['WORMSCRATCH_CAT'];
		#$this->xx = $details['RESETDRIVES'];
	}

	function setAttr($attr,$value) {
		$this->attr[$attr] = $value;
	}

	function getAttr($attr) {
		if (isset($this->attr[$attr]))
			return $this->attr[$attr];
		else
			return null;
	}

	function addSlots($details) {
		$this->slots = $details;
	}

	function addVolumes($details) {
		$this->volumes = $details;
	}

	function addDrives($details) {
		$this->drives = $details;
	}

	function getDrives() {
		if (isset($this->drives))
			return $this->drives;
		else
			return null;
	}

	function slotVolumes($checkedIn=true) {
		$result = array();

		if (isset($this->slots)) {
			foreach ($this->slots as $element => $details)
				if ($checkedIn && $details['status'] == 'Allocated')
					$result[$element] = $details;
				elseif (! $checkedIn && $details['status'] != 'Allocated')
					$result[$element] = $details;

		}

		return $result;
	}

	function getLibraryEmpty() {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ($object->isLibraryEmpty())
				$result[$volume] = $object;
		}

		return $result;
	}

	function getLibraryPending() {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ($object->isLibraryPending())
				$result[$volume] = $object;
		}

		return $result;
	}

	function getLibraryScratch() {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ($object->isLibraryScratch())
				$result[$volume] = $object;
		}

		return $result;
	}
}

class mgmtclass extends base {
	function __construct($name) {
		$this->name = $name;
	}

	function setDetails($details) {
		$this->domain = $details['DOMAIN_NAME'];
		#$this->xx = $details['SET_NAME'];
		$this->name = $details['CLASS_NAME'];
		$this->default = $details['DEFAULTMC'] == 'Yes' ? true : false;
		#$this->xx = $details['DESCRIPTION'];
		#$this->xx = $details['SPACEMGTECHNIQUE'];
		#$this->xx = $details['AUTOMIGNONUSE'];
		#$this->xx = $details['MIGREQUIRESBKUP'];
		#$this->xx = $details['MIGDESTINATION'];
		#$this->xx = $details['CHG_TIME'];
		#$this->xx = $details['CHG_ADMIN'];
		#$this->xx = $details['PROFILE'];
	}
}

class node extends base {
	function node($name) {
		$this->name = $name;
	}

	function setDetails($details) {
		$this->os = $details['PLATFORM_NAME'];
		$this->domain = $details['DOMAIN_NAME'];
		$this->time['pwset'] = $details['PWSET_TIME'];
		$this->passwd['invalid'] = $details['INVALID_PW_COUNT'];
		$this->contact = $details['CONTACT'];
		$this->compression = $details['COMPRESSION'] == 'NO' ? false : true;
		$this->delete['arch'] = $details['ARCHDELETE'] == 'NO' ? false : true;
		$this->delete['back'] = $details['BACKDELETE'] == 'NO' ? false : true;
		$this->locked = $details['LOCKED'] == 'NO' ? false : true;
		$this->time['lastacc'] = $details['LASTACC_TIME'];
		$this->time['registered'] = $details['REG_TIME'];
		#$this->xx = $details['REG_ADMIN'];
		#$this->xx = $details['LASTSESS_COMMMETH'];
		#$this->xx = $details['LASTSESS_RECVD'];
		#$this->xx = $details['LASTSESS_SENT'];
		#$this->xx = $details['LASTSESS_DURATION'];
		#$this->xx = $details['LASTSESS_IDLEWAIT'];
		#$this->xx = $details['LASTSESS_COMMWAIT'];
		#$this->xx = $details['LASTSESS_MEDIAWAIT'];
		$this->level['tsm_ver'] = $details['CLIENT_VERSION'];
		$this->level['tsm_rel'] = $details['CLIENT_RELEASE'];
		$this->level['tsm_lvl'] = $details['CLIENT_LEVEL'];
		$this->level['tsm_slv'] = $details['CLIENT_SUBLEVEL'];
		$this->level['os'] = $details['CLIENT_OS_LEVEL'];
		$this->cloptset = $details['OPTION_SET'];
		#$this->xx = $details['AGGREGATION'];
		$this->url = $details['URL'];
		#$this->xx = $details['NODETYPE'];
		$this->passwd['expiry'] = $details['PASSEXP'];
		$this->mp['keep'] = $details['KEEP_MP'] == 'NO' ? false : true;
		$this->mp['max'] = $details['MAX_MP_ALLOWED'];
		#$this->xx = $details['AUTO_FS_RENAME'];
		#$this->xx = $details['VALIDATEPROTOCOL'];
		$this->hostname = $details['TCP_NAME'];
		$this->ipaddr = $details['TCP_ADDRESS'];
		#$this->xx = $details['GUID'];
		$this->txngroupmax = $details['TXNGROUPMAX'];
		#$this->xx = $details['DATAWRITEPATH'];
		#$this->xx = $details['DATAREADPATH'];
		#$this->xx = $details['SESSION_INITIATION'];
		#$this->xx = $details['CLIENT_HLA'];
		#$this->xx = $details['CLIENT_LLA'];
		$this->group = $details['COLLOCGROUP_NAME'];
		#$this->xx = $details['PROXY_TARGET'];
		#$this->xx = $details['PROXY_AGENT'];
	}

	function addFileSpace($details) {
		$this->fs[$details['FILESPACE_ID']] = new filesystem($details['FILESPACE_NAME']);
		$this->fs[$details['FILESPACE_ID']]->setDetails($details);
	}

	function addOccupancy($details) {
		$this->fs[$details->filespace_id]->setOccupancy($details);
	}

	function addVolumeUsage($details) {
		$this->fs[$details['FILESPACE_ID']]->setVolumeUsage($details);
	}

	function getFileSystems() {
		if (isset($this->fs)) 
			return $this->fs;
		else
			return array();
	}

	/**
	 * Return a list of ALL STORAGE POOLS that this node has data in.
	 * @return: array (STORAGE POOL NAMES)
	 */
	function getStoragePools() {
		$result = array();

		if (isset($this->fs)) 
			foreach ($this->fs as $fs => $object) {
				$stgpools = $object->getStoragePools();
				$result = array_unique(array_merge($result,$stgpools));
			}

		return $result;
	}

	/**
	 * Return a list of ALL VOLUMES that this node has data on.
	 * @return: array (VOLUME NAMES)
	 */
	function getVolumeUsage() {
		$result = array();

		if (isset($this->fs))
			foreach ($this->fs as $fs => $object) {
				$vols = $object->getVolumeUsage();
				$result = array_unique(array_merge($result,$vols));
			}

		return $result;
	}

	/**
	 * Return a list of ALL PRIMARY VOLUMES that this node has data on.
	 * return: array (VOLUME OBJECTS)
	 */
	function getPrimaryVolumes($type='Bkup') {
		$result = array();

		if (isset($this->fs))
			foreach ($this->fs as $fs => $object)
				foreach ($object->getVolumes($type) as $stgp => $volumes)
					foreach ($volumes as $volume)
						if ($volume->isPrimaryVol())
							$result[$volume->name] = $volume;

		return $result;
	}

	/**
	 * Return a list of ALL COPYPOOL VOLUMES that this node has data on.
	 * return: array (VOLUME OBJECTS)
	 */
	function getCopyVolumes($type='Bkup') {
		$result = array();

		if (isset($this->fs))
			foreach ($this->fs as $fs => $object)
				foreach ($object->getVolumes($type) as $stgp => $volumes)
					foreach ($volumes as $volume)
						if ($volume->isCopyVol())
							$result[$volume->name] = $volume;

		return $result;
	}

	/**
	 * Return a list of ALL STORAGE POOLS by FILESYSTEM
	 * @return: array (FILE SYSTEM OBJECTS)
	 */
	function getFSOccupancy($type='Bkup') {
		$result = array();

		foreach ($this->fs as $fs => $object)
			if (count($object->getOccupancy($type)))
				$result[$fs] = $object;

		return $result;
	}

	function getVolumes($type='Bkup') {
		$result = array();

		foreach ($this->fs as $fs => $object)
			if (count($object->getVolumes($type)))
				$result[$fs] = $object;

		return $result;
	}

	function getOccupancy() {
		$result = array();

		if (isset($this->fs)) 
			foreach ($this->fs as $fs => $object) {
				if (isset($object->occupancy))
					foreach ($object->occupancy as $type => $stgpools) {
						foreach ($stgpools as $stgp => $details) {
							@$result[$type][$stgp]['num'] += $details['num'];
							@$result[$type][$stgp]['physical'] += $details['physical'];
							@$result[$type][$stgp]['logical'] += $details['logical'];
						}
					}
			}

		return $result;
	}

	function getTapeVolumes($stgp,$type) {
		$result = array();

		if (! isset($this->fs))
			return null;

		foreach ($this->fs as $fsid => $fsobject) {
			if (! isset($fsobject->volume))
				continue;

			foreach ($fsobject->getVolumesStgp($type,$stgp) as $vol => $voldetails)
				$result[] = $voldetails;
		}
	
		return $result;
	}
}

class occupant extends base {
	function setDetails($details) {
		$this->name = $details['NODE_NAME'];
		$this->type = $details['TYPE'];
		$this->filespace = $details['FILESPACE_NAME'];
		$this->stgpool = $details['STGPOOL_NAME'];
		$this->files['num'] = $details['NUM_FILES'];
		$this->files['physical'] = $details['PHYSICAL_MB'];
		$this->files['logical'] = $details['LOGICAL_MB'];
		$this->filespace_id = $details['FILESPACE_ID'];
	}

	function getNode() {
		return ($this->name);
	}

	function getStoragePool() {
		return ($this->stgpool);
	}

	function getType() {
		return ($this->type);
	}
}

/**
 * This class defines a volume.
 */
class storagePool extends base {
	function storagePool($name) {
		$this->name = $name;
	}

	function setDetails($details) {
		$this->type = $details['POOLTYPE'];
		$this->devclass = $details['DEVCLASS'];
		#$this->xx = $details['EST_CAPACITY_MB'];
		#$this->xx = $details['TRIGGER_PCT_UTIL'];
		$this->utilisation = $details['PCT_UTILIZED'];
		$this->migratable = $details['PCT_MIGR'];
		#$this->xx = $details['PCT_LOGICAL'];
		$this->migr['hi'] = $details['HIGHMIG'];
		$this->migr['low'] = $details['LOWMIG'];
		#$this->xx = $details['MIGPROCESS'];
		$this->nextstgp = $details['NEXTSTGPOOL'];
		$this->maxsize = $details['MAXSIZE'];
		$this->access = $details['ACCESS'];
		#$this->xx = $details['DESCRIPTION'];
		#$this->xx = $details['OVFLOCATION'];
		$this->cache = $details['CACHE'];
		$this->collocate = $details['COLLOCATE'];
		$this->reclaim = $details['RECLAIM'];
		$this->maxscratch = $details['MAXSCRATCH'];
		#$this->xx = $details['NUMSCRATCHUSED'];
		$this->reuse = $details['REUSEDELAY'] ? $details['REUSEDELAY'] : 0;
		$this->migr['running'] = $details['MIGR_RUNNING'] == 'YES' ? true : false;
		$this->migr['mb'] = $details['MIGR_MB'];
		$this->migr['sec'] = $details['MIGR_SECONDS'];
		$this->reclaimrunning = $details['RECL_RUNNING'] == 'YES' ? true : false;
		#$this->xx = $details['CHG_TIME'];
		#$this->xx = $details['CHG_ADMIN'];
		$this->reclaimstgp = $details['RECLAIMSTGPOOL'];
		#$this->xx = $details['MIGDELAY'];
		#$this->xx = $details['MIGCONTINUE'];
		#$this->xx = $details['DATAFORMAT'];
		#$this->xx = $details['COPYSTGPOOLS'];
		#$this->xx = $details['COPYCONTINUE'];
		#$this->xx = $details['CRCDATA'];
		#$this->xx = $details['RECLAIMPROCESS'];
	}

	function isPrimaryPool() {
		if ($this->type == 'PRIMARY')
			return true;
		else
			return false;
	}

	function isCopyPool() {
		if ($this->type == 'COPY')
			return true;
		else
			return false;
	}

	function getReclaim() {
		return $this->reclaim;
	}

	function getReUse() {
		return $this->reuse;
	}
}

class summary extends base {
	function summary($name) {
		$this->name = $name;
	}

	function setDetails($details) {
		#$this->xx = $details['LAST_UPDATE'];
	}
}

/**
 * This class defines a volume.
 */
class volume extends base {
	function volume($name,$server) {
		$this->name = $name;
		$this->index = $server;
	}

	function setDetails($details) {
		$this->stgpool = isset($details['STGPOOL_NAME']) ? $details['STGPOOL_NAME'] : null;
		$this->devclass = isset($details['DEVCLASS_NAME']) ? $details['DEVCLASS_NAME'] : null;
		$this->estcap = isset($details['EST_CAPACITY_MB']) ? $details['EST_CAPACITY_MB'] : null;
		$this->utilisation = isset($details['PCT_UTILIZED']) ? $details['PCT_UTILIZED'] : null;
		$this->status['volume'] = isset($details['STATUS']) ? $details['STATUS'] : null;
		$this->access = isset($details['ACCESS']) ? $details['ACCESS'] : null;
		$this->reclaim = isset($details['PCT_RECLAIM']) ? $details['PCT_RECLAIM'] : null;
		$this->scratch = isset($details['SCRATCH']) ? ($details['SCRATCH'] == 'YES' ? true : false) : null;
		$this->mounted = isset($details['TIMES_MOUNTED']) ? $details['TIMES_MOUNTED'] : null;
		$this->writepass = isset($details['WRITE_PASS']) ? $details['WRITE_PASS'] : null;
		$this->last['read'] = isset($details['LAST_READ_DATE']) ? $details['LAST_READ_DATE'] : null;
		$this->last['write'] = isset($details['LAST_WRITE_DATE']) ? $details['LAST_WRITE_DATE'] : null;
		$this->pending['start'] = isset($details['PENDING_DATE']) ? $details['PENDING_DATE'] : null;
		$this->error['read'] = isset($details['READ_ERRORS']) ? $details['READ_ERRORS'] : null;
		$this->error['write'] = isset($details['WRITE_ERRORS']) ? $details['WRITE_ERRORS'] : null;
		$this->error['status'] = isset($details['ERROR_STATE']) ? $details['ERROR_STATE'] : null;
		$this->location = isset($details['LOCATION']) ? $details['LOCATION'] : null;
		#$this->xx = $details['SCALEDCAP_APPLIED'];
		#$this->xx = $details['NUM_SIDES'];
		#$this->xx = $details['MVSLF_CAPABLE'];
		#$this->xx = $details['CHG_TIME'];
		#$this->xx = $details['CHG_ADMIN'];
		#$this->xx = $details['BEGIN_RCLM_DATE'];
		#$this->xx = $details['END_RCLM_DATE'];
	}

	function setLibrary($details) {
		$this->setLibraryName($details['LIBRARY_NAME']);
		$this->status['library'] = $details['STATUS'];
		$this->lib['owner'] = $details['OWNER'];
		$this->lib['use'] = $details['LAST_USE'];
		$this->lib['element'] = $details['HOME_ELEMENT'];
		#$this->xx = $details['CLEANINGS_LEFT'];
		#$this->xx = $details['DEVTYPE'];
		#$this->xx = $details['MEDIATYPE'];
	}

	function setDBBackup($details) {
		$this->dbv['date'] = $details['DATE_TIME'];
		$this->dbv['type'] = $details['TYPE'];
		$this->dbv['series'] = $details['BACKUP_SERIES'];
		$this->dbv['operation'] = $details['BACKUP_OPERATION'];
		$this->dbv['sequence'] = $details['VOLUME_SEQ'];
		$this->devclass = $details['DEVCLASS'];
		$this->location = $details['LOCATION'];
		#$this->xx = $details['UNIQUE'];
		#$this->xx = $details['COMMAND'];
	}

	/**
	 * Is volume in library
	 */
	function inLibrary() {
		if (isset($this->lib['name']) && ! is_null($this->lib['name']))
			return true;
		else
			return false;
	}

	function inLibraryName($library) {
		if ($this->inLibrary() && $this->lib['name'] == $library)
			return true;
		else
			return false;
	}

	function isPrimaryVol() {
		if (isset($this->stgpool))
			return isPrimaryPool($this->stgpool);
		else
			return false;
	}

	function isCopyVol() {
		if (isset($this->stgpool))
			return isCopyPool($this->stgpool);
		else
			return false;
	}

	function isReadWrite() {
		if (isset($this->access))
			return $this->access == 'READWRITE' ? true : false;
		else
			return null;
	}

	function isOutOfLibrary() {
		if (! $this->inLibrary() && LibraryDevClass($this->devclass))
			return true;
		else
			return null;
	}

	function isOffSite() {
		if (isset($this->access))
			return $this->access == 'OFFSITE' ? true : false;
		else
			return null;
	}

	function isPending() {
		if (isset($this->status['volume']))
			if ($this->status['volume'] == 'PENDING') {
				$start = strtotime(tsmDate($this->pending['start'],'nomsec'));
				$end = $start + getReUse($this->stgpool)*86400;
				$this->pending['end'] = strftime('%Y-%m-%d %H:%M:%S',$end);
				return true;
			} else
				return false;
		else
			return null;
	}

	function isEmpty() {
		if (isset($this->status['volume']))
			return $this->status['volume'] == 'EMPTY' ? true : false;
		else
			return null;
	}

	function tobeReclaimed() {
		if (isset($this->reclaim))
			return $this->reclaim > getReclaim($this->stgpool) ? true : false;
		else
			return null;
	}

	function hasWriteErrors() {
		if (isset($this->error['write']))
			return $this->error['write'] ? true : false;
		else
			return null;
	}

	function hasReadErrors() {
		if (isset($this->error['read']))
			return $this->error['read'] ? true : false;
		else
			return null;
	}

	function lastWrite() {
		if (isset($this->last['write']) && trim($this->last['write']))
			return strtotime(tsmDate($this->last['write'],'notime'));
		else
			return null;
	}

	function lastRead() {
		if (isset($this->last['read']) && trim($this->last['read']))
			return strtotime(tsmDate($this->last['read'],'notime'));
		else
			return null;
	}

	function setLibraryName($name) {
		$this->lib['name'] = $name;
	}

	function setSlot($slot) {
		$this->lib['slot'] = $slot;
	}

	function getSlot() {
		if (isset($this->lib['slot']))
			return $this->lib['slot'];
		else
			return null;
	}

	function getLocation() {
		if (isset($this->location))
			return $this->location;
		else
			return null;
	}

	function getStoragePool() {
		if (isset($this->stgpool))
			return $this->stgpool;
		else
			return null;
	}

	function isLibraryEmpty() {
		if ($this->inLibrary() && isset($this->status['volume']) && $this->status['volume'] == 'EMPTY')
			return true;
		else
			return false;
	}

	function isLibraryPending() {
		if ($this->inLibrary() && isset($this->status['volume']) && $this->status['volume'] == 'PENDING')
			return true;
		else
			return false;
	}

	function isLibraryScratch() {
		if ($this->inLibrary() && $this->status['library'] == 'Scratch')
			return true;
		else
			return false;
	}

	function isScratch() {
		if ($this->scratch)
			return true;
		else
			return false;
	}

	function inElement($library,$element) {
		if ($this->inLibraryName($library) && $this->lib['element'] == $element)
			return true;
		else
			return false;
	}
}

class xtsm extends tsm {
	# Record when information retrieved from TSM
	public $cache = null;

	# Our TSM Server
	protected $server = null;

	function expired() {
		if ($this->cache+$_SESSION[APPCONFIG]->getValue('cache','time')< time() || (isset($this->expired) && $this->expired))
			return true;
		else
			return false;
	}
}

class deviceClasses extends xtsm {
	var $devclasses = array();

	function deviceClasses($server) {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our devclass info.
	function load() {
		$this->devclasses = array();

		# Get our defined device classes.
		$result = $this->server->query('select * from DEVCLASSES',null,'DEVCLASS_NAME');
		if ($result) {
			foreach ($result as $devc => $details) {
				$this->devclasses[$devc] = new deviceClass($devc);
				$this->devclasses[$devc]->setDetails($details);
			}
		}
	}

	function isLibraryDevClass($devclass) {
		if (isset($this->devclasses[$devclass]))
			return $this->devclasses[$devclass]->isLibraryDevClass();
		else
			return null;
	}

	function LibraryDevClass($devclass) {
		if (isset($this->devclasses[$devclass]))
			return $this->devclasses[$devclass]->LibraryDevClass();
		else
			return null;
	}

	function getDevClasses() {
		return $this->devclasses;
	}
}

/**
 * This class defines all drives.
 */
class drives extends xtsm {
	var $drives = array();

	function drives($server) {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our drive info.
	function load() {
		$this->drives = array();

		# Get our defined drives.
		$result = $this->server->query('select * from DRIVES',null,'DRIVE_NAME');
		if ($result) {
			foreach ($result as $drive => $details) {
				$this->drives[$drive] = new drive($drive);
				$this->drives[$drive]->setDetails($details);
			}
		}
	}

	function getDrives($library) {
		$result = array();

		foreach ($this->drives as $drive => $object) {
			if ($object->inLibraryName($library))
			$result[$drive] = $object;
		}

		return $result;
	}
}

# Get TSM Help
class help extends xtsm {
	function help($server) {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our help info.
	function load() {
		$this->commands = $this->server->query('help',null);
	}

	function getCommands() {
		return $this->commands;
	}

	function getCommand($command) {
		$helpText = new helpText($command);
		$commandHelp = $this->server->query("help $command",null);
		$helpText->raw = $commandHelp;

		# Skip the two lines, its just the command again.
		array_shift($commandHelp);
		array_shift($commandHelp);

		# The 2nd line is the command description.
		$helpText->addTitle(array_shift($commandHelp));
		array_shift($commandHelp);
		$mode = 'description';

		# Work through the output.
		foreach ($commandHelp as $line) {
			if (preg_match('/^Privilege Class$/',$line))
				$mode = 'class';
			elseif (preg_match('/^Syntax$/',$line))
				$mode = 'syntax';
			elseif (preg_match('/^Parameters$/',$line))
				$mode = 'parameter';
			elseif (preg_match('/^Examples$/',$line))
				$mode = 'example';
			elseif (preg_match('/^Related Commands$/',$line))
				$mode = 'related';

			if (! isset($skip[$mode]))
				$skip[$mode] = 1;
			else
				$skip[$mode]++;

			# Cut out the 2nd  or more blank lines.
			if (trim($line))
				$isBlank[$mode] = false;

			if ((! trim($line)) && isset($isBlank[$mode]) && $isBlank[$mode])
				continue;
			elseif (! trim($line)) 
				$isBlank[$mode] = true;

			switch ($mode) {
				case 'description' : $helpText->addDescription($line);
					break;
				case 'class' : if ($skip[$mode] > 2)
							$helpText->addClass($line);
					break;
				case 'syntax' : if ($skip[$mode] > 2)
							$helpText->addSyntax($line);
					break;
				case 'parameter' : if ($skip[$mode] > 2)
							$helpText->addParameter($line);
					break;
				case 'example' : $helpText->addExample($line);
					break;
				case 'related' : if ($skip[$mode] > 4)
							$helpText->addRelated($line);
					break;
				default : debug_dump("Unknown Text [$line]",1);
			}
		}

		return $helpText;
//		debug_dump(array('command'=>$command,'commandHelp'=>$commandHelp,'helpText'=>$helpText),1);
	}
}

class libraries extends xtsm {
	# Our libraries.
	var $libraries = array();

	function libraries($server) {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our library info.
	function load() {
		debug_log(sprintf('%s::load(): Entered (%s).',get_class($this),$this->cache),1);

		$this->libraries = array();

		$result = $this->server->query('select * from LIBRARIES',null,'LIBRARY_NAME');
		if ($result) {
			foreach ($result as $library => $details) {
				if (! isset($this->libraries[$library]))
					$this->libraries[$library] = new library($library,$this->server->index);

				$this->libraries[$library]->setLibrary($details);
			}
		}

		# Add our volumes & drives
		objectCache('volumes');
		objectCache('drives');
		foreach ($this->libraries as $library) {
			# Does this library support show slots?
			if (in_array($library->type,array('SCSI'))) {
				$result = $this->server->query(sprintf('show slots %s',$library->name),null,'Library');

				if (! count($result)) {
					error(sprintf('querying library %s didnt return any information - is the library operational?',$library->name),'error',false);
					$this->expired = true;
				}

				if (isset($result[$library->name])) {
					$this->libraries[$library->name]->addSlots($result[$library->name]['SlotUsage']);
					$this->libraries[$library->name]->setAttr('ProductId',$result[$library->name]['Product Id']);
					#$this->libraries[$library->name]->setAttr('xx',$result[$library->name]['Support module']);
					#$this->libraries[$library->name]->setAttr('xx',$result[$library->name]['Mount count']);
					$this->libraries[$library->name]->setAttr('Drives',$result[$library->name]['Drives']);
					$this->libraries[$library->name]->setAttr('Slots',$result[$library->name]['Slots']);
					$this->libraries[$library->name]->setAttr('Changers',$result[$library->name]['Changers']);
					$this->libraries[$library->name]->setAttr('IO',$result[$library->name]['Import/Exports']);
					#$this->libraries[$library->name]->setAttr('xx',$result[$library->name]['Device']);
				}

				$this->libraries[$library->name]->addVolumes($_SESSION['cache'][$this->server->index]['volumes']->libraryVolumes($library->name));
				$this->libraries[$library->name]->addDrives($_SESSION['cache'][$this->server->index]['drives']->getDrives($library->name));
			}
		}
	}

	function libVolumes($checkedin=true) {
		$result = array();

		$volumes = objectCache('volumes');

		foreach ($this->libraries as $library) {
			foreach ($library->slotVolumes($checkedin) as $element => $details) {
				$result[$library->name][$element] = $volumes->getVolume($details['barcodelabel']);
				$result[$library->name][$element]->setSlot($details['slot']);
				$result[$library->name][$element]->setDetails($details);
				$result[$library->name][$element]->setLibraryName($library->name);
			}
		}

		return $result;
	}

	function getLibraries() {
		return $this->libraries;
	}
}

class mgmtClasses extends xtsm {
	var $copygroups = array();
	var $mgmtclasses = array();

	function __construct() {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our devclass info.
	function load() {
		$this->copygroups = array();
		$this->mgmtclasses = array();

		# Get our defined mgmt classes
		$result = $this->server->query(sprintf("select * from MGMTCLASSES where SET_NAME='%s'",'ACTIVE'),null);
		if ($result) {
			foreach ($result as $id => $details) {
				$this->mgmtclasses[$id] = new mgmtClass($id);
				$this->mgmtclasses[$id]->setDetails($details);
			}
		}

		# Get our defined copy groups
		# Copygroup name is always STANDARD
		$result = $this->server->query(sprintf("select * from BU_COPYGROUPS where SET_NAME='%s' and COPYGROUP_NAME='%s'",'ACTIVE','STANDARD'),null);
		if ($result) {
			foreach ($result as $id => $details) {
				$this->copygroups[$id] = new copyGroupBackup($id);
				$this->copygroups[$id]->setDetails($details);

				# Set the default mgmtclass
				if ($this->isDefaultMgmtClass($this->copygroups[$id]->name))
					$this->copygroups[$id]->setDefaultMgmtClass();
			}
		}

		$result = $this->server->query(sprintf("select * from AR_COPYGROUPS where SET_NAME='%s' and COPYGROUP_NAME='%s'",'ACTIVE','STANDARD'),null);
		if ($result) {
			foreach ($result as $id => $details) {
				$this->copygroups[$id] = new copyGroupArchive($id);
				$this->copygroups[$id]->setDetails($details);

				# Set the default mgmtclass
				if ($this->isDefaultMgmtClass($this->copygroups[$id]->name))
					$this->copygroups[$id]->setDefaultMgmtClass();
			}
		}
	}

	private function getMgmtClass($name) {
		foreach ($this->mgmtclasses as $mgmtclass)
			if ($mgmtclass->name == $name)
				return $mgmtclass;
	}

	private function isDefaultMgmtClass($name) {
		$mgmtclass = $this->getMgmtClass($name);

		if ($mgmtclass)
			return $mgmtclass->default;
		else
			return null;
	}

	private function getCopyGroup($domain,$mgmtclass,$type='Bkup') {
		foreach ($this->copygroups as $copygroup)
			if ($copygroup->domain == $domain && $copygroup->name == $mgmtclass && $copygroup->type == $type)
				return $copygroup;

		return null;
	}

	public function getMgmtClasses($domain,$type='Bkup') {
		$result = array();

		foreach ($this->mgmtclasses as $mgmtclass) {
			if ($mgmtclass->domain == $domain)
				$result[$mgmtclass->name] = $this->getCopyGroup($mgmtclass->domain,$mgmtclass->name,$type);
		}

		return $result;
	}
}

class nodes extends xtsm {
	var $nodes = array();

	function nodes($server) {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our node info.
	function load() {
		$this->nodes= array();
		$occupancy = objectcache('occupancy');

		# Get our defined nodes.
		$result = $this->server->query('select * from NODES',null,'NODE_NAME');
		if ($result) {
			foreach ($result as $node => $details) {
				$this->nodes[$node] = new node($node);
				$this->nodes[$node]->setDetails($details);
			}
		}

		# Get the file systems.
		$result = $this->server->query('select * from FILESPACES',null);
		if ($result)
			foreach ($result as $details)
				$this->nodes[$details['NODE_NAME']]->addFileSpace($details);

		# Get the file systems occupancy.
		foreach ($this->getNodes() as $node) {
			foreach ($occupancy->getOccupancy($node->name) as $details)
				$this->nodes[$node->name]->addOccupancy($details);
		}

		# Get the volume usage.
		$result = $this->server->query('select * from VOLUMEUSAGE',null);
		if ($result)
			foreach ($result as $details)
				$this->nodes[$details['NODE_NAME']]->addVolumeUsage($details);
	}

	function getNodes() {
		return $this->nodes;
	}

	function getNode($node) {
		if (isset($this->nodes[$node]))
			return $this->nodes[$node];
		else
			return null;
	}
}

/**
 * This class obtains storage pool occupancy
 */
class occupancy extends xtsm {
	var $occupancy = array();

	function occupancy($server) {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our drive info.
	function load() {
		$this->occupancy = array();
		$count = 0;

		# Get our defined drives.
		$result = $this->server->query('select * from OCCUPANCY',null);
		if ($result) {
			foreach ($result as $details) {
				$this->occupancy[$count] = new occupant();
				$this->occupancy[$count]->setDetails($details);
				$count++;
			}
		}
	}

	function getOccupancy($node) {
		$result = array();

		foreach ($this->occupancy as $details) {
			if ($details->getNode() == $node)
				$result[] = $details;
		}

		return $result;
	}

	function getStoragePoolTotals($stgp) {
		$result = array();

		foreach ($this->occupancy as $details) {
			if ($details->getStoragePool() == $stgp) {
				@$result[$details->getNode()][$details->getType()]['files'] = $details->files['num'];
				@$result[$details->getNode()][$details->getType()]['physical'] = $details->files['physical'];
				@$result[$details->getNode()][$details->getType()]['logical'] = $details->files['logical'];
			}
		}

		return $result;
	}
}

/**
 * This class defines all storage pools.
 */
class storagePools extends xtsm {
	var $stgpools = array();

	function storagePools($server) {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our storagepool info.
	function load() {
		$this->stgpools = array();

		# Get our defined storagepools.
		$result = $this->server->query('select * from STGPOOLS',null,'STGPOOL_NAME');
		if ($result) {
			foreach ($result as $stgp => $details) {
				$this->stgpools[$stgp] = new storagePool($stgp);
				$this->stgpools[$stgp]->setDetails($details);
			}
		}
	}

	function isPrimaryPool($pool) {
		if (isset($this->stgpools[$pool]))
			return $this->stgpools[$pool]->isPrimaryPool();
		else
			return null;
	}

	function isCopyPool($pool) {
		if (isset($this->stgpools[$pool]))
			return $this->stgpools[$pool]->isCopyPool();
		else
			return null;
	}

	function getReclaim($pool) {
		if (isset($this->stgpools[$pool]))
			return $this->stgpools[$pool]->getReclaim();
		else
			return null;
	}

	function getReUse($pool) {
		if (isset($this->stgpools[$pool]))
			return $this->stgpools[$pool]->getReUse();
		else
			return null;
	}

	function getStoragePools() {
		return $this->stgpools;
	}

	function ifExist($pool) {
		if (isset($this->stgpools[$pool]))
			return true;
		else
			return false;
	}

	function getStoragePool($pool) {
		if (isset($this->stgpools[$pool]))
			return $this->stgpools[$pool];
		else
			return null;
	}
}

class summaryInfo extends xtsm {
	# Our summary info.
	var $summaryInfo = array();

	public function __construct($server) {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our summary info.
	public function load() {
		$this->summaryInfo = $this->server->query('select START_TIME,END_TIME,ACTIVITY,ENTITY,SCHEDULE_NAME,SUCCESSFUL,MEDIAW,VOLUME_NAME,DRIVE_NAME,BYTES,LAST_USE,AFFECTED,NUMBER,EXAMINED,AFFECTED,FAILED,BYTES,IDLE from SUMMARY order by START_TIME,END_TIME',null);
	}

	# Show media actions in the summary table.
	function mediaActions($list=false) {
		$result = array();

		foreach ($this->summaryInfo as $index => $details) {
			if (trim($details['MEDIAW']) || $details['BYTES'] || $details['AFFECTED'])
				$result[$details['ACTIVITY']][$index] = $details;
		}

		if ($list)
			return array_keys($result);
		else
			return $result;
	}

	/**
	 * Get the range of dates available for the summary table
	 */
	public function getSummaryRange() {
		$sum['start'] = null;
		$sum['end'] = null;

		foreach ($this->summaryInfo as $index => $details) {
			if (($details['START_TIME'] < $sum['start']) || is_null($sum['start']))
				$sum['start'] = $details['START_TIME'];

			if (($details['END_TIME'] > $sum['end']) || is_null($sum['end']))
				$sum['end'] = $details['END_TIME'];
		}

		$sum['starti'] = strtotime(tsmDate($sum['start'],'notime'));
		$sum['endi'] = strtotime(tsmDate($sum['end'],'notime'));

		for ($i=$sum['starti']; $i <= $sum['endi']; $i+=86400) {
			$sum['date'][] = date('Y-m-d',$i);
		}

		return $sum['date'];
	}

	function getSummary($start,$end) {
		$result = array();

		foreach ($this->summaryInfo as $index => $details) {
			$sum['start'] = tsmDate($details['START_TIME'],'notime');
			$sum['end'] = tsmDate($details['END_TIME'],'notime');
			if (($sum['start'] >= $start && ! trim($sum['end'])) ||
				($sum['start'] >= $start && $sum['end'] <= $end) ||
				(! trim($sum['start']) && $sum['end'] <= $end))

				$result[$index] = $details;
		}
		return $result;
	}
}

/**
 * This class defines all volumes.
 */
class volumes extends xtsm {
	# Our volumes.
	var $volumes = array();

	function volumes($server) {
		global $app;

		$this->server = $app['server'];
		$this->load();
	}

	# Load our media info.
	function load() {
		$this->volumes = array();

		# Get our defined volumes.
		$result = $this->server->query('select * from VOLUMES',null,'VOLUME_NAME');
		if ($result) {
			foreach ($result as $volume => $details) {
				$this->volumes[$volume] = new volume($volume,$this->server->index);
				$this->volumes[$volume]->setDetails($details);
			}
		}

		# Get our library volumes.
		$result = $this->server->query('select * from LIBVOLUMES',null,'VOLUME_NAME');
		if ($result) {
			foreach ($result as $volume => $details) {
				if (! isset($this->volumes[$volume]))
					$this->volumes[$volume] = new volume($volume,$this->server->index);

				$this->volumes[$volume]->setLibrary($details);
			}
		}

		# Get our DB volumes.
		$result = $this->server->query("select * from VOLHISTORY where TYPE in ('BACKUPFULL','BACKUPINCR','DBSNAPSHOT') order by BACKUP_SERIES,BACKUP_OPERATION,VOLUME_SEQ",null,'VOLUME_NAME');
		if ($result) {
			foreach ($result as $volume => $details) {
				$this->volumes[$volume] = new volume($volume,$this->server->index);
				$this->volumes[$volume]->setDBBackup($details);
				$this->volumes[$volume]->setDetails($details);
			}
		}
	}

	/**
	 * Return a list of COPY POOL volumes that are in the library
	 */
	function libCopyVolumes($inlib) {
		$result = array();

		foreach ($this->volumes as $volume => $object)
			if ($object->isCopyVol() && isLibraryDevclass($object->devclass) && ($object->inLibrary() == $inlib))
				$result[$volume] = $object;

		return $result;
	}

	/**
	 * Return a list of NON READ/WRITE volumes that need to be fixed.
	 */
	function nonReadWriteVolumes() {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if (! $object->isReadWrite() && ! is_null($object->isReadWrite()) && ! $object->isOffSite() &&
				! $object->isOutOfLibrary())

				$result[$volume] = $object;
		}

		return $result;
	}

	/**
	 * Return a list of volumes that should be RECLAIMed.
	 */
	function reclaimVolumes() {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ($object->tobeReclaimed())
				$result[$volume] = $object;
		}

		return $result;
	}

	/**
	 * Return a list of volumes that have had errors.
	 */
	function errorVolumes() {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ($object->hasReadErrors() || $object->hasWriteErrors())
				$result[$volume] = $object;
		}

		return $result;
	}

	/**
	 * Return a list of volumes that have not been read/written to for a long time.
	 */
	function staleVolumes($days=0) {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ((! is_null($object->lastRead()) && ($object->lastRead() + $days*86400) < time()) ||
				(! is_null($object->lastWrite()) && ($object->lastWrite() + $days*86400) < time())) {
				$result[$volume] = $object;
			}
		}

		return $result;
	}

	/**
	 * Return a list of volumes that are PENDING.
	 */
	function pendingVolumes() {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ($object->isPending())
				$result[$volume] = $object;
		}

		return $result;
	}

	/**
	 * Return a list of volumes that are EMPTY.
	 */
	function emptyVolumes() {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ($object->isEmpty())
				$result[$volume] = $object;
		}

		return $result;
	}

	function libraryVolumes($library) {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ($object->inLibraryName($library))
				$result[$volume] = $object;
		}

		return $result;
	}

	function getVolume($volume) {
		if (isset($this->volumes[$volume]))
			return $this->volumes[$volume];
		else
			return new volume('Unknown Label',$this->server->index);
	}

	function primaryNotInLib() {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if ($object->isOutOfLibrary() && $object->isPrimaryVol())
				$result[$volume] = $object;
		}

		return $result;
	}

	function getStoragePoolVolumes($stgp) {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if (isset($object->stgpool) && $object->stgpool == $stgp)
				$result[$volume] = $object;
		}

		return $result;
	}

	function getStoragePoolScratchVolumes($stgp) {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if (isset($object->stgpool) && $object->stgpool == $stgp && $object->isScratch())
				$result[$volume] = $object;
		}

		return $result;
	}

	function getStoragePoolDefinedVolumes($stgp) {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if (isset($object->stgpool) && $object->stgpool == $stgp && ! $object->isScratch())
				$result[$volume] = $object;
		}

		return $result;
	}

	function getStoragePoolVolumesStatus($stgp,$status) {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if (isset($object->stgpool) && $object->stgpool == $stgp && $object->status['volume'] == $status)
				$result[$volume] = $object;
		}

		return $result;
	}

	function getStoragePoolVolumesAccess($stgp,$access) {
		$result = array();

		foreach ($this->volumes as $volume => $object) {
			if (isset($object->stgpool) && $object->stgpool == $stgp && $object->access == $access)
				$result[$volume] = $object;
		}

		return $result;
	}

	function inElement($library,$element) {
		foreach ($this->volumes as $volume => $object) {
			if ($object->inElement($library,$element))
				return $object->name;
		}

		return null;
	}
}
?>
