#!/usr/bin/perl
#
# $Revision: 1.117 $
# Copyright 2009 Teleflora
# Re-purposed shell script for all remote teleflora customer service activities.
#

use strict;
use warnings;
use Getopt::Long;
use POSIX;
use Digest::MD5;


my $POSDIR  = "";
my $VERSION = 0;
my $INSTALL = 0;
my $CSMENU = 0;
my $HELP = 0;
my $key = "";
my $OS = "";
my $TIMEOUT_MENU_ARG = "";
my $CVS_REVISION = '$Revision: 1.117 $';
my $CVS_REV_NR = $CVS_REVISION;
if ($CVS_REVISION =~ /(\$Revision)(: )(\d+\.\d+)( \$)/) {
	$CVS_REV_NR = $3;
}


# Handle signals.
# Mainly, prevent "breaking out" to a shell.
set_signal_handlers('IGNORE');

GetOptions(
	"install" => \$INSTALL,
	"csmenu" => \$CSMENU,
	"version" => \$VERSION,
	"help" => \$HELP,
);


if($VERSION != 0) {
	print("OSTools Version:  1.12.3\n");
	print("$0: $CVS_REVISION\n");
	exit(0);
}

if($HELP != 0) {
	print("Usage:\n");
	print("$0\n");
	print("$0 --help\n");
	print("$0 --version\n");
	print("$0 --csmenu\n");
	print("$0 --installkeys /path/to/authorized_keys\n");
	print("This script offers a system of menus for customer service to perform most\n");
	print("common tasks of an RTI/Daisy server. This script does occasionally run commands via \n");
	print("'sudo', thus, a member of the POS 'admins' should run the script.\n");
	print("\n");
	exit(0);
}



$POSDIR = $ENV{'RTI_DIR'};
if( (! $POSDIR)
||  ("$POSDIR" eq "")) {
	if(-d "/d/daisy") {
		$POSDIR="/d/daisy";
	} else {
		$POSDIR="/usr2/bbx";
	}
	print("Warning: Assuming POS is installed in $POSDIR\n");
}



if($INSTALL != 0) {
	exit(install());
}


# --csmenu
if($CSMENU != 0) {
	exit(csmenu_main());
}




#
# If TERM is unset, dump them to a shell.
#
unless (defined($ENV{'TERM'})) {
	print("The TERM environemnt variable is not defined - please fix.\n");
	print("\n");
	print("The Support Admin menus require TERM to be defined in order to run.\n");
	print("Please configure the environment to define TERM.  After TERM is defined,\n");
	print("the Support Admin menus may be reached by entering this command:\n");
	print("\texec $POSDIR/bin/tfsupport.pl\n");
	print("\n");
	print("execing the Bash Shell...\n");
	set_signal_handlers('DEFAULT');
	exec("/bin/bash");
}

#
# "scoansi-old" emulation works for both the "dialog" and "sshbbx" applications.
#
if($ENV{'TERM'} eq "ansi") {
	$ENV{'TERM'} = "scoansi-old";
}

determine_os();

if ($OS eq "RH72") {
	$TIMEOUT_MENU_ARG = "";
} else {
	$TIMEOUT_MENU_ARG = " --timeout 900";
}

my $title = "";
my $command = "";
my $returnval =  "";
logevent("Starting Support Menu");
while(1) {




	# Summary information about this shop.
	$title = titlestring("Support Menu");
	$title .= "OSTools Package Version: 1.12.3\\n";
	$title .= "  Support Menus Version: $CVS_REV_NR\\n";
	$title .= "      Linux Platform ID: $OS\\n";
	$title .= "          " . get_pos_version();
	$title .= "\\n";
	$title .= "\\n";

	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	$command .= " --no-cancel";
	$command .= " --default-item \"Exit\"";
	$command .= " --menu '$title'";
	$command .= " 0 0 0";

	if(-d "/usr2/bbx") {
		$command .= " \"RTI\"" . " \"RTI Application\"";
	}
	if(-d "/d/daisy") {
		$command .= " \"Daisy\"" . " \"Daisy Application\"";
	}

	$command .= " \"Users\"" . " \"Linux Users\"";
	$command .= " \"Printers\"" . " \"Printers\"";
	$command .= " \"Network\"" . " \"Network Connectivity\"";
	$command .= " \"Backups\"" . " \"System and Data Backup Tools\"";
	$command .= " \"Hardware\"" . " \"Hardware Related Items\"";
	$command .= " \"Linux\"" . " \"Linux and Operating System\"";
	if(-d "/usr2/bbx") {
		$command .= " \"Commandline\"" . " \"Go to the Linux Shell\"";
	}

	$command .= " \"Exit\"" . " \"Exit\"";

	# Redirect stderr to stdout so that we can tell if there was a timeout
	# since 'dialog' writes "timeout" to stderr and exits if a timeout happens.
	$returnval = qx($command 2>&1);

	# Remove trailing and leading newlines because if there was a timeout,
	# the form of the output is:
	#	^\ntimeout\n$
	chomp($returnval);
	$returnval =~ s/^\n//;

	next if (!$returnval);

	if($returnval eq "timeout") {
		logevent("Inactivity Timeout");
		exit(0);

	# Backups.
	} elsif($returnval eq "Backups") {
		if(-f "$POSDIR/bin/rtibackup.pl") {
			rtibackup_main();
		} else {
			lonetar_main();
		}



	# Dove
	} elsif($returnval eq "Dove") {
		dove_menu();


	} elsif($returnval eq "Network") {
		network_main();

	} elsif($returnval eq "Linux") {
		linux_main();

	} elsif($returnval eq "ODBC") {
		odbc_menu();

	} elsif($returnval eq "Printers") {
		printers_main();


	} elsif($returnval eq "RTI") {
		rti_menu();

	} elsif($returnval eq "Daisy") {
		daisy_menu();

	} elsif($returnval eq "Hardware") {
		hardware_main();

	} elsif($returnval eq "Users") {
		users_main();

	} elsif($returnval eq "Commandline") {
		system("/usr/bin/clear");
		logevent("Begin Shellout to Commandline.");

		set_signal_handlers('DEFAULT');
		system("PS1=\"\\n\\u\@\\h: \\w\\n\\d \\t \\\$ \" /bin/bash");
		set_signal_handlers('IGNORE');

		logevent("Finish Shellout to Commandline.");


	} elsif($returnval eq "Exit") {
		$returnval = menu_confirm("Exit Support Menu?", "No");
		if($returnval eq "Y") {
			logevent("Finish Support Menu.");
			exit(0);
		}
	}
}

exit(0);
###############################################################################
###############################################################################
###############################################################################


#
# Install this script into /usr2/bbx/bin and add an entry into the "tfsupport" 
# user's bash profile which exec's this script.
#
sub install
{
	my %userinfo = ();

	# Copy script into place.
	if(-f "$0") {
		logevent("Installing 'tfsupport.pl' script.");
		system("cp $0 /usr2/bbx/bin");
		system("chown root:tfsupport /usr2/bbx/bin/tfsupport.pl");
	}

	# Setup tfsupport to "auto-run" the script.
	%userinfo = get_userinfo("tfsupport");
	system("grep 'tfsupport.pl' $userinfo{'homedir'}/.bash_profile > /dev/null 2> /dev/null");
	if($? != 0) {
		logevent("Updating 'tfsupport' user's bash_profile.");
		open(NEW, ">> $userinfo{'homedir'}/.bash_profile");
		print(NEW << "EOF");

# Run the 'tfsupport' menus if they are available.
if [ -f /usr2/bbx/bin/tfsupport.pl ] ; then
	exec /usr2/bbx/bin/tfsupport.pl
fi
if [ -f /d/daisy/bin/tfsupport.pl ] ; then
	exec /d/daisy/bin/tfsupport.pl
fi

EOF
		close(NEW);

	}
}



sub hardware_main
{
	my $title = "Hardware Menu";
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $user = "";

	while(1) {
		$title = titlestring("Hardware Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"Hardware List\"" . " \"Server Hardware Information\"";
		$command .= " \"Disk\"" . " \"Disk Usage Statistics\"";
		if(-f "/etc/init.d/apcupsd") {
			$command .= " \"Battery Backup\"" . " \"Battery Backup Info\"";
		}
		if(-f "/etc/init.d/dgrp_daemon") {
			$command .= " \"Restart Digi\"" . " \"Restart Digi Services.\"";
		}
		$command .= " \"Advanced\"" . " \"Advanced Tools.\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";


		open(USERDIALOG, "$command |");
		$returnval = <USERDIALOG>;
		close(USERDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);
		


		} elsif($returnval eq "Restart Digi") {
			system("/usr/bin/clear");
			system("sudo /sbin/service dgrp_daemon restart ; sudo /sbin/service dgrp_ditty restart ; sudo /sbin/init q");
			wait_for_user();

		} elsif($returnval eq "Disk") {
			system("/usr/bin/clear");
			system("df -h");
			print("\n\n");
			system("df -ih");
			wait_for_user();


		} elsif($returnval eq "Battery Backup") {
			hardware_battery_backup();


		} elsif($returnval eq "Hardware List") {
			$command = "sudo /usr/sbin/dmidecode | grep -A 5 \"System Information\"";
			$command .= " ; sudo /usr/sbin/dmidecode | grep -A 4 \"BIOS Information\"";
			$command .= " ; /bin/echo ; /bin/echo";
			$command .= " ; cat /etc/redhat-release";
			unless ($OS eq "RH72") {
				$command .= " ; uname --kernel-release --processor";
			}
			$command .= " ; /bin/echo ; /bin/echo";
			$command .= " ; cat /proc/meminfo";
			$command .= " ; /bin/echo ; /bin/echo";
			$command .= " ; cat /proc/cpuinfo";
			unless ($OS eq "RH72" || $OS eq "FC3" || $OS eq "FC5") {
				$command .= " ; /bin/echo ; /bin/echo";
				$command .= " ; /sbin/lsusb";
			}
			$command .= " ; /bin/echo ; /bin/echo";
			$command .= " ; /sbin/lspci";
			$command .= " ; /bin/echo ; /bin/echo";
			$command .= " ; /sbin/lsmod";
			$command .= " ; /bin/echo ; /bin/echo";
			$command .= " ; cat /proc/interrupts";
			system("($command) | less");


		} elsif($returnval eq "Advanced") {
			hardware_advanced();

		#  Exit
		} elsif($returnval eq "Close") {
			return(0);
	
		}
	}
}

sub hardware_advanced
{
	my $title = "Hardware Advanced Menu";
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $user = "";

	while(1) {
		$title = titlestring("Hardware Advanced Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		if (-f '/etc/apcupsd/apcupsd.conf') {
			$command .= " \"Battery Backup Config\"" . " \"Edit Battery Backup Conf File\"";
		}
		$command .= " \"Eject Devices\"" . " \"Eject Removable Media\"";
		if(-f "/etc/dgap/dgapview") {
			$command .= " \"Digi DGapview\"" . " \"Run Digi Utility\"";
		}
		if(-f "/usr/bin/mpi") {
			$command .= " \"Digi MPI\"" . " \"Run Digi Control Software\"";
		}
		if(-f "/usr/bin/minicom && -f /etc/minirc.dfl") {
			$command .= " \"Minicom\"" . " \"Run Modem Terminal Program\"";
		}
		$command .= " \"Close\"" . " \"Close This Menu\"";


		open(USERDIALOG, "$command |");
		$returnval = <USERDIALOG>;
		close(USERDIALOG);
		next if(! $returnval);
		chomp($returnval);

		if($returnval eq "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);
		

		} elsif($returnval eq "Battery Backup Config") {
			system("sudo rvim /etc/apcupsd/apcupsd.conf");

		} elsif($returnval eq "Eject Devices") {
			if(-f "$POSDIR/bin/rtibackup.pl") {
				system("sudo $POSDIR/bin/rtibackup.pl --eject");
			}
			system("eject /dev/scd0");
			system("eject /dev/scd1");
			wait_for_user();

		} elsif($returnval eq "Digi MPI") {
			system("sudo /usr/bin/mpi");

		} elsif($returnval eq "Digi DGapview") {
			system("sudo /etc/dgap/dgapview");

		} elsif($returnval eq "Minicom") {
			system("/usr/bin/minicom");

		} elsif($returnval eq "Close") {
			return(0);
	
		}
	}
}


sub hardware_battery_backup
{
	my $apcupsd_service = 'apcupsd';
	my $apcstatus_cmd = '/sbin/apcaccess';

	system("/usr/bin/clear");

	# is the service installed?
	unless (-f "/etc/init.d/$apcupsd_service") {
		print("Warning: the $apcupsd_service system service is not installed.\n");
		wait_for_user();
		return;
	}

	# is the service running?
	my $is_running = 0;
	open(PIPE, "sudo /sbin/service $apcupsd_service status |");
	while(<PIPE>) {
		if(/is running/) {
			$is_running = 1;
			last;
		}
	}
	close(PIPE);

	unless ($is_running) {
		print("Warning: the $apcupsd_service system service is not running...\n");
		print("The UPS signal cable, either USB or Serial, must be connected or\n");
		print("the $apcupsd_service system service will not run.\n");
		wait_for_user();
		return;
	}

	unless (-f $apcstatus_cmd) {
		print("Warning: can't find $apcupsd_service status command: $apcstatus_cmd\n");
		wait_for_user();
		return;
	}

	print("---[ $apcupsd_service System Service Summary ]---\n");
	open(PIPE, "sudo $apcstatus_cmd |");
	while(<PIPE>) {
		if ( /HOSTNAME :/ ||
		     /CABLE    :/ ||
		     /MODEL    :/ ||
		     /STATUS   :/ ||
		     /LOADPCT  :/ ||
		     /BCHARGE  :/ ||
		     /TIMELEFT :/ ||
		     /MBATTCHG :/ ||
		     /MINTIMEL :/ ||
		     /MAXTIME  :/ ||
		     /ITEMP    :/ ||
		     /BATTV    :/ ||
		     /SERIALNO :/ ||
		     /BATTDATE :/ ||
		     /FIRMWARE :/ ||
		     /APCMODEL :/ ) {
			print("$_");
			next;
		}
	}
	close(PIPE);
	print("\n");
	wait_for_user();

	print("---[ $apcupsd_service System Service Status ]---\n");
	system("sudo /sbin/service $apcupsd_service status");
	print("\n");
	wait_for_user();

	if (-f '/sbin/lsusb') {
		print("---[ List of USB devices ]---\n");
		system("sudo /sbin/lsusb | less");
		print("\n");
		wait_for_user();
	}

	print("---[ $apcupsd_service System Service Details ]---\n");
	system("sudo $apcstatus_cmd | less");
}


sub advanced_truncate_root_mbox
{
	my $path = "/var/spool/mail/root";
	my $maxsize = 250000;
        my $root_mbox_size;

	if (-e $path) {
		$root_mbox_size = -s $path;
		if ($root_mbox_size > $maxsize) {
			print("Sizeof $path ($root_mbox_size) > limit ($maxsize)... removing\n");
			system("sudo rm -f $path");
			system("sudo touch $path");
			print("$path truncated\n");
		} else {
			print("Sizeof $path ($root_mbox_size) <= limit ($maxsize)... keeping\n");
		}
	} else {
		print("$path: file not found\n");
	}
}

