package XXX;

# XXX.pm - these are operating system specific routines for XXX
#
# Rules for these subroutines:
# 
#	1.  These subroutines can be called in any order except
#	    for Initialize${OSName}.  That will always be called
#	    before any others.
#	2.  These subroutines can be called in any order...
# 
# ==============================================================
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 
# 2 of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be 
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License for more details.
# 
# Original source:
#	Copyright (c) 1999, 2000 SAIC (Bruce W. Mohler)
# 
# Contributed source:
#	Copyright (c) 1999, 2000 <author)
# 
# ==============================================================
# 
# $Header$
# 
# $Revision$
#
# $Log$

use Sys::Hostname;
use common;

require Exporter;
@ISA = qw(Exporter);
###########################################################################
# the following sub-routines (&) are variables ($) will be 
# visible in a program using this module...
@EXPORT = qw(
	&InitializeXXX
);
# 
# Note that you do not need to export the Return* subroutine
# names since they are being called by reference.
# 
###########################################################################

###########################################################################
# Public Global Variables (must be declared above)
###########################################################################


###########################################################################
# Private Global Variables
###########################################################################

# parts of OS version - filled in by InitializeXXX()
$OSVersion = "";
$OSVersionMajor = "";
$OSVersionMinor = "";

# where commands are located			standard args
# CUSTOMIZE
$BdfCommand = "/usr/bin/bdf";			$LocalFileSystems = "-t hfs";
						$LocalvxfsFileSystems = "-t vxfs";
						$NFSFileSystems = "-t nfs";
$DiskinfoCommand = "";				# filled in below
$DomainnameCommand = "/usr/bin/domainname";
$IfconfigCommand = "/usr/sbin/ifconfig";
$IoscanCommand = "/etc/ioscan";			$IoscanArgs = "-fn";
$LanscanCommand = "/usr/sbin/lanscan";		$LanscanArgs = "-v";
$LpstatCommand = "/usr/bin/lpstat";		$LpstatArgs = "-p";
$PsCommand = "/usr/bin/ps";			$PsArgs = "-aef";
$PvcreateCommand = "/usr/sbin/pvcreate";
$SwapCommand = "";
$SwlistCommand = "/usr/sbin/swlist";
$UnameCommand = "/bin/uname";

# where files are located
# CUSTOMIZE
$AccountingConfPath = "/etc/rc.config.d/acct";	$AccountingTag = "START_ACCT";
$FontServerConfPath = "/etc/rc.config.d/xfs";	$FontServerTag = "RUN_X_FONT_SERVER";
$GUIConfPath = "/etc/rc.config.d/desktop";	$GUITag = "DESKTOP";
$InetdConfPath = "/etc/inetd.conf";
$LpschedConfPath = "/etc/rc.config.d/lp";	$LpschedTag = "LP";
$MailservsConfPath = "/etc/rc.config.d/mailservs"; $MailservsTag = "SENDMAIL_SERVER";
$NameserverConfPath = "/etc/rc.config.d/namesvrs"; $NameserverTag = "NAMED";
						$NISmasterTag = "NIS_MASTER_SERVER";
						$NISslaveTag = "NIS_SLAVE_SERVER";
						$NISclientTag = "NIS_CLIENT";
$NetConfPath = "/etc/rc.config.d/netconf";	$IPAddressTag = "IP_ADDRESS";
						$LoopbackTag = "LOOPBACK_ADDRESS";
						$SubnetMaskTag = "SUBNET_MASK";
						$DefaultRouterTag = "ROUTE_GATEWAY";
$NfsConfPath = "/etc/rc.config.d/nfsconf";	$NFSServerTag = "NFS_SERVER";
						$NFSClientTag = "NFS_CLIENT";
						$AutomountTag = "AUTOMOUNT";
$ResolvConfPath = "/etc/resolv.conf";
$SendmailConfPath = '/etc/mail/sendmail.cf';

$SubroutineSuffix = "";

# device path patterns - filled in by InitializeXXX()
$DiskNamePattern = "";
$TapeNamePattern = "";


###########################################################################
# Subroutines
###########################################################################

# 
# This subroutine is called before any others.  It's
# reason for existence is to plug in the references to
# subroutines below to actually generate the information.
# 

sub InitializeXXX ()
{
	print "InitializeXXX()...\n" if $main::Debug;

	# initialize $SubroutineSuffix...
	WhatVersionOfXXX();

	# we need the nodename for later on...
	$main::NodeName = hostname();
	print "\tNodeName is $main::NodeName\n" if $main::Debug;

# 	# fill in different file and command paths
# 	if ( $OSVersionMajor == 9 ) {
# 		$DiskinfoCommand = "/etc/diskinfo";
# 	}
# 	elsif ( $OSVersionMajor == 10 or $OSVersionMajor == 11 ) {
# 		$DiskinfoCommand = "/usr/sbin/diskinfo";
# 	}
# 	else {
# 		die "syssumm doesn't support XXX version $OSVersionMajor (yet)";
# 	}

# 	# fill in device path patterns
# 	if ( $OSVersionMajor == 10 or $OSVersionMajor == 11 ) {
# 		$DiskNamePattern = "/dev/rdsk/c%st%sd0";	# cont, addr
# 		$TapeNamePattern = "/dev/rmt/%sm";		# addr
# 	}

	# plug in appropriate subroutines
# 	$main::Routines{General}{Vendor} = \&ReturnVendorXXX;
# 	$main::Routines{General}{Model} = \&ReturnModelXXX;
# 	$main::Routines{General}{HostId} = \&ReturnHostIdXXX;

# 	$main::Routines{Hardware}{Processors} = \&ReturnProcessorsXXX;
# 	$main::Routines{Hardware}{Memory} = \&ReturnMemoryXXX;
# 	$main::Routines{Hardware}{Disks} = \&ReturnDisksXXX;
# 	$main::Routines{Hardware}{Tapes} = \&ReturnTapesXXX;
# 	$main::Routines{Hardware}{StorageManager} = \&ReturnStorageManagerXXX;
# 	$main::Routines{Hardware}{Eeprom} = \&ReturnEepromXXX;

# 	$main::Routines{Network}{DomainName} = \&ReturnDomainNameXXX;
# 	$main::Routines{Network}{DefaultRouter} = \&ReturnDefaultRouterXXX;
# 	$main::Routines{Network}{NameServer} = \&ReturnNameServerXXX;
# 	$main::Routines{Network}{IPAddress} = \&ReturnIPAddressXXX;
# 	$main::Routines{Network}{SubnetMask} = \&ReturnSubnetMaskXXX;
# 	$main::Routines{Network}{NetworkInterfaces} = \&ReturnNetworkInterfacesXXX;

# 	$main::Routines{Software}{OsName} = \&ReturnOsNameXXX;
# 	$main::Routines{Software}{OsVersion} = \&ReturnOsVersionXXX;
# 	$main::Routines{Software}{NbrOfLicenses} = \&ReturnNbrOfLicensesXXX;
# 	$main::Routines{Software}{Patches} = \&ReturnPatchesXXX;
# 	$main::Routines{Software}{Printers} = \&ReturnPrintersXXX;
# 	$main::Routines{Software}{Services} = \&ReturnServices;
# 	$main::Routines{Software}{IPAddressResolution} = \&ReturnIPAddressResolutionXXX;
# 	$main::Routines{Software}{GraphicalUserInterface} = \&ReturnGraphicalUserInterfaceXXX;
# 	$main::Routines{Software}{FontServer} = \&ReturnFontServerXXX;
# 	$main::Routines{Software}{Fstab} = \&ReturnFstab;
# 	$main::Routines{Software}{LocalFileSystems} = \&ReturnLocalFileSystemsXXX;
# 	$main::Routines{Software}{RemoteFileSystems} = \&ReturnRemoteFileSystemsXXX;
# 	$main::Routines{Software}{ExportedFileSystems} = \&ReturnExportedFileSystemsXXX;
# 	$main::Routines{Software}{Swap} = \&ReturnSwapXXX;

	# if you have OS-specific services, add them here
	# push @main::Services, "Local-Service";

	RemoveLocalExclusions();

	return;
}


###########################################################################
# Global
###########################################################################


sub WhatVersionOfXXX
{
	print "WhatVersionOfXXX()...\n" if $main::Debug;

	$OSVersion = `$UnameCommand -r`;
	chomp($OSVersion);

	( $OSVersionMajor, $OSVersionMinor ) = split(/\./, $OSVersion);
	print "\tMajor OS version is $OSVersionMajor...\n" if $main::Debug;
	print "\tMinor OS version is $OSVersionMinor...\n" if $main::Debug;

	$SubroutineSuffix = $OSVersionMajor;

	return;
}


###########################################################################
# General
###########################################################################

sub ReturnVendorXXX ($)
{	my $Subcategory = shift;

	# CUSTOMIZE
	return ( "XXX" );
}