sub users_password_gen
{
	my $pwdocument = "";
	my $alphanumeric_only = 0;
	my $pw_min_size = 8;
	my $pw_sample_size = 7;
	my $i;
	my $j;

	my $openssl_cmd = '/usr/bin/openssl';
	my $strings_cmd = '/usr/bin/strings';

	# Can not proceed without basic utilities
	unless (-f $openssl_cmd && -f $strings_cmd) {

		unless (-f $openssl_cmd) {
			$pwdocument = "Required utility not found: $openssl_cmd";
		}
		unless (-f $strings_cmd) {
			$pwdocument .= "\n";
			$pwdocument .= "Required utility not found: $strings_cmd";
			$pwdocument .= "\n";
		}
		system("/usr/bin/clear");
		print("$pwdocument");
		return;

	}

	#
	# Generate more than three passwords to choose from.
	#
	$pwdocument = "";
	$pwdocument .= "- - - === === === === PASSWORD  GENERATOR  RESULTS === === === === - - -\n";
	$pwdocument .= "\n";
	$pwdocument .= "Generated on Day:" . strftime("%Y-%m-%d %H:%M:%S", localtime()) . "\n";
	$pwdocument .= "Generated by User: $ENV{'USER'}\n";
	$pwdocument .= "\n";
	$pwdocument .= "\n";

	my $pw_found_count = 0;

	for ($i = 0; $i < 15; $i++) {
		my $pwbuf = "";
		my $thispw = "";

		open(PIPE, "openssl rand 512 | /usr/bin/strings |");
		while(<PIPE>) {
			chomp;
			$pwbuf .= $_;
		}
		close(PIPE);

		$pwbuf =~ s/\s+//g; # Strip whitespace.
		$pwbuf =~ s/[^[:print:]]+//g; # Strip non-printable chars
		$pwbuf =~ s/[()`{}<>|~,'"\\[\]]//g; # Strip inconvenient chars
		if ($alphanumeric_only) {
			$pwbuf =~ s/[^[:alnum:]]+//g; # Strip non-alphanumeric chars
		}

		my $pwbuf_size = length($pwbuf);

		for ($j=0; $j < $pwbuf_size; $j += $pw_min_size) {
			$thispw = substr($pwbuf, $j, $pw_min_size);  #PCI 8.5.10
			next if ($thispw !~ /[0-9]/); # PCI 8.5.11
			next if ($thispw !~ /[a-z]/); # PCI 8.5.11
			next if ($thispw !~ /[A-Z]/); # PCI 8.5.11
			next if (length($thispw) < $pw_min_size);
			$pwdocument .= "$thispw\n";
			$pwdocument .= "\n";
			$pwdocument .= "\n";
			$pw_found_count++;
			last if ($pw_found_count >= $pw_sample_size);
		}
		last if ($pw_found_count >= $pw_sample_size);
	}

	# Print results to the screen.
	return("$pwdocument");
}

sub users_main
{
	my $title = "User Menu";
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $user = "";
	my $userscript = "";


	# WHich user management script are we using?
	foreach("$POSDIR/bin/rtiuser.pl", "$POSDIR/bin/dsyuser.pl") {
		next until -f $_;
		$userscript = $_;
		last;
	}


	while(1) {
		$title = titlestring("User Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		if("$userscript" ne "") {
			$command .= " \"Add User\"" . " \"Add User\"";
			$command .= " \"Enable Admin\"" . " \"Set User as Administrator\"";
			$command .= " \"Disable Admin\"" . " \"Remove Administrative Privileges\"";
			$command .= " \"Remove\"" . " \"Remove User\"";
			$command .= " \"Info\"" . " \"Get User Info\"";
			$command .= " \"List\"" . " \"List all users.\"";
			$command .= " \"Who\"" . " \"Who is currently Logged In?\"";
			$command .= " \"ResetPW\"" . " \"Reset Password\"";
			$command .= " \"Unlock\"" . " \"Unlock Account\"";
			$command .= " \"Password Generator\"" . " \"Suggest New Passwords\"";
			#$command .= " \"Enable tfremote\"" . " \"Allow User to remotely access server\"";
			#$command .= " \"Disable tfremote\"" . " \"Remove Remote Access Capabilities\"";
		}
		$command .= " \"Advanced\"" . " \"Advanced Tools.\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(USERDIALOG, "$command |");
		$returnval = <USERDIALOG>;
		close(USERDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);
			
		} elsif($returnval eq "Add User") {
			$user = menu_getstring("Choose a Username to Add");
			if($user ne "") {

				system("sudo $userscript --info $user > /dev/null 2> /dev/null");
				if($? == 0) {
					menu_info("User \"$user\" already exists.\n");

				} else {
					$suboption = menu_confirm("Add '$user' Account?");
					if($suboption eq "Y") {
						system("sudo $userscript --add $user");
					}
				}
			}

		} elsif($returnval eq "Password Generator") {
			$suboption = choose_printer("(Optional) Send Password list to which Printer?");
			$returnval = users_password_gen();
			if("$suboption" ne "") {
				open(PIPE, "| $POSDIR/bin/tfprinter.pl --print \"$suboption\"");
				while(<PIPE>) {
					print(PIPE "$returnval");
				}
				close(PIPE);
			}
			system("clear");
			print("$returnval");
			wait_for_user();

		} elsif($returnval eq "Enable Admin") {
			$user = users_menu_choose("Enable Administrative Privileges");
			if($user ne "") {
				if( ($user eq "daisy") 
				||  ($user eq "rti") ) {
					menu_info("Will not enable admin for \"$user\".\n");
				} else {
					system("/usr/bin/clear");
					system("sudo $userscript --enable-admin $user 2>&1");
					wait_for_user();
				}
			}

		} elsif($returnval eq "Disable Admin") {
			$user = users_menu_choose("Disable Administrative Privileges");
			if("$user" ne "") {
				if( ("$user" eq "tfsupport") 
				||  ("$user" eq "root") ) {
					menu_info("Will not disable admin for \"$user\"");
				} else {
					system("/usr/bin/clear");
					system("sudo $userscript --disable-admin $user 2>&1");
					wait_for_user();
				}
			}


		} elsif($returnval eq "Enable tfremote") {
			$user = users_menu_choose("Enable (tfremote) Remote Access");
			if($user ne "") {
				if( ($user eq "daisy") 
				||  ($user eq "rti")
				||  ($user eq "root") ) {
					menu_info("Will not enable Remote Access for \"$user\".\n");
				} else {
					system("/usr/bin/clear");
					system("(sudo $userscript --enable-tfremote $user) 2>&1");
					wait_for_user();
				}
			}

		} elsif($returnval eq "Disable tfremote") {
			$user = users_menu_choose("Disable (tfremote) Remote Access");
			if($user ne "") {
				if( ($user eq "tfsupport") ) {
					menu_info("Will not disable Remote Access for \"$user\".\n");
				} else {
					system("/usr/bin/clear");
					system("sudo $userscript --disable-tfremote $user 2>&1");
					wait_for_user();
				}
			}



		} elsif($returnval eq "Info") {
			$user = users_menu_choose("Get User Information");
			if($user ne "") {
				system("/usr/bin/clear");
				system("sudo $userscript --info $user 2>&1");
				wait_for_user();
			}

		} elsif($returnval eq "List") {
			system("sudo $userscript --list 2>&1 | less");

		} elsif($returnval eq "Who") {
			system("clear");
			system("who");
			wait_for_user();

		# Change Password
		} elsif($returnval eq "ResetPW") {
			$user = users_menu_choose("Which User to Reset Password?");
			if($user ne "") {
				$suboption = menu_confirm("Reset Password for '$user'?");
				if($suboption eq "Y") {
					system("/usr/bin/clear");
					system("sudo $userscript --resetpw $user");
					wait_for_user();
				}
			}

		} elsif($returnval eq "Unlock") {
			$user = users_menu_choose("Which User to Unlock?");
			if($user ne "") {
				system("/usr/bin/clear");
				system("sudo $userscript --unlock $user");
				wait_for_user();
			}


		# Remove User
		} elsif($returnval eq "Remove") {
			$user = users_menu_choose("Which User to Remove?");
			if($user ne "") {
				$suboption = menu_confirm("Remove User \"$user\"?");
				if($suboption eq "Y") {
					system("/usr/bin/clear");
					system("sudo $userscript --remove $user 2>&1");
					wait_for_user();
				}
			}

		# Adfvanced Menu
		} elsif($returnval eq "Advanced") {
			users_advanced();

		#  Exit
		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}

sub users_advanced
{
	my $title = "User (Advanced) Menu";
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $user = "";
	my $userscript = "";


	# WHich user management script are we using?
	foreach("$POSDIR/bin/rtiuser.pl", "$POSDIR/bin/dsyuser.pl") {
		next until -f $_;
		$userscript = $_;
		last;
	}


	while(1) {
		$title = titlestring("User Advanced Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		if("$userscript" ne "") {
			$command .= " \"Login\"" . " \"Login as a different user.\"";
		}
		$command .= " \"Login History\"" . " \"Show History of a User's Logins.\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(USERDIALOG, "$command |");
		$returnval = <USERDIALOG>;
		close(USERDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);
			

		} elsif($returnval eq "Login") {
			$user = users_menu_choose("Login as Which User?");
			if("$user" ne "") {
				system("/usr/bin/clear");
				system("/usr/bin/clear && ssh $user\@localhost");
			}

		} elsif($returnval eq "Login History") {
			$user = users_menu_choose("Which User to see Login History?");
			if("$user" ne "") {
				system("/usr/bin/clear");
				system("/usr/bin/last -a \"$user\" | less");
			}


		#  Exit
		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}


sub lonetar_main
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "Backup Menu";
	my $user = "";
	my $logfile = "";

	while(1) {

		$title = titlestring("Lonetar Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"Backup History\"" . " \"History of previous Backups\"";
		$command .= " \"Backup Results\"" . " \"Display Backup Results\"";
		$command .= " \"Ltar Log\"" . " \"Lone-Tar \"ltar.log\" File\"";
		$command .= " \"Master Log\"" . " \"Lone-Tar \"Master\" Logfiles\"";
		$command .= " \"Eject\"" . " \"Eject Rev Tape\"";
		$command .= " \"LoneTar\"" . " \"Lone-Tar Menu\"";
		$command .= " \"Tapetell\"" . " \"Verify Tape Contents\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);

		if($returnval eq  "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);

		} elsif($returnval eq "Backup History") {
			backup_summary_logs();

		} elsif($returnval eq "Backup Results") {
			system("grep -B 3 \"RESULT:\" /log/ltar.log | tac | less");


		} elsif($returnval eq "Ltar Log") {
			viewfiles("/log/ltar.log");

		} elsif($returnval eq "Master Log") {
			viewfiles("/log/Master*");
			
		} elsif($returnval eq "Eject") {
			system("sudo /usr/sbin/eject /dev/scd0");

		} elsif($returnval eq "LoneTar") {
			system("sudo /usr/lone-tar/ltmenu");

		} elsif($returnval eq "Tapetell") {
			system("sudo /usr/lone-tar/tapetell");

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}


sub rtibackup_main
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "Backup Menu";
	my $backupscript = "";
	my $thisday = strftime("%d", localtime());


	foreach("$POSDIR/bin/rtibackup.pl", "/d/daisy/rtibackup.pl", "/usr2/bbx/bin/rtibackup.pl") {
		next until(-f $_);
		$backupscript = $_;
		last;
	}


	while(1) {

		$title = titlestring("Backup Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		if("$backupscript" ne "") {
			$command .= " \"Find Device\"" . " \"Find Backup Device\"";
			$command .= " \"Backup History\"" . " \"History of previous Backups\"";
			$command .= " \"Eject\"" . " \"Eject Backup Media\"";
			$command .= " \"Full Backup\"" . " \"Perform a full backup.\"";
			$command .= " \"Verify\"" . " \"Verify Checksums on Backup Media.\"";
			$command .= " \"Format\"" . " \"Format Backup Media.\"";
		}
		$command .= " \"Advanced\"" . " \"Advanced Tools\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);

		if($returnval eq  "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);

		} elsif($returnval eq "Find Device") {
			system("clear && sudo $backupscript --finddev");
			wait_for_user();

		} elsif($returnval eq "Backup History") {
			backup_summary_logs();

		} elsif($returnval eq "Eject") {
			system("sudo $backupscript --eject");
			wait_for_user();

		} elsif($returnval eq "Full Backup") {
			system("sudo $backupscript --format --backup=all --verbose");
			wait_for_user();



		} elsif($returnval eq "Verify") {
			my %options = ();
			my $type = "";
			my $printer = "";
			$options{"Screen"} = "Send Results to the screen.";
			$options{"Printer"} = "Send Results to a Printer.";
			$type = menu_pickone("Where to send Verify Results?", \%options, "Screen");
			if ("$type" eq "Printer") {
				$printer = choose_printer("Which Printer to send Results to?");
			}
			if("$printer" eq "") {
				system("sudo $backupscript --verify");
				wait_for_user();
			} else {
				system("sudo $backupscript --verify | $POSDIR/bin/tfprinter.pl --print $printer");
				print("Verify Results sent to printer \"$printer\".\n");
				wait_for_user();
			}


			
		} elsif($returnval eq "Format") {
			$returnval = menu_confirm("Remove all data from Backup Media?");
			if($returnval eq "Y") {
				system("sudo $backupscript --force --format");
				wait_for_user();
			} else {
				menu_info("Format Not Performed");
			}

		} elsif($returnval eq "Advanced") {
			$returnval = rtibackup_advanced();

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}


sub rtibackup_advanced
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "Backup Menu";
	my $backupscript = "";
	my $thisday = strftime("%d", localtime());


	foreach("$POSDIR/bin/rtibackup.pl", "/d/daisy/rtibackup.pl", "/usr2/bbx/bin/rtibackup.pl", "/teleflora/ostools/bin/rtibackup.pl") {
		next until(-f $_);
		$backupscript = $_;
		last;
	}


	while(1) {

		$title = titlestring("Backup Advanced Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"Logs\"" . " \"View Backup Logfiles.\"";
		if("$backupscript" ne "") {
			$command .= " \"Configfile\"" . " \"Modify backup config file.\"";
			$command .= " \"Check Disk\"" . " \"Scan for Errors on Backup Media (This will take a Very Long Time)\"";
			$command .= " \"List Files\"" . " \"List all files currently on the backup media.\"";

			$command .= " \"Restore Individual File\"" . " \"Restore files(s) from backup media, to the Hard Disk.\"";
			$command .= " \"Check Individual File\"" . " \"Verify a file on disk is same as file on Backup Media.\"";
			if(-d "/usr2") {
				$command .= " \"Backup /usr2\"" . " \"Backup only contents of /usr2\"";
			}
			if(-d "/d") {
				$command .= " \"Backup /d\"" . " \"Backup only contents of /d\"";
			}
		}
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);

		if($returnval eq  "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);


		} elsif ($returnval eq "Logs") {
			viewfiles("$POSDIR/log/rtibackup-*.log");


		} elsif($returnval eq "Configfile") {
			system("sudo rvim $POSDIR/config/backups.config");

		} elsif($returnval eq "Check Disk") {
			$suboption = menu_getstring("(Optional) Email Address to send Checkdisk Results to?");
			if($suboption ne "") {
				system("clear && sudo $backupscript --checkmedia --email=\"$suboption\"");
			} else {
				system("clear && sudo $backupscript --checkmedia");
			}
			wait_for_user();
			

		} elsif($returnval eq "List Files") {
			system("(sudo $backupscript --list=all) | less");

		} elsif($returnval eq "Restore Individual File") {
			$suboption = menu_getstring("Which File/Directory to Restore?");
			if($suboption ne "") {
				system("sudo $backupscript --verbose --rootdir=/tmp --restore \"$suboption\"");
				print("File(s) Restored in /tmp directory.\n");
				wait_for_user();
			}


		} elsif($returnval eq "Check Individual File") {
			$suboption = menu_getstring("Which File/Directory to Verify?");
			if($suboption ne "") {
				system("sudo $backupscript --checkfile \"$suboption\"");
				wait_for_user();
			}

		} elsif($returnval eq "Backup /usr2") {
			system("sudo $backupscript --backup=usr2 --dvd --verbose");
			wait_for_user();

		} elsif($returnval eq "Backup /d") {
			system("sudo $backupscript --backup=daisy --verbose");
			wait_for_user();

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}




sub backup_summary_logs
{
	my $command = "";
	my $backupprog = "";
	my $day = "";
	my $began = "";
	my $end = "";
	my $tmpfile = "/tmp/rtibackup.viewlogs.$$";

	if(-f "$POSDIR/bin/rtibackup.pl") {
		$backupprog = "rtibackup";
	} else {
		$backupprog = "LoneTar";
	}

	$day = strftime("%d", localtime(time()));

	if ($backupprog eq "LoneTar") {

		my $ltar_logpath = "/log/ltar.log";

		unless (-f $ltar_logpath) {
			menu_info("Backup logfile \"$ltar_logpath\" does not exist.");
			return;
		}

		open(LOG, "> $tmpfile");
		open(FILE, $ltar_logpath);
		while(<FILE>) {	
			chomp;
			chop;
			s/(\s*)//;
			if(/^(\s*)(BEGAN:)/) {
				s/BEGAN: //;
				$began = $_;
			}
			if(/^(\s*)(ENDED:)/) {
				s/ENDED: //;
				$end = $_;
			}
			if(/^(\s*)(RESULT:)(\s*)(SUCCESSFUL)(\s*)(LONE-TAR)(\s*)(Master)/) {
				print(LOG "Good Backup $began\n");
			}
			if(/^(\s*)(RESULT:)(\s*)(SUCCESSFUL)(\s*)(LONE-TAR)(\s*)(Bit)/) {
				print(LOG "Good Verify $end\n");
				print(LOG"\n");
			}
			if(/^(\s*)(RESULT:)(\s*)(WARNING)([[:print:]])(\d{1,3})/) {
				s/RESULT: WARNING//;
				print(LOG "$_\n");
				print(LOG "\n");
			}
			next;
		}
		close(LOG);
		close(FILE);	

	} elsif ($backupprog eq "rtibackup") {

		my $pos_logdir = "$POSDIR/log";
		my $rtibackup_logs = "$pos_logdir/rtibackup-Day_*.log";
		my @logfiles = glob($rtibackup_logs);

		unless (@logfiles > 0) {
			menu_info("There are no backup logfiles in \"$pos_logdir\".");
			return;
		}

		unless (open(SF, "> $tmpfile")) {
			menu_info("Can't open temp file for summary info: \"$tmpfile\".");
			return;
		}

		foreach my $logfile (@logfiles) {

			unless (open(LOG, "< $logfile")) {
				print(SF "\n");
				print(SF "Error: skipping log file \"$logfile\": open failed.");
				print(SF "\n");
				next;
			}

			print(SF "########\n");
			print(SF "######## Backup Summary for \"$logfile\"\n");
			print(SF "########\n");

			my $found = 0;
			while (<LOG>) {	
				chomp;
				chop;
				s/(\s*)//;
				if(/^(\s*)(######## TAPEID: )/) {
					s/######## //;
					print(SF "\n");
					print(SF "$_\n");
					$found = 1;
				}
				if(/^(\s*)(######## NOW: )/) {
					s/######## NOW: //;
					print(SF "$_\n");
					$found = 1;
				}
				if(/^(\s*)(######## VERIFY SUCCEEDED: )/) {
					s/######## //;
					print(SF "$_\n");
					$found = 1;
				}
				if(/^(\s*)(######## VERIFY FAILED: )/) {
					s/######## //;
					print(SF "$_\n");
					$found = 1;
				}
				if(/^(\s*)(wwwwwwww WARN: )/) {
					s/wwwwwwww //;
					print(SF "$_\n");
					$found = 1;
				}
			}
			close(LOG);

			unless ($found) {
				print(SF "wwwwwwww WARN: no summary info\n");
			}
		}
		close(SF);
	}

	unless (-e $tmpfile) {
		menu_info("Backup logfiles summary is empty.");
		return;
	}

	$title = "======== Backup Log Viewer ========";

	$command .= "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	$command .= " --clear";
	$command .= " --title '$title'";
	$command .= " --textbox '$tmpfile' 18 68";

	system("$command");

	system("rm -f $tmpfile");
}

sub cc_menu
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "Credit Card Menu\\n";
	my $user = "";
	my $logfile = "";



	while(1) {

		$title = titlestring("Credit Card Menu");

		# Which version of TCC?
		open(TCC, "$POSDIR/bin/tcc --version |");
		while(<TCC>) {
			chomp;
			if(/Version:/) {
				$title .= "TCC $_\\n";
			}
		}
		close(TCC);

		# What is the md5sum of our tcc executable?
		open(TCC, "< $POSDIR/bin/tcc");
			binmode(TCC);
			$title .= "TCC MD5: " . Digest::MD5->new->addfile(*TCC)->hexdigest . "\\n";
		close(TCC);




		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"Log\"" . " \"Show TCC Logfile\"";
		$command .= " \"Live Logs\"" . " \"Watch Live Logfile Activity\"";
		$command .= " \"Errors\"" . " \"TCC Errors and Warnings\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);


		# Unlock a user.
		if($returnval eq  "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);

		} elsif($returnval eq "Live Logs") {
			system("tail -f $POSDIR/log/tcc.log");

		} elsif($returnval eq "Log") {
			viewfiles("$POSDIR/log/tcc*.log");

		} elsif($returnval eq "Errors") {
			viewfiles("$POSDIR/log/tcc*.log", "", "grep -e '<E>' -e '<W>'");

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}





sub network_main
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $ipaddr = "";
	my $macaddr = "";
	my $title = "Network Menu\n";
	my $user = "";
	my $device = "";
	my $logfile = "";
	my $i = 0;
	my $temp = "";




	$title .="\n";
	while(1) {

		$title = titlestring("Network Menu");

		$returnval = get_hostname("--long");
		$title .= "Hostname: $returnval\\n";

		# Private IP Address(es)
		foreach $device("eth0", "eth1", "bond0") {
			$ipaddr = "";
			$macaddr = "";
			open(PIPE, "/sbin/ifconfig $device 2> /dev/null |");
			while(<PIPE>) {
				chomp;
				if(/(inet addr:)(\d+\.\d+\.\d+\.\d+)/) {
					$ipaddr = $2;
					$ipaddr =~ s/[[:space:]]+//g;
				}
				if(/(HWaddr)(\s+)([[:print:]]+)/) {
					$macaddr = $3;
					$macaddr =~ s/[[:space:]]+//g;
				}
				
			}
			close(PIPE);
			if("$ipaddr" ne "") {
				$title .= "$device IPADDR=\"$ipaddr\" MAC=\"$macaddr\" \\n";
			}
		}


		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"Host Connectivity Test\"" . " \"Verify Critical Hosts are Available\"";
		$command .= " \"Ping Test\"" . " \"Ping Various Hosts\"";
		$command .= " \"DNS Test\"" . " \"Test Domain Name Service (DNS)\"";
		$command .= " \"Cable Connectivity\"" . " \"Is a Cable Connected?\"";
		$command .= " \"Test Workstation\"" . " \"Can we see a workstation or Printer?\"";
		$command .= " \"Advanced\"" . " \"Advanced Tools\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq  "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);




		} elsif($returnval eq "DNS Test") {
			system("clear");
			print("\n");
			print("Lookup www.google.com...\n");
			system("nslookup www.google.com");
			print("\n");
			print("Lookup www.teleflora.com...\n");
			system("nslookup www.teleflora.com");
			print("\n");
			print("Lookup igusproda.globalpay.com...\n");
			system("nslookup igusproda.globalpay.com");
			wait_for_user();

		} elsif($returnval eq "Test Workstation") {
			$ipaddr = menu_getstring("Workstation IP Address?");
			if("$ipaddr" ne "") {
				system("ping -c 3 $ipaddr");
				system("sudo /usr/bin/nmap -v -sP $ipaddr");
				print("Customer may want to run \"Start -> Run -> 'netsh diag gui'\"\n");
				wait_for_user();
			}



		} elsif($returnval eq "Cable Connectivity") {
			system("clear");
			foreach $device("eth0", "eth1", "eth2", "eth3", "eth4") {
				print("--- /dev/$device ---\n");
				system("sudo /sbin/ethtool $device 2> /dev/null | grep -i -e 'Speed' -e 'detected'");
				print("\n");
			}
			wait_for_user();


		} elsif($returnval eq "Ping Test") {
			my $host = "";
			system("clear");
			foreach $host ("4.2.2.2",
			"igusproda.globalpay.com",
			"192.168.10.1",
			"192.168.1.1",
			) {
				system("ping -c 3 $host");
			}
			wait_for_user();



		} elsif($returnval eq "Host Connectivity Test") {
			my $url = "";
			my $found = 0;
			system("/usr/bin/clear");
			foreach $url ("http://tws.teleflora.com/TelefloraWebService.asmx", 
			"http://twsstg.teleflora.com/TelefloraWebService.asmx",
			"http://65.198.163.214/TelefloraWebService.asmx",
			"http://65.198.163.124/TelefloraWebService.asmx",
			) {
				$found = 0;
				print("-- $url --\n");
				open(DOVE, "curl --connect-timeout 3 $url |");
				while(<DOVE>) {
					if(/disco/) {
						$found = 1;
					}
				}
				close(DOVE);
				if($found == 1) {
					print("Connection OK      - $url\n\n");
				} else {
					print("Connection FAILED  - $url\n\n");
				}
			}

			# Actually connect to Global and validate that their SSL Certificate indicates they are who we think they are.
			foreach $url ("igusproda.globalpay.com", "igusprodb.globalpay.com") {
				$found = 0;
				print("-- $url --\n");
				open(PIPE, "openssl s_client -host $url -port 443 -verify 5 |");
				while(<PIPE>) {
					if(/Global Payments/) {
						$found = 1;	
					}
				}
				close(PIPE);
				if($found == 1) {
					print("Connection OK      - $url\n\n");
				} else {
					print("Connection FAILED  - $url\n\n");
				}
			}

			wait_for_user();


		} elsif($returnval eq "Advanced") {
			network_advanced();

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}

sub network_advanced
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $ipaddr = "";
	my $macaddr = "";
	my $title = "Network Advanced Menu";
	my $user = "";
	my $device = "";
	my $logfile = "";
	my $i = 0;
	my $temp = "";




	$title .="\n";
	while(1) {

		$title = titlestring("Network Advanced Menu");

		$returnval = get_hostname("--long");
		$title .= "Hostname: $returnval\\n";

		# Private IP Address(es)
		foreach $device("eth0", "eth1", "bond0") {
			$ipaddr = "";
			$macaddr = "";
			open(PIPE, "/sbin/ifconfig $device 2> /dev/null |");
			while(<PIPE>) {
				chomp;
				if(/(inet addr:)(\d+\.\d+\.\d+\.\d+)/) {
					$ipaddr = $2;
					$ipaddr =~ s/[[:space:]]+//g;
				}
				if(/(HWaddr)(\s+)([[:print:]]+)/) {
					$macaddr = $3;
					$macaddr =~ s/[[:space:]]+//g;
				}
				
			}
			close(PIPE);
			if("$ipaddr" ne "") {
				$title .= "$device IPADDR=\"$ipaddr\" MAC=\"$macaddr\" \\n";
			}
		}


		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"Routes\"" . " \"Routing Information.\"";
		$command .= " \"Arp\"" . " \"View Current Arp Cache\"";
		$command .= " \"IPTables Rules\"" . " \"View IPTables Rules.\"";
		$command .= " \"IP Addresses\"" . " \"Network Interface Information.\"";
		$command .= " \"Restart Network\"" . " \"Restart all Network Interfaces.\"";
		if(-f "/usr/sbin/system-config-network") {
			$command .= " \"Configure\"" . " \"Configure Ethernet Device(s)\"";
		}
		if(-f "/etc/sysconfig/network") {
			$command .= " \"Set Hostname\"" . " \"Re-Set the Computer's Hostname\"";
		}
		if(-f "/usr/bin/nmap") {
			$command .= " \"Network Discovery\"" . " \"Scan Network for Hosts\"";
		}
		if(-f "/etc/init.d/tfremote") {
			$command .= " \"tfremote Start\"" . " \"Enable Remote Access\"";
			$command .= " \"tfremote Stop\"" . " \"Disable Remote Access\"";
		}
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq  "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);

		} elsif($returnval eq "Arp") {
			system("/usr/bin/clear");
			system("/sbin/arp -vn");
			wait_for_user();

		} elsif($returnval eq "Configure") {
			system("sudo /usr/sbin/system-config-network");



		} elsif($returnval eq "Routes") {
			system("clear && /sbin/ifconfig && /sbin/route -n && traceroute -n www.teleflora.com");
			wait_for_user();

		} elsif($returnval eq "IP Addresses") {
			system("clear");
			system("/sbin/ifconfig -a | less");


		} elsif($returnval eq "Restart Network") {
			$returnval = menu_confirm("Restart Network Connections?");
			if($returnval eq "Y") {
				system("clear && sudo /sbin/service network restart");
				wait_for_user();
			}

		} elsif($returnval eq "IPTables Rules") {
			system("clear");
			system("sudo /sbin/service iptables status | less");

		} elsif($returnval eq "Network Discovery") {
			system("clear");
			print("Discovering Network Hosts. This may take some time....\n");
			system("sudo /usr/bin/nmap -n -sP 192.168.1.1/16 | less");

		} elsif($returnval eq "tfremote Start") {
			system("sudo /sbin/service tfremote start");
			wait_for_user();

		} elsif($returnval eq "tfremote Stop") {
			system("sudo /sbin/service tfremote stop");
			wait_for_user();

		} elsif($returnval eq "Set Hostname") {
			my $new_hostname = network_set_hostname();
			if ($new_hostname eq "") {
				menu_info("Error Setting Hostname.");
			} else {
				menu_info("Hostname changed to $new_hostname. Please reboot.");
			}

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}

#
# On Redhat systems, the steps for changing the hostname are:
# 1) edit /etc/sysconfig/network
# 2) edit /etc/hosts
# 3) run the hostname command
# 4) reboot or at least restart the network service
#

sub network_set_hostname
{
	my $hostname = qx(hostname);

	unless ($hostname) {
		menu_info("Error setting hostname: can't get current hostname");
		return "";
	}

	$hostname = menu_getstring("Enter New Hostname (Currently $hostname)");

	unless ($hostname) {
		menu_info("Set Hostname Cancelled. No Changes Made.");
		return "";
	}

	unless (network_edit_network_file($hostname)) {
		menu_info("Error Setting Hostname: sysconfig network file.");
		return "";
	}

	unless (network_edit_hosts_file($hostname)) {
		menu_info("Error Setting Hostname: hosts file.");
		return "";
	}

	system("sudo hostname $hostname");
	my $strerror = system_exit_status($?);
	if ($strerror) {
		menu_info("Error Setting Hostname: \"hostname\" command error.");
		return "";
	}

	return($hostname);
}

sub network_edit_network_file
{
	my $hostname = $_[0];
	my $current_file = "/etc/sysconfig/network";
	my $saved_file = "${current_file}.orig";
	my $tmpfile = "/tmp/tfsupport.sethostname.$$";

	open(OLDFILE, "< $current_file");
	open(NEWFILE, "> $tmpfile");
	while (<OLDFILE>) {
		if(/^(\s*)(HOSTNAME)(\s*)(=)(\s*)(\S+)/) {
			print(NEWFILE "HOSTNAME=$hostname\n");
		} else {
			print(NEWFILE);
		}
	}
	close(OLDFILE);
	close(NEWFILE);

	# measure of success: the generated file contains something
	if (-s $tmpfile > 0) {
		system("sudo mv $current_file $saved_file");
		system("sudo cp $tmpfile $current_file");
		system("sudo chown root:root $current_file");
		system("sudo chmod 644 $current_file");
		system("sudo rm $tmpfile");
	} else {
		menu_info("Error Setting Hostname: generated file empty.");
		system("rm $tmpfile");
		return(0);
	}

	return(1);
}

sub network_edit_hosts_file
{
	my $hostname = $_[0];
	my $current_file = "/etc/hosts";
	my $saved_file = "${current_file}.orig";
	my $tmpfile = "/tmp/tfsupport.sethostname.$$";

	open(OLDFILE, "< $current_file");
	open(NEWFILE, "> $tmpfile");
	while (<OLDFILE>) {
		if (/^127.0.0.1[ \t]+/) {
			print(NEWFILE "127.0.0.1\t$hostname localhost.localdomain localhost\n");
		} else {
			print(NEWFILE);
		}
	}
	close(OLDFILE);
	close(NEWFILE);

	# measure of success: the generated file contains something
	if (-s $tmpfile > 0) {
		system("sudo mv $current_file $saved_file");
		system("sudo cp $tmpfile $current_file");
		system("sudo chown root:root $current_file");
		system("sudo chmod 644 $current_file");
		system("sudo rm $tmpfile");
	} else {
		menu_info("Error Setting Hostname: generated file empty.");
		system("rm $tmpfile");
		return(0);
	}

	return(1);
}

sub linux_main
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "Linux Menu";
	my $user = "";
	my $runlevel = "";
	my $logfile = "";

	while(1) {

		$title = titlestring("Linux Menu");


		# Which version of Linux?
		open(FILE, "< /etc/redhat-release");
		while(<FILE>) {
			chomp;
			if(/Linux/) {
				$title .= "$_\\n";
			}
		}
		close(FILE);


		unless ($OS eq "RH72") {
			# Which version of Linux?
			open(UNAME, "uname --kernel-release --processor |");
			while(<UNAME>) {
				chomp;
				if("$_" ne "") {
					$title .= "Kernel: $_\\n";
				}
			}
			close(UNAME);
		}


		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";

		$command .= " \"Halt\"" . " \"Halt the Server\"";
		$command .= " \"Reboot\"" . " \"Reboot the Server.\"";
		$command .= " \"Altiris Menu\"" . " \"Run Altiris Updates Menu\"";
		$command .= " \"Redhat Updates\"" . " \"Apply Redhat OS Updates\"";
		$command .= " \"OSTools Updates\"" . " \"Apply Teleflora OSTools Updates\"";
		$command .= " \"Uptime\"" . " \"Server Uptime / Reboot History\"";
		$command .= " \"Top\"" . " \"Running Processes (Top)\"";
		$command .= " \"Advanced\"" . " \"Advanced Tools\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(OSDIALOG, "$command |");
		$returnval = <OSDIALOG>;
		close(OSDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq  "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);



		} elsif($returnval eq "Halt") {
			my %options = ();
			my $when = "";
			$options{"Now"} = "Halt Immediately.";
			$options{"1 Minute"} = "Halt in One Minute.";
			$options{"5 Minutes"} = "Halt in Five Minutes.";
			$options{"Cancel"} = "Don't Halt. Cancel Current Halt.";
			$when = menu_pickone("Halt the Linux Server?", \%options, "Now");
			if ("$when" eq "Now") {
				system("sudo /sbin/shutdown -h now");
			} elsif ("$when" eq "1 Minute") {
				system("sudo /sbin/shutdown -h +1 &");
				wait_for_user();
			} elsif ("$when" eq "5 Minutes") {
				system("sudo /sbin/shutdown -h +5 &");
				wait_for_user();
			} elsif ("$when" eq "Cancel") {
				system("sudo /sbin/shutdown -c");
				wait_for_user();
			} else {
				menu_info("No System Shutdown will occur.");
			}

		} elsif($returnval eq "Reboot") {

			my %options = ();
			my $when = "";
			$options{"Now"} = "Reboot Immediately.";
			$options{"1 Minute"} = "Reboot in One Minute.";
			$options{"5 Minutes"} = "Reboot in Five Minutes.";
			$options{"Cancel"} = "Don't Reboot. Cancel Current Reboot.";
			$when = menu_pickone("When to Reboot?", \%options, "Now");
			if ("$when" eq "Now") {
				system("sudo $POSDIR/bin/updateos.pl --reboot");
				wait_for_user();
			} elsif ("$when" eq "1 Minute") {
				system("sudo /sbin/shutdown -r +1 &");
				wait_for_user();
			} elsif ("$when" eq "5 Minutes") {
				system("sudo /sbin/shutdown -r +5 &");
				wait_for_user();
			} elsif ("$when" eq "Cancel") {
				system("sudo /sbin/shutdown -c");
				wait_for_user();
			} else {
				menu_info("No Reboot will occur.");
			}



		} elsif($returnval eq "Redhat Updates") {
			$returnval = menu_confirm("Download and Apply Redhat OS Updates Now?");
			if($returnval eq "Y") {
				system("sudo $POSDIR/bin/updateos.pl --ospatches");
				wait_for_user();
			}

		} elsif($returnval eq "OSTools Updates") {
			$returnval = menu_confirm("Download and Apply Teleflora OS Tools Updates?");
			if($returnval eq "Y") {
				system("sudo $POSDIR/bin/updateos.pl --ostools");
				wait_for_user();
				$returnval = menu_confirm("Re-run the newly-updated admin menus now?");
				if($returnval eq "Y") {
					exec("$POSDIR/bin/tfsupport.pl");
				}
			}

		} elsif($returnval eq "Altiris Menu") {
			system("/usr/bin/clear");
			system("sudo $POSDIR/bin/altiriscontrol.pl --updates");

		} elsif($returnval eq "Uptime") {
			system("clear");
			system("last reboot");
			system("uptime");
			wait_for_user();

			
		} elsif($returnval eq "Top") {
			system("top");


		} elsif($returnval eq "Advanced") {
			linux_advanced();

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}

sub linux_advanced
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "Linux Advanced Menu";
	my $user = "";
	my $runlevel = "";
	my $logfile = "";

	while(1) {

		$title = titlestring("Linux Advanced Menu");


		# Which version of Linux?
		open(FILE, "< /etc/redhat-release");
		while(<FILE>) {
			chomp;
			if(/Linux/) {
				$title .= "$_\\n";
			}
		}
		close(FILE);


		unless ($OS eq "RH72") {
			# Which version of Linux?
			open(UNAME, "uname --kernel-release --processor |");
			while(<UNAME>) {
				chomp;
				if("$_" ne "") {
					$title .= "Kernel: $_\\n";
				}
			}
			close(UNAME);
		}
				

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";

		if(is_admin_user() != 0) {
			$command .= " \"Commandline\"" . " \"Go the the Linux Shell\"";
		}
		$command .= " \"Redhat SOS\"" . " \"Create a Redhat 'SOS' Report\"";
		$command .= " \"Redhat List\"" . " \"List Available Redhat Updates\"";
		$command .= " \"Altiris Checkin\"" . " \"Perform an Altiris 'Checkin'\"";
		$command .= " \"FSCK on Reboot\"" . " \"Require Filesystem Check on Reboot\"";
		$command .= " \"Samba Stop\"" . " \"Stop Samba (Network Neighborhood) Shares\"";
		$command .= " \"Samba Start\"" . " \"Start Samba (Network Neighborhood) Shares\"";
		$command .= " \"Samba Status\"" . " \"Samba Share Status\"";
		$command .= " \"Samba Config\"" . " \"Edit Samba Config File\"";
		$command .= " \"IPTables Start\"" . " \"Start IPTables (Linux Firewall)\"";
		$command .= " \"IPTables Stop\"" . " \"Stop IPTables (Linux Firewall)\"";
		$command .= " \"Services\"" . " \"Show Running Services\"";
		$command .= " \"Truncate\"" . " \"Truncate /var/spool/mail/root\"";
		$command .= " \"vmstat\"" . " \"CPU and Swap Status\"";
		$command .= " \"iostat\"" . " \"Disk IO Statistics\"";
		$command .= " \"Messages\"" . " \"/var/log/messages Logs\"";
		$command .= " \"Secure\"" . " \"/var/log/secure Logs\"";
		$command .= " \"Sudo Actions\"" . " \"Monitor Super-User Actions\"";
		$command .= " \"PS\"" . " \"Current Running Processes (PS)\"";
		$command .= " \"Inittab\"" . " \"Edit inittab file\"";
		$command .= " \"dmesg\"" . " \"Recent Kernel Messages\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(OSDIALOG, "$command |");
		$returnval = <OSDIALOG>;
		close(OSDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq  "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);



		} elsif($returnval eq "Redhat SOS") {
			system("/usr/bin/clear");
			system("sudo /usr/sbin/sosreport");
			wait_for_user();

		} elsif($returnval eq "Redhat List") {
			# RHWS 5
			if(-f "/usr/bin/yum") {
				system("/usr/bin/clear");
				system("sudo yum clean all");
				system("sudo /usr/bin/yum check-update 2>&1 | less");
			# RHEL 4
			} elsif (-f "/usr/sbin/up2date") {
				system("/usr/bin/clear");
				system("sudo /usr/sbin/up2date --list 2>&1 | less");
			}

		} elsif($returnval eq "FSCK on Reboot") {
			open(FILE, "> /fsckoptions");
				print(FILE "-f -v -y");
			close(FILE);
			system("sudo touch /forcefsck");
			$returnval = menu_confirm("Reboot Server Now?");
			if($returnval eq "Y") {
				system("sudo /sbin/shutdown -r now");
				wait_for_user();
			}


		} elsif($returnval eq "Altiris Checkin") {
			system("/usr/bin/clear");
			system("sudo $POSDIR/bin/altiriscontrol.pl --checkin");
			wait_for_user();

		} elsif($returnval eq "Samba Stop") {
			system("/usr/bin/clear");
			system("sudo /sbin/service smb stop");
			wait_for_user();

		} elsif($returnval eq "Samba Start") {
			system("/usr/bin/clear");
			system("sudo /sbin/service smb start");
			wait_for_user();

		} elsif($returnval eq "Samba Status") {
			system("/usr/bin/clear");
			system("smbstatus");
			wait_for_user();

		} elsif($returnval eq "Samba Config") {
			system("sudo rvim /etc/samba/smb.conf");

		} elsif($returnval eq "IPTables Start") {
			system("sudo /sbin/service iptables start");
			wait_for_user();

		} elsif($returnval eq "IPTables Stop") {
			system("sudo /sbin/service iptables stop");
			wait_for_user();


		} elsif($returnval eq "dmesg") {
			system("dmesg | less");

		} elsif($returnval eq "Inittab") {
			system("sudo rvim /etc/inittab");

		} elsif($returnval eq "vmstat") {
			system("/usr/bin/clear");
			system("vmstat 2 15");
			wait_for_user();

		} elsif($returnval eq "iostat") {
			system("/usr/bin/clear");
			system("iostat 2 15");
			wait_for_user();

		} elsif($returnval eq "Messages") {
			viewfiles("/var/log/messages*", "sudo");

		} elsif($returnval eq "Truncate") {
			system("/usr/bin/clear");
			advanced_truncate_root_mbox();
			wait_for_user();
			
		} elsif($returnval eq "Secure") {
			$command = viewfiles("/var/log/secure*", "sudo");
			$returnval = menu_confirm("Send these logs to a Printer?", "N");
			if($returnval eq "Y") {
				$suboption = choose_printer("Print Security logs to which Printer ?");
				if("$suboption" ne "") {
					system("$command | $POSDIR/bin/tfprinter.pl --print $suboption");
				}
			}


		} elsif($returnval eq "Sudo Actions") {
			$command = viewfiles("/var/log/secure*", "sudo", "grep sudo");
			$returnval = menu_confirm("Send these logs to a Printer?", "N");
			if($returnval eq "Y") {
				$suboption = choose_printer("Print Security logs to which Printer ?");
				if("$suboption" ne "") {
					system("$command | $POSDIR/bin/tfprinter.pl --print $suboption");
				}
			}


		} elsif($returnval eq "Services") {
			my $runlevel  = "";
			system("/usr/bin/clear");
			open(INIT, "< /etc/inittab");
			while(<INIT>) {
				if(/^(\s*)(id:)(\d+)(:)/) {
					$runlevel = $3;
					last;
				}
			}
			close(INIT);
			system("/sbin/chkconfig --list | grep -v $runlevel:off | less");

		} elsif($returnval eq "PS") {
			system("watch --interval=5 \"ps wwaux\"");

		# Prompt - Commandline.
		} elsif($returnval eq "Commandline") {
			system("/usr/bin/clear");
			logevent("Begin Shellout to Commandline.");

			set_signal_handlers('DEFAULT');
			system("PS1=\"\\n\\u\@\\h: \\w\\n\\d \\t \\\$ \" /bin/bash");
			set_signal_handlers('IGNORE');

			logevent("Finish Shellout to Commandline.");

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}



sub odbc_menu
{
	my @array = ();
	my $printer = "";
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "";
	my $logfile = "";

	while(1) {
		$title = titlestring("ODBC Menu");
		$title .= "\n\n";

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"Server Logs\"" . " \"View Logfile(s) for BBj Data Server.\"";
		$command .= " \"Live Logs\"" . " \"Watch Live Logfile Activity\"";
		$command .= " \"Close\"" . " \"Close SubMenu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);

		if($returnval eq "Server Logs") {
			viewfiles("/var/log/ds.log");

		} elsif($returnval eq "Live Logs") {
			system("sudo tail -f /var/log/ds.log");

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}


sub printers_main
{
	my @array = ();
	my $printer = "";
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "";
	my $logfile = "";

	while(1) {
		$title = titlestring("Printer Menu");
		$title .= "\n\n";
		$title .= get_printer_status();

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";

		if(-f "$POSDIR/bin/tfprinter.pl") {
			$command .= " \"Add\"" . " \"Add a new Printer\"";
			$command .= " \"Delete\"" . " \"Delete an Existing Printer\"";
			$command .= " \"Queues\"" . " \"View Printer Queues\"";
			$command .= " \"Test\"" . " \"Send Test Page to Printer\"";
		}
		$command .= " \"Kill\"" . " \"Kill a Print Job\"";
		$command .= " \"Restart\"" . " \"Restart Cups\"";
		$command .= " \"Purge Queue\"" . " \"Purge Print Jobs for a Printer\"";
		if(-f "$POSDIR/config/config.bbx") {
			$command .= " \"ConfigBBX\"" . " \"Edit Config.bbx\"";
		}

		$command .= " \"Advanced\"" . " \"Advanced Tools\"";
		$command .= " \"Close\"" . " \"Close SubMenu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq "Add") {
			my $printer = "";
			$printer = add_printer();
			if($printer) {
				$returnval = menu_confirm("Print a Test Page to printer \"$printer\" ?");
				if($returnval eq "Y") {
					test_printer($printer);
				}
			}

		} elsif($returnval eq "Delete") {
			del_printer();

		} elsif($returnval eq "Test") {
			test_printer("");

		} elsif($returnval eq "Kill") {
			kill_printjob();

		} elsif($returnval eq "Restart") {
			my @array = ();
			system("sudo /sbin/service cups stop");
			system("sudo $POSDIR/bin/updateos.pl --cupstmp");
			system("sudo /sbin/service cups start");
			# Need to run 'accept' on every single printer here.
			open(PIPE, "$POSDIR/bin/tfprinter.pl --list |");
			while(<PIPE>) {
				chomp;
				@array = split(/\s+/);
				print("Resetting Printer \"$array[0]\"...\n");
				system("sudo /usr/sbin/accept $array[0] > /dev/null 2> /dev/null");
			}
			close(PIPE);
			wait_for_user();

		} elsif($returnval eq "Queues") {
			if(-f "$POSDIR/bin/tfprinter.pl") {
				system("$POSDIR/bin/tfprinter.pl --list");
			} else {
				show_printer_queues();
			}
			wait_for_user();


		} elsif($returnval eq "ConfigBBX") {
			system("sudo rvim $POSDIR/config/config.bbx");

		# Delete all print jobs for all printers.
		} elsif($returnval eq "Purge Queue") {

			$printer = choose_printer("Which Print Queue to Clear?");
			if(! $printer) {
				menu_info("No Printers Present.");
			}
			if("$printer" ne "") {
				$returnval = menu_confirm("Remove ALL Print Jobs for \"$printer\"?");
				if($returnval eq "Y") {
					system("sudo /usr/bin/cancel -a \"$printer\"");
					show_printer_queues();
				}
			}

		} elsif($returnval eq "Advanced") {
			printers_advanced();

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}

sub printers_advanced
{
	my @array = ();
	my $printer = "";
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "Advanced Printer Menu";
	my $logfile = "";

	while(1) {
		$title = titlestring("Advanced Printer Menu");
		$title .= "\n\n";
		$title .= get_printer_status();

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";

		if(-d "/usr2/bbx") {
			$command .= " \"Barcode\"" . " \"Send Barcode Font to a Printer\"";
		}
		if(-f "/usr/sbin/lpmove") {
			$command .= " \"Move Jobs\"" . " \"Move ALL Jobs from one printer to another.\"";
		}
		$command .= " \"Enable\"" . " \"Cups Enable Printer\"";
		$command .= " \"Disable\"" . " \"Cups Disable Printer\"";
		$command .= " \"Error\"" . " \"View Cups Error Logfile\"";
		$command .= " \"Live Logs\"" . " \"Watch Live Logfile Activity\"";
		$command .= " \"Close\"" . " \"Close SubMenu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq "Barcode") {
			$printer = choose_printer("Which Printer Send a Barcode to?");
			if("$printer" ne "") {
				system("lp -d $printer $POSDIR/bbxd/barcode");
			}

		} elsif($returnval eq "Enable") {
			$printer = choose_printer("Which Printer to Enable?");
			if("$printer" ne "") {
				system("sudo /usr/sbin/cupsenable $printer");
			}
		} elsif($returnval eq "Disable") {
			$printer = choose_printer("Which Printer to Disable?");
			if("$printer" ne "") {
				system("sudo /usr/sbin/cupsdisable -r \"$ENV{'USER'} admin menus\" $printer");
			}

		} elsif($returnval eq "Move Jobs") {
			my $srcprinter = "";
			my $destprinter = "";
			$srcprinter = choose_printer("Move Jobs FROM which Printer?");
			if("$srcprinter" ne "") {
				$destprinter = choose_printer("Move Jobs TO which Printer?");
				if("$destprinter" ne "") {
					system("clear && /usr/sbin/lpmove $srcprinter $destprinter");
					wait_for_user();
				}
			}
	
		} elsif($returnval eq "Error") {
			viewfiles("/var/log/cups/error_log*", "sudo");

		} elsif($returnval eq "Live Logs") {
			system("sudo tail -f /var/log/cups/error_log /var/log/cups/access_log /var/log/cups/page_log");



		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}



sub add_printer
{
	my $interface_type = "";
	my $printer_type = "";
	my $ipaddress = "";
	my %options = ();
	my $printer = "";
	my $username = "";
	my $password = "";
	my $workgroup = "";
	my $share = "";
	my $tfprinter_cmd = "$POSDIR/bin/tfprinter.pl";
	my $tfprinter_opts = "";

	#
	# RH72 not supported.
	#
	if ($OS eq "RH72") {
		if(-f "/usr/sbin/system-config-printer") {
			system("sudo /usr/sbin/system-config-printer");
		} else {
			menu_info("Add printer for RH72 platform not supported from the Support Menu");
		}
		return("");
	}

	# What type of interface?
	$options{"Auto"} = "Automatically Detect";
	$options{"Jetdirect"} = "HP Jetdirect (Network) Printers";
	$options{"LPD"} = "LPD (Network) Printer";
	$options{"Windows"} = "Printer Attached to a Windows PC";
	$options{"Parallel"} = "Printer Connected to Parallel Port.";
	$interface_type = menu_pickone("What type of interface?", \%options, "Auto");
	return("") if (! $interface_type);


	# What kind of printer?
	%options = ();
	$options{"raw"} = "Raw Print Queue";
	$options{"PCL"} = "HP LaserJet 4200 PCL Printer";
	$options{"PostScript"} = "Dell 5200 PostScript Printer";
	$printer_type = menu_pickone("What kind of printer?", \%options, "raw");
	return("") if(! $printer_type);


	my $ppd_arg = "";
	if ($printer_type eq "PCL") {
		$ppd_arg = "--ppd=hplj4200.ppd";
	} elsif ($printer_type eq "PostScript") {
		$ppd_arg = "--ppd=dell5200.ppd";
	}
	$tfprinter_opts = "$ppd_arg";

	#
	# Warn the user about special chars not allowed in printer names.
	#
	my $printer_name_title = "Printer Name?";
	$printer_name_title .= "\nNames may not contain SPACE, TAB, /, or #";

	if( ("$interface_type" eq "Auto") 
	||  ("$interface_type" eq "LPD")
	||  ("$interface_type" eq "Jetdirect") ) {

		$printer = menu_getstring($printer_name_title);
		return("") if (! $printer);
		$ipaddress = menu_getstring("IP Address or Device Name?");
		return("") if (! $ipaddress);


		# LPD Printer
		if ("$interface_type" eq "LPD") {
			$tfprinter_opts .= " --lpd --add $printer:$ipaddress";
			$share = menu_getstring("Windows 7 LPD Printer Share Name? (Optional)");
			if ($share ne "") {
				$tfprinter_opts .= " --share=\"$share\"";
			}

		# Jetdirect Printer
		} elsif ("$interface_type" eq "Jetdirect") {
			$tfprinter_opts .= " --jetdirect --add $printer:$ipaddress";

		# Auto Detect
		} else {
			$tfprinter_opts .= " --add $printer:$ipaddress";
		}

	# Samba Printer
	} elsif ("$interface_type" eq "Windows") {
		$printer = menu_getstring($printer_name_title);
		return("") if (! $printer);

		$ipaddress = menu_getstring("IP Address?");
		if("$ipaddress" !~ /(\d+)(\.)(\d+)(\.)(\d+)(\.)(\d+)/) {
			return("");
		}
 
		$username = menu_getstring("Username? (Optional)");
		if("$username" ne "") {
			$username = " --user=\"$username\"";

			$password = menu_getstring("Password? (Optional)");
			if("$password" ne "") {
				$password = " --password=\"$password\"";
			}
		}
		$workgroup = menu_getstring("Windows Workgroup?");
		if("$workgroup" ne "") {
			$workgroup = " --workgroup=\"$workgroup\"";
		}

		$share = menu_getstring("Windows Printer Share?");
		if("$share" ne "") {
			$share = " --share=\"$share\"";
		}
		$tfprinter_opts .= " --add $printer:$ipaddress";
		$tfprinter_opts .= " --samba $username $password $share $workgroup";

	} elsif ("$interface_type" eq "Parallel") {
		$printer = menu_getstring($printer_name_title);
		return("") if (! $printer);

		$tfprinter_opts .= " --add $printer:/dev/lp0";
	}

	#
	# Now that the info is gathered, the printer can actually be added.
	# The tfprinter.pl script will output a message about the status
	# of adding the printer, so do a wait so the user can see the
	# status message.
	#
	system("sudo $tfprinter_cmd $tfprinter_opts");
	wait_for_user();

	return($printer);
}

sub del_printer
{
	my $printer = "";

	#
	# RH72 not supported.
	#
	if ($OS eq "RH72") {
		menu_info("Removing printer for RH72 platform not supported from the Support Menu");
		return;
	}

	$printer = choose_printer("Which Printer to Delete?");
	if ("$printer" ne "") {
		system("sudo $POSDIR/bin/tfprinter.pl --delete $printer");
		wait_for_user();
	}
}

sub test_printer
{
	my $the_choice = $_[0];
	my $printer_script = "$POSDIR/bin/tfprinter.pl";
	my @output = ();
	my %printers = ();
	my %options = ();
	my $title = "Choose Printer to Send Test Page";

	unless (-f $printer_script) {
		menu_info("Printer script missing: $printer_script.");
		return;
	}

	if (! defined($the_choice) || $the_choice eq "") {
		#
		# output from "tfprinter.pl --list" looks like:
		#	"printer_name" \s \t "(n" \s "Jobs)" \n
		#
		open(PIPE, "$printer_script --list |");
		while(<PIPE>) {
			chomp;
			@output = split(/\s+/);
			next if ($output[0] eq "null");
			# kill leading open paren
			$output[1] =~ s/^\(//;
			# key = printer name, value = q size
			$printers{$output[0]} = $output[1];
		}
		close(PIPE);

		unless (scalar(keys(%printers)) > 0) {
			menu_info("No Printers Configured.");
			return;
		}

		#
		# fill out list of printers for the menu_pickone() function.
		#
		foreach (sort(keys(%printers))) {
			$options{$_} = "";
		}

		$the_choice = menu_pickone($title, \%options, "");
	}

	if ($the_choice eq "") {
		return;
	}

	my $test_page = "/tmp/tfsupport.test.page.$$";
	my $hostname = get_hostname("--long");
	my $localtime = strftime("%a %B %d, %Y %T %Z", localtime());
	my $username = getpwuid($<);
	my $ttyname = qx(tty);
	chomp($ttyname);
	my $printer_type = get_printer_type($the_choice);
	my $cups_file_count = get_cups_file_count();
	my $cups_free_space = get_cups_free_space();
	my $pos_version = get_pos_version();
	my $linux_version = get_linux_version();
	my $cups_version = get_cups_version();
	my $tfsupport_version = get_script_version("tfsupport");
	my $tfprinter_version = get_script_version("tfprinter");

	open(TP, "> $test_page");
	print TP "=================================\r\n";
	print TP "P R I N T E R   T E S T   P A G E\r\n";
	print TP "=================================\r\n";
	print TP "\r\n";
	print TP "time: $localtime\r\n";
	print TP "\r\n\r\n";
	print TP "---------------------------------\r\n";
	print TP "      S Y S T E M    I N F O     \r\n";
	print TP "---------------------------------\r\n";
	print TP "\r\n";
	print TP "server hostname: $hostname\r\n";
	print TP "user: $username\r\n";
	print TP "tty: $ttyname\r\n";
	print TP "\r\n\r\n";
	print TP "---------------------------------\r\n";
	print TP "     P R I N T E R   I N F O     \r\n";
	print TP "---------------------------------\r\n";
	print TP "\r\n";
	print TP "printer: $the_choice\r\n";
	print TP "printer queue size: $printers{$the_choice}\r\n";
	print TP "printer type: $printer_type\r\n";
	print TP "cups file count: $cups_file_count\r\n";
	print TP "cups free space: $cups_free_space\r\n";
	print TP "\r\n\r\n";
	print TP "---------------------------------\r\n";
	print TP "     V E R S I O N   I N F O     \r\n";
	print TP "---------------------------------\r\n";
	print TP "\r\n";
	print TP "POS version: $pos_version\r\n";
	print TP "Linux version: $linux_version\r\n";
	print TP "CUPS version: $cups_version\r\n";
	print TP "Support Menu version: $tfsupport_version\r\n";
	print TP "Printer Util version: $tfprinter_version\r\n";
	close(TP);

	system("/usr/bin/clear");
	system("cat $test_page | $printer_script --print $the_choice");
	system("cat $test_page");
	system("rm -f $test_page");
	wait_for_user();

}


sub get_printer_status
{
	my @array = ();
	my $printer = "";
	my $found = 0;
	my $message = "";
	my $timestamp = "";


	# Is cups service running?
	$found = 0;
	open(PIPE, "sudo /sbin/service cups status |");
	while(<PIPE>) {
		if(/is running/) {
			$found = 1;
			last;
		}
	}
	close(PIPE);

	$message .= "CUPS System Service is ";
	$message .= "NOT " unless ($found);
	$message .= "running.\\n";


	# Is Cups listening on TCP Port?
	$found = 0;
	open(PIPE, "netstat -plan 2> /dev/null |");
	while(<PIPE>) {
		if(/(\d+\.\d+\.\d+\.\d+:631)([[:print:]]+)(LISTEN)/) {
			$found = 1;
			last;
		}
	}
	close(PIPE);
	if($found == 0) {
		$message .= "Cups Printer Daemon is NOT LISTENING on TCP port.\\n";
	}


	# system("sudo cat /var/log/cups/error_log | less");
	# system("sudo cat /var/log/cups/access_log | less");
	# system("sudo cat /var/log/cups/page_log | less");

	# How many files in /var/spool/cups/tmp? 
	$found = get_cups_file_count();
	if($found > 1000) {
		$message .= "$found jobs in /var/spool/cups/tmp\\n";
	}

	return($message);
}

#
# Show "lpq" for each and every printer.
#
sub show_printer_queues
{
	my @array = ();
	my @printers = ();
	my $printer = "";
	my $command = "";
	my $i = 0;


	# Which printers are present?
	# What are their queue counts.
	open(PRINTERS, "lpstat -a |");
	while(<PRINTERS>) {
		@array = split(/[[:space:]]+/);
		$printer = $array[0];
		next if("$printer" eq "");
		push(@printers, "$printer");
	}
	close(PRINTERS);

	# We did not find a printer. This is odd.
	if($#printers < 0) {
		system("echo \"No Printers Found.\" | less");
		return(0);
	}

	$command = "(date ";
	$command .= " ; sudo lpq -P $printers[0]";
	for ($i = 1; $i <= $#printers; $i++) {
		$command .= " ; /bin/echo";
		$command .= " ; /bin/echo";
		$command .= " ; sudo lpq -P $printers[$i]";
	}
	$command .= ") | less";

	system("$command");

	return(0);
}


#
# Request a job ID, and then kill that.
#
sub kill_printjob
{
	my $command = "";
	my $returnval = "";
	my $printer = "";
	my $user = "";
	my $line = "";
	my $jobnum = "";
	my %printers = ();
	my %printjobs = ();
	my @array = ();


	#
	# RH72 not supported.
	#
	if ($OS eq "RH72") {
		menu_info("Kill Print Job for RH72 platform not supported from the Support Menu");
		return;
	}


	# Expected output:
	#
	#Rank    Owner   Job     File(s)                         Total Size
	#active  daffentr23592   (stdin)                         2048 bytes
	#1st     daffentr23593   (stdin)                         2048 bytes
	#2nd     daffentr23594   (stdin)                         2048 bytes
	#
	# Which printers are present?
	# What are their queue counts.
	open(QUEUE, "lpq -a |");
	while(<QUEUE>) {
		next if (/Total Size/);
		chomp;
		$line = $_;
		$user = substr($line, 8,8);
		$jobnum = substr($line, 16,8);
		next if ("$user" eq "");
		$printjobs{$jobnum}{"user"} = $user;
		$printjobs{$jobnum}{"jobnum"} = $jobnum;
	}
	close(QUEUE);


	$command = "dialog --separate-output --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	$command .= " --title 'Kill Which Print Jobs?'";
	$command .= " --checklist 'Select which print jobs to kill.'";
	$command .= " 0 0 0";
	foreach $jobnum (sort(keys(%printjobs))) {
		$command .= " " . "\"$jobnum\" \"User $printjobs{$jobnum}{'user'} \" \"off\"";
	}


	@array = ();
	open(DIALOG, "$command |");
	while(<DIALOG>) {
		chomp;
		$returnval = $_;
		$returnval =~ s/\s+//g; # Strip leading and trailing spaces.
		if("$returnval" eq "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);
		}
		push(@array, $returnval);
	}
	close(DIALOG);



	if($#array < 0) {
		menu_info("No Print Job Specified.");
		return(0);
	}

	system("/usr/bin/clear");
	foreach $jobnum(@array) {
		system("sudo /usr/bin/cancel $jobnum");
	}

	menu_info("Print Job(s) Killed.");
}



#
# Choose one printer from a list of printers.
#
sub choose_printer
{
	my $title = $_[0];
	my @array = ();
	my $printer = "";
	my $command = "";



	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	$command .= " --menu '$title'";
	$command .= " 0 0 0";

	# Which printers are present?
	# What are their queue counts.
	open(PRINTERS, "lpstat -a |");
	while(<PRINTERS>) {
		@array = split(/[[:space:]]+/);
		$printer = $array[0];
		next if("$printer" eq "");
		$command .= " \"$printer\" \"$printer\"";
	}
	close(PRINTERS);
	if(! $printer) {
		$command .= " \"\" \"\"";
	}


	open(BARCODE, "$command |");
	$printer = <BARCODE>;
	close(BARCODE);
	return if(! $printer);
	chomp($printer);


	if($printer eq "timeout") {
		logevent("Inactivity Timeout.");
		exit(0);
	}

	return($printer);


	return($?);
}


sub get_printer_type
{
	my $printer_name = $_[0];
	my $device = "";

	return ($printer_name) if ($printer_name eq "null");
	return ($printer_name) if ($printer_name eq "screen");

	#
	# Expecting the output of the "lpstat -v" to look like this:
	#
	# $ lpstat -v
	# device for printer1: socket://192.168.10.52/
	# device for hppcl: ipp://192.168.1.52/
	# device for dell5210: ipp://192.168.10.52/
	#

	open(PIPE, "lpstat -v |");
	while(<PIPE>) {
		if (/^device for $printer_name:/) {
			$device = (split(/\s+/))[3];
		}
	}
	close(PIPE);

	return($device);
}


# How many files in /var/spool/cups/tmp? 
sub get_cups_file_count
{
	my $cups_file_count = 0;
	open(PIPE, "sudo /usr/bin/find /var/spool/cups/tmp -type f -print |");
	while(<PIPE>) {
		$cups_file_count++;
	}
	close(PIPE);

	return($cups_file_count);
}

sub get_cups_free_space
{
	my @df_values = ();

	open(PIPE, "sudo df -Ph /var/spool/cups |");
	while(<PIPE>) {
		next if (/^Filesystem/);
		chomp;
		@df_values = split(/\s+/);
	}
	close(PIPE);

	return($df_values[3]);
}


# Pick a user from the results of "rtiuser.pl".
sub users_menu_choose
{
	my $title = $_[0];
	my $command = "";
	my $returnval = "";
	my $userscript = "";
	my @array = ();


	# Where is our 'xxxuser.pl' script?
	foreach("$POSDIR/bin/rtiuser.pl", "$POSDIR/bin/dsyuser.pl", "/d/daisy/dsyuser.pl", "/usr2/bbx/bin/rtiuser.pl") {
		next until -f $_;
		$userscript = $_;
		last;
	}
	if("$userscript" eq "") {
		print("rtiuser.pl or dsyuser.pl scripts not found on this system.");
		wait_for_user();
		return;
	}


	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	$command .= " --menu '$title'";
	$command .= " 0 0 0";

	# Create a list of all users who could be unlocked.
	open(PIPE, "$userscript --list | grep User | sort |");
	while(<PIPE>) {
		chomp;
		@array = split(/[[:space:]]+/);

		#
		# The output from the xxxusers.pl --list can be up to 5 elements.
		# For example, with a Daisy non-admin user, there would be:
		#	daisy (Daisy User)                    <-- 3 space separated elements
		# With a Daisy admin user, there would be:
		#	daisy (Daisy User) (Daisy Admin)      <-- 5 space separated elements

		if (@array) {
			$command .= " \"$array[0]\"";
			for (my $i = 1; $i <= 4; $i++) {
				if (defined($array[$i])) {
					$command .= " ";
					$command .= "\"" if ($i == 1);
					$command .= "$array[$i]";
				} else {
					last;
				}
			}
			$command .= "\"" if ($#array > 0);
		}
	}
	close(PIPE);

	#
	# SPECIAL CASE:
	# If this function was called by Support Menu -> Users -> ResetPW, then
	# add "root" as one of the users eligible to have it's password reset.
	#

	if ($title eq "Which User to Reset Password?") {
		$command .= " \"root\" \"root user\"";
	}

	open(USERCHOOSE, "$command |");
	$returnval = <USERCHOOSE>;
	close(USERCHOOSE);
	next if(! $returnval);
	chomp($returnval);


	if($returnval eq "timeout") {
		logevent("Inactivity Timeout.");
		exit(0);
	}


	return($returnval);
}



sub rti_menu
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "RTI Application Menu";
	my $user = "";
	my $logfile = "";

	while(1) {

		$title = titlestring("RTI Application Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"Killem\"" . " \"Stop RTI Background Processes.\"";
		$command .= " \"Startbbx\"" . " \"Restart RTI Background Processes.\"";
		$command .= " \"Checkit\"" . " \"RTI Background Process Status.\"";
		$command .= " \"RTI\"" . " \"Run RTI as current user\"";
		$command .= " \"CC Log\"" . " \"Credit Card (TCC) Logfile.\"";
		$command .= " \"DoveOut Log\"" . " \"Logfile for outbound Dove Txns.\"";
		$command .= " \"Doveserver Log\"" . " \"Logfile for inbound Dove Txns.\"";
		if(-f "$POSDIR/bin/killterms.pl") {
			$command .= " \"Killterms\"" . " \"Kill stuck terminals.\"";
		}
		$command .= " \"Advanced\"" . " \"Advanced Tools.\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);


		} elsif($returnval eq "RTI") {
			system("$POSDIR/bin/sshbbx");



		} elsif($returnval eq "Checkit") {
			system("watch --interval=10 \"$POSDIR/bin/checkit\"");


			
		} elsif($returnval eq "Killem") {
			my @progs = ();

			# Let user pick which Background programs to stop.
			@progs = choose_rtibackgr();
			if(@progs) {
				$returnval = menu_confirm("Stop RTI Background Processes?", "N");
				if($returnval eq "Y") {
					system("clear");
					if(grep(/^All$/, @progs)) {
						system("sudo $POSDIR/bin/killem");
					} else {
						system("sudo $POSDIR/bin/killem @progs");
					}
					system("$POSDIR/bin/checkit");
					wait_for_user();
				}
			}




		} elsif($returnval eq "Startbbx") {
			my @progs = ();

			# Let user pick which Background programs to stop.
			@progs = choose_rtibackgr();
			if(@progs) {
				$returnval = menu_confirm("Start RTI Background Processes?", "N");
				if($returnval eq "Y") {
					system("clear");
					if(grep(/^All$/, @progs)) {
						system("sudo $POSDIR/bin/startbbx");
					} else {
						system("sudo $POSDIR/bin/startbbx @progs");
					}
					system("$POSDIR/bin/checkit");
					wait_for_user();
				}
			}


		} elsif($returnval eq "DoveOut Log") {
			viewfiles("$POSDIR/log/callout-*.log");

		} elsif($returnval eq "Doveserver Log") {
			viewfiles("$POSDIR/log/doveserver-*.log");

		} elsif($returnval eq "CC Log") {
			viewfiles("$POSDIR/log/tcc*.log");

		} elsif($returnval eq "Killterms") {
			system("sudo $POSDIR/bin/killterms.pl --nobbterm");
			wait_for_user();


		} elsif($returnval eq "Advanced") {
			rti_advanced();

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}


sub rti_advanced
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "RTI Application Menu";
	my $user = "";
	my $logfile = "";

	while(1) {

		$title = titlestring("RTI Advanced Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"RTI as User\"" . " \"Run RTI as another user.\"";
		$command .= " \"Basis Logs\"" . " \"Basis License Manager Logs.\"";
		$command .= " \"CC Log\"" . " \"Credit Card (TCC) Logfile.\"";
		$command .= " \"Fax Logs\"" . " \"RTI-Sendfax Logs.\"";
		$command .= " \"Fax Queue\"" . " \"Queue of items to be Faxed.\"";
		$command .= " \"Fax Unlock\"" . " \"Remove Fax Lock.\"";
		$command .= " \"DoveOut Log\"" . " \"Logfile for outbound Dove Txns.\"";
		$command .= " \"Doveserver Log\"" . " \"Logfile for inbound Dove Txns.\"";
		$command .= " \"Patchlog\"" . " \"View RTI Patch Logfile.\"";
		$command .= " \"Verify Data\"" . " \"Verify Integrity of bbxd Data Files.\"";
		$command .= " \"Permissions\"" . " \"Reset Permissions on All RTI Files.\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);


		} elsif($returnval eq "RTI as User") {
			$returnval = users_menu_choose("Choose RTI User");
			if($returnval ne "") {
				system("sudo -u $returnval $POSDIR/bin/sshbbx");
			}

		} elsif($returnval eq "Fax Logs") {
			viewfiles("$POSDIR/log/rti_sendfax-*.log");

		} elsif($returnval eq "Fax Queue") {
			system("watch --interval=10 \"$POSDIR/bin/rti_sendfax.pl --list\"");

		} elsif($returnval eq "Fax Unlock") {
			system("$POSDIR/bin/rti_sendfax.pl --unlock");



		} elsif($returnval eq "RTI") {
			system("$POSDIR/bin/sshbbx");

		} elsif($returnval eq "RTI as User") {
			$returnval = users_menu_choose("Choose RTI User");
			if($returnval ne "") {
				system("sudo -u $returnval $POSDIR/bin/sshbbx");
			}


		} elsif($returnval eq "Basis Logs") {
			viewfiles("/usr2/basis/blmgr/log/blm.log*");



		} elsif($returnval eq "Patchlog") {
			viewfiles("$POSDIR/log/RTI-Patches.log");

		} elsif($returnval eq "Permissions") {
			system("/usr/bin/clear");
			system("sudo $POSDIR/bin/rtiperms.pl");
			wait_for_user();


		} elsif($returnval eq "DoveOut Log") {
			viewfiles("$POSDIR/log/callout-*.log");

		} elsif($returnval eq "Doveserver Log") {
			viewfiles("$POSDIR/log/doveserver-*.log");

		} elsif($returnval eq "Dove Stop") {
			system("sudo $POSDIR/bin/doveserver.pl --stop");
			wait_for_user();

		} elsif($returnval eq "Dove Start") {
			system("sudo $POSDIR/bin/doveserver.pl --start");
			wait_for_user();

		} elsif($returnval eq "Dove Status") {
			system("watch --interval=10 \"$POSDIR/bin/doveserver.pl --status\" ");

		} elsif($returnval eq "CC Log") {
			viewfiles("$POSDIR/log/tcc*.log");

		} elsif($returnval eq "Killterms") {
			system("sudo $POSDIR/bin/killterms.pl");
			wait_for_user();

		} elsif($returnval eq "Verify Data") {
			system("(sudo /usr2/basis/pro5/mkrecover/mrebuild -s -s $POSDIR/bbxd/*) | less");

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}


#
# Choose one or more "background" programs as configured in the "rtiBackgr" config file.
# This primarily used for "killem" and "startbbx".
#
sub choose_rtibackgr
{
	my @progs = ();
	my @array = ();
	my $string = "";
	my $command = "";


	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	$command .= " --checklist 'Choose RTI Bacgkround Program'";
	$command .= " 0 0 0";


	# Get a  list of programs from our 'rtiBackgr' file.
	open(RTIBACKGR, "< $POSDIR/config/rtiBackgr");
	$command .= " \"All\" \"All Background Programs\" \"on\"";
	while(<RTIBACKGR>) {
		chomp;
		$string =~ s/#.*//g; # Strip comments.
		@array = split(/,/, $string);  # First 'word' of comma separated data.
		$string = $array[0];
		$string =~ s/(\s)+//g; # Strip spaces.
		$command .= " \"$string\" \"\" \"off\"";
	}
	close(RTIBACKGR);


	open(DIALOG, "$command |");
	$string = <DIALOG>;
	close(DIALOG);
	return if(! $string);
	chomp($string);
	system("clear");
	foreach ( split(/"/, $string)) {
		next if(! /[[:alnum:]]+/);
		push(@progs, $_);
	}

	if($string eq "timeout") {
		logevent("Inactivity Timeout.");
		exit(0);
	}


	return(@progs);
}


# Return full path to a daisy database dir.
# If "Cancel" selected, return NULL string.

sub daisy_select_db_dir
{
	my %options = ();
	my @daisy_db_dirs = ();
	my $default_db_dir = "/d/daisy";
	my $title = "Choose Daisy DB Directory";

	# first add the default value to the list
	push(@daisy_db_dirs, $default_db_dir);

	# now get any others and add them to the list
	open(PIPE, "sudo $POSDIR/bin/tfupdate.pl --list |");
	while(<PIPE>) {
		chomp;
		push(@daisy_db_dirs, $_);
	}
	close(PIPE);

	return($default_db_dir) if (@daisy_db_dirs == 1);


	# now fill out the hash for the radio box
	my $filler = "";
	my $counter = 2;
	foreach (@daisy_db_dirs) {
		if (/^$default_db_dir$/) {
			$options{$_} = "Default Daisy DB Directory";
		} else {
			$filler = "second" if ($counter == 2);
			$filler = "third" if ($counter == 3);
			$filler = "fourth" if ($counter == 4);
			$filler = "fifth" if ($counter == 5);
			$filler = "yet another" if ($counter > 5);
			$options{$_} = "$filler Daisy DB Directory";
			$counter++;
		}
	}

	my $the_choice = menu_pickone($title, \%options, $default_db_dir);
	unless (defined($the_choice)) {
		$the_choice = "";
	}

	return ($the_choice);
}


sub daisy_update_software_menu
{
	my $the_choice = "";
	my %options = ();
	my @daisy_db_dirs = ();
	my $default_db_dir = "/d/daisy";
	my $title = "Choose Daisy DB Directory to Update";

	# first add the default value to the list
	push(@daisy_db_dirs, $default_db_dir);

	# now get any others and add them to the list
	open(PIPE, "sudo $POSDIR/bin/tfupdate.pl --list |");
	while(<PIPE>) {
		chomp;
		push(@daisy_db_dirs, $_);
	}
	close(PIPE);

	# and finally add a way to specify an arbitrary path
	push(@daisy_db_dirs, "other");

	# now fill out the hash for the radio box
	foreach (@daisy_db_dirs) {
		if (/^$default_db_dir$/) {
			$options{$_} = "Default Daisy DB Directory";
		} elsif (/other/) {
			$options{$_} = "Specify Path to Other Daisy DB Directory";
		} else {
			$options{$_} = "";
		}
	}

	print("\nYou will be logged out after a successful update.\n");
	wait_for_user();

	$the_choice = menu_pickone($title, \%options, $default_db_dir);

	if (!defined($the_choice) || $the_choice eq "") {
		return;
	}

	if ($the_choice eq "other") {
		$the_choice = menu_getstring("Enter full path to other Daisy DB dir");

		if (!defined($the_choice) || $the_choice eq "") {
			return;
		}
	}

	system("/usr/bin/clear");
	system("sudo $POSDIR/bin/tfupdate.pl --pos $the_choice");
	if ($? != 0) {
		print("The tfupdate.pl script returned an error.\n");
		wait_for_user();
		return;
	}

	print("\nUser will now be logged out...");
	wait_for_user();
	exit(0);
}

sub daisy_update_directory_menu
{
	my $title = "Update Wire Service Directory";

	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	$command .= " --default-item \"All\"";
	$command .= " --menu '$title'";
	$command .= " 0 0 0";
	$command .= " \"All\"" . " \"Update All Daisy Database Directories\"";

	# Redirect stderr to stdout so that we can tell if there was a timeout
	# since 'dialog' writes "timeout" to stderr and exits if a timeout happens.
	my $returnval = qx($command 2>&1);

	# Remove trailing and leading newlines because if there was a timeout,
	# the form of the output is:
	#	^\ntimeout\n$
	chomp($returnval);
	$returnval =~ s/^\n//;

	return unless ($returnval);

	if ($returnval eq "timeout") {
		logevent("Inactivity Timeout: tfsupport menu $title");
		exit(0);
	}

	system("/usr/bin/clear");
	system("sudo $POSDIR/bin/tfupdate.pl --directory");
	wait_for_user();
}

sub daisy_dayend_processor
{
	my $report_file = $_[0];	# input: name of file to print
	my $output = $_[1];		# input: value is either "Screen" or "Printer"
	my $printer = "printer0";

	if (-e $report_file) {
		if ($output eq "Screen" ) {
			system("clear");
			system("cat $report_file | less");

		} elsif ($output eq "Printer" ) {
			open (FH, "/etc/redhat-release");
			my @buf = <FH>;
			close(FH);
			my @matches = grep (/Fedora/, @buf);

			system("lpr -P $printer $report_file");
			if (@matches) {
				system("lpr -P $printer $POSDIR/ff.txt");
			}
			menu_info("Report $report_file sent to printer $printer.");

		} else {
			menu_info("Can't happen in function daisy_dayend_processor()");
		}
	} else {
		menu_info("No Dayend/Closeout Report for $report_file exists.");
	}
}

sub daisy_dayend_reporter
{
	my $day = "Mon";
	my $output = "Printer";
	my %options = ();

	$options{"Screen"} = "Send Results to the Screen.";
	$options{"Printer"} = "Send Results to Printer.";
	$output = menu_pickone("Select destination for Dayend/Audit Reports", \%options, $output);

	if ($output eq "Cancel") {
		return;
	}

	%options = ();
	$options{"1. Sun"} = "Dayend report for Sunday.";
	$options{"2. Mon"} = "Dayend report for Monday.";
	$options{"3. Tue"} = "Dayend report for Tuesday.";
	$options{"4. Wed"} = "Dayend report for Wednesday.";
	$options{"5. Thu"} = "Dayend report for Thursday.";
	$options{"6. Fri"} = "Dayend report for Friday.";
	$options{"7. Sat"} = "Dayend report for Saturday.";
	$day = menu_pickone("Select the Day of the Week of the Dayend/Audit Reports", \%options, $day);

	if ($day eq "Cancel") {
		return;
	}

	# get rid of number prefix which was only there for sort order
	$day =~ s/^\d\.\s//;

	# emit the files
	daisy_dayend_processor("${POSDIR}/dayend.$day", $output);
	daisy_dayend_processor("${POSDIR}/audit.$day", $output);
}

sub daisy_menu
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "Daisy Application Menu";
	my $user = "";
	my $logfile = "";

	while(1) {

		$title = titlestring("Daisy Application Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"Start Daisy\"" . " \"Start Daisy Programs.\"";
		$command .= " \"Stop Daisy\"" . " \"Stop all Daisy Programs.\"";
		$command .= " \"Update Software\"" . " \"Update Daisy Point-of-Sale Software.\"";
		$command .= " \"Update Directory\"" . " \"Update Wire Service Directory.\"";
		$command .= " \"POS\"" . " \"'pos' as current user\"";
		$command .= " \"Daisy\"" . " \"Run 'daisy' as current user.\"";
		$command .= " \"Dayend Report\"" . " \"Print Dayend Reports.\"";
		$command .= " \"Advanced\"" . " \"Advanced Tools.\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);

		} elsif($returnval eq "Start Daisy") {
			my $runlevelout = qx(/sbin/runlevel);
			chomp($runlevelout);
			my @runlevel = split(/\s+/, $runlevelout);

			if (@runlevel) {
				if ($runlevel[1] ne "3") {
					system("/usr/bin/clear");
					system("sudo /sbin/init 3");
					wait_for_user();
				}
			} else {
				menu_info("Can't determine current runlevel.");
			}

		} elsif($returnval eq "Stop Daisy") {
			$returnval = menu_confirm("Stop Daisy Background Processes?", "N");
			if($returnval eq "Y") {
				system("sudo -k");
				system("/usr/bin/clear");
				system("sudo /sbin/init 4");
				system("sudo $POSDIR/utils/killemall");
				wait_for_user();
			}

		} elsif($returnval eq "POS") {
			system("cd $POSDIR && $POSDIR/pos");


		} elsif($returnval eq "Daisy") {
			system("cd $POSDIR && $POSDIR/daisy");


		} elsif($returnval eq "Update Software") {
			daisy_update_software_menu();

		} elsif($returnval eq "Update Directory") {
			daisy_update_directory_menu();

		} elsif($returnval eq "Dayend Report") {
			daisy_dayend_reporter();

		} elsif($returnval eq "Advanced") {
			daisy_advanced();

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}



sub daisy_advanced
{
	my $command = "";
	my $returnval = "";
	my $suboption = "";
	my $title = "Daisy Advanced Menu";
	my $user = "";
	my $logfile = "";
	my $daisy_db_dir = "";

	while(1) {

		$title = titlestring("Daisy Advanced Menu");

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";
		$command .= " \"POS as User\"" . " \"'pos' as another user.\"";
		$command .= " \"Daisy as User\"" . " \"Run 'daisy' as another user.\"";
		$command .= " \"Permissions\"" . " \"Run Permissions on All Daisy Files.\"";
		$command .= " \"Rotate Keys\"" . " \"Rotate Encryption Keys.\"";
		$command .= " \"CC Purge\"" . " \"Purge Expired Credit Cards.\"";
		$command .= " \"Quick Restore\"" . " \"Quick restore (QREST) saved transaction files\"";
		$command .= " \"Close\"" . " \"Close This Menu\"";

		open(BACKDIALOG, "$command |");
		$returnval = <BACKDIALOG>;
		close(BACKDIALOG);
		next if(! $returnval);
		chomp($returnval);


		if($returnval eq "timeout") {
			logevent("Inactivity Timeout.");
			exit(0);


		} elsif($returnval eq "POS as User") {
			$returnval = users_menu_choose("Choose Daisy User");
			if($returnval ne "") {
				system("cd $POSDIR && sudo -u $returnval $POSDIR/pos");
			}

		} elsif($returnval eq "Daisy as User") {
			$returnval = users_menu_choose("Choose Daisy User");
			if($returnval ne "") {
				system("cd $POSDIR && sudo -u $returnval $POSDIR/daisy");
			}

		} elsif($returnval eq "Permissions") {
			$daisy_db_dir = daisy_select_db_dir();
			unless ($daisy_db_dir eq "") {
				system("/usr/bin/clear");
				print("Running Daisy Perms...\n");
				system("sudo $POSDIR/bin/dsyperms.pl $daisy_db_dir");
				wait_for_user();
			}

		} elsif($returnval eq "Rotate Keys") {
			$daisy_db_dir = daisy_select_db_dir();
			unless ($daisy_db_dir eq "") {
				system("/usr/bin/clear");
				system("sudo $POSDIR/bin/dokeyrotate.pl $daisy_db_dir");
				wait_for_user();
			}

		} elsif($returnval eq "CC Purge") {
			$daisy_db_dir = daisy_select_db_dir();
			unless ($daisy_db_dir eq "") {
				system("/usr/bin/clear");
				system("sudo $POSDIR/bin/doccpurge.pl $daisy_db_dir");
				wait_for_user();
			}

		} elsif($returnval eq "Quick Restore") {
			$daisy_db_dir = daisy_select_db_dir();
			unless ($daisy_db_dir eq "") {
				system("/usr/bin/clear");
				system("cd $daisy_db_dir && sudo $daisy_db_dir/qrest");
				wait_for_user();
			}

		} elsif($returnval eq "Close") {
			return(0);
		}
	}
}



#
# Main menu for customer service side.
#
sub csmenu_main
{
	my $title = "Customer Service";
	my @array = ();
	my $shopcode = "";
	my $ipaddr = "";
	my $returnval = "";
	my $keyval = "";
	my $command = "";
	my %customers = ();

	# Step through our "customers.txt" file
	# which has a shopcode,public_ip_address,shopname
	system("groups | grep daisy > /dev/null 2> /dev/null");

	while(1) {


		# Summary information about this shop.
		#$title = titlestring("Customer Service Menu");
		$title = "";
		$title .= "$0 ($CVS_REVISION)\\n";

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --backtitle 'Connect to POS Server'";
		$command .= " --default-item \"Exit\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";

		system("groups | grep daisy > /dev/null 2> /dev/null");
		if($? == 0) {
			$command .= " \"Daisy\"" . " \"Connect to a Daisy Server.\"";
		}
		system("groups | grep rti > /dev/null 2> /dev/null");
		if($? == 0) {
			$command .= " \"RTI\"" . " \"Connect to an RTI Server.\"";
		}
		$command .= " \"User Specified Shop\"" . " \"Specify an IP Address to Connect to.\"";
		$command .= " \"Exit\"" . " \"Exit\"";


		# Redirect stderr to stdout so that we can tell if there was a timeout
		# since 'dialog' writes "timeout" to stderr and exits if a timeout happens.
		$returnval = qx($command 2>&1);

		# Remove trailing and leading newlines because if there was a timeout,
		# the form of the output is:
		#	^\ntimeout\n$
		chomp($returnval);
		$returnval =~ s/^\n//;
		next if (!$returnval);

		if($returnval eq "timeout") {
			logevent("Inactivity Timeout");
			exit(0);

		# A Shop Code
		} elsif($returnval eq "User Specified Shop") {
			$ipaddr = csmenu_confirmconnect("", \%customers);
			if($ipaddr ne "") {
				system("/usr/bin/clear && $POSDIR/bin/tfremote.pl --connect \"$ipaddr\"");
				if($? != 0) {
					wait_for_user();
				}
			}

		} elsif($returnval eq "Daisy") {
			csmenu_listshops("Daisy");
		} elsif($returnval eq "RTI") {
			csmenu_listshops("RTI");


		} elsif($returnval eq "Exit") {;
			$returnval = menu_confirm("Exit Support Menu?", "No");
			if($returnval eq "Y") {
				logevent("Finish Support Menu.");
				exit(0);
			}
		}
	}

	exit(0);
}

#
# Main menu for customer service side.
#
sub csmenu_listshops
{
	my $pos = $_[0];
	my $title = "Customer Service";
	my @array = ();
	my $shopcode = "";
	my $ipaddr = "";
	my $returnval = "";
	my $keyval = "";
	my $command = "";
	my %customers = ();

	# Step through our "customers.txt" file
	# which has a shopcode,public_ip_address,shopname
	if("$pos" eq "Daisy") {
		open(CUSTOMERS, "< /etc/daisy-customers.txt");
		while(<CUSTOMERS>) {
			chomp;
			@array = split(/,/);
			next if ($#array < 0);
			#next if ($array[0] !~ /\d+/);
			$ipaddr = $array[1];
			$keyval = sprintf('%-25s - %s', $array[2], $array[0]);
			$customers{$keyval}{"shopcode"} = $array[0];
			$customers{$keyval}{"ipaddress"} = $array[1];
			$customers{$keyval}{"name"} = $array[2];
		}
		close(CUSTOMERS);
	}
	if("$pos" eq "RTI") {
		open(CUSTOMERS, "< /etc/RTI-customers.txt");
		while(<CUSTOMERS>) {
			chomp;
			@array = split(/,/);
			next if ($#array < 0);
			#next if ($array[0] !~ /\d+/);
			$ipaddr = $array[1];
			$keyval = sprintf('%-25s - %s', $array[2], $array[0]);
			$customers{$keyval}{"shopcode"} = $array[0];
			$customers{$keyval}{"ipaddress"} = $array[1];
			$customers{$keyval}{"name"} = $array[2];
		}
		close(CUSTOMERS);
	}


	logevent("Starting $pos Customer Service Menu");
	while(1) {


		# Summary information about this shop.
		#$title = titlestring("Customer Service Menu");
		$title = "";
		$title .= "$0 ($CVS_REVISION)\\n";

		$command = "dialog --stdout";
		$command .= " $TIMEOUT_MENU_ARG";
		$command .= " --no-cancel";
		$command .= " --backtitle 'Connect to $pos Customer System'";
		$command .= " --default-item \"Close\"";
		$command .= " --menu '$title'";
		$command .= " 0 0 0";

		$command .= " \"Close\"" . " \"Close This Menu\"";
		$command .= " \"User Specified Shop\"" . " \"Specify an IP Address to Connect to.\"";
		#$command .= " \"Advanced\"" . " \"Advanced Options\"";

		foreach $keyval (sort {$customers{$a}{'name'} cmp $customers{$b}{'name'}} keys(%customers)) {
			$command .= " \"$keyval\" \"$customers{$keyval}{'ipaddress'}\"";
		}



		# Redirect stderr to stdout so that we can tell if there was a timeout
		# since 'dialog' writes "timeout" to stderr and exits if a timeout happens.
		$returnval = qx($command 2>&1);

		# Remove trailing and leading newlines because if there was a timeout,
		# the form of the output is:
		#	^\ntimeout\n$
		chomp($returnval);
		$returnval =~ s/^\n//;
		next if (!$returnval);

		if($returnval eq "timeout") {
			logevent("Inactivity Timeout");
			exit(0);

		# A Shop Code
		} elsif($returnval eq "User Specified Shop") {
			$ipaddr = csmenu_confirmconnect("", \%customers);
			if($ipaddr ne "") {
				system("/usr/bin/clear && tfremote.pl --connect \"$ipaddr\"");
			}


		# A Shop Code
		} elsif($returnval =~ /\S{8}/) {
			$ipaddr = csmenu_confirmconnect($returnval, \%customers);
			if($ipaddr ne "") {
				system("/usr/bin/clear && tfremote.pl --connect \"$ipaddr\"");
			}


		} elsif($returnval eq "Close") {
			return(0);
		}
	}

	exit(0);
}


#
# Confirm the IP Address we want to connect to.
# Connect to that IP Address.
#
sub csmenu_confirmconnect
{
	my $keyval = $_[0];
	my %customers = %{$_[1]};
	my $command = "";
	my $returnval = "";

	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";


	if("$keyval" eq "") {
		# Connect to an anonymous IP Address.
		$command .= " --backtitle 'Connect to User-Specified Host'";
		$command .= " --inputbox 'Connect to which IP Address?";
		$command .= "\\n\\nNote:";
		$command .= "\\nYou may need to have the customer go to...\\n\\nhttp://www.ipchicken.com\\n\\n ...to obtain their IP Address.";
		$command .= "'";
	} else {
		# List all properties we know about this shop.
		# One property per line.
		$command .= " --backtitle 'Connect to Selected Shop'";
		$command .= " --inputbox '";
		foreach $returnval (sort(keys(%{$customers{$keyval}}))) {
			$command .= "\\n$returnval:  $customers{$keyval}{$returnval}";
		}
		$command .= "\\n\\nNote:";
		$command .= "\\nYou may need to have the customer go to...\\n\\nhttp://www.ipchicken.com\\n\\n ...to obtain their IP Address.";
		$command .= "'";
	}

	$command .= " 0 0";

	# Default IP Address
	if($customers{$keyval}{'ipaddress'}) {
		$command .= " \"$customers{$keyval}{'ipaddress'}\"";
	}


	open(DIALOG, "$command |");
	$returnval = <DIALOG>;
	close(DIALOG);

	unless (defined $returnval) {
		menu_info("No IP Address or host chosen.");
		return("");
	}

	chomp($returnval);
	
	$returnval = validate_input($returnval);

	if($returnval eq "timeout") {
		# Timeout
		logevent("Inactivity Timeout.");
		exit(0);
	}

	return("$returnval");
}



sub menu_confirm
{
	my $title = $_[0];
	my $default = $_[1];
	my $command = "";


	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	if( ($default) && ($default =~ /^no$/i)) {
		$command .= " --defaultno";
	}
	$command .= " --yesno";
	$command .= " \"$title\"";
	$command .= " 0 0";

	system("$command");

	if($? == 0) {
		return("Y");

	} elsif ($? == 255) {
		# Timeout
		logevent("Inactivity Timeout.");
		exit(0);
		
	} else {
		return("N");
	}
}


sub menu_info
{
	my $title = $_[0];
	my $command = "";


	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	$command .= " --msgbox";
	$command .= " \"$title\"";
	$command .= " 0 0";

	system("$command");
	if($? == 255) {
		# Timeout
		logevent("Inactivity Timeout.");
		exit(0);
	}

	return(0);
}


sub menu_getstring
{
	my $title = $_[0];
	my $default = $_[1];
	my $command = "";
	my $returnval = "";

	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	$command .= " --no-cancel";
	$command .= " --inputbox '$title'";

	#
	# One, I don't want to change the interface to menu_getstring()
	# to provide values for the height and width of the inputbox...
	# so we will just look at the length of the title string passed
	# as the first arg to this function.
	#
	# Two, the following section of code contains magic numbers to try to
	# get the dialog --inputbox to provide enough width for the title string...
	# values determined via trying various title lengths and menu box widths
	# at the command line.
	#
	my $menu_width = 0;
	my $title_len = length($title);
	if ($title_len > 25) {
		$menu_width = $title_len + 5;
	}
	$command .= " 0 $menu_width";

	if( ($default) && ("$default" ne "")) {
		$command .= " \"$default\"";
	}

	open(DIALOG, "$command |");
	$returnval = <DIALOG>;
	close(DIALOG);

	unless (defined $returnval) {
		return("");
	}

	chomp($returnval);
	
	$returnval = validate_input($returnval);

	#
	# Three, the following code does not work - upon a timeout, the dialog command
	# writes the string "\ntimeout\n" to stderr, not stdout, and the call to open()
	# above only captures stdout.
	#
	if($returnval eq "timeout") {
		# Timeout
		logevent("Inactivity Timeout.");
		exit(0);
	}

	return("$returnval");
}


#
# Simple radio button box.
#
sub menu_pickone
{
	my $title = $_[0];
	my %options = %{$_[1]};
	my $default = $_[2];
	my $key = "";
	my $value = "";


	my $command = "";
	my $returnval = "";

	$command = "dialog --stdout";
	$command .= " $TIMEOUT_MENU_ARG";
	# $command .= " --no-cancel";
	$command .= " --radiolist '$title' 0 0 0 ";
	foreach $key (sort(keys(%options))) {
		$value = $options{$key};
		$command .= " " . "\"$key\" \"$value\" ";
		if("$key" eq "$default") {
			$command .= " on";
		} else {
			$command .= " off";
		}
	}


	open(DIALOG, "$command |");
	$returnval = <DIALOG>;
	close(DIALOG);
	return if(! $returnval);
	chomp($returnval);
	
	$returnval = validate_input($returnval);

	if($returnval eq "timeout") {
		# Timeout
		logevent("Inactivity Timeout.");
		exit(0);
	}

	return("$returnval");
}


sub titlestring
{
	my $title = $_[0];
	my $returnval = "";

	$returnval = "--------======== $title =======---------\\n";
	
	# Get our hostname.
	$returnval .= get_hostname("--short");

	# Current timestamp.
	$returnval .= " - ";
	$returnval .= strftime("%a %B %d, %Y %T %Z", localtime());
	$returnval .= "\\n";
	$returnval .= "\\n";



	return($returnval);
}




sub viewfiles
{
	my $filepattern = $_[0];
	my $sudo = $_[1];
	my $filter = $_[2];
	my @files = ();
	my $file = "";
	my $lasttype = "";
	my $command = "";


	if((! $filepattern) || ("$filepattern" eq "")) {
		return("");
	}


	if (($sudo) && ("$sudo" ne "")) {
		$sudo = "sudo ";
	} else {
		$sudo = "";
	}

	if(! $filter) {
		$filter = "";
	}


	if("$sudo" ne "") {
		open(FILELIST, "sudo /bin/ls -t $filepattern |");
	} else {
		open(FILELIST, "/bin/ls -t $filepattern |");
	}
	while(<FILELIST>) {
		chomp;
		push(@files, $_);
	}
	close(FILELIST);





	$command = "(/bin/true";
	$lasttype = "";
	foreach $file(@files) {

		if($file =~ /\.gz$/) {
			$command .= " ; $sudo /bin/zcat $file | tac";
		} else {
			$command .= " ; $sudo /usr/bin/tac $file";
		}
	}
	$command .= ") ";
	if($filter ne "") {
		$command .= " | $filter";
	}
	system("$command | less");

	# Return the command... without trailing "| less"
	# This allow our caller to re-run the command and, print results to a printer
	# (Especially useful for security logs.)
	return($command);
}


sub get_cups_version
{
	my $cups_version = "";

	open(PIPE, "rpm -qa |");
	while(<PIPE>) {
		chomp;
		if (/^cups-(\d)/) {
			$cups_version = $_;
			last;
		}
	}
	close(PIPE);

	return($cups_version);
}


sub get_script_version
{
	my $script_name = $_[0];
	my $version = "";
	my $cmd = "/d/daisy/bin/" . $script_name . ".pl --version";

	$version = qx($cmd);
	chomp($version);

	return($version);
}


sub get_linux_version
{
	my $linux_version = qx(cat /etc/redhat-release);

	chomp($linux_version);

	return($linux_version);
}


sub get_pos_version
{
	my $returnval = "";

	if (-d "$POSDIR/bbxd/RTI.ini") {
		open(FILE, "< $POSDIR/bbxd/RTI.ini");
		while(<FILE>) {
			chomp;
			if (/(VERSION)(\s*)(=)(\s*)([[:print:]]+)/) {
				$returnval = "RTI Version: $5";
				last;
			}
		}
		close(FILE);
	} elsif (-d "/d/daisy") {
		open (PIPE, "/d/daisy/bin/identify_daisy_distro.pl /d/daisy |");
		while(<PIPE>) {
			chomp;
			$returnval = "Daisy Version: " . (split(/\s+/))[3];
			last;
		}
		close(PIPE);
	}

	return($returnval);
}

# Get our hostname.
sub get_hostname
{
	my $hostname_type = $_[0];
	my $returnval = "";

	open(HOST, "/bin/hostname $hostname_type |");
	while(<HOST>) {
		chomp;
		if ($_ ne "") {
			$returnval = $_;
			last;
		}
	}
	close(HOST);

	return ($returnval);
}


#
# Sets global variable $OS to one of:
#	RH72
#	FC3
#	FC4
#	FC5
#	RHEL4
#	RHEL5

sub determine_os
{
	$OS = "";

	# We could also use /usr/bin/lsb-release
	open(FILE, "< /etc/redhat-release");
	while(<FILE>) {

		# Fedora Core 3
		if(/(Fedora)(\s+)(Core)(\s+)(release)(\s+)(3)/) {
			$OS = "FC3";
			last;
		}

		# Fedora Core 4
		if(/(Fedora)(\s+)(Core)(\s+)(release)(\s+)(4)/) {
			$OS = "FC4";
			last;
		}

		# Fedora Core 5
		if(/(Fedora)(\s+)(Core)(\s+)(release)(\s+)(5)/) {
			$OS = "FC5";
			last;
		}

		# ES 6
		# Redhat Enterprise Linux Server 6
		if( /(release)(\s+)(6)/ ) {
			$OS = "RHEL6";
			last;
		}

		# ES 5
		if( (/(release)(\s+)(5)/)
		||  (/(CentOS)([[:print:]]+)(\s)(5)/) ) {
			$OS = "RHEL5";
			last;
		}

		# EL 4
		if( (/(release)(\s+)(4)/) 
		||  (/(CentOS)([[:print:]]+)(\s)(4)/) ) {
			$OS = "RHEL4";
			last;
		}

		# Redhat 7.2
		if(/(release)(\s+)(7\.2)/) {
			$OS = "RH72";
			last;
		}
	}
	close(FILE);
}


sub set_signal_handlers
{
	my $handler = $_[0];

	$SIG{'STOP'} = $handler;
	$SIG{'TSTP'} = $handler;
	$SIG{'INT'} = $handler;
}


# trim whitespace from start and end of string
sub trim
{
	my $string = $_[0];

	$string =~ s/^\s+//;
	$string =~ s/\s+$//;

	return $string;
}
# trim leading whitespace
sub ltrim
{
	my $string = $_[0];

	$string =~ s/^\s+//;

        return $string;
}
# trim trailing whitespace
sub rtrim
{
        my $string = $_[0];

        $string =~ s/\s+$//;

        return $string;
}

sub system_exit_status
{
        my $exit_status = $_[0];
        my $strerror = "";

        if ($exit_status == -1) {
                $strerror = "system() failed to execute: $!";
        } elsif ($exit_status & 127) {
                my $signalnr = ($exit_status & 127);
                $strerror = "system() died from signal: $signalnr";
        } else {
                my $return_status = ($exit_status >> 8);
                if ($return_status) {
                        $strerror = "system() exited with value: $return_status";
                }
        }

        return $strerror;
}

#
# User presses enter to clear input of a screen.
#
sub wait_for_user
{
	my $temp = "";

	print("\nPress the Enter key to continue ...");
	$temp = <STDIN>;
	return(0);
}


# PCI 6.5.6
# "some string; `cat /etc/passwd`" -> "some string cat /etc/passwd"
# "`echo $ENV; $(sudo ls)`" -> "echo ENV sudo ls"
# etc.
sub validate_input
{
	my $var = $_[0];
	my $temp = "";

	if(! $var) {
		return "";
	}

	$temp = $var;

	# "`bad command`" -> "bad command"
	$temp =~ s/\`//g;

	# "$(bad command)" -> "bad command"
	$temp =~ s/(\$\()(.*.)(\))/$2/g;


	# "stuff ; bad command" -> "stuff bad command"
	$temp =~ s/\;//g;

	# "stuff && bad command" -> "stuff bad command"
	$temp =~ s/\&//g;

	# "stuff | bad command" -> "stuff bad command"
	$temp =~ s/\|//g;

	# "stuff > bad command" -> "stuff bad command"
	$temp =~ s/\>//g;

	# "stuff < bad command" -> "stuff bad command"
	$temp =~ s/\<//g;

	# Filter non printables
	$temp =~ s/[[:cntrl:]]//g;


	return($temp);
}


# 
# Is the current user an administrative user?
#
sub is_admin_user
{
	my $returnval = 0;
	my @array = ();


	# We can have a shll option if we are either tfsupport, or root.
	# In 12.6 systems, "tfsupport" and "root" are always memebers of rtiadmins, however,
	# in 12.5 systmes, such may not be the case.
	open(NAME, "/usr/bin/whoami |");
	while(<NAME>) {
		chomp;
		if(/^tfsupport$/) {
			$returnval = 1;
		} elsif(/^root$/) {
			$returnval = 1;
		}
	}
	close(NAME);
	if($returnval != 0) {
		return($returnval);
	}


	open(GROUPS, "groups |");
	while(<GROUPS>) {
		chomp;
		@array = split(/\s+/);
		if(grep(/^rtiadmins$/, @array)) {
			$returnval = 1;
		}
		if(grep(/^dsyadmins$/, @array)) {
			$returnval = 1;
		}
	}
	close(GROUPS);

	return($returnval);
}


#
# Send an event to syslog.
#
sub logevent
{
	my $event = $_[0];
	my $logger = "";
	my $user =  "";
	my $client = "";

	if(-f "/bin/logger") {
		$logger = "/bin/logger";
	} elsif(-f "/usr/bin/logger") {
		$logger = "/usr/bin/logger";
	} else {
		# Hope for the best.
		$logger = "logger";
	}

	if(defined $ENV{'USER'}) {
		$user = $ENV{'USER'};
	}
	if(defined $ENV{'SSH_CLIENT'}) {
		$client = $ENV{'SSH_CLIENT'};
	} else {
		open(TTY, "/usr/bin/tty |");
		while(<TTY>) {
			chomp;
			$client = $_;
			last;
		}
		close(TTY);
	}

	system("$logger \"(PID $$: $user\@$client) $event\"");
	print("$event\n");
}

#
# Get useful information such as groups and home directory
# about a given user.
sub get_userinfo
{
	my $username = $_[0];
	my $groupname = "";
	my $users = "";
	my @ent = ();
	my @groups = ();
	my %hash;
	my $found = 0;

	if($username eq "") {
		return %hash;
	}



	# Get user related info.
	setpwent();
	@ent = getpwent();
	while(@ent) {
		if( "$ent[0]" eq "$username") {
			$found = 1;
			$hash{"username"} = $username;
			$hash{"homedir"} = "$ent[7]";
			$hash{"shell"} = "$ent[8]";
			last;
		}
		@ent = getpwent();
	}
	endpwent();
 

	# We did  not find this user.
	if($found == 0) {
		return %hash;
	}


	# Get user's associated groups.
	# ($name,$passwd,$gid,$members) = getgr*
	$hash{"groups"} = ();
	@ent = getgrent();
	while(@ent) {
		$groupname = $ent[0];
		$users = $ent[3];
		if($users =~ /([[:space:]]*)($username)([[:space:]]{1}|$)/) {
			push @groups, $groupname;
		}
		@ent = getgrent();
	}
	endgrent();
	$hash{'groups'} = [ @groups ];
 

	return(%hash);
}