sub ReturnModelXXX ($)
{	my $Subcategory = shift;

# 	my $Model = `$UnameCommand -m`;
# 	chomp($Model);

	return ( $Model );
}


sub ReturnHostIdXXX ($)
{	my $Subcategory = shift;

# 	my $IdNbr = `$UnameCommand -i`;
# 	chomp($IdNbr);

	return ( $IdNbr );
}


###########################################################################
# Hardware
###########################################################################

sub ReturnProcessorsXXX ($)
{	my $Subcategory = shift;
	my @Processors = ( );

#	# DON'T GET YOUR INFORMATION FROM THE SYSLOG!
# 	my @SyslogText = ReturnArrayFile($SyslogPath);
# 	foreach $Line ( @SyslogText ) {
# 
# 		# we're looking for patterns like "62 proc..."
# 		if ( $Line =~ /^([\d]{2}) (.*)/ ) {
# 
# 			# map regexp variables to something more mnemonic
# 			my $Address = $1;
# 			my $DeviceType = $2;
# 
# 			if ( $DeviceType =~ /processor/ ) {
# 				push @Processors, "processor $Address";
# 			}
# 			next;
# 		}
# 	}
# 
# 	my $NbrOfProcessors = scalar(@Processors);
# 	my $ProcessorString = $NbrOfProcessors . " processor" . 
# 		( ( $NbrOfProcessors != 1 ) ? "s" : "" ) . " (speed unknown)";
# 
# 	# 
# 	# Note that we save the hardware address of the
# 	# processor into @processors, but don't return 
# 	# it in @Response...
# 	# 

	return ( $ProcessorString );
}


sub ReturnMemoryXXX ($)
{	my $Subcategory = shift;

#	# DON'T GET YOUR INFORMATION FROM THE SYSLOG!
# 	# how much memory?
# 	my $Memory = SearchFileForPattern($SyslogPath, "Physical:", 1);
# 	$Memory = int ( $Memory / 1024 );
# 	$Memory = "$Memory" . "MB";

	return ( $Memory );
}


sub ReturnDisksXXX ($)
{	my $Subcategory = shift;
	my @Controllers = ( );
	my $ControllerNbr = -1;
	my $CurrentController = -1;
	my @Response = ( );

#	# DON'T GET YOUR INFORMATION FROM THE SYSLOG!
# 	my @SyslogText = ReturnArrayFile($SyslogPath);
# 	foreach $Line ( @SyslogText ) {
# 
# 		# we're looking for patterns like "56/52.0.0 disc..."
# 		if ( $Line =~ /^[\d]{2}\/([\d]{2})\.([\d]+)\.[\d]+ (.*)/ ) {
# 
# 			# map regexp variables to something more mnemonic
# 			my $Controller = $1;
# 			my $Address = $2;
# 			my $DeviceType = $3;
# 
# 			# keep track of the controllers
# 			if ( $Controller != $CurrentController ) {
# 				push @Controllers, "controller $Controller";
# 				$CurrentController = $Controller;
# 
# 				$ControllerNbr += 1;
# 			}
# 
# 			if ( $DeviceType =~ /disc/ ) {
# 				my $Response = AddDiskinfo10("disk $ControllerNbr $Address");
# 				push @Response, $Response if ( $Response);
# 			}
# 		}
# 	}

	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


sub ReturnTapesXXX ($)
{	my $Subcategory = shift;
	my @Controllers = ( );
	my $ControllerNbr = -1;
	my $CurrentController = -1;
	my @Response = ( );

#	# DON'T GET YOUR INFORMATION FROM THE SYSLOG!
# 	my @SyslogText = ReturnArrayFile($SyslogPath);
# 	foreach $Line ( @SyslogText ) {
# 
# 		# we're looking for patterns like "56/52.0.0 disc..."
# 		if ( $Line =~ /^([\d]{2})\/[\d]{2}\.([\d]+)\.[\d]+ (.*)/ ) {
# 
# 			# map regexp variables to something more mnemonic
# 			my $Controller = $1;
# 			my $Address = $2;
# 			my $DeviceType = $3;
# 
# 			# keep track of the controllers
# 			if ( $Controller != $CurrentController ) {
# 				push @Controllers, "controller $Controller";
# 				$CurrentController = $Controller;
# 
# 				$ControllerNbr += 1;
# 			}
# 
# 			if ( $DeviceType =~ /tape/ ) {
# 				my $Response = AddDiskinfo10("tape $ControllerNbr $Address");
# 				push @Response, $Response if ( $Response);
# 			}
# 		}
# 	}

	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


# 
# Build the device name, then feed it to the diskinfo
# command to retrieve the vendor and model of the device
# 

sub AddDiskinfo10 ($)
{	my $DeviceInfo = shift;
	my $ValidDevice = 0;

# 	print "AddDiskinfo10($DeviceInfo)...\n" if $main::Debug;
# 
# 	# build the name of the drive from controller/address info
# 	my $DeviceName = "";
# 	my ( $DeviceType, $Controller, $Address ) = split(/ /, $DeviceInfo);
# 	if ( $DeviceType eq "disk" ) {
# 		$DeviceName = sprintf($DiskNamePattern, $Controller, $Address);
# 	}
# 	elsif ( $DeviceType eq "tape" ) {
# 		$DeviceName = sprintf($TapeNamePattern, $Controller, $Address);
# 	}
# 	return "" if ! $DeviceName;
# 	print "\tDeviceName is $DeviceName...\n" if $main::Debug;

	return AddDiskinfo($DeviceName);
}


sub AddDiskinfo ($)
{	my $DeviceName = shift;
	my $ValidDevice = 0;
	my $UnknownDevice = "model=unknown";

# 	print "AddDiskinfo($DeviceName)...\n" if $main::Debug;
# 
# 	# what does diskinfo say about the device?
# 	open DISKINFO, "$DiskinfoCommand $DeviceName 2>&1 |" or
# 		die "Can't read output from diskinfo: $!";
# 	my @DiskinfoText = <DISKINFO>;
# 	close(DISKINFO);
# 	chomp(@DiskinfoText);
# 
# 	my $Vendor = "";
# 	my $Model = "";
# 	my $Type = "";
# 	foreach $Line ( @DiskinfoText ) {
# 		my $Tag = "";
# 
# 		if ( $Vendor and $Model ) {
# 			return ("$DeviceName vendor=$Vendor $Type model=$Model");
# 		}
# 
# 		print "\t$Line\n" if $main::Debug;
# 		if ( $Line =~ /permission denied/i ) {
# 			$main::RunAsRoot = 1;
# 			return "$DeviceName $UnknownDevice";
# 		}
# 		if ( $Line =~ /no such device/i ) {
# 			return "$DeviceName $UnknownDevice";
# 		}
# 		if ( $Line =~ /vendor/ ) {
# 			( $Tag, $Vendor ) = split(/:/, $Line);
# 			# strip off any leading/trailing whitespace
# 			$Vendor =~ s/^[\s]+//g;
# 			$Vendor =~ s/[\s]+$//g;
# 			print "\tVendor is $Vendor...\n" if $main::Debug;
# 			next;
# 		}
# 		if ( $Line =~ /product id/ ) {
# 			( $Tag, $Model ) = split(/:/, $Line);
# 			# strip off any leading/trailing whitespace
# 			$Model =~ s/^[\s]+//g;
# 			$Model =~ s/[\s]+$//g;
# 			# if it's a cd-rom, split that out as the type
# 			if ( $Model =~ /^(CD-ROM) (.*)$/ ) {
# 				$Type = "type=$1";
# 				$Model = $2;
# 				print "\tType is $Type...\n" if $main::Debug;
# 			}
# 			print "\tModel is $Model...\n" if $main::Debug;
# 			next;
# 		}
# 	}
# 
# 	# return what we have
# 	if ( $Vendor ) {
# 		return ("$DeviceName vendor=$Vendor");
# 	}
# 	else {
# 		return ("$DeviceName model=$Model");
# 	}
}


sub ReturnStorageManagerXXX ($)
{	my $Subcategory = shift;
	my @Response = ();

	if ( -x $PvcreateCommand ) {
		push @Response, "Logical Volume Manager (LVM)";
	}
	else {
		push @Response, "None";
	}

	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


sub ReturnEepromXXX ($)
{	my $Subcategory = shift;
	my $Eeprom = "";

	# XXX - this is a stub routine to be filled in later...

	return ( $Eeprom );
}


###########################################################################
# Network
###########################################################################

sub ReturnDomainNameXXX ($)
{	my $Subcategory = shift;

	return ReturnDomainName($Subcategory, $ResolvConfPath);
}


sub ReturnDefaultRouterXXX ($)
{	my $Subcategory = shift;

# 	my $DefaultRouter = SearchFileForTagValue($NetConfPath, $DefaultRouterTag);
	$DefaultRouter = IPtoFQDN($DefaultRouter);

	return ( $DefaultRouter );
}


sub ReturnNameServerXXX ($)
{	my $Subcategory = shift;
	my @Response = ( );

# 	my @ResolvConfText = ReturnArrayFile($ResolvConfPath);
# 	if ( scalar(@ResolvConfText) < 1 ) {
# 		push @Response, "None";
# 	}
# 	else {
# 		foreach $Line (@ResolvConfText) {
# 			# find the first line with "nameserver" in it?
# 			if ( $Line =~ /^nameserver\s+([\d]+\.[\d]+\.[\d]+\.[\d]+)/ ) {
# 				my $NameServerIP = $1;
# 				# do we recognize this nameserver?
# 				my $NameServerFQDN = IPtoFQDN($NameServerIP);
# 				if ( ! $NameServerFQDN ) {
# 					$XXX::NonStandardNameServer = 1;
# 				}
# 				push @Response, $NameServerFQDN;
# 				next;
# 			}
# 		}
# 	}

	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


sub ReturnIPAddressXXX
{	my $Subcategory = shift;

# 	# Returns the IP address associated with "$main::nodename"
# 	# The "default" IP address. This subroutine will be used  
# 	# if Bruce decides to implement this function in syssumm.pl 
# 	my @Addresses = (gethostbyname $main::NodeName)[4];         
# 	my ($a, $b, $c, $d) = unpack('C4', $Addresses[0]);
# 	$IPAddress = "$a." . "$b." . "$c." . "$d" ;

	return ( $IPAddress );
}


sub ReturnSubnetMaskXXX
{	my $Subcategory = shift;

# 	# Returns netmask associated with the "default" IP address
# 	# This subroutine will be used if Bruce decides to implement
# 	# this function in syssumm.pl
# 	my $SubnetMask = "";       
# 	my $IPAddress = ReturnIPAddressXXX($Subcategory);
# 	my @Interfaces = ReturnNetworkInterfacesXXX($Subcategory);
# 
# 	# find interface corresponding to "default" IP
# 	# and get netmask from it
# 	foreach $Line (@Interfaces) {
# 		next unless ( $Line =~ /$IPAddress/ ); 
# 		if ( $Line =~ /netmask=(\w+)/ ) {      
# 			# ReturnNetworkInterfacesXXX() returns netmask in hex.
# 			# convert back to decimal
# 			my $a=substr($1,0,2); 
# 			my $b=substr($1,2,2); 
# 			my $c=substr($1,4,2); 
# 			my $d=substr($1,6,2);
# 			$SubnetMask = hex($a) . "." . hex($b) . "." . hex($c) . "." . hex($d);
# 		}
# 	}

	return ($SubnetMask);
}     


sub ReturnNetworkInterfacesXXX ($)
{	my $Subcategory = shift;
	my @Response = ( );

#	# DON'T GET YOUR INFORMATION FROM THE SYSLOG!
# 	my @SyslogText = ReturnArrayFile($SyslogPath);
# 	foreach $Line ( @SyslogText ) {
# 
# 		# we're looking for patterns like "60/6 lan..."
# 		if ( $Line =~ /^([\d]{2}\/[\d]{1}) (.*)/ ) {
# 
# 			# map regexp variables to something more mnemonic
# 			my $Address = $1;
# 			my $DeviceType = $2;
# 
# 			if ( $DeviceType =~ /lan/ ) {
# 				my $Response = AddNetInfo("$Address");
# 				push @Response, $Response if ( $Response);
# 			}
# 		}
# 	}

	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


sub AddNetInfo ($)
{	my $BusHardwareAddress = shift;
	my $MACAddress = "";
	my $NetworkInterfaceName = "";
	my $NICType = "";

# 	print "AddNetInfo($BusHardwareAddress)...\n" if $main::Debug;
# 
# 	# map hardware network address to lan address
# 	# "60/6" --> "lan0"
# 	my @LanscanText = ReturnArrayExec("$LanscanCommand $LanscanArgs");
# 	foreach $Line ( @LanscanText ) {
# 		if ( $Line =~ /^$BusHardwareAddress/ ) {
# 			$Line =~ s/  / /g;	# strip out dup spaces
# 			$MACAddress = (split(' ', $Line))[1];
# 			print "\tMACAddress is $MACAddress...\n" if $main::Debug;
# 			$NetworkInterfaceName = (split(' ', $Line))[4];
# 			print "\tNetworkInterfaceName is $NetworkInterfaceName...\n" if $main::Debug;
# 			$NICType = (split(' ', $Line))[7];
# 			print "\tNICType is $NICType...\n" if $main::Debug;
# 			last;
# 		}
# 	}
# 	# we didn't find it
# 	if ( ! $NetworkInterfaceName ) {
# 		return "";
# 	}
# 
# 	# use ifconfig to get the rest of the information
# 	open IFCONFIG, "$IfconfigCommand $NetworkInterfaceName 2>&1 |" or
# 		die "Can't read output from ifconfig: $!";
# 	my @IfconfigText = <IFCONFIG>;
# 	close(IFCONFIG);
# 	chomp(@IfconfigText);
# 
# 	# let's "operate" on the 2nd line returned
# 	$IfconfigText[1] =~ s/^[\s]*//g;	# trim leading whitespace
# 	$IfconfigText[1] =~ s/inet /ip=/;
# 	$IfconfigText[1] =~ s/netmask /netmask=/;
# 	$IfconfigText[1] =~ s/broadcast /broadcast=/;
# 	print "\tifconfig info is $IfconfigText[1]...\n" if $main::Debug;
# 
# 	my $NICDescription = 
# 		"$NetworkInterfaceName type=$NICType macaddr=$MACAddress " .
# 		$IfconfigText[1];

	return $NICDescription;
}


###########################################################################
# Software
###########################################################################

sub ReturnOsNameXXX ($)
{	my $Subcategory = shift;

	return ( "XXX" );
}


sub ReturnOsVersionXXX ($)
{	my $Subcategory = shift;

	return ( "$OSVersion" );
}


sub ReturnNbrOfLicensesXXX ($)
{	my $Subcategory = shift;

# 	my $NbrOfLicenses = `$UnameCommand -l`;
# 	chomp($NbrOfLicenses);

	return ( $NbrOfLicenses );
}


sub ReturnPatchesXXX ($)
{	my $Subcategory = shift;
	my @Response = ( );

# 	# what patches are installed?
# 	open SWLIST, "$SwlistCommand -l product 2>&1 |" or
# 		die "Can't read output from swlist: $!";
# 	my @SwlistText = <SWLIST>;
# 	close(SWLIST);
# 	chomp(@SwlistText);
# 	foreach $Line ( @SwlistText ) {
# 		$Line =~ s/^[\s]*//;		# no leading spaces
# 		$Line =~ s/[\s]+/ /g;		# single spaces separating fields
# 		$Line =~ s/[\s]*$//;		# no trailing spaces
# 		if ( $Line =~ /^PH/ ) {
# 			my ( $PatchName, $PatchVersion, $PatchDescription ) =
# 				split(/ /, $Line, 3);
# 			push @Response, "$PatchName desc=\"$PatchDescription\"";
# 		}
# 	}
# 
# 	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


sub ReturnRunningLpschedXXX ($)
{	my $Subcategory = shift;
	my @Responses = ( );

	# XXX comment out as necessary
	my $Response = ReturnRunningSysvLp($Subcategory, $PsCommand, $PsArgs);
	push @Responses, $Response if $Response =~ /Yes/;
	$Response = ReturnRunningBSDLpr($Subcategory, $PsCommand, $PsArgs);
	push @Responses, $Response if $Response =~ /Yes/;
	$Response = ReturnRunningLPRng($Subcategory);
	push @Responses, $Response if $Response =~ /Yes/;

	# concatenate the final responses as necessary
	my $FinalResponse = "";
	foreach $Response (@Responses) {
		if ( $FinalResponse eq "" ) {
			$FinalResponse = $Response;
		}
		else {
			$FinalResponse = "$FinalResponse, $Response";
		}
	}

	return ($FinalResponse);
}


sub ReturnPrintersXXX ($)
{	my $Subcategory = shift;
	my @Response = ( );

# 	my $LocalPrinters = SearchFileForPattern("$LpstatCommand $LpstatArgs", "^printer", 1);
# 	my @LocalPrinters = split(/ /, $LocalPrinters);
# 	@Response = @LocalPrinters;

	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


# 
# Note that this subroutine has a side-effect of setting
# a global variable in main:: called EmailAvailable if
# sendmail is running...
# 

sub ReturnRunningSendmailXXX ($)
{	my $Subcategory = shift;

# 	my $Sendmail = SearchFileForTagValue($MailservsConfPath, $MailservsTag);
# 
# 	if ( $Sendmail == $NotFound or $Sendmail eq "" ) {
# 		$Sendmail = SearchFileForPattern("$PsCommand $PsArgs", "sendmail", -1);
# 		# if we still didn't find anything...
# 		if ( $Sendmail == $NotFound or $Sendmail eq "" ) {
# 			$Sendmail = "";
# 		}
# 	}
# 
# 	$Sendmail = ( $Sendmail ? "Yes" : "No" );
# 
# 	# what version of sendmail are we running?
# 	if ( ( $Sendmail eq 'Yes' ) and ( -r $SendmailConfPath ) ) {
# 		@SendmailConfig = ReturnArrayFile("$SendmailConfPath");
# 		foreach $Line (@SendmailConfig) {
# 			if ( $Line =~ /^DZ(\d+\.\d+\.\d+)/ ) {
# 				$Sendmail .= " (version $1)";
# 				last;
# 			}
# 		}
# 	}
# 
# 	# side-effect
# 	$main::EmailAvailable = ( $Sendmail eq "Yes" );

	return ( $Sendmail );
}


sub ReturnRunningNFSXXX ($)
{	my $Subcategory = shift;

# 	my $NFSState = "";
# 	my $NFSServer = SearchFileForTagValue($NfsConfPath, $NFSServerTag);
# 	print "\tNFSServer is $NFSServer\n" if $main::Debug;
# 	my $NFSClient = SearchFileForTagValue($NfsConfPath, $NFSClientTag);
# 	print "\tNFSClient is $NFSClient\n" if $main::Debug;
# 	if ( $NFSServer and $NFSClient) {
# 		$NFSState = "Yes, both server and client";
# 	}
# 	elsif ( $NFSServer ) {
# 		$NFSState = "Yes, server only";
# 	}
# 	elsif ( $NFSClient ) {
# 		$NFSState = "Yes, client only";
# 	}
# 	else {
# 		$NFSState = "No";
# 	}

	return ( $NFSState );
}


sub ReturnRunningAutomountXXX ($)
{	my $Subcategory = shift;

# 	my $Automount = SearchFileForTagValue($NfsConfPath, $AutomountTag);
# 	$Automount = ( $Automount ? "Yes" : "No" );

	return ( $Automount );
}


sub ReturnRunningNISXXX ($)
{	my $Subcategory = shift;

# 	my $NISState = "";
# 	my $NISmaster = SearchFileForTagValue($NameserverConfPath, $NISmasterTag);
# 	my $NISslave = SearchFileForTagValue($NameserverConfPath, $NISslaveTag);
# 	my $NISclient = SearchFileForTagValue($NameserverConfPath, $NISclientTag);
# 	if ( $NISmaster or $NISslave ) {
# 		$NISmaster = 1;
# 	}
# 	if ( $NISmaster and $NISclient ) {
# 		$NISState = "Yes, both server and client";
# 	}
# 	elsif ( $NISmaster ) {
# 		$NISState = "Yes, server only";
# 	}
# 	elsif ( $NISclient ) {
# 		$NISState = "Yes, client only";
# 	}
# 	else {
# 		$NISState = "No";
# 	}
# 
# 	# if we're running NIS, document the domain name
# 	if ( $NISState =~ /^yes/oi ) {
# 		my $Domainname = `$DomainnameCommand`;
# 		chomp($Domainname);
# 		$NISState .= ", domain is $Domainname";
# 	}

	return ( $NISState );
}


sub ReturnRunningNameserverXXX ($)
{	my $Subcategory = shift;

# 	my $Nameserver = SearchFileForTagValue($NameserverConfPath, $NameserverTag);
# 	if ( $Nameserver == $NotFound or $Nameserver eq "" ) {
# 		$Nameserver = "Unknown";
# 	}
# 	else {
# 		$Nameserver = ( $Nameserver ? "Yes" : "No" );
# 	}

	return ( $Nameserver );
}


sub ReturnIPAddressResolutionXXX ($)
{	my $Subcategory = shift;

# 	my $IPAddressResolution = "/etc/hosts";
# 	if ( -f $ResolvConfPath ) {
# 		$IPAddressResolution = "DNS";
# 	}

	return ( $IPAddressResolution );
}


sub ReturnRunningSambaXXX ($)
{	my $Subcategory = shift;

	return ReturnRunningSamba($Subcategory, $PsCommand, $PsArgs, $InetdConfPath);
}


sub ReturnGraphicalUserInterfaceXXX ($)
{	my $Subcategory = shift;

# 	my $GUI = SearchFileForTagValue($GUIConfPath, $GUITag);
# 	if ( $GUI eq $NotFound or $GUI eq "" ) {
# 		$GUI = "Unknown";
# 	}

	return ( $GUI );
}


sub ReturnFontServerXXX ($)
{	my $Subcategory = shift;

# 	my $FontServer = SearchFileForTagValue($FontServerConfPath, $FontServerTag);
# 	if ( $FontServer == $NotFound or $FontServer eq "" ) {
# 		$FontServer = "Unknown";
# 	}
# 	else {
# 		$FontServer = ( $FontServer ? "Yes" : "No" );
# 	}

	return ( $FontServer );
}


sub ReturnLocalFileSystemsXXX ($)
{	my $Subcategory = shift;
	my @Response = ( );

# 	my @BdfText = ReturnArrayExec("$BdfCommand $LocalFileSystems");
# 	my @BdfvxfsText = ReturnArrayExec("$BdfCommand $LocalvxfsFileSystems");
# 	push @BdfText, @BdfvxfsText;
# 
# 	my $PreviousLine = "";
# 	$Suffix = 0;
# 	foreach $Line (@BdfText) {
# 
# 		# bypass the header line
# 		next if $Line =~ /^Filesystem/;
# 		# bypass any cdrom drives or remote file systems
# 		next if $Line =~ /cdrom/;
# 		next if $Line =~ /^[\w]/;
# 
# 		# partial line?
# 		if ( $PreviousLine ) {
# 			$Line = $PreviousLine . $Line;
# 			$PreviousLine = "";
# 		}
# 
# 		# clean and split line
# 		$Line =~ s/[\s]+/ /g;
# 		my @BdfFields = split(/ /, $Line);
# 
# 		# partial line?
# 		if ( scalar(@BdfFields) < 2 ) {
# 			$PreviousLine = $Line;
# 			# go get the rest of it
# 			next;
# 		}
# 
# 		# calc size in MB
# 		my $Size = sprintf("%.1fMB", ( $BdfFields[1] / 1024 ) );
# 
# 		push @Response, "$BdfFields[5] mount=$BdfFields[0] size=$Size sat=$BdfFields[4]";
# 	}

	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


sub ReturnRemoteFileSystemsXXX ($)
{	my $Subcategory = shift;
	my @Response = ( );

# 	my @BdfText = ReturnArrayExec("$BdfCommand $NFSFileSystems");
# 
# 	my $PreviousLine = "";
# 	$Suffix = 0;
# 	foreach $Line (@BdfText) {
# 
# 		# bypass the header line
# 		next if $Line =~ /^Filesystem/;
# 		# bypass any cdrom drives or local file systems
# 		next if $Line =~ /cdrom/;
# 		next if $Line =~ /^\//;
# 
# 		# partial line?
# 		if ( $PreviousLine ) {
# 			$Line = $PreviousLine . $Line;
# 			$PreviousLine = "";
# 		}
# 
# 		# clean and split line
# 		$Line =~ s/[\s]+/ /g;
# 		my @BdfFields = split(/ /, $Line);
# 
# 		# partial line?
# 		if ( scalar(@BdfFields) < 2 ) {
# 			$PreviousLine = $Line;
# 			# go get the rest of it
# 			next;
# 		}
# 
# 		# calc size in MB
# 		my $Size = sprintf("%.1f", ( $BdfFields[1] / 1000 ) );
# 
# 		my ( $RemoteSystem, $RemoteFileSystem ) = split(':', $BdfFields[0]);
# 		push @Response, "$BdfFields[5] remote=$RemoteSystem mount=$RemoteFileSystem size=$Size sat=$BdfFields[4]";
# 	}

	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


sub ReturnExportedFileSystemsXXX ($)
{	my $Subcategory = shift;
	my @Response = ( );

	# XXX - this is a stub routine to be filled in later...

	@Response = ForceMultipleResponses(\@Response);

	return @Response;
}


sub ReturnSwapXXX ($)
{	my $Subcategory = shift;

	#
	# XXX - This is a dummy routine
	# 
	# The value of $SwapCommand needs to be initialized above.
	# 

	ReturnSwap($Subcategory, "$SwapCommand");
}


sub ReturnRunningAccountingXXX ($)
{	my $Subcategory = shift;

# 	my $Accounting = SearchFileForTagValue($AccountingConfPath, $AccountingTag);
# 	if ( $Accounting == $NotFound or $Accounting eq "" ) {
# 		$Accounting = "Unknown";
# 	}
# 	else {
# 		$Accounting = ( $Accounting ? "Yes" : "No" );
# 	}

	return ( $Accounting );
}


###########################################################################
# End of XXX.pm
###########################################################################

1;
