From: Andrew DeFaria Date: Tue, 12 Jul 2022 15:55:58 +0000 (-0700) Subject: Added client work scripts X-Git-Url: https://defaria.com/gitweb/?a=commitdiff_plain;h=a8c84d2892f07a6863b68a11eb0a4a79ffd71fb5;p=clearscm.git Added client work scripts --- diff --git a/clients/Ameriquest/bin/PMO-CM.cmd b/clients/Ameriquest/bin/PMO-CM.cmd new file mode 100644 index 0000000..e106e07 --- /dev/null +++ b/clients/Ameriquest/bin/PMO-CM.cmd @@ -0,0 +1,13 @@ +@echo off +rem ------------------------------------------------------------------------- +rem - +rem - File: PMO-CM.cmd +rem - Description: This script is designed to be called when the user +rem - logs into his/her desktop. The purpose of this +rem - script is to do start up type things. Currently this +rem - means nothing but in the future we may add things. +rem - Author: Andrew@DeFaria.com +rem - Created: Mon Mar 27 14:00:00 PST 2004 +rem - Language: Dumb CMD stuff! :-( +rem - +rem ------------------------------------------------------------------------- diff --git a/clients/Ameriquest/bin/backup.pl b/clients/Ameriquest/bin/backup.pl new file mode 100644 index 0000000..0f98e98 --- /dev/null +++ b/clients/Ameriquest/bin/backup.pl @@ -0,0 +1,251 @@ +#!/usr/bin/perl +################################################################################# +# +# File: backup.pl +# Description: This script performs backups of vobs. By backup we mean that it +# will lock a vob then copy that vobs storage area to another area +# on disk then unlock the vob. +# Author: Andrew@DeFaria.com +# Created: June 23, 2004 +# Language: Perl +# Warnings: Since we use Windows commands like xcopy this script will only +# work under Windows. +# +# (c) Copyright 2004, Andrew@DeFaria.com, all rights reserved. +# +################################################################################ +use strict; +use warnings; + +my $me = $0; + +$me =~ s/\.\///; + +my $backup_loc = "d:\\backup"; +my $history_loc = "d:\\vobstore\\backup"; +my $from_loc = "d:\\"; +my $vob_server = "rtnlprod01"; +my $day_nbr = (localtime ()) [6]; # Day # of week. +my $total_size; + +# Options +my $verbose = "no"; + +sub Duration { + use integer; + + my $start_time = shift; + my $end_time = shift; + + my $hours; + my $minutes; + my $seconds = $end_time - $start_time; + + if ($seconds eq 0) { + return "less than a second"; + } elsif ($seconds eq 1) { + return "a second"; + } elsif ($seconds < 60) { + return "$seconds seconds"; + } elsif ($seconds < (60 * 60)) { + $minutes = $seconds / 60; + $seconds = $seconds % 60; + my $minutes_string = ($minutes eq 1) ? "minute" : "minutes"; + my $seconds_string = ($seconds eq 1) ? "second" : "seconds"; + return "$minutes $minutes_string $seconds $seconds_string"; + } else { + $hours = $seconds / (60 * 60); + $seconds = $seconds % (60 * 60); + $minutes = $seconds / 60; + $seconds = $seconds % 60; + my $hours_string = ($hours eq 1) ? "hour" : "hours"; + my $minutes_string = ($minutes eq 1) ? "minute" : "minutes"; + my $seconds_string = ($seconds eq 1) ? "second" : "seconds"; + return "$hours $hours_string $minutes $minutes_string $seconds $seconds_string"; + } # fi +} # Duration + +sub Usage { + print "Usage $me: [-v]"; + print "\nWhere:\n"; + print "\t-v\tVerbose\n"; + exit 1; +} # Usage + +sub verbose { + my $msg = shift; + + print "$msg\n" if $verbose eq "yes"; +} # verbose + +sub warning { + my $msg = shift; + + print "$me: WARNING: $msg\n"; +} # warning + +sub error { + my $msg = shift; + my $errno = shift; + + print "$me: ERROR "; + print "# $errno: " if defined $errno; + print "$msg\n"; + + exit $errno if defined $errno; +} # error + +sub VobSize { + my $vob = shift; + + my $size = 0; + my $cleartext = 0; + my @space = `cleartool space $vob 2> NUL`; + + foreach (@space) { + if (/Subtotal $/) { + ($size) = split; + } # if + if (/cleartext/) { + ($cleartext) = split; + } # if + } # foreach + + return $size - $cleartext; +} # VobSize + +sub LockVobs { + my @vobs = @_; + + my $status = 0; + + foreach (@vobs) { + chomp; + my $return_code = system "cleartool lock vob:$_ > NUL 2>&1"; + warning "Unable to lock vob $_" if $return_code ne 0; + $status += $return_code; + } # foreach + + return $status; +} # LockVobs + +sub UnlockVobs { + my @vobs = @_; + + my $status = 0; + + foreach (@vobs) { + my $return_code = system "cleartool unlock vob:$_ > NUL 2>&1"; + warning "Unable to unlock vob $_" if $return_code ne 0; + $status += $return_code; + } # foreach + + return $status; +} # UnlockVobs + +sub MoveOldStorage { + my $vob_storage_basename = shift; + + my $storage = "$backup_loc\\$vob_storage_basename"; + my $old_storage_loc = "$history_loc\\$day_nbr\\$vob_storage_basename"; + my @output; + + if (-e $old_storage_loc) { + @output = `rmdir /s /q $old_storage_loc`; + + if ($? ne 0) { + error "Error in removing old storage area $old_storage_loc"; + error (join "\n", @output); + } else { + verbose "Removed old storage area $old_storage_loc"; + } # if + } # if + + @output = `move $storage $old_storage_loc`; + + if ($? ne 0) { + error "Error in moving storage area $storage to $old_storage_loc"; + error (join "\n", @output); + } else { + verbose "Moved old storage $storage to $old_storage_loc"; + } # if +} # MoveOldStorage + +sub CopyStorage { + my $vob = shift; + my $from = shift; + my $vob_storage_basename = shift; + + my $to = "$backup_loc\\$vob_storage_basename"; + my $size = VobSize $vob; + + $total_size += $size; + verbose "Copying $vob ($size meg) from $from -> $to"; + + my $start_time = time; + + MoveOldStorage $vob_storage_basename if -e $to; + + # Copy storage but exclude any file containing strings found in the + # d:\backup\exclude.strings file See + # http://www-1.ibm.com/support/docview.wss?rs=0&q1=being-deleted&uid=swg21129318&loc=en_US&cs=utf-8&cc=us&lang=en + # for more info. + my @output = `xcopy $from $to /q /e /i /h /k /x /exclude:d:\\backup\\exclude.strings`; + + my $end_time = time; + + if ($? ne 0) { + print "Error in copy of vob $vob\n"; + print @output; + } else { + verbose "Copying of $vob ($size meg) took " . Duration $start_time, $end_time; + } # if +} # CopyStorage + +# Get parms +while ($#ARGV >= 0) { + if ($ARGV [0] eq "-v") { + $verbose = "yes"; + shift; + next; + } # if + + if ($ARGV [0] ne "") { + error "Unknown option: \"" . $ARGV [0] . "\"\n"; + Usage; + } # if +} # while + +# Iterrate through the list of vobs +my $start_time = time; + +my @vobs = `cleartool lsvob -short -host $vob_server 2> NUL`; + +warning "Unable to lock all vobs" if (LockVobs @vobs) ne 0; + +foreach (@vobs) { + chomp; + my $line = `cleartool lsvob $_ 2> NUL`; + chomp $line; + $line =~ s/\//\\/g; + + my $storage; + + if ($line =~ m/(\\\\\S*)/) { + $storage = $1; + } # if + + $storage =~ s/\\\\$vob_server\\/$from_loc/; + + my $vob_storage_basename = substr ($storage, rindex ($storage, "\\") + 1); + + CopyStorage $_, $storage, $vob_storage_basename; +} # foreach + +warning "Unable to unlock all vobs" if (UnlockVobs @vobs) ne 0; + +my $end_time = time; + +verbose "Total of $total_size meg copied in: " . Duration $start_time, $end_time; +# All done... +exit 0; diff --git a/clients/Ameriquest/bin/ccase_lock_vobs.bat b/clients/Ameriquest/bin/ccase_lock_vobs.bat new file mode 100644 index 0000000..d413e8c --- /dev/null +++ b/clients/Ameriquest/bin/ccase_lock_vobs.bat @@ -0,0 +1,9 @@ +@echo off + +set view_server=rtnlprod02 +set view_share=viewstore +set view=PMO +set vob=CM_TOOLS +set bin_path=\\%view_server%\%view_share%\%view%\%vob%\bin + +"%CLEARCASEHOME%\bin\ccperl.exe" "%bin_path%\lockvobs.pl" diff --git a/clients/Ameriquest/bin/ccase_unlock_vobs.bat b/clients/Ameriquest/bin/ccase_unlock_vobs.bat new file mode 100644 index 0000000..f140ed5 --- /dev/null +++ b/clients/Ameriquest/bin/ccase_unlock_vobs.bat @@ -0,0 +1,9 @@ +@echo off + +set view_server=rtnlprod02 +set view_share=viewstore +set view=PMO +set vob=CM_TOOLS +set bin_path=\\%view_server%\%view_share%\%view%\%vob%\bin + +"%CLEARCASEHOME%\bin\ccperl.exe" "%bin_path%\lockvobs.pl" -u diff --git a/clients/Ameriquest/bin/ccverify.pl b/clients/Ameriquest/bin/ccverify.pl new file mode 100644 index 0000000..52b39fa --- /dev/null +++ b/clients/Ameriquest/bin/ccverify.pl @@ -0,0 +1,152 @@ +#!/usr/bin/perl -w +################################################################################# +# +# File: ccverify.pl +# Description: Verify that Rational Clearcase was installed correctly +# Author: Andrew@DeFaria.com +# Created: Mon Mar 15 08:48:24 PST 2004 +# Language: None +# +# (c) Copyright 2004, Andrew@DeFaria.com, all rights reserved. +# +################################################################################ +use strict; + +my $ccverify = "1.0"; +my $logpath = "\\\\rtnlprod02\\viewstore\\PMO\\CM_TOOLS\\log"; +my $hostname = `hostname`; chomp $hostname; +my $logfile = "$logpath\\$hostname.log"; +my $status = 0; +my $tag = "ccverify"; + +open LOGFILE, ">>$logfile" + or die "Unable to open logfile: $logfile - $!\n"; + +sub logmsg { + my $message = shift; + + print "$message\n"; + print LOGFILE "$message\n"; +} # logmsg + +sub mktag { + my $tag = shift; + + my $status = system "cleartool lsvob \\$tag > NUL 2>&1"; + + if ($status ne 0) { + return system "cleartool mktag -vob -tag \\$tag \\\\rtnlprod01\\vobstore\\$tag.vbs > NUL 2>&1"; + } # if +} # mktag + +sub rmtag { + my $tag = shift; + + return system "cleartool rmtag -vob \\$tag > NUL 2>&1"; +} # rmtag + +sub rmview { + my $tag = shift; + + return system "cleartool rmview -force -tag $tag > NUL 2>&1"; +} # rmview + +sub mkview { + my $tag = shift; + + my $status = system "cleartool lsview -short $tag > NUL 2>&1"; + + if ($status ne 0) { + return system "cleartool mkview -tag $tag -stgloc -auto > NUL 2>&1"; + } else { + rmview $tag; + return system "cleartool mkview -tag $tag -stgloc -auto > NUL 2>&1"; + } # if +} # mkview + +sub mount_vob { + my $tag = shift; + + mktag $tag; + + return system "cleartool mount \\$tag > NUL 2>&1"; +} # mount_vob + +sub umount_vob { + my $tag = shift; + + my $status = system "cleartool umount \\$tag > NUL 2>&1"; + + rmtag $tag; + + return $status; +} # umount_vob + +my $version = `cleartool -ver`; +my $primary_group = $ENV {CLEARCASE_PRIMARY_GROUP}; + +my @hostinfo = `cleartool hostinfo -long`; +my $region = "Not Set"; + +foreach (@hostinfo) { + chomp; + if (/\s*Registry region:\s*(\S*)/) { + $region = $1; + last; + } # if +} # foreach + +logmsg "CCVerify Version $ccverify"; +logmsg "Verifying Clearcase installation on $hostname (" . scalar (localtime) . ")\n"; +logmsg "Clearcase Version Information\n"; +logmsg "$version\n"; + +if (!defined $primary_group) { + $primary_group = ""; + $status++; +} # if + +logmsg "Clearcase Primary Group:\t$primary_group"; +logmsg "Clearcase Region:\t\t$region\n"; + +if (mkview ($tag) eq 0) { + logmsg "Created a dynamic view named $tag"; +} else { + $status++; + logmsg "Unable to create the $tag dynamic view!"; +} # if + +if (mount_vob ($tag) eq 0) { + logmsg "Mounted the vob \\$tag"; +} else { + $status++; + logmsg "Unable to mount the vob \\$tag"; +} # if + +if (umount_vob ($tag) eq 0) { + logmsg "Unmounted the vob \\$tag"; +} else { + $status++; + logmsg "Unable to unmount vob \\$tag"; +} # if + +if (rmview ($tag) eq 0) { + logmsg "Removed view $tag"; +} else { + $status++; + logmsg "Unable to remove view $tag"; +} # if + +if ($status eq 0) { + logmsg +"\n-------------------------------------------- +Clearcase installed and functioning properly +--------------------------------------------\n"; +} else { + logmsg +"\n------------------------------------------------ +Clearcase NOT installed and functioning properly +------------------------------------------------\n"; +} # if + +exit $status; diff --git a/clients/Ameriquest/bin/cmverify.cmd b/clients/Ameriquest/bin/cmverify.cmd new file mode 100644 index 0000000..12516f7 --- /dev/null +++ b/clients/Ameriquest/bin/cmverify.cmd @@ -0,0 +1,53 @@ +@echo off +rem ------------------------------------------------------------------------- +rem - +rem - File: verify.cmd +rem - Description: This command verifies the installation of Rational +rem - tools. +rem - Author: Andrew@DeFaria.com +rem - Created: Mon Mar 28 14:52:00 PST 2004 +rem - Language: Dumb CMD stuff! :-( +rem - Parameters: There is only one parameter that is taken and that is +rem - the number of seconds that cqverify should wait +rem - before starting. This is only needed if this cmvery +rem - command is run from the various install scripts. +rem - +rem ------------------------------------------------------------------------- +set ccperl=C:\Program Files\Rational\Clearcase\bin\ccperl.exe +set cqperl=C:\Program Files\Rational\Common\cqperl.exe +set ccverify=\\rtnlprod02\viewstore\PMO\CM_TOOLS\bin\ccverify.pl +set cqverify=\\rtnlprod02\viewstore\PMO\CM_TOOLS\bin\cqverify.pl +set wait=\\rtnlprod02\viewstore\PMO\CM_TOOLS\bin\wait.pl +set logfile=\\rtnlprod02\viewstore\PMO\CM_TOOLS\log\%COMPUTERNAME%.log + +rem Clear out logfile +if exist %logfile% del /q /f %logfile% + +rem Check for necessary tools +set msg= +if not exist "%ccperl%" set msg=Clearcase is not installed +if not exist "%ccverify%" set msg=Unable to find ccverify script (%ccverify%)! + +if not "%msg%" == "" goto Error + +rem Since we found ccperl assume that the installation was done so now +rem we'll check the configuration +"%ccperl%" %ccverify% + +rem Wait for Clearquest/TUP install to finish +if not "%1" == "" echo Waitng for Clearquest/TUP installation to finish&& "%ccperl%" %wait% %1 + +rem Now check cq +if not exist "%cqperl%" set msg=Clearquest/TUP is not installed +if not exist "%cqverify%" set msg=Unable to find cqverify script (%cqverify%)! + +if not "%msg%" == "" goto Error + +"%cqperl%" %cqverify% +goto EXIT + +:Error +echo %msg% +echo %msg% >> %logfile% + +:EXIT \ No newline at end of file diff --git a/clients/Ameriquest/bin/cqverify.pl b/clients/Ameriquest/bin/cqverify.pl new file mode 100644 index 0000000..6bb97f0 --- /dev/null +++ b/clients/Ameriquest/bin/cqverify.pl @@ -0,0 +1,74 @@ +#!/usr/bin/perl -w +################################################################################# +# +# File: cqverify.pl +# Description: Verify that Rational Clearquest was installed correctly +# Author: Andrew@DeFaria.com +# Created: Mon Mar 15 08:48:24 PST 2004 +# Language: Perl +# +################################################################################ +use strict; +use CQPerlExt; + +my $cqverify = "1.0"; +my $logpath = "\\\\rtnlprod02\\viewstore\\PMO\\CM_TOOLS\\log"; +my $hostname = `hostname`; chomp $hostname; +my $logfile = "$logpath\\$hostname.log"; +my $status = 0; + +open LOGFILE, ">>$logfile" + or die "Unable to open logfile: $logfile - $!\n"; + +sub logmsg { + my $message = shift; + + print "$message\n"; + print LOGFILE "$message\n"; +} # logmsg + +# Log in to CQ as guest +logmsg "CQVerify Version $cqverify"; +logmsg "Verifying Clearquest/TUP installation on $hostname (" . scalar (localtime) . ")"; + +my $CQsession = CQPerlExt::CQSession_Build () + or logmsg "Unable to establish CQSession", die; + +my ($queryDef, $resultSet, $result); +eval { + $CQsession->UserLogon ("guest", "guest", "AMQST", "AMQST"); + # Construct a CQ query that will return the ID of the first CQ record + $queryDef = $CQsession->BuildQuery ("defect"); + $queryDef->BuildField ("id"); + $resultSet = $CQsession->BuildResultSet ($queryDef); + $resultSet->Execute; + $resultSet->GetNumberOfColumns; + $status = $resultSet->MoveNext; + $result = $resultSet->GetColumnValue ("1"); + CQSession::Unbuild ($CQsession); +}; + +if ($@) { + logmsg $@; + logmsg +"----------------------------------------------------- +Clearquest/TUP NOT installed and functioning properly +-----------------------------------------------------"; + exit 1; +} else { + if ($result =~ m/^AMQST/) { + logmsg "Clearquest query succeeded"; + logmsg +"------------------------------------------------- +Clearquest/TUP installed and functioning properly +-------------------------------------------------"; + exit 0; + } else { + logmsg "Value returned not was not expected: $result"; + logmsg +"----------------------------------------------------- +Clearquest/TUP NOT installed and functioning properly +-----------------------------------------------------"; + exit 1; + } # if +} # if diff --git a/clients/Ameriquest/bin/getccgroups.vbs b/clients/Ameriquest/bin/getccgroups.vbs new file mode 100644 index 0000000..46da523 --- /dev/null +++ b/clients/Ameriquest/bin/getccgroups.vbs @@ -0,0 +1,215 @@ +On Error Resume Next + +Set WshShell = WScript.CreateObject ("WScript.Shell") +Set fso = CreateObject ("Scripting.FileSystemObject") + +groups_file = "\\rtnlprod02\viewstore\PMO\CM_TOOLS\etc\groups.dat" + +' Simple routine to shorten WScript.Echo! +Sub echo (msg) + WScript.Echo msg +End Sub ' echo + +Sub Email_Owner (sendTo, groupname, members) + sch = "http://schemas.microsoft.com/cdo/configuration/" + + Set cdoConfig = CreateObject ("CDO.Configuration") + + With cdoConfig.Fields + .Item (sch & "sendusing") = 2 ' cdoSendUsingPort + .Item (sch & "smtpserver") = "appsmtp.ameriquest.net" + .Update + End With + + Set email_msg = CreateObject ("CDO.Message") + + email_msg.Configuration = cdoConfig + email_msg.From = "PMO-CM@Ameriquest.net" + email_msg.To = sendTo + email_msg.Subject = "Members of the " & UCase (groupname) & " Group" + email_msg.HTMLBody = "

Members of the " & UCase (groupname) & " Group

 

    " + + previous_member = "" + For Each member in members + If member <> previous_member Then + email_msg.HTMLBody = email_msg.HTMLBody & "
  1. " & member & "
  2. " + previous_member = member + End If + Next + + email_msg.HTMLBody = email_msg.HTMLBody & "
" + email_msg.Send +End Sub + +' Routine to push things onto an array +Sub pushArray (a, e) + On Error Resume Next + size = UBound (a) + + If Err.Number <> 0 Then + size = 0 + Else + size = size + 1 + End If + + ReDim preserve a (size) + + a (UBound (a)) = e +End Sub 'pushArray + +' The famous QuickSort! +Sub QuickSort (vec, loBound, hiBound) + Dim pivot + Dim loSwap + Dim hiSwap + Dim temp + + ' This procedure is adapted from the algorithm given in: + ' Data Abstractions & Structures using C++ by + ' Mark Headington and David Riley, pg. 586 + ' Quicksort is the fastest array sorting routine for + ' unordered arrays. Its big O is n log n + + ' Two items to sort + If hiBound - loBound = 1 Then + If vec(loBound) > vec(hiBound) Then + temp = vec (loBound) + vec (loBound) = vec (hiBound) + vec (hiBound) = temp + End If + End If + + ' Three or more items to sort + pivot = vec (Int ((loBound + hiBound) / 2)) + vec (Int ((loBound + hiBound) / 2)) = vec (loBound) + vec (loBound) = pivot + loSwap = loBound + 1 + hiSwap = hiBound + + Do + ' Find the right loSwap + While loSwap < hiSwap and vec (loSwap) <= pivot + loSwap = loSwap + 1 + Wend + + ' Find the right hiSwap + While vec (hiSwap) > pivot + hiSwap = hiSwap - 1 + Wend + + ' Swap values if loSwap is less then hiSwap + If loSwap < hiSwap Then + temp = vec (loSwap) + vec (loSwap) = vec (hiSwap) + vec (hiSwap) = temp + End If + Loop While loSwap < hiSwap + + vec (loBound) = vec(hiSwap) + vec (hiSwap) = pivot + + ' Recursively call function .. the beauty of Quicksort + ' 2 or more items in first section + If loBound < (hiSwap - 1) Then + QuickSort vec, loBound, hiSwap - 1 + End If + + ' 2 or more items in second section + If hiSwap + 1 < hibound Then + QuickSort vec, hiSwap+1, hiBound + End If +End Sub ' QuickSort + +' Get the group members out of Active Directory and push them +' onto the grp_mbrs array +Sub DumpGroup (groupname) + ' Create an LDAP object and set up the search for groupname + On Error Resume Next + Err.Clear + Set LDAPGroups = GetObject ( _ + "LDAP://cn=" & _ + groupname & _ + ",ou=apps,ou=Groups,ou=Corp,dc=ameriquest,dc=net" _ + ) + + If Err.Number <> 0 Then + Err.Clear + echo "Warning: " & UCase (groupname) & " is empty!" + Exit Sub + End If + + LDAPGroups.GetInfo + + ' Get an array of members + members = LDAPGroups.GetEx ("member") + + ' For each member get their displayName and push it onto the array + For Each member in members + Set user = GetObject ("LDAP://"& member) + LDAPGroups.filter = array ("user") + user.GetInfo + + ' Kludgy way to check to see if this is a group: We attempt + ' to get groupType which should only be in a group type + ' record. If this fails then process the member as an + ' individual member, otherwise recurse to process the + ' group within the group... + Err.Clear + user.Get ("groupType") + + if Err.Number = 0 Then + Err.Clear + groupname = LCase (user.Get ("cn")) + DumpGroup (groupname) + Else + name = user.Get ("displayName") + pushArray grp_mbrs, name + End If + Next +End Sub + +' Open the groups definition file +Set groups = fso.OpenTextFile (groups_file) + +Do While Not groups.AtEndOfStream + line = groups.ReadLine + + ' *** Need to also skip blank lines + If Line <> "" Then + If InStr (line, "#") <> 1 Then + With New RegExp + .Pattern = "\s+" + .Global = True + line = Trim (.replace (line, " ")) + End With + + ' Split out fields + groupname = "" + owner = "" + fields = Split (line) + groupname = LCase (fields (0)) + owner = LCase (fields (1)) + + echo "Processing group " & UCase (groupname) & " (" & owner & ")" + + Dim grp_mbrs () + + ' Get members of this group + DumpGroup (groupname) + + If UBound (grp_mbrs) > 0 Then + ' Sort them + QuickSort grp_mbrs, LBound (grp_mbrs), UBound (grp_mbrs) + + ' Output them + If owner <> "" Then + Email_Owner owner, groupname, grp_mbrs + Else + echo "Group: " & UCase (groupname) & " has no owner email in " & groups_file + End If + + Erase grp_mbrs + End If + End If + End If +Loop diff --git a/clients/Ameriquest/bin/tagit.pl b/clients/Ameriquest/bin/tagit.pl new file mode 100644 index 0000000..9696b94 --- /dev/null +++ b/clients/Ameriquest/bin/tagit.pl @@ -0,0 +1,183 @@ +#!/usr/bin/perl -w +################################################################################# +# +# File: tagit +# Description: Script to tag views or vobs into the current region. The main +# motivation for this script is to be able to tag things quickly +# and easily. As such we employ heuristics to find these objects. +# Author: Andrew@DeFaria.com +# Created: Fri Apr 9 12:19:04 PDT 2004 +# Language: Perl +# +# (c) Copyright 2004, Andrew@DeFaria.com, all rights reserved. +# +################################################################################ +use strict; +use File::Spec; + +my $me; + +BEGIN { + # Extract relative path and basename from script name. + $0 =~ /.*[\/\\](.*)/; + $me = (!defined $1) ? $0 : $1; +} # BEGIN + +# Check to see if we are running on Windows +my $windows = ($^O =~ /MSWin/) ? "yes" : "no"; +my $null = $windows eq "yes" ? "NUL" : "/dev/null"; +my $backslashes = $windows eq "yes" ? "\\" : "\\\\"; + +sub Usage { + print "Usage $me: [[ -view ] ] [ -vob ]\n"; + print "\nWhere:\n"; + print "\t-view\tView tag to tag in current region\n"; + print "\t-vob\tVob tag to tag in current region\n"; + exit 1; +} # Usage + +sub GetCurrentRegion { + my @lines = `cleartool hostinfo -l`; + + foreach (@lines) { + chomp; chop $_ if /\r/; + + if (/Registry region: (\S+)/) { + return $1; + } # if + } # foreach + + return undef; +} # GetCurrentRegion + +my $current_region = GetCurrentRegion; +my @regions = `cleartool lsregion`; + +sub FindView { + my $view_tag = shift; + + foreach (@regions) { + chomp; chop if /\r/; + + my $output = `cleartool lsview -region $_ $view_tag 2> $null`; + chomp $output; chop $output if /\r/; + + if ($output =~ /$view_tag\s*(.*)/) { + my $view_storage = $1; + $view_storage =~ tr /\\/\/\//; + return ($view_storage, $_); + } # if + } # foreach + + return; +} # FindView + +sub FindVob { + my $vob_tag = shift; + + foreach (@regions) { + chomp; chop if /\r/; + + my $output = `cleartool lsvob -region $_ $backslashes$vob_tag 2> $null`; + chomp $output; chop $output if /\r/; + + if ($output =~ /$vob_tag\s*(\S*)/) { + my $vob_storage = $1; + $vob_storage =~ tr /\\/\/\//; + return ($vob_storage, $_); + } # if + } # foreach + + return; +} # FindVob + +sub MkViewTag { + my $view_tag = shift; + my $view_storage = shift; + + # Check to see if view tag already exists + if (!system "cleartool lsview $view_tag > $null 2>&1") { + print "$view_tag already exists in $current_region\n"; + return 0; + } else { + if (system "cleartool mktag -view -tag $view_tag $view_storage") { + die "Unable to make view tag: $view_tag in $current_region\n"; + } # if + return 1; + } # if +} # MkViewTag + +sub MkVobTag { + my $vob_tag = shift; + my $vob_storage = shift; + + # Check to see if vob tag already exists + if (!system "cleartool lsvob $backslashes$vob_tag > $null 2>&1") { + print "$vob_tag already exists in $current_region\n"; + return 1; + } else { + print "cleartool mktag -vob -tag $backslashes$vob_tag $vob_storage\n"; + if (system "cleartool mktag -vob -tag $backslashes$vob_tag $vob_storage") { + die "Unable to make vob tag: $vob_tag in $current_region\n"; + } # if + return 0; + } # if +} # MkVobTag + +my $view_tag; +my $vob_tag; + +# Get parms +while ($#ARGV >= 0) { + if ($ARGV [0] eq "-u" or $ARGV [0] eq "-usage") { + Usage; + } # if + + if ($ARGV [0] eq "-vob") { + shift; + $vob_tag = $ARGV [0]; + # Script all backslashes - we'll re-add them when needed... + $vob_tag =~ s/\\//; + shift; + next; + } # if + + if ($ARGV [0] eq "-view") { + shift; + $view_tag = $ARGV [0]; + next; + } # if +} # while + +if (!(defined $view_tag or defined $vob_tag)) { + Usage "Must specify a view or a vob to tag!"; +} # if + +if (defined $view_tag) { + my ($view_storage, $view_region) = FindView $view_tag; + + die "Unable to find view $view_tag in any region!\n" if !defined $view_region; + die "Unable to find storage area for $view_tag\n" if !defined $view_storage; + + if ($view_region eq $current_region) { + print "$view_tag already exists in $current_region\n"; + } else { + print "$view_tag, from $view_region region, added to $current_region region\n" if MkViewTag $view_tag, $view_storage;; + } # if +} # if + +if (defined $vob_tag) { + my ($vob_storage, $vob_region) = FindVob $vob_tag; + + die "Unable to find vob $vob_tag in any region!\n" if !defined $vob_region; + die "Unable to find storage area for $vob_tag\n" if !defined $vob_storage; + + if ($vob_region eq $current_region) { + print "$vob_tag already exists in $current_region\n"; + } else { + print "$vob_tag, from $vob_region, added to $current_region region\n" if MkVobTag $vob_tag, $vob_storage;; + } # if +} # if + +exit 0; + diff --git a/clients/Ameriquest/bin/vobsize.pl b/clients/Ameriquest/bin/vobsize.pl new file mode 100644 index 0000000..8574565 --- /dev/null +++ b/clients/Ameriquest/bin/vobsize.pl @@ -0,0 +1,72 @@ +#!/usr/bin/perl +use strict; +use warnings; + +my $windows = $^O =~ /MSWin/ ? "yes" : "no"; +my $vob_server = "rtnlprod01"; + +sub VobSize { + my $vob = shift; + + my @space; + + if ($windows eq "yes") { + @space = `cleartool space $vob 2>&1`; + } else { + @space = `cleartool space \\$vob 2>&1`; + } # if + + foreach (@space) { + chomp; chop if /\r/; + if (/Subtotal $/) { + my ($size) = split; + return $size; + } # if + } # foreach + + return 0; +} # VobSize + +my ( + $vob, + $size, + $count, + $total_size +); + +format STDOUT_TOP = + Nbr VOB Size +---- ----------------------- ----------- +. +format STDOUT = +@>>) @<<<<<<<<<<<<<<<<<<<<<< @>>>>>> Meg +$count,$vob,$size +. + +format TOTAL_TOP = +---- ----------------------- ----------- +. + +format TOTAL_LINE = +Total vob size: @>>>>>> Meg +$total_size +. + +my @vobs = `cleartool lsvob -short -host $vob_server`; + +foreach $vob (sort (@vobs)) { + $count++; + chomp $vob; chop $vob if $vob =~ /\r/; + + $size = VobSize $vob; + + $total_size += $size; + + write; $- = 1; +} # foreach + +$~ = "TOTAL_TOP"; +write; $- = 1; + +$~ = "TOTAL_LINE"; +write; $- = 1; diff --git a/clients/Ameriquest/bin/whosin.cmd b/clients/Ameriquest/bin/whosin.cmd new file mode 100644 index 0000000..c15be66 --- /dev/null +++ b/clients/Ameriquest/bin/whosin.cmd @@ -0,0 +1,3 @@ +@echo off +set CM_TOOLS=\\rtnlprod02\viewstore\PMO\CM_TOOLS +cscript /nologo "%CM_TOOLS%\bin\whosin.vbs" %* \ No newline at end of file diff --git a/clients/Ameriquest/bin/whosin.vbs b/clients/Ameriquest/bin/whosin.vbs new file mode 100644 index 0000000..5f836f6 --- /dev/null +++ b/clients/Ameriquest/bin/whosin.vbs @@ -0,0 +1,169 @@ +On Error Resume Next + +Set WshShell = WScript.CreateObject ("WScript.Shell") +Set fso = CreateObject ("Scripting.FileSystemObject") + +' Argument vector +Set ARGV = Wscript.Arguments + +' Simple routine to shorten WScript.Echo! +Sub echo (msg) + WScript.Echo msg +End Sub ' echo + +Sub Display_Members (sendTo, groupname, members) + echo "Members of the " & UCase (groupname) & " Group" + + previous_member = "" + For Each member in members + If member <> previous_member Then + echo vbTAB & member + previous_member = member + End If + Next +End Sub + +' Routine to push things onto an array +Sub pushArray (a, e) + On Error Resume Next + size = UBound (a) + + If Err.Number <> 0 Then + size = 0 + Else + size = size + 1 + End If + + ReDim preserve a (size) + + a (UBound (a)) = e +End Sub 'pushArray + +' The famous QuickSort! +Sub QuickSort (vec, loBound, hiBound) + Dim pivot + Dim loSwap + Dim hiSwap + Dim temp + + ' This procedure is adapted from the algorithm given in: + ' Data Abstractions & Structures using C++ by + ' Mark Headington and David Riley, pg. 586 + ' Quicksort is the fastest array sorting routine for + ' unordered arrays. Its big O is n log n + + ' Two items to sort + If hiBound - loBound = 1 Then + If vec(loBound) > vec(hiBound) Then + temp = vec (loBound) + vec (loBound) = vec (hiBound) + vec (hiBound) = temp + End If + End If + + ' Three or more items to sort + pivot = vec (Int ((loBound + hiBound) / 2)) + vec (Int ((loBound + hiBound) / 2)) = vec (loBound) + vec (loBound) = pivot + loSwap = loBound + 1 + hiSwap = hiBound + + Do + ' Find the right loSwap + While loSwap < hiSwap and vec (loSwap) <= pivot + loSwap = loSwap + 1 + Wend + + ' Find the right hiSwap + While vec (hiSwap) > pivot + hiSwap = hiSwap - 1 + Wend + + ' Swap values if loSwap is less then hiSwap + If loSwap < hiSwap Then + temp = vec (loSwap) + vec (loSwap) = vec (hiSwap) + vec (hiSwap) = temp + End If + Loop While loSwap < hiSwap + + vec (loBound) = vec(hiSwap) + vec (hiSwap) = pivot + + ' Recursively call function .. the beauty of Quicksort + ' 2 or more items in first section + If loBound < (hiSwap - 1) Then + QuickSort vec, loBound, hiSwap - 1 + End If + + ' 2 or more items in second section + If hiSwap + 1 < hibound Then + QuickSort vec, hiSwap+1, hiBound + End If +End Sub ' QuickSort + +' Get the group members out of Active Directory and push them +' onto the grp_mbrs array +Sub DumpGroup (groupname) + ' Create an LDAP object and set up the search for groupname + On Error Resume Next + Err.Clear + Set LDAPGroups = GetObject ( _ + "LDAP://cn=" & _ + groupname & _ + ",ou=apps,ou=Groups,ou=Corp,dc=ameriquest,dc=net" _ + ) + + If Err.Number <> 0 Then + Err.Clear + echo "Warning: " & UCase (groupname) & " is empty!" + Exit Sub + End If + + LDAPGroups.GetInfo + + ' Get an array of members + members = LDAPGroups.GetEx ("member") + + ' For each member get their displayName and push it onto the array + For Each member in members + Set user = GetObject ("LDAP://"& member) + LDAPGroups.filter = array ("user") + user.GetInfo + + ' Kludgy way to check to see if this is a group: We attempt + ' to get groupType which should only be in a group type + ' record. If this fails then process the member as an + ' individual member, otherwise recurse to process the + ' group within the group... + Err.Clear + user.Get ("groupType") + + if Err.Number = 0 Then + Err.Clear + groupname = LCase (user.Get ("cn")) + DumpGroup (groupname) + Else + name = user.Get ("displayName") + pushArray grp_mbrs, name + End If + Next +End Sub + +For Each ARG in ARGV + Dim grp_mbrs () + + ' Get members of this group + DumpGroup (ARG) + + If UBound (grp_mbrs) > 0 Then + ' Sort them + QuickSort grp_mbrs, LBound (grp_mbrs), UBound (grp_mbrs) + + ' Output them + Display_Members owner, ARG, grp_mbrs + + Erase grp_mbrs + echo + End If +Next \ No newline at end of file diff --git a/clients/Ameriquest/triggers/ASAPNotify.msg b/clients/Ameriquest/triggers/ASAPNotify.msg new file mode 100644 index 0000000..882ebb4 --- /dev/null +++ b/clients/Ameriquest/triggers/ASAPNotify.msg @@ -0,0 +1,16 @@ +From: ASAP Adm +To: GSaha@Ameriquest.com, RRao@Amerquest.com +Subject: $CLEARCASE_OP_KIND: $CLEARCASE_PN +-- +This is a notification that a $CLEARCASE_OP_KIND has occurred: + +Element: $CLEARCASE_PN +Branch: $CLEARCASE_BRTYPE +Operation: $CLEARCASE_OP_KIND +User: $CLEARCASE_USER +View: $CLEARCASE_VIEW_TAG +Comments: + +$CLEARCASE_COMMENT + +For information about recent activity see http://asapcm.ameriquest.net/logs diff --git a/clients/Ameriquest/triggers/ASAP_BUS_REQ_Notify.msg b/clients/Ameriquest/triggers/ASAP_BUS_REQ_Notify.msg new file mode 100644 index 0000000..1f80c95 --- /dev/null +++ b/clients/Ameriquest/triggers/ASAP_BUS_REQ_Notify.msg @@ -0,0 +1,16 @@ +From: ASAP Adm +To: MMonterrey@Ameriquest.com, GSaha@Ameriquest.com, RRao@Amerquest.com, abhijit.bhide@tavant.com +Subject: $CLEARCASE_OP_KIND: $CLEARCASE_PN +-- +This is a notification that a $CLEARCASE_OP_KIND has occurred: + +Element: $CLEARCASE_PN +Branch: $CLEARCASE_BRTYPE +Operation: $CLEARCASE_OP_KIND +User: $CLEARCASE_USER +View: $CLEARCASE_VIEW_TAG +Comments: + +$CLEARCASE_COMMENT + +For information about recent activity see http://asapcm.ameriquest.net/logs diff --git a/clients/Ameriquest/triggers/AddExecute.pl b/clients/Ameriquest/triggers/AddExecute.pl new file mode 100644 index 0000000..5037675 --- /dev/null +++ b/clients/Ameriquest/triggers/AddExecute.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +################################################################################ +# +# File: AddExecute.pl +# Description: This trigger script simply adds execute permission to an element +# when it is created in Clearcase +# Trigger Type: All element +# Operation: Postop mkelem +# Author: Andrew@DeFaria.com +# Created: Fri Mar 12 10:17:44 PST 2004 +# Language: Perl +# Modifications: +# +# (c) Copyright 2004, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +use strict; +use warnings; + +my $element = $ENV{CLEARCASE_PN}; + +system "cleartool protect -chmod +x \"$element\""; + +exit 0; diff --git a/clients/Ameriquest/triggers/CommentSQLCode.pl b/clients/Ameriquest/triggers/CommentSQLCode.pl new file mode 100644 index 0000000..038794a --- /dev/null +++ b/clients/Ameriquest/triggers/CommentSQLCode.pl @@ -0,0 +1,153 @@ +#!/usr/bin/perl +################################################################################ +# +# File: CommentSQLCode.pl +# Description: This trigger script will gather certain information and write +# that information into the element being checked in in the form +# of a comment. +# +# Here are the requirements as I understand them for the +# trigger that Steve Lipson wants for the SQL +# checkins. Basically he desires a trigger that will +# capture the checkin comment and other information and +# insert that information in the form of a comment at +# the top of the checked in element. This trigger will: +# +# * Be a postop trigger for the checkin action +# * Not be an all element trigger rather it will +# be attached to certain file elements in the +# vob +# * Be made for the vob +# * Only work on file elements - directory +# elements are to be skipped +# * Only work on file elements that have an +# extension of .sql - other elements will be +# skipped +# +# Author: Andrew@DeFaria.com +# Created: Mon Jul 19 10:54:01 PDT 2004 +# Language: Perl +# Modifications:Wed Aug 4 12:41:47 PDT 2004 +# +# (c) Copyright 2004, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +use strict; +use warnings; +use File::Spec; + +# This will be set in the BEGIN block but by putting them here the become +# available for the whole script. +my ( + $abs_path, + $lib_path, + $log_path, + $me, + $triggers_path +); + +BEGIN { + # Extract relative path and basename from script name. + $0 =~ /(.*)[\/\\](.*)/; + + $abs_path = (!defined $1) ? "." : File::Spec->rel2abs ($1); + $me = (!defined $2) ? $0 : $2; + + # Setup paths + $lib_path = "$abs_path/../lib"; + $log_path = "$abs_path/../log"; + $triggers_path = "$abs_path/../triggers"; + + # Add the appropriate path to our modules to @INC array. + unshift (@INC, "$lib_path"); +} # BEGIN + +use TriggerUtils; + +sub getCurrentTime { + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime (time); + $mon++; + $year += 1900; + $hour = "0" . $hour if $hour < 10; + $min = "0" . $min if $min < 10; + return "$mon/$mday/$year\@$hour:$min"; +} # getCurrentTime + +sub parseLSActivity { + my ($activity_id, $activity_title, $activity_owner); + + my @output = `cleartool lsactivity -cact -long`; + + if ($? ne 0 || $#output eq -1) { + clearmsg "You are not set to an activity!"; + exit 1; + } # if + + foreach (@output) { + if (/^activity \"(\S*)\"/) { + $activity_id = $1; + next; + } elsif (/owner: AMERIQUEST\\(\S*)/) { + $activity_owner = $1; + next; + } elsif (/title: (.*)/) { + $_ = $1; + chomp; chop if /\r/; + $activity_title = $_; + next; + } # if + } # foreach + + return ($activity_id, $activity_owner, $activity_title); +} # parseLSActivity + +# Get name of element and its type +my $pname = $ENV{CLEARCASE_PN}; +my $element_type = $ENV{CLEARCASE_ELTYPE}; + +# Skip directories and elements that aren't .sql +exit if $element_type =~ /directory/i || $pname !~ /\.sql$/i; + +# Get comment and user +my $comment = $ENV{CLEARCASE_COMMENT}; +my $userid = $ENV{CLEARCASE_USER}; + +# Format timestamp +my $timestamp = getCurrentTime; + +# Parse output of lsactivity -cact -long +my ($activity_id, $activity_owner, $activity_title) = parseLSActivity; + +# Open up $pname for reading and $pname.trig for writting +open PNAME_IN, $pname + or clearlogmsg "Unable to open $pname for reading - $!\n", exit 1; + +open PNAME_OUT, ">$pname.trig" + or clearlogmsg "Unable to open $pname.trig for writing - $!\n", exit 1; + +# Add comment to top of file +my $activity_str = "$activity_id: $activity_title"; +my $owner_str = $activity_owner =~ /\$userid/i ? "$activity_owner ($userid)" : "$activity_owner"; + +print PNAME_OUT <) { + print PNAME_OUT $_; +} # while + +close PNAME_IN; +close PNAME_OUT; + +# Switch $pname.trig -> $pname +rename "$pname.trig", $pname + or clearlogmsg "Internal error - Unable to rename $pname.trig to $pname", exit 1; + +# Allow checkin to proceed +exit 0; diff --git a/clients/Ameriquest/triggers/LogActivity.pl b/clients/Ameriquest/triggers/LogActivity.pl new file mode 100644 index 0000000..25d3c7a --- /dev/null +++ b/clients/Ameriquest/triggers/LogActivity.pl @@ -0,0 +1,198 @@ +#!/usr/bin/perl +################################################################################ +# +# File: LogActivity.pl +# Description: This trigger will log all activity into a "log" file of HTML +# format. Logfiles are kept per day thus the date appears as +# part of their names. +# +# This script requires one parameter, which is a path to a +# folder where to store the log files. Generally this is a UNC +# path to an area under some web server's DocumentRoot. +# +# Author: Andrew@DeFaria.com +# Created: May 18, 2004 +# Language: Perl +# Modifications: +# +# (c) Copyright 2004, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +use strict; +use warnings; +use File::Spec; + +# This will be set in the BEGIN block but by putting them here the become +# available for the whole script. +my ( + $abs_path, + $me, + $bin_path, + $triggers_path, + $lib_path, + $log_path, + $windows +); + +BEGIN { + # Extract relative path and basename from script name. + $0 =~ /(.*)[\/\\](.*)/; + + $abs_path = (!defined $1) ? "." : File::Spec->rel2abs ($1); + $me = (!defined $2) ? $0 : $2; + + # Check to see if we are running on Windows + $windows = ($^O =~ /MSWin/) ? "yes" : "no"; + + # Setup paths + $bin_path = "$abs_path"; + $triggers_path = "$abs_path/../triggers"; + $lib_path = "$abs_path/../lib"; + $log_path = "$abs_path/../log"; + + # Add the appropriate path to our modules to @INC array. + unshift (@INC, "$lib_path"); +} # BEGIN + +use TriggerUtils; + +use Time::localtime; + +if (!defined $ARGV [0]) { + clearlogmsg "Must specify a logpath!"; + exit 1; +} # if + +my $logpath = $ARGV [0]; + +sub Log { + my $logfile = shift; + my $vob = shift; + my $title = shift; + my $time = shift; + my $user = shift; + my $type = shift; + my $action = shift; + my $path = shift; + my $element = shift; + my $version = shift; + my $comments = shift; + + $logfile = $logpath . "\\" . $logfile; + + if (-e "$logfile") { + my $status = open LOG, ">>$logfile"; + + if (!defined $status) { + clearlogmsg "Unable to open log file $logfile - $!"; + return 1; + } # if + + print LOG < + $time + $user + $type + $action + $path + $element + $version + $comments + +END + } else { + my $status = open LOG, ">>$logfile"; + + if (!defined $status) { + clearlogmsg "Unable to open log file $logfile - $!"; + return 1; + } # if + + print LOG < + + $title + + +

$title

+ + + + + + + + + + + + + + + + + + + + +END + } # if + + close LOG; + + return 0; +} # Log + +# Format $curdate as yyyy-mm-dd and $curtime as hh:mm [AP]m +my $time = localtime; +my $year = $time->year + 1900; +my $month = ($time->mon < 9) ? "0" . ($time->mon + 1) : $time->mon + 1; +my $day = ($time->mday < 10) ? "0" . $time->mday : $time->mday; +my $hours = $time->hour; +my $minutes = ($time->min < 10) ? "0" . $time->min : $time->min; +my $ampm = "Am"; + +if ($hours > 12) { + $ampm = "Pm"; + $hours -= 12; +} elsif ($hours eq 12) { + $ampm = "Pm"; +} # if + +my $curtime = $hours . ":" . $minutes . " $ampm"; +my $curdate = $year . "-" . $month . "-" . $day; + +# Get Clearcase environment variables that we'll need +my $type = $ENV {CLEARCASE_ELTYPE}; +my $user = $ENV {CLEARCASE_USER}; +my $vob = $ENV {CLEARCASE_VOB_PN}; + +# Remove leading "\" from vob, just cause it looks ugly! :-) +$vob =~ s/^\\//; + +my $version = $ENV {CLEARCASE_ID_STR}; + +# $version is N/A for mkelem and rmname +$version = "N/A" if (!defined $version); + +my $comments = $ENV {CLEARCASE_COMMENT}; + +# $comments is N/A for rmname +$comments = "N/A" if (!defined $comments); + +my $pname = $ENV {CLEARCASE_PN}; +my $action = $ENV {CLEARCASE_OP_KIND}; + +my $title = "Activity in vob $vob on $month/$day/$year"; + +# Extract element +my $element = substr ($pname, rindex ($pname, "\\") + 1); +my $path = substr ($pname, rindex ($pname, $vob) + length ($vob) + 1); + +$path = ($path eq $element) ? ".\\" : substr ($path, 0, rindex ($path, $element) - 1); + +my $logfile = "${vob}_$curdate.html"; + +# Create/Add to HTML logfile. +exit (Log $logfile, $vob, $title, $curtime, $user, $type, $action, $path, $element, $version, $comments); diff --git a/clients/Ameriquest/triggers/NoPBLs.pl b/clients/Ameriquest/triggers/NoPBLs.pl new file mode 100644 index 0000000..d7d1281 --- /dev/null +++ b/clients/Ameriquest/triggers/NoPBLs.pl @@ -0,0 +1,65 @@ +#!/usr/bin/perl +################################################################################ +# +# File: NoPBLs.pl +# Description: This trigger stops all users except for vobadm and Steve Lipson +# (userid to be specified) from checking in PBLs which are +# PowerBuilder libraries and should never be checked into a vob. +# Why Steve Lipson would want this capability is unknown. +# +# Author: Andrew@DeFaria.com +# Created: May 18, 2004 +# Language: Perl +# Modifications: +# +# (c) Copyright 2004, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +use strict; +use warnings; +use File::Spec; + +# This will be set in the BEGIN block but by putting them here the become +# available for the whole script. +my ( + $abs_path, + $me, + $bin_path, + $triggers_path, + $lib_path, + $log_path, + $windows +); + +BEGIN { + # Extract relative path and basename from script name. + $0 =~ /(.*)[\/\\](.*)/; + + $abs_path = (!defined $1) ? "." : File::Spec->rel2abs ($1); + $me = (!defined $2) ? $0 : $2; + + # Check to see if we are running on Windows + $windows = ($^O =~ /MSWin/) ? "yes" : "no"; + + # Setup paths + $bin_path = "$abs_path"; + $triggers_path = "$abs_path/../triggers"; + $lib_path = "$abs_path/../lib"; + $log_path = "$abs_path/../log"; + + # Add the appropriate path to our modules to @INC array. + unshift (@INC, "$lib_path"); +} # BEGIN + +use TriggerUtils; + +my $steve_lipson = "sl020353"; +my $user = $ENV {CLEARCASE_USER}; +my $pname = $ENV {CLEARCASE_PN}; + +if ($pname =~ /\.pbl$/i and lc ($user) !~ $steve_lipson) { + clearmsg "Check in's of pbl's are not allowed except for administrators"; + exit 1; +} # if + +exit 0; diff --git a/clients/Ameriquest/triggers/Permissions.pl b/clients/Ameriquest/triggers/Permissions.pl new file mode 100644 index 0000000..476353f --- /dev/null +++ b/clients/Ameriquest/triggers/Permissions.pl @@ -0,0 +1,228 @@ +#!/usr/bin/perl +################################################################################ +# +# File: Permissions.pl +# Description: This trigger script implements additional permissions checking. +# The general idea is to open up permissions at the group level +# and to control who gets to checkout elements at the folder +# level. You do this by making an element named +# $permissions_element which contains group names of which +# groups have "checkout" permissions in that folder downward. +# Author: Andrew@DeFaria.com +# Created: Mon Jul 19 10:54:01 PDT 2004 +# Language: Perl +# Modifications: +# +# (c) Copyright 2004, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +use strict; +use warnings; +use File::Spec; + +# This will be set in the BEGIN block but by putting them here the become +# available for the whole script. +my ( + $abs_path, + $lib_path, + $log_path, + $me, + $triggers_path +); + +BEGIN { + # Extract relative path and basename from script name. + $0 =~ /(.*)[\/\\](.*)/; + + $abs_path = (!defined $1) ? "." : File::Spec->rel2abs ($1); + $me = (!defined $2) ? $0 : $2; + + # Setup paths + $lib_path = "$abs_path/../lib"; + $log_path = "$abs_path/../log"; + $triggers_path = "$abs_path/../triggers"; + + # Add the appropriate path to our modules to @INC array. + unshift (@INC, "$lib_path"); +} # BEGIN + +use TriggerUtils; + +# Name of permissions element to search for +my $permissions_element = ".perms"; + +# Trigger environment variables used +my $pname = $ENV{CLEARCASE_PN}; +my $user = $ENV{CLEARCASE_USER}; +my $vob = $ENV{CLEARCASE_VOB_PN}; + +sub ParentDir { + my $path = shift; + + $path =~ m/(.*)[\/\\].*/; + + return $1; +} # ParentDir + +# Returns the current group owner of the vob. This is the first group listed, not the' +# "Additional groups". +sub GetGroupOwner { + my $vob = shift; + + my @output = `cleartool describe vob:$vob 2>&1`; + + foreach (@output) { + chomp; chop if /\r/; + if (/group AMERIQUEST\\(.*)/) { + return $1; + } # if + } # foreach + + return "Unknown"; +} # GetGroupOwner + +# Returns the primary group using creds +sub GetPrimaryGroup { + my @output = `"C:\\Program Files\\Rational\\Clearcase\\etc\\utils\\creds.exe" 2>&1`; + + foreach (@output) { + chomp; chop if /\r/; + if (/Primary group: AMERIQUEST\\(\S*).*/) { + return $1; + } # if + } # foreach + + return "Domain Users"; +} # GetPrimaryGroup + +# Parsed the $permissions_element returning a list of permitted groups. +sub Parse { + my $permissions_element = shift; + + open PERMISSIONS_ELEMENT, $permissions_element + or clearlogmsg "Unable to open $permissions_element - $!\n", exit 1; + + my @lines = ; + my @tidy_lines; + + foreach (@lines) { + chomp; chop if /\r/; + next if $_ eq ""; + push @tidy_lines, $_; + } # foreach + + return @tidy_lines; +} # Parse + +# Compare the two string arrays and return 1 if there are any matches. +sub IsAMember { + my $set1 = shift; + my $set2 = shift; + + # Convert two array references to actual arrays + my @set1 = @{$set1}; + my @set2 = @{$set2}; + + foreach my $item1 (@set1) { + foreach my $item2 (@set2) { + return 1 if $item1 eq $item2; + } # foreach + } # foreach + + return 0; +} # IsAMember + +# Returns an array of (AMERIQUEST) group names for the user using creds. +sub GetUserGroups { + my @output = `"C:\\Program Files\\Rational\\Clearcase\\etc\\utils\\creds.exe" 2>&1`; + my @groups; + my $found = 0; + + foreach (@output) { + chomp; chop if /\r/; + + # We should first see the Primary Grou + if (/Primary group: AMERIQUEST\\(.*) \(/) { + push @groups, $1; + } # if + + # When we hit the "Groups:" line then what follows is a list of groups + if (/^Groups:/) { + $found = 1; + next + } # if + + # Select only those that are specifically in the AMERIQUEST domain + if ($found eq 1 and /\s*AMERIQUEST\\(.*) \(/) { + push @groups, $1; + } # if + } # foreach + + return @groups +} # GetUserGroups + +# This routine will check to see if any of the user's groups are in the +# $permissions_element(s) by recursing up the directory looking for +# $permissions_element(s) then comparing those groups to the user's groups. +sub Permitted { + my $vob = shift; + my $pname = shift; + my @user_groups = @_; + + # User may be attemptign to Add to Source Control in the current + # directory and have permissions to do so. When Add to Source + # Control runs it checks out the parent directory. The user + # typically will NOT have permissions to check out the parent + # directory! So for directory elements first check if the user is + # permitted as per $pname/$permissions_element BEFORE traversing up + # to the parent directory. + my @permitted_groups; + my $element_type = $ENV{CLEARCASE_ELTYPE}; + + if ($element_type =~ /directory/i) { + if (-e "$pname/$permissions_element") { + @permitted_groups = Parse ("$pname/$permissions_element"); + return 1 if (IsAMember (\@user_groups, \@permitted_groups)); + } # if + } # if + + # Get parent directory + $pname = ParentDir $pname; + + # Exhausted $pname + return 0 if !defined $pname; + + if (-e "$pname/$permissions_element") { + @permitted_groups = Parse ("$pname/$permissions_element"); + return 1 if (IsAMember (\@user_groups, \@permitted_groups)); + } # if + + # Recurse up to parent directory + return Permitted ($vob, $pname, @user_groups); +} # Permitted + +# Main +my $vob_group_owner = GetGroupOwner $vob; +my $group = GetPrimaryGroup; +my @user_groups = GetUserGroups; +my $msg; + +if ($vob_group_owner eq $group) { + # Vob group openers are always permitted + exit 0; +} elsif ($pname =~ m/$permissions_element$/) { + # User trying to check out the $permissions_element! + $msg .= "Only members of the vob's initial group owners,\\n"; + $msg .= "$vob_group_owner, may checkout the $permissions_element element!"; + clearmsg $msg; + exit 1; +} elsif (Permitted ($vob, $pname, @user_groups)) { + exit 0; +} else { + $msg .= "The userid of $user is not a member of a group who is\\n"; + $msg .= "permitted to check out elements from the folder\\n"; + $msg .= ParentDir $pname; + $msg .= " of the $vob vob."; + clearmsg $msg; + exit 1; +} # if diff --git a/clients/Ameriquest/triggers/defaria_notify.msg b/clients/Ameriquest/triggers/defaria_notify.msg new file mode 100644 index 0000000..48efe5b --- /dev/null +++ b/clients/Ameriquest/triggers/defaria_notify.msg @@ -0,0 +1,16 @@ +From: ASAP Adm +To: ADeFaria@Ameriquest.net +Subject: $CLEARCASE_OP_KIND: $CLEARCASE_PN +-- +This is a notification that a $CLEARCASE_OP_KIND has occurred: + +Element: $CLEARCASE_PN +Branch: $CLEARCASE_BRTYPE +Operation: $CLEARCASE_OP_KIND +User: $CLEARCASE_USER +View: $CLEARCASE_VIEW_TAG +Comments: + +$CLEARCASE_COMMENT + +For information about recent activity see http://asapcm.ameriquest.net/logs diff --git a/clients/GD/FSMon/Filesystem.pm b/clients/GD/FSMon/Filesystem.pm new file mode 100644 index 0000000..3d230d6 --- /dev/null +++ b/clients/GD/FSMon/Filesystem.pm @@ -0,0 +1,324 @@ +=pod + +=head2 NAME $RCSfile: FileSystem.pm,v $ + +Object oriented interface to filesystems + +=head2 VERSION + +=over + +=item Author: + +Andrew DeFaria + +=item Revision: + +$Revision: $ + +=item Created: + +Thu Dec 11 10:39:12 MST 2008 + +=item Modified: + +$Date:$ + +=back + +=head2 SYNOPSIS + +This module implements a FileSystem object. + + $fs = new FileSystem ("hosta"); + + while ($fs->filesystem) { + display "Filesystem: $_"; + display "\tSize:\t$fs{$_}->size"; + display "\tUsed:$fs{$_}->used"; + display "\tFree:$fs{$_}->free"; + display "\tUsed %:$fs{$_}->usedPct"; + display "\tMounted on:$fs{$_}->mount"; + } # while + +=head2 DESCRIPTION + +Filesystem creates a filesystem object that encapsulates information +about the file system as a whole. + +=head2 ROUTINES + +The following routines are exported: + +=over + +=cut + +use strict; +use warnings; + +package Filesystem; + +use base "Exporter"; + +use OSDep; +use Display; +use Utils; +use Rexec; + +=pod + +=head3 new () + +Construct a new Filesystem object. The following OO style arguments are +supported: + +Parameters: + +=for html
+ +=over + +=item none + +Returns: + +=for html
+ +=over + +=item Filesystem object + +=back + +=for html
+ +=cut + +sub new ($;$$$$) { + my ($class, $system, $ostype, $username, $password, $prompt, $shellstyle) = @_; + + # Set prompt if not passed in + $prompt ||= $Rexec::default_prompt; + + # Connect to remote machine + my $remote = new Rexec ( + host => $system, + username => $username, + password => $password, + prompt => $prompt, + shellstyle => $shellstyle, + ); + + unless ($remote) { + error "Unable to connect to $system"; + + return undef; + } # if + + my (@fs, %fs); + + # Sun is so braindead! + if ($ostype eq "Unix") { + foreach ("ufs", "vxfs") { + my $cmd = "/usr/bin/df -k -F $_"; + + my @unixfs = $remote->exec ($cmd); + + if ($remote->status != 0) { + error ("Unable to determine fsinfo on $system ($cmd)\n" . join ("\n", @fs));; + return undef; + } # if + + # Skip heading + shift @unixfs; + + for (my $i = 0; $i < scalar @unixfs; $i++) { + my (%fsinfo, $firstField); + + # Trim leading and trailing spaces + $unixfs[$i] =~ s/^\s+//; + $unixfs[$i] =~ s/\s+$//; + + my @fields = split /\s+/, $unixfs[$i]; + + if (scalar @fields == 1) { + $fsinfo{fs} = $fields[0]; + $firstField = 0; + $i++; + + # Trim leading and trailing spaces + $unixfs[$i] =~ s/^\s+//; + $unixfs[$i] =~ s/\s+$//; + + @fields = split /\s+/, $unixfs[$i];; + } else { + $fsinfo{fs} = $fields[0]; + $firstField = 1; + } #if + + $fsinfo{size} = $fields[$firstField] * 1024; + $fsinfo{used} = $fields[$firstField + 1] * 1024; + $fsinfo{free} = $fields[$firstField + 2] * 1024; + $fsinfo{reserve} = $fsinfo{size} - $fsinfo{used} - $fsinfo{free}; + + $fs{$fields[$firstField + 4]} = \%fsinfo; + } # for + } # foreach + } elsif ($ostype eq "Linux") { + foreach ("ext3") { + my $cmd = "/bin/df --block-size=1 -t $_"; + + my @linuxfs = $remote->exec ($cmd); + + if ($remote->status != 0) { + error ("Unable to determine fsinfo on $system ($cmd)\n" . join ("\n", @fs));; + return undef; + } # if + + # Skip heading + shift @linuxfs; + + foreach (@linuxfs) { + my %fsinfo; + my @fields = split; + + $fsinfo{fs} = $fields[0]; + $fsinfo{size} = $fields[1]; + $fsinfo{used} = $fields[2]; + $fsinfo{free} = $fields[3]; + $fsinfo{reserve} = $fsinfo{size} - $fsinfo{used} - $fsinfo{free}; + + $fs{$fields[5]} = \%fsinfo; + } # foreach + } # foreach + } else { + error "Can't handle $ostype", 1; + } # if + + bless \%fs, $class; +} # new + +=pod + +=head3 mounts () + +Returns an array of mount points + +Parameters: + +=for html
+ +=over + +=item none + +None + +=back + +=for html
+ +Returns: + +=for html
+ +=over + +=item Array of mount points + +=back + +=for html
+ +=cut + +sub mounts () { + my ($self) = shift; + + return keys %{$self} +} # mounts + +=pod + +=head3 getFSInfo ($mount) + +Returns a hash of filesystem info for a mount point + +Parameters: + +=for html
+ +=over + +=item $mount: Mount point + +None + +=back + +=for html
+ +Returns: + +=for html
+ +=over + +=item Hash of filesystem info + +=back + +=for html
+ +=cut + +sub getFSInfo ($) { + my ($self, $mount) = @_; + + return %{$self->{$mount}}; +} # getFSInfo + +1; + +=back + +=head2 CONFIGURATION AND ENVIRONMENT + +None + +=head2 DEPENDENCIES + + Display + OSDep + Utils + +=head2 INCOMPATABILITIES + +None yet... + +=head2 BUGS AND LIMITATIONS + +There are no known bugs in this module. + +Please report problems to Andrew DeFaria (Andrew@ClearSCM.com). + +=head2 LICENSE AND COPYRIGHT + +This Perl Module is freely available; you can redistribute it and/or +modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This Perl Module is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License (L) for more +details. + +You should have received a copy of the GNU General Public License +along with this Perl Module; if not, write to the Free Software Foundation, +Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +reserved. + +=cut diff --git a/clients/GD/FSMon/Fonts/GeosansLight.ttf b/clients/GD/FSMon/Fonts/GeosansLight.ttf new file mode 100644 index 0000000..055932a Binary files /dev/null and b/clients/GD/FSMon/Fonts/GeosansLight.ttf differ diff --git a/clients/GD/FSMon/Fonts/MankSans.ttf b/clients/GD/FSMon/Fonts/MankSans.ttf new file mode 100644 index 0000000..a6146a9 Binary files /dev/null and b/clients/GD/FSMon/Fonts/MankSans.ttf differ diff --git a/clients/GD/FSMon/Fonts/Silkscreen.ttf b/clients/GD/FSMon/Fonts/Silkscreen.ttf new file mode 100644 index 0000000..ae4425d Binary files /dev/null and b/clients/GD/FSMon/Fonts/Silkscreen.ttf differ diff --git a/clients/GD/FSMon/Fonts/pf_arma_five.ttf b/clients/GD/FSMon/Fonts/pf_arma_five.ttf new file mode 100644 index 0000000..db04ec3 Binary files /dev/null and b/clients/GD/FSMon/Fonts/pf_arma_five.ttf differ diff --git a/clients/GD/FSMon/Fonts/tahoma.ttf b/clients/GD/FSMon/Fonts/tahoma.ttf new file mode 100644 index 0000000..59b14a2 Binary files /dev/null and b/clients/GD/FSMon/Fonts/tahoma.ttf differ diff --git a/clients/GD/FSMon/FsmonDB.php b/clients/GD/FSMon/FsmonDB.php new file mode 100644 index 0000000..d39021b --- /dev/null +++ b/clients/GD/FSMon/FsmonDB.php @@ -0,0 +1,181 @@ +N/A"; + +function dbError ($msg, $statement) { + $errno = mysql_errno (); + $errmsg = mysql_error (); + + print <<ERROR: $msg +Error #$errno:
+
$errmsg
+SQL Statement:
+
$statement
+END; + + exit ($errno); +} // dbError + +function openDB () { + global $dbserver, $userid, $password, $dbname; + + $db = mysql_connect ($dbserver, $userid, $password) + or dbError (__FUNCTION__ . ": Unable to connect to database server $dbserver", "Connect"); + + mysql_select_db ($dbname) + or dbError (__FUNCTION__ . ": Unable to select the $dbname database", "$dbname"); +} // openDB + +function getFSInfo ($system = "", $mount = "", $period = "daily") { + $sysCondition = (isset ($system)) ? "where sysname = \"$system\"" : ""; + $mountCondition = (isset ($mount)) ? " and mount = \"$mount\"" : ""; + + if (!($period == "hourly" or + $period == "daily" or + $period == "weekly" or + $period == "monthly")) { + error ("Invalid period - $period - specified", 1); + } // if + + $statement = << $maxUsed) { + $maxUsed = $row["used"]; + $line["size"] = $row["size"]; + $line["used"] = $row["used"]; + $line["free"] = $row["free"]; + $line["reserve"] = $row["reserve"]; + } else { + continue; + } // if + } elseif ($period == "weekly") { + error ("Weekly not handled yet", 1); + } elseif ($period == "monthly") { + $thisPeriod = substr ($row["timestamp"], 0, 7); + if ($lastPeriod == "") { + $lastPeriod = $thisPeriod; + } elseif ($lastPeriod == $thisPeriod) { + continue; + } // if + + if ($row["used"] > $maxUsed) { + $maxUsed = $row["used"]; + $line["size"] = $row["size"]; + $line["used"] = $row["used"]; + $line["free"] = $row["free"]; + $line["reserve"] = $row["reserve"]; + } else { + continue; + } // if + } // if + + array_push ($data, $line); + } // while + + return $data; +} // getFSInfo + +function getSystem ($system = "") { + $statement = "select * from system"; + + if (isset ($system) and $system != "") { + $statement .= " where name = \"$system\""; + } // if + + $result = mysql_query ($statement) + or DBError ("Unable to execute query: ", $statement); + + $data = array (); + + while ($row = mysql_fetch_array ($result, MYSQL_ASSOC)) { + array_push ($data, $row); + } // while + + return $data; +} // getSystem + +function getMounts ($system) { + $statement = "select mount from filesystems where sysname = \"$system\" order by mount"; + + $result = mysql_query ($statement) + or DBError ("Unable to execute query: ", $statement); + + $data = array (); + + while ($row = mysql_fetch_array ($result)) { + array_push ($data, $row["mount"]); + } // while + + return $data; +} // getMounts +?> diff --git a/clients/GD/FSMon/FsmonDB.pm b/clients/GD/FSMon/FsmonDB.pm new file mode 100644 index 0000000..786f4cd --- /dev/null +++ b/clients/GD/FSMon/FsmonDB.pm @@ -0,0 +1,700 @@ +=pod + +=head2 NAME $RCSfile: FsmonDB.pm,v $ + +Object oriented interface to filesystems + +=head2 VERSION + +=over + +=item Author: + +Andrew DeFaria + +=item Revision: + +$Revision: $ + +=item Created: + +Thu Dec 11 10:39:12 MST 2008 + +=item Modified: + +$Date:$ + +=back + +=head2 SYNOPSIS + +=head1 SYNOPSIS + + use FsmonDB; + + my $username = "fsmonadm"; + my $password = ""; + + my $fsmondb = new FsmonDB ($username, $password); + + my ($errno, $errmsg) = $fsmondb->addSystem ( + name => hostname, + owner => "root", + description => "Database server", + ostype => "Unix", + osversion => `uname -a`, + monitorAllFS => 1, + ); + + $status = $fsmondb->fsSnapshot (hostname); + +=head2 DESCRIPTION + +Filesystem creates a filesystem object that encapsulates information +about the file system as a whole. + +=head2 ROUTINES + +The following routines are exported: + +=over + +=cut + +use strict; +use warnings; + +package FsmonDB; + +use Carp; +use DBI; + +use DateUtils; +use Display; +use Filesystem; + +############################################################################ +# +# insert: Construct SQL insert statement based on passed in table +# name and hash values. +# +# Parms: +# table Table name +# record Name value hash +# +# Returns: +# status ($errno, $errmsg) +# +############################################################################ +sub insert ($%) { + my ($self, $table, %values) = @_; + + my $first = 1; + my $fields; + my $values; + + foreach (keys %values) { + if ($first) { + $first = 0; + } else { + $fields .= ","; + $values .= ","; + } # if + + if (!defined $_) { + $values .= "NULL"; + } else { + $fields .= $_; + $values .= "\"" . quotemeta ($values{$_}) . "\""; + } # if + } # foreach + + my $statement = "insert into $table ($fields) values ($values)"; + + $self->{db}->do ($statement) + or return $self->_dberror ("Unable to add system", $statement); + + return (0, undef); +} # insert + +############################################################################ +# +# _dberror: Output the DB error message and exit (Internal) +# +# Parms: +# msg User defined message to output +# statement SQL Statement attempted (optional) +# +# Returns: +# Nothing +# +############################################################################ +sub _dberror ($;$) { + my ($self, $msg, $statement) = @_; + + my $caller = (caller (1))[3]; + + my $returnMsg = "$caller: DBError: " + . $msg + . "\nError #" + . $self->{db}->err + . " " + . $self->{db}->errstr; + + $returnMsg .= "\nSQL Statement: $statement\n" if $statement; + + return ($self->{db}->err, $returnMsg); +} # _dberror + +############################################################################ +# +# _exists: Return 1 if the value exists in the table otherwise 0 +# +# Parms: +# table Name of table to search +# column Column name to search +# value Value to look for +# column2 Secondary column to search for +# value2 Secondary value to search for +# +# Returns: +# 1 if found, 0 if not +# +############################################################################ +sub _exists ($$$;$$) { + my ($self, $table, $column, $value, $column2, $value2) = @_; + + my $statement = "select count(*) from $table where $column = \"" + . quotemeta ($value) + . "\""; + + $statement .= " and $column2 = \"" + . quotemeta ($value2) + . "\"" if $column2; + + my $sth; + + unless ($sth = $self->{db}->prepare ($statement)) { + my ($errNo, $errMsg) = $self->_dberror ("Unable to prepare statement", $statement); + display $errMsg; + return 0; + } # unless + + unless ($sth->execute) { + my ($errNo, $errMsg) = $self->_dberror ("Unable to execute statement", $statement); + display $errMsg; + return 0; + } # unless + + my @row = $sth->fetchrow_array; + + $sth->finish; + + if ($row[0]) { + return $row[0] + } else { + return 0; + } # if +} # _exists + +############################################################################ +# +# _count: Returns the number of entries in a table that qualify for +# the given condition. +# +# Parms: +# table Name of table to search +# id condition (Default: All entries in the table) +# +# Returns: +# Count of qualifying entries +# +############################################################################ +sub _count ($;$) { + my ($self, $table, $condition) = @_; + + $condition = $condition ? "where $condition" : ""; + + my $statement = "select count(*) from $table $condition"; + + my $sth; + + unless ($sth = $self->{db}->prepare ($statement)) { + my ($errNo, $errMsg) = $self->_dberror ("Unable to prepare statement", $statement); + display $errMsg; + return -1; + } # unless + + unless ($sth->execute) { + my ($errNo, $errMsg) = $self->_dberror ("Unable to execute statement", $statement); + display $errMsg; + return -1; + } # unless + + my @row = $sth->fetchrow_array; + + $sth->finish; + + if ($row[0]) { + return $row[0] + } else { + return 0; + } # if +} # _count + +=pod + +=head3 new () + +Construct a new FsmonDB object. The following OO style arguments are +supported: + +Parameters: + +=for html
+ +=over + +=item none + +Returns: + +=for html
+ +=over + +=item FsmonDB object + +=back + +=for html
+ +=cut + +sub new (;$$) { + my ($class, $username, $password) = @_; + + $username = $username ? $username : "fsmon"; + $password = $password ? $password : "fsmon"; + + my $dbname = $ENV{FSMON_DBNAME} + ? $ENV{FSMON_DBNAME} + : "fsmon"; + my $dbserver = $ENV{FSMON_DBSERVER} + ? $ENV{FSMON_DBSERVER} + : "seast1"; + my $dbdriver = "mysql"; + + my $db = DBI->connect ("DBI:$dbdriver:$dbname:$dbserver", $username, + $password, {PrintError => 0}) + or croak "Unable to connect to $dbname database as $username"; + + return bless { + db => $db, + username => $username, + password => $password, + }, $class; +} # new + +=pod + +=head3 addSystem (%system) + +Add a system record + +Parameters: + +=for html
+ +=over + +%system is a hash containing the following keys: + +=item $name (required) + +Name of the system + +=item $owner (optional) + +Person or persons responsible for this system + +=item $description (optional) + +Description of this system + +=item $ostype (required) + +An enumeration of "Linux", "Unix" or "Windows" (default Linux) + +=item $osversion (optional) + +String representing an OS version + +Returns: + +=for html
+ +=over + +=item FsmonDB object + +=back + +=for html
+ +=cut + +sub addSystem (%) { + my ($self, %record) = @_; + + return $self->insert ("system", %record); +} # addSystem + +=pod + +=head3 getSystem ($system) + +Get a system record + +Parameters: + +=for html
+ +=over + +=item $system (option) + +Name of the system to return information about. If not specified then +getSystem returns all systems + +Returns: + +=for html
+ +=over + +=item If $system was specified, a hash of that system's +information. If $system is not specified then an array of hashes +containing information on all systems. + +=back + +=for html
+ +=cut + +sub getSystem (;$) { + my ($self, $system) = @_; + + my ($statement, $sth); + + if ($system) { + $statement = "select * from system where name = \"$system\""; + } else { + $statement = "select name from system"; + } # unless + + unless ($sth = $self->{db}->prepare ($statement)) { + my ($errno, $errmsg) = $self->_dberror ("Unable to prepare statement", $statement); + error $errmsg, $errno; + } # unless + + unless ($sth->execute) { + my ($errno, $errmsg) = $self->_dberror ("Unable to execute statement", $statement); + error $errmsg, $errno; + } # unless + + if ($system) { + return %{my $row = $sth->fetchrow_hashref}; + } else { + my @records; + + while (my @record = $sth->fetchrow_array) { + push @records, pop @record; + } # while + + return @records; + } # if +} # addSystem + +=pod + +=head3 addFilesystem ($system, $mount) + +Add monitoring of a filesytem identified by $mount from a $system + +Parameters: + +=for html
+ +=over + +=item $system (required) + +Name of the system that this filesystem is local to + +=item mount (optional) + +Mount point for this file system. If undef then add all local file systems. + +Returns: + +=for html
+ +=over + +=item ($errno, $errmsg) + +=back + +=for html
+ +=cut + +sub addFilesystem ($;$) { + my ($self, $system, $mount) = @_; + + my $fs = new Filesystem; + + foreach ($fs->mounts ()) { + my %fsinfo = $fs->getFSInfo ($_); + my %filesystem = ( + "sysname" => $system, + "mount" => $_, + "fs" => $fsinfo{fs}, + ); + my ($errno, $errmsg); + + if ($mount) { + if ($mount eq $_) { + ($errno, $errmsg) = $self->insert ("filesystems", %filesystem); + + return ($errno, $errmsg) if $errno != 0; + } # if + } else { + ($errno, $errmsg) = $self->insert ("filesystems", %filesystem); + + return ($errno, $errmsg) if $errno != 0; + } # if + } # foreach + + return (0, undef); +} # addFilesystem + +=pod + +=head3 addSnapshot (%snapshot) + +Add a snapshot record of a filesystem + +Parameters: + +=for html
+ +=over + +%snapshot is a hash containing the following keys: + +=item sysname (required) + +Name of the system that this filesystem is local to + +=item mount (required) + +Mount point for this file system + +=item timestamp (required) + +Timestamp representing the time that the snapshot of the filesystem +was taken. + +=item size (optional) + +Total size of the filesystem in bytes + +=item used (optional) + +Number of bytes of used space + +=item free (optional) + +Number of bytes free or available for use + +=item reserve (optional) + +Number of bytes held in reserve + +Returns: + +=for html
+ +=over + +=item ($errno, $errmsg) + +=back + +=for html
+ +=cut + +sub addSnapshot (%) { + my ($self, %snapshot) = @_; + + return $self->insert ("fs", %snapshot); +} # addSnapshot + +=pod + +=head3 snapshot ($system) + +Take a snapshot of all configured file systems for a given system + +Parameters: + +=for html
+ +=over + +=item $system + +Name of the system to snapshot + +Returns: + +=for html
+ +=over + +=item ($errno, $errmsg) + +=back + +=for html
+ +=cut + +sub snapshot ($;$) { + my ($self, $system) = @_; + + my %system = $self->getSystem ($system); + my $fs = new Filesystem ( + $system, + $system{ostype}, + $system{username}, + $system{password}, + qr "$system{prompt}", + $system{shellstyle}, + ); + + if ($fs) { + foreach ($fs->mounts ()) { + my %fsinfo = $fs->getFSInfo ($_); + my %fs; + + # Format record + $fs{sysname} = $system; + $fs{mount} = $_; + $fs{timestamp} = Today2SQLDatetime; + $fs{size} = $fsinfo{size}; + $fs{used} = $fsinfo{used}; + $fs{free} = $fsinfo{free}; + $fs{reserve} = $fsinfo{reserve}; + + my ($errno, $errmsg) = $self->addSnapshot (%fs); + + return ($errno, $errmsg) if $errno != 0; + } # foreach + } # if + + return (0, ""); +} # snapshot + +1; + +=head1 NAME + +FsmonDB - Access routines to the fsmon SQL database + +=head1 VERSION + +Version 1.0 + +=head1 DESCRIPTION + +This module provides for access routines to the fsmon SQL database. + +=head1 METHODS + +=head2 new ($username, $password) + +Opens the fsmon SQL database for the specified $username and +$password and returns a FsmonDB object + +Parameters: + +=over + +=item username: + +Username to connect to the database. At this time "fsmonadm" is the R/W +user and "fsmon" (password "reader") has R/O access (Default: +fsmon). + +=item password: + +Password to use. (Default: "fsmon"). + +=item Returns FsmonDB object + +=back + +=head2 addSystem (%testrun) + +Adds the system record. Pass in a hash of field name/value pairs. + +=over + +=item ($errno, $errmsg) + +=back + +=back + +=head2 CONFIGURATION AND ENVIRONMENT + +None + +=head2 DEPENDENCIES + + ... + +=head2 INCOMPATABILITIES + +None yet... + +=head2 BUGS AND LIMITATIONS + +There are no known bugs in this module. + +Please report problems to Andrew DeFaria (Andrew@ClearSCM.com). + +=head2 LICENSE AND COPYRIGHT + +This Perl Module is freely available; you can redistribute it and/or +modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This Perl Module is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License (L) for more +details. + +You should have received a copy of the GNU General Public License +along with this Perl Module; if not, write to the Free Software Foundation, +Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +reserved. + +=cut diff --git a/clients/GD/FSMon/FsmonDB.sql b/clients/GD/FSMon/FsmonDB.sql new file mode 100644 index 0000000..0d0e091 --- /dev/null +++ b/clients/GD/FSMon/FsmonDB.sql @@ -0,0 +1,81 @@ +-------------------------------------------------------------------------------- +-- +-- File: FsmonDB.sql +-- Revision: 0.1 +-- Description: Database definition for fsmon +-- Author: Andrew@ClearSCM.com +-- Created: Thu Dec 11 13:43:06 MST 2008 +-- Modified: +-- Language: SQL +-- +-- Copyright (c) 2008, General Dynamics, all rights reserved +-- +-------------------------------------------------------------------------------- +-- Warning: The following line will delete the old database! +drop database if exists fsmon; + +-- Create a new database +create database fsmon; + +-- Now let's focus on this new database +use fsmon; + +-- system: Contains information about the various machines that we are +-- monitoring file systems on + +create table system ( + name varchar(255) not null, + owner tinytext, + description text, + ostype enum ( + "Linux", + "Unix", + "Windows" + ) not null, + osversion tinytext, + username tinytext, + password tinytext, + prompt tinytext, + shellstyle enum ( + "sh", + "csh" + ) not null, + + primary key (name) +) engine = InnoDB; + +-- filesystems: Describes the filesystems for a system +create table filesystems ( + sysname varchar(255) not null, + mount varchar(255) not null, + fs tinytext not null, + + primary key (sysname, mount) +) engine = InnoDB; + +-- fs: Contains a snapshot reading of a filesystem at a given date and time +create table fs ( + sysname varchar(255) not null, + mount varchar(255) not null, + timestamp datetime not null, + size bigint, + used bigint, + free bigint, + reserve bigint, + + primary key (sysname, mount, timestamp), + foreign key (sysname, mount) + references filesystems (sysname, mount) + on delete cascade + on update cascade +) engine = InnoDB; + +grant all privileges + on fsmon.* + to fsmonadm@"%" + identified by "fsmonadm" with grant option; + +grant select + on fsmon.* + to fsmon@"%" + identified by "fsmon"; diff --git a/clients/GD/FSMon/Fsutils.php b/clients/GD/FSMon/Fsutils.php new file mode 100644 index 0000000..d5166cd --- /dev/null +++ b/clients/GD/FSMon/Fsutils.php @@ -0,0 +1,105 @@ +DEBUG: $msg
"; + } // if +} // debug + +function dumpObject ($object) { + print "
";
+  print_r ($object);
+  print "
"; +} // dumpObject + +function error ($msg, $errno = 0) { + print "

ERROR: $msg"; + + if ($errno != 0) { + print " ($errno)

"; + exit; + } else { + print "

"; + } // if +} // error + +function banner () { + return $banner; +} // banner + +function YMD2MDY ($date) { + return substr ($date, 5, 2) . "/" . + substr ($date, 8, 2) . "/" . + substr ($date, 0, 4); +} // YMD2MDY + +function MDY2YMD ($date) { + return substr ($date, 6, 4) . "-" . + substr ($date, 0, 2) . "-" . + substr ($date, 3, 2); +} // MDY2YMD + +function copyright () { + $year = date ("Y"); + + $thisFile = "$_SERVER[DOCUMENT_ROOT]/$_SERVER[PHP_SELF]"; + $lastModified = date ("F d Y @ g:i a", filemtime ($thisFile)); + + $copyright .= << +Fsmon Version +END; + $copyright .= VERSION; + $copyright .= <<Last Modified: $lastModified
+Copyright $year © ClearSCM, Inc., all rights reserved
+Home + +END; + + return $copyright; +} // copyright + +function Today2SQLDatetime () { + return date ("Y-m-d H:i:s"); +} // Today2SQLDatetime + +function getPeriods () { + return array ( + "hourly", + "daily", + "weekly", + "monthly" + ); +} // getPeriods + +function getScales () { + return array ( + "byte", + "kbyte", + "meg", + "gig" + ); +} // getScales +?> \ No newline at end of file diff --git a/clients/GD/FSMon/fsmon b/clients/GD/FSMon/fsmon new file mode 100755 index 0000000..b3307ba --- /dev/null +++ b/clients/GD/FSMon/fsmon @@ -0,0 +1,83 @@ +#!/bin/env /usr/local/bin/perl +################################################################################ +# +# File: fsmon +# Revision: 0.1 +# Description: Monitor filesystem growth +# +# Author: Andrew@ClearSCM.com +# Created: Thu Dec 11 10:39:12 MST 2008 +# Modified: +# Language: Perl +# +# (c) Copyright 2008, ClearSCM, Inc., all rights reserved. +# +################################################################################# +use strict; +use warnings; + +use FindBin; +use Getopt::Long; +use Net::Domain qw(hostname); + +use lib ($FindBin::Bin, "/cleartrig/ent/SNSD/muos/ccadm_tools/vobs/ranccadm/scripts/lib"); + +use Display; +use Rexec; +use Filesystem; +use FsmonDB; + +# This is a non-standard, but commonly used prompt around here. For +# EAST systems they use a terminator of "]$" as in "[p6258c@ceast1 +# p6258c]$ " however on ranray it's more like "[ranray/home/pwit] +# ". So we look for both. +use constant PROMPT => qr'(\]\$|\] $)'; + +my %_opts; + +sub usage (;$) { + my ($msg) = $_; + + my $usage = "ERROR: $msg\n\n" if $msg; + + $usage .= < sub { set_verbose }, + debug => sub { set_debug }, + usage => sub { usage; exit 0 }, +); + +# Connect to database +my $fsmondb = new FsmonDB ("fsmonadm", "fsmonadm"); + +# Take a snapshot of all systems +verbose "Taking snapshots..."; + +foreach ($fsmondb->getSystem) { + verbose "Snapshotting $_"; + +# my ($errno, $errmsg) = $fsmondb->snapshot ($_, PROMPT); + my ($errno, $errmsg) = $fsmondb->snapshot ($_); + + warning "Unable to take snapshot of $_\n$errmsg" + if $errno != 0; +} # foreach + +verbose "Done"; diff --git a/clients/GD/FSMon/fsmon.php b/clients/GD/FSMon/fsmon.php new file mode 100644 index 0000000..e784569 --- /dev/null +++ b/clients/GD/FSMon/fsmon.php @@ -0,0 +1,233 @@ + + + + + + + FSMon v($version) $sysLabel - $mountLabel + + +END; + + $header .= banner (); + $header .= <<Filesystem Monitor +END; + + return $header; +} // createHeader + +function createPage ($system, $mount = "", $period = "daily", $scale = "gig") { + $data = getFSInfo ($system, $mount, $period); + + $page .= << +
+ + + + + + + + + + + +END; + + foreach ($data as $line) { + $page .= << + + + + + + + + +END; + } // foreach + + $page .=<< +
TimeUserTypeActionPathNameVersion + Comment
$time$user$type$action$path$element$version$comments
SystemMount PointTimestampSizeUsedFreeReserve
$line[sysname]$line[mount]$line[timestamp]$line[size]$line[used]$line[free]$line[reserve]
+END; + + return $page; +} // createPage + +function displayReport ($system = "", $mount = "", $period = "daily", $scale = "gig") { + print createPage ($system, $mount, $period, $scale); +} // displayReport + +function displayMount ($system = "", $mount = "", $period = "daily", $scale = "gig") { + global $script; + + print << + +
+ System:  + +END; + + foreach (getMounts ($system) as $item) { + print "$item"; + } // foreach + + print << +  Period:  + +END; + + foreach (getScales () as $item) { + print "$item"; + } // foreach + + print << +   + + + + + + + + +END; +// displayReport ($system, $mount, $period, $scale); +} // displayMount + +function displayFilesystems ($system = "", $mount = "", $period = "daily", $scale = "gig") { + if (empty ($mount)) { + foreach (getMounts ($system) as $mount) { + displayMount ($system, $mount, $period, $scale); + print "

"; + } // foreach + } else { + displayMount ($system, $mount, $period, $scale); + } // if +} // displayFilesystems + +function displayGraph ($system = "", $mount = "", $period = "daily", $scale = "gig") { + print createHeader (); + + if (empty ($system)) { + foreach (getSystem () as $system) { + displayFilesystems ($system["name"], $mount, $period, $scale); + } // foreach + } else { + displayFilesystems ($system, $mount, $period, $scale); + } // if +} // displayGraph + +openDB (); + +if (empty ($system)) { + print createHeader (); + print "
    "; + + foreach (getSystem () as $system) { + print "
  • $system[name]
  • "; + +// print "
      "; + +// $mounts = getMounts ($system["name"]); + +// foreach ($mounts as $mount) { +// print "
    • $mount
    • "; +// } // foreach + +// print "
    "; + } // foreach + + print "
"; +} else { + displayGraph ($system, $mount, $period, $scale); +} // if + +print copyright (); +?> + + diff --git a/clients/GD/FSMon/graphFS.php b/clients/GD/FSMon/graphFS.php new file mode 100644 index 0000000..db1b945 --- /dev/null +++ b/clients/GD/FSMon/graphFS.php @@ -0,0 +1,174 @@ + 12) { + $hours = $hours - 12; + $ampm = "Pm"; + } elseif ($hours < 10) { + $hours = substr ($hours, 1, 1); + } // if + + $Xlabel = "$hours:$minutes $ampm"; + } elseif ($period == "daily") { + $day = substr ($result["timestamp"], 8, 2); + + if ($day < 10) { + $day = substr ($day, 1, 1); + } // if + + $month = substr ($result["timestamp"], 5, 2); + + if ($month < 10) { + $month = substr ($month, 1, 1); + } // if + + $year = substr ($result["timestamp"], 0, 4); + $Xlabel = "$month/$day/$year"; + } elseif ($period == "weekly") { + $Xlabel = "Weekly not implemented"; + } elseif ($period == "monthly") { + $month = substr ($result["timestamp"], 5, 2); + + if ($month < 10) { + $month = substr ($month, 1, 1); + } // if + + $year = substr ($result["timestamp"], 0, 4); + $Xlabel = "$month/$year"; + } else { + $Xlabel = $result["timestamp"]; + } // if + + $DataSet->AddPoint ($result["used"] / $scaling, "Used", $Xlabel); + $DataSet->AddPoint ($result["free"] / $scaling, "Free", $Xlabel); +} // foreach + +$DataSet->AddAllSeries(); +$DataSet->SetAbsciseLabelSerie(); + +$DataSet->SetXAxisName ("Time"); + +// Initialise the graph +$Test = new pChart (700, 280); + +$Test->setColorPalette (1, 0, 255, 0); +$Test->setColorPalette (0, 255, 0, 0); + +$Test->drawGraphAreaGradient (100, 150, 175, 100, TARGET_BACKGROUND); +$Test->setFontProperties ("$fonts/tahoma.ttf", 8); + +if ($scaling == BYTE) { + $Test->setGraphArea (110, 30, 680, 200); + $DataSet->SetYAxisName ("Bytes"); +} elseif ($scaling == KBYTE) { + $Test->setGraphArea (90, 30, 680, 200); + $DataSet->SetYAxisName ("Kbytes"); +} elseif ($scaling == MEG) { + $Test->setGraphArea (70, 30, 680, 200); + $DataSet->SetYAxisName ("Meg"); +} else { + $Test->setGraphArea (55, 30, 680, 200); + $DataSet->SetYAxisName ("Gig"); +} // if + +$Test->drawRoundedRectangle (5, 5, 695, 275, 5, 230, 230, 230); +$Test->drawGraphAreaGradient (162, 183, 202, 50); +$Test->drawScale ($DataSet->GetData (), $DataSet->GetDataDescription (), SCALE_ADDALLSTART0, 200, 200, 200, true, 70, 2, true); +$Test->drawGrid (4, true, 230, 230, 230, 50); + +// Draw the 0 line +$Test->setFontProperties ("$fonts/tahoma.ttf", 6); +$Test->drawTreshold (0, 143, 55, 72, true, true); + +// Draw the bar graph +$Test->drawStackedBarGraph ($DataSet->GetData (), $DataSet->GetDataDescription (), 75); + +// Finish the graph +$Test->setFontProperties ("$fonts/tahoma.ttf",8); +$Test->drawLegend (610, 35, $DataSet->GetDataDescription (), 130, 180, 205); +$Test->setFontProperties ("$fonts/tahoma.ttf", 10); +$Test->drawTitle (50, 22, "$system:$mount ($period)", 255, 255, 255, 675); +$Test->Stroke (); +?> \ No newline at end of file diff --git a/clients/GD/FSMon/pChart/pCache.class b/clients/GD/FSMon/pChart/pCache.class new file mode 100644 index 0000000..454bbad --- /dev/null +++ b/clients/GD/FSMon/pChart/pCache.class @@ -0,0 +1,119 @@ +. + + Class initialisation : + pCache($CacheFolder="Cache/") + Cache management : + IsInCache($Data) + GetFromCache($ID,$Data) + WriteToCache($ID,$Data,$Picture) + DeleteFromCache($ID,$Data) + ClearCache() + Inner functions : + GetHash($ID,$Data) + */ + + /* pCache class definition */ + class pCache + { + var $HashKey = ""; + var $CacheFolder = "Cache/"; + + /* Create the pCache object */ + function pCache($CacheFolder="Cache/") + { + $this->CacheFolder = $CacheFolder; + } + + /* This function is clearing the cache folder */ + function ClearCache() + { + if ($handle = opendir($this->CacheFolder)) + { + while (false !== ($file = readdir($handle))) + { + if ( $file != "." && $file != ".." ) + unlink($this->CacheFolder.$file); + } + closedir($handle); + } + } + + /* This function is checking if we have an offline version of this chart */ + function IsInCache($ID,$Data,$Hash="") + { + if ( $Hash == "" ) + $Hash = $this->GetHash($ID,$Data); + + if ( file_exists($this->CacheFolder.$Hash) ) + return(TRUE); + else + return(FALSE); + } + + /* This function is making a copy of drawn chart in the cache folder */ + function WriteToCache($ID,$Data,$Picture) + { + $Hash = $this->GetHash($ID,$Data); + $FileName = $this->CacheFolder.$Hash; + + imagepng($Picture->Picture,$FileName); + } + + /* This function is removing any cached copy of this chart */ + function DeleteFromCache($ID,$Data) + { + $Hash = $this->GetHash($ID,$Data); + $FileName = $this->CacheFolder.$Hash; + + if ( file_exists($FileName ) ) + unlink($FileName); + } + + /* This function is retrieving the cached picture if applicable */ + function GetFromCache($ID,$Data) + { + $Hash = $this->GetHash($ID,$Data); + if ( $this->IsInCache("","",$Hash ) ) + { + $FileName = $this->CacheFolder.$Hash; + + header('Content-type: image/png'); + @readfile($FileName); + exit(); + } + } + + /* This function is building the graph unique hash key */ + function GetHash($ID,$Data) + { + $mKey = "$ID"; + foreach($Data as $key => $Values) + { + $tKey = ""; + foreach($Values as $Serie => $Value) + $tKey = $tKey.$Serie.$Value; + $mKey = $mKey.md5($tKey); + } + return(md5($mKey)); + } + } +?> \ No newline at end of file diff --git a/clients/GD/FSMon/pChart/pChart.class b/clients/GD/FSMon/pChart/pChart.class new file mode 100644 index 0000000..2c56b20 --- /dev/null +++ b/clients/GD/FSMon/pChart/pChart.class @@ -0,0 +1,2883 @@ +. + + Class initialisation : + pChart($XSize,$YSize) + Draw methods : + drawBackground($R,$G,$B) + drawRectangle($X1,$Y1,$X2,$Y2,$R,$G,$B) + drawFilledRectangle($X1,$Y1,$X2,$Y2,$R,$G,$B,$DrawBorder=TRUE,$Alpha=100) + drawRoundedRectangle($X1,$Y1,$X2,$Y2,$Radius,$R,$G,$B) + drawFilledRoundedRectangle($X1,$Y1,$X2,$Y2,$Radius,$R,$G,$B) + drawCircle($Xc,$Yc,$Height,$R,$G,$B,$Width=0) + drawFilledCircle($Xc,$Yc,$Height,$R,$G,$B,$Width=0) + drawEllipse($Xc,$Yc,$Height,$Width,$R,$G,$B) + drawFilledEllipse($Xc,$Yc,$Height,$Width,$R,$G,$B) + drawLine($X1,$Y1,$X2,$Y2,$R,$G,$B,$GraphFunction=FALSE) + drawDottedLine($X1,$Y1,$X2,$Y2,$DotSize,$R,$G,$B) + drawAlphaPixel($X,$Y,$Alpha,$R,$G,$B) + drawFromPNG($FileName,$X,$Y,$Alpha=100) + drawFromGIF($FileName,$X,$Y,$Alpha=100) + drawFromJPG($FileName,$X,$Y,$Alpha=100) + Graph setup methods : + addBorder($Width=3,$R=0,$G=0,$B=0) + drawGraphArea($R,$G,$B,$Stripe=FALSE) + drawScale(&$Data,&$DataDescription,$ScaleMode,$R,$G,$B,$DrawTicks=TRUE,$Angle=0,$Decimals=1,$WithMargin=FALSE,$SkipLabels=1) + drawGrid($LineWidth,$Mosaic=TRUE,$R=220,$G=220,$B=220,$Alpha=100) + drawLegend($XPos,$YPos,&$DataDescription,$R,$G,$B,$Rs=-1,$Gs=-1,$Bs=-1) + drawPieLegend($XPos,$YPos,$Data,$DataDescription,$R,$G,$B) + drawTitle($XPos,$YPos,$Value,$R,$G,$B,$XPos2=-1,$YPos2=-1) + drawTreshold($Value,$R,$G,$B,$ShowLabel=FALSE,$ShowOnRight=FALSE,$TickWidth=4,$FreeText=NULL) + drawArea(&$Data,$Serie1,$Serie2,$R,$G,$B,$Alpha = 50) + drawRadarAxis(&$Data,&$DataDescription,$Mosaic=TRUE,$BorderOffset=10,$A_R=60,$A_G=60,$A_B=60,$S_R=200,$S_G=200,$S_B=200,$MaxValue=-1) + drawGraphAreaGradient($R,$G,$B,$Decay,$Target=TARGET_GRAPHAREA) + drawTextBox($X1,$Y1,$X2,$Y2,$Text,$Angle=0,$R=255,$G=255,$B=255,$Align=ALIGN_LEFT,$Shadow=TRUE,$BgR=-1,$BgG=-1,$BgB=-1,$Alpha=100) + getLegendBoxSize($DataDescription) + loadColorPalette($FileName,$Delimiter=",") + reportWarnings($Interface="CLI") + setGraphArea($X1,$Y1,$X2,$Y2) + setFixedScale($VMin,$VMax) + setLabel(&$Data,&$DataDescription,$SerieName,$ValueName,$Caption,$R=210,$G=210,$B=210) + setColorPalette($ID,$R,$G,$B) + setDateFormat($Format) + setFontProperties($FontName,$FontSize) + setLineStyle($Width=1,$DotSize=0) + setFixedScale($VMin,$VMax,$Divisions=5) + writeValues(&$Data,&$DataDescription,$Series) + Graphs methods : + drawPlotGraph(&$Data,&$DataDescription,$BigRadius=5,$SmallRadius=2,$R2=-1,$G2=-1,$B2=-1) + drawLineGraph(&$Data,&$DataDescription,$SerieName="") + drawFilledLineGraph(&$Data,&$DataDescription,$Alpha=100,$AroundZero=FALSE) + drawCubicCurve(&$Data,&$DataDescription,$Accuracy=.1,$SerieName="") + drawFilledCubicCurve(&$Data,&$DataDescription,$Accuracy=.1,$Alpha=100,$AroundZero=FALSE) + drawOverlayBarGraph(&$Data,&$DataDescription,$Alpha=50) + drawBarGraph(&$Data,&$DataDescription,$Shadow=FALSE) + drawStackedBarGraph(&$Data,&$DataDescription,$Alpha=50) + drawLimitsGraph(&$Data,&$DataDescription,$R=0,$G=0,$B=0) + drawRadar(&$Data,&$DataDescription,$BorderOffset=10,$MaxValue=-1) + drawFilledRadar(&$Data,&$DataDescription,$Alpha=50,$BorderOffset=10,$MaxValue=-1) + drawBasicPieGraph(&$Data,&$DataDescription,$XPos,$YPos,$Radius=100,$DrawLabels=PIE_NOLABEL,$R=255,$G=255,$B=255,$Decimals=0) + drawFlatPieGraph(&$Data,&$DataDescription,$XPos,$YPos,$Radius=100,$DrawLabels=PIE_NOLABEL,$SpliceDistance=0,$Decimals = 0) + drawPieGraph(&$Data,&$DataDescription,$XPos,$YPos,$Radius=100,$DrawLabels=PIE_NOLABEL,$EnhanceColors=TRUE,$Skew=60,$SpliceHeight=20,$SpliceDistance=0,$Decimals=0) + Other methods : + setImageMap($Mode=TRUE,$GraphID="MyGraph") + getImageMap($MapName,$Flush=TRUE) + Render($FileName) + Stroke() + */ + + /* Andrew@DeFaria.com: Empty array for imageftbbox call + See http://bugs.php.net/bug.php?id=26309 + */ + /* Declare some script wide constants */ + define("SCALE_NORMAL",1); + define("SCALE_ADDALL",2); + define("SCALE_START0",3); + define("SCALE_ADDALLSTART0",4); + define("PIE_PERCENTAGE", 1); + define("PIE_LABELS",2); + define("PIE_NOLABEL",3); + define("TARGET_GRAPHAREA",1); + define("TARGET_BACKGROUND",2); + define("ALIGN_TOP_LEFT",1); + define("ALIGN_TOP_CENTER",2); + define("ALIGN_TOP_RIGHT",3); + define("ALIGN_LEFT",4); + define("ALIGN_CENTER",5); + define("ALIGN_RIGHT",6); + define("ALIGN_BOTTOM_LEFT",7); + define("ALIGN_BOTTOM_CENTER",8); + define("ALIGN_BOTTOM_RIGHT",9); + + /* pChart class definition */ + class pChart + { + /* Palettes definition */ + var $Palette = array("0"=>array("R"=>188,"G"=>224,"B"=>46), + "1"=>array("R"=>224,"G"=>100,"B"=>46), + "2"=>array("R"=>224,"G"=>214,"B"=>46), + "3"=>array("R"=>46,"G"=>151,"B"=>224), + "4"=>array("R"=>176,"G"=>46,"B"=>224), + "5"=>array("R"=>224,"G"=>46,"B"=>117), + "6"=>array("R"=>92,"G"=>224,"B"=>46), + "7"=>array("R"=>224,"G"=>176,"B"=>46)); + + /* Some static vars used in the class */ + var $XSize = NULL; + var $YSize = NULL; + var $Picture = NULL; + var $ImageMap = NULL; + + /* Error management */ + var $ErrorReporting = FALSE; + var $ErrorInterface = "CLI"; + var $Errors = NULL; + var $ErrorFontName = "Fonts/pf_arma_five.ttf"; + var $ErrorFontSize = 6; + + /* vars related to the graphing area */ + var $GArea_X1 = NULL; + var $GArea_Y1 = NULL; + var $GArea_X2 = NULL; + var $GArea_Y2 = NULL; + var $GAreaXOffset = NULL; + var $VMax = NULL; + var $VMin = NULL; + var $Divisions = NULL; + var $DivisionHeight = NULL; + var $DivisionCount = NULL; + var $DivisionRatio = NULL; + var $DivisionWidth = NULL; + var $DataCount = NULL; + + /* Text format related vars */ + var $FontName = NULL; + var $FontSize = NULL; + var $DateFormat = "d/m/Y"; + + /* Lines format related vars */ + var $LineWidth = 1; + var $LineDotSize = 0; + + /* Layer related vars */ + var $Layers = NULL; + + /* Set antialias quality : 0 is maximum, 100 minimum*/ + var $AntialiasQuality = 10; + + /* Image Map settings */ + var $BuildMap = FALSE; + var $MapFunction = NULL; + var $tmpFolder = "tmp/"; + var $MapID = NULL; + + /* This function create the background picture */ + function pChart($XSize,$YSize) + { + $this->XSize = $XSize; + $this->YSize = $YSize; + $this->Picture = imagecreatetruecolor($XSize,$YSize); + + $C_White = imagecolorallocate($this->Picture,255,255,255); + imagefilledrectangle($this->Picture,0,0,$XSize,$YSize,$C_White); + imagecolortransparent($this->Picture,$C_White); + + $this->setFontProperties("tahoma.ttf",8); + } + + /* Set if warnings should be reported */ + function reportWarnings($Interface="CLI") + { + $this->ErrorReporting = TRUE; + $this->ErrorInterface = $Interface; + } + + /* Set the font properties */ + function setFontProperties($FontName,$FontSize) + { + $this->FontName = $FontName; + $this->FontSize = $FontSize; + } + + /* Set Palette color */ + function setColorPalette($ID,$R,$G,$B) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $this->Palette[$ID]["R"] = $R; + $this->Palette[$ID]["G"] = $G; + $this->Palette[$ID]["B"] = $B; + } + + /* Load Color Palette from file */ + function loadColorPalette($FileName,$Delimiter=",") + { + $handle = @fopen($FileName,"r"); + $ColorID = 0; + if ($handle) + { + while (!feof($handle)) + { + $buffer = fgets($handle, 4096); + $buffer = str_replace(chr(10),"",$buffer); + $buffer = str_replace(chr(13),"",$buffer); + $Values = split($Delimiter,$buffer); + if ( count($Values) == 3 ) + { + $this->Palette[$ColorID]["R"] = $Values[0]; + $this->Palette[$ColorID]["G"] = $Values[1]; + $this->Palette[$ColorID]["B"] = $Values[2]; + $ColorID++; + } + } + } + } + + /* Set line style */ + function setLineStyle($Width=1,$DotSize=0) + { + $this->LineWidth = $Width; + $this->LineDotSize = $DotSize; + } + + /* Set the graph area location */ + function setGraphArea($X1,$Y1,$X2,$Y2) + { + $this->GArea_X1 = $X1; + $this->GArea_Y1 = $Y1; + $this->GArea_X2 = $X2; + $this->GArea_Y2 = $Y2; + } + + /* Prepare the graph area */ + function drawGraphArea($R,$G,$B,$Stripe=FALSE) + { + $this->drawFilledRectangle($this->GArea_X1,$this->GArea_Y1,$this->GArea_X2,$this->GArea_Y2,$R,$G,$B,FALSE); + $this->drawRectangle($this->GArea_X1,$this->GArea_Y1,$this->GArea_X2,$this->GArea_Y2,$R-40,$G-40,$B-40); + + if ( $Stripe ) + { + $R2 = $R-15; if ( $R2 < 0 ) { $R2 = 0; } + $G2 = $R-15; if ( $G2 < 0 ) { $G2 = 0; } + $B2 = $R-15; if ( $B2 < 0 ) { $B2 = 0; } + + $LineColor = imagecolorallocate($this->Picture,$R2,$G2,$B2); + $SkewWidth = $this->GArea_Y2-$this->GArea_Y1-1; + + for($i=$this->GArea_X1-$SkewWidth;$i<=$this->GArea_X2;$i=$i+4) + { + $X1 = $i; $Y1 = $this->GArea_Y2; + $X2 = $i+$SkewWidth; $Y2 = $this->GArea_Y1; + + + if ( $X1 < $this->GArea_X1 ) + { $X1 = $this->GArea_X1; $Y1 = $this->GArea_Y1 + $X2 - $this->GArea_X1 + 1; } + + if ( $X2 >= $this->GArea_X2 ) + { $Y2 = $this->GArea_Y1 + $X2 - $this->GArea_X2 +1; $X2 = $this->GArea_X2 - 1; } +// * Fixed in 1.27 * { $X2 = $this->GArea_X2 - 1; $Y2 = $this->GArea_Y2 - ($this->GArea_X2 - $X1); } + + imageline($this->Picture,$X1,$Y1,$X2,$Y2+1,$LineColor); + } + } + } + + /* Allow you to fix the scale, use this to bypass the automatic scaling */ + function setFixedScale($VMin,$VMax,$Divisions=5) + { + $this->VMin = $VMin; + $this->VMax = $VMax; + $this->Divisions = $Divisions; + } + + /* Compute and draw the scale */ + function drawScale(&$Data,&$DataDescription,$ScaleMode,$R,$G,$B,$DrawTicks=TRUE,$Angle=0,$Decimals=1,$WithMargin=FALSE,$SkipLabels=1) + { + /* Validate the Data and DataDescription array */ + $this->validateData("drawScale",$Data); + + $C_TextColor = imagecolorallocate($this->Picture,$R,$G,$B); + + $this->drawLine($this->GArea_X1,$this->GArea_Y1,$this->GArea_X1,$this->GArea_Y2,$R,$G,$B); + $this->drawLine($this->GArea_X1,$this->GArea_Y2,$this->GArea_X2,$this->GArea_Y2,$R,$G,$B); + + if ( $this->VMin == NULL && $this->VMax == NULL) + { + if (isset($DataDescription["Values"][0])) + { + $this->VMin = $Data[0][$DataDescription["Values"][0]]; + $this->VMax = $Data[0][$DataDescription["Values"][0]]; + } + else { $this->VMin = 2147483647; $this->VMax = -2147483647; } + + /* Compute Min and Max values */ + if ( $ScaleMode == SCALE_NORMAL || $ScaleMode == SCALE_START0 ) + { + if ( $ScaleMode == SCALE_START0 ) { $this->VMin = 0; } + + foreach ( $Data as $Key => $Values ) + { + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + if (isset($Data[$Key][$ColName])) + { + $Value = $Data[$Key][$ColName]; + + if ( is_numeric($Value) ) + { + if ( $this->VMax < $Value) { $this->VMax = $Value; } + if ( $this->VMin > $Value) { $this->VMin = $Value; } + } + } + } + } + } + elseif ( $ScaleMode == SCALE_ADDALL || $ScaleMode == SCALE_ADDALLSTART0 ) /* Experimental */ + { + if ( $ScaleMode == SCALE_ADDALLSTART0 ) { $this->VMin = 0; } + + foreach ( $Data as $Key => $Values ) + { + $Sum = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + if (isset($Data[$Key][$ColName])) + { + $Value = $Data[$Key][$ColName]; + if ( is_numeric($Value) ) + $Sum += $Value; + } + } + if ( $this->VMax < $Sum) { $this->VMax = $Sum; } + if ( $this->VMin > $Sum) { $this->VMin = $Sum; } + } + } + + $DataRange = $this->VMax - $this->VMin; + if ( $DataRange == 0 ) { $DataRange = .1; } + + /* Compute automatic scaling */ + $ScaleOk = FALSE; $Factor = 1; + $MinDivHeight = 25; $MaxDivs = ($this->GArea_Y2 - $this->GArea_Y1) / $MinDivHeight; + if ($MaxDivs > 1) + { + while(!$ScaleOk) + { + $Scale1 = ( $this->VMax - $this->VMin ) / $Factor; + $Scale2 = ( $this->VMax - $this->VMin ) / $Factor / 2; + $Scale4 = ( $this->VMax - $this->VMin ) / $Factor / 4; + + if ( $Scale1 > 1 && $Scale1 <= $MaxDivs && !$ScaleOk) { $ScaleOk = TRUE; $Divisions = floor($Scale1); $Scale = 1;} + if ( $Scale2 > 1 && $Scale2 <= $MaxDivs && !$ScaleOk) { $ScaleOk = TRUE; $Divisions = floor($Scale2); $Scale = 2;} + if (!$ScaleOk) + { + if ( $Scale2 > 1 ) { $Factor = $Factor * 10; } + if ( $Scale2 < 1 ) { $Factor = $Factor / 10; } + } + } + + if ( floor($this->VMax / $Scale / $Factor) != $this->VMax / $Scale / $Factor) + { + $GridID = floor ( $this->VMax / $Scale / $Factor) + 1; + $this->VMax = $GridID * $Scale * $Factor; + $Divisions++; + } + + if ( floor($this->VMin / $Scale / $Factor) != $this->VMin / $Scale / $Factor) + { + $GridID = floor( $this->VMin / $Scale / $Factor); + $this->VMin = $GridID * $Scale * $Factor; + $Divisions++; + } + } + else /* Can occurs for small graphs */ + $Scale = 1; + + if ( !isset($Divisions) ) + $Divisions = 2; + + if ($Scale == 1 && $Divisions%2 == 1) + $Divisions--; + } + else + $Divisions = $this->Divisions; + + $this->DivisionCount = $Divisions; + + $DataRange = $this->VMax - $this->VMin; + if ( $DataRange == 0 ) { $DataRange = .1; } + + $this->DivisionHeight = ( $this->GArea_Y2 - $this->GArea_Y1 ) / $Divisions; + $this->DivisionRatio = ( $this->GArea_Y2 - $this->GArea_Y1 ) / $DataRange; + + $this->GAreaXOffset = 0; + if ( count($Data) > 1 ) + { + if ( $WithMargin == FALSE ) + $this->DivisionWidth = ( $this->GArea_X2 - $this->GArea_X1 ) / (count($Data)-1); + else + { + $this->DivisionWidth = ( $this->GArea_X2 - $this->GArea_X1 ) / (count($Data)); + $this->GAreaXOffset = $this->DivisionWidth / 2; + } + } + else + { + $this->DivisionWidth = $this->GArea_X2 - $this->GArea_X1; + $this->GAreaXOffset = $this->DivisionWidth / 2; + } + + $this->DataCount = count($Data); + + if ( $DrawTicks == FALSE ) + return(0); + + $YPos = $this->GArea_Y2; $XMin = NULL; + for($i=1;$i<=$Divisions+1;$i++) + { + $this->drawLine($this->GArea_X1,$YPos,$this->GArea_X1-5,$YPos,$R,$G,$B); + $Value = $this->VMin + ($i-1) * (( $this->VMax - $this->VMin ) / $Divisions); + $Value = round($Value * pow(10,$Decimals)) / pow(10,$Decimals); + if ( $DataDescription["Format"]["Y"] == "number" ) + $Value = $Value.$DataDescription["Unit"]["Y"]; + if ( $DataDescription["Format"]["Y"] == "time" ) + $Value = $this->ToTime($Value); + if ( $DataDescription["Format"]["Y"] == "date" ) + $Value = $this->ToDate($Value); + if ( $DataDescription["Format"]["Y"] == "metric" ) + $Value = $this->ToMetric($Value); + + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Value,$bogus); + $TextWidth = $Position[2]-$Position[0]; + imagettftext($this->Picture,$this->FontSize,0,$this->GArea_X1-10-$TextWidth,$YPos+($this->FontSize/2),$C_TextColor,$this->FontName,$Value); + + if ( $XMin > $this->GArea_X1-10-$TextWidth || $XMin == NULL ) { $XMin = $this->GArea_X1-10-$TextWidth; } + + $YPos = $YPos - $this->DivisionHeight; + } + + /* Write the Y Axis caption if set */ + if ( isset($DataDescription["Axis"]["Y"]) ) + { + $Position = imageftbbox($this->FontSize,90,$this->FontName,$DataDescription["Axis"]["Y"],$bogus); + $TextHeight = abs($Position[1])+abs($Position[3]); + $TextTop = (($this->GArea_Y2 - $this->GArea_Y1) / 2) + $this->GArea_Y1 + ($TextHeight/2); + imagettftext($this->Picture,$this->FontSize,90,$XMin-$this->FontSize,$TextTop,$C_TextColor,$this->FontName,$DataDescription["Axis"]["Y"]); + } + + /* Horizontal Axis */ + $XPos = $this->GArea_X1 + $this->GAreaXOffset; + $ID = 1; $YMax = NULL; + foreach ( $Data as $Key => $Values ) + { + if ( $ID % $SkipLabels == 0 ) + { + $this->drawLine(floor($XPos),$this->GArea_Y2,floor($XPos),$this->GArea_Y2+5,$R,$G,$B); + $Value = $Data[$Key][$DataDescription["Position"]]; + if ( $DataDescription["Format"]["X"] == "number" ) + $Value = $Value.$DataDescription["Unit"]["X"]; + if ( $DataDescription["Format"]["X"] == "time" ) + $Value = $this->ToTime($Value); + if ( $DataDescription["Format"]["X"] == "date" ) + $Value = $this->ToDate($Value); + if ( $DataDescription["Format"]["X"] == "metric" ) + $Value = $this->ToMetric($Value); + + $Position = imageftbbox($this->FontSize,$Angle,$this->FontName,$Value,$bogus); + $TextWidth = abs($Position[2])+abs($Position[0]); + $TextHeight = abs($Position[1])+abs($Position[3]); + + if ( $Angle == 0 ) + { + $YPos = $this->GArea_Y2+18; + imagettftext($this->Picture,$this->FontSize,$Angle,floor($XPos)-floor($TextWidth/2),$YPos,$C_TextColor,$this->FontName,$Value); + } + else + { + $YPos = $this->GArea_Y2+10+$TextHeight; + if ( $Angle <= 90 ) + imagettftext($this->Picture,$this->FontSize,$Angle,floor($XPos)-$TextWidth+5,$YPos,$C_TextColor,$this->FontName,$Value); + else + imagettftext($this->Picture,$this->FontSize,$Angle,floor($XPos)+$TextWidth+5,$YPos,$C_TextColor,$this->FontName,$Value); + } + if ( $YMax < $YPos || $YMax == NULL ) { $YMax = $YPos; } + } + + $XPos = $XPos + $this->DivisionWidth; + $ID++; + } + + /* Write the X Axis caption if set */ + if ( isset($DataDescription["Axis"]["X"]) ) + { + $Position = imageftbbox($this->FontSize,90,$this->FontName,$DataDescription["Axis"]["X"],$bogus); + $TextWidth = abs($Position[2])+abs($Position[0]); + $TextLeft = (($this->GArea_X2 - $this->GArea_X1) / 2) + $this->GArea_X1 + ($TextWidth/2); + imagettftext($this->Picture,$this->FontSize,0,$TextLeft,$YMax+$this->FontSize+5,$C_TextColor,$this->FontName,$DataDescription["Axis"]["X"]); + } + } + + /* Compute and draw the scale */ + function drawGrid($LineWidth,$Mosaic=TRUE,$R=220,$G=220,$B=220,$Alpha=100) + { + /* Draw mosaic */ + if ( $Mosaic ) + { + $LayerWidth = $this->GArea_X2-$this->GArea_X1; + $LayerHeight = $this->GArea_Y2-$this->GArea_Y1; + + $this->Layers[0] = imagecreatetruecolor($LayerWidth,$LayerHeight); + $C_White = imagecolorallocate($this->Layers[0],255,255,255); + imagefilledrectangle($this->Layers[0],0,0,$LayerWidth,$LayerHeight,$C_White); + imagecolortransparent($this->Layers[0],$C_White); + + $C_Rectangle = imagecolorallocate($this->Layers[0],250,250,250); + + $YPos = $LayerHeight; //$this->GArea_Y2-1; + $LastY = $YPos; + for($i=0;$i<=$this->DivisionCount;$i++) + { + $LastY = $YPos; + $YPos = $YPos - $this->DivisionHeight; + + if ( $YPos <= 0 ) { $YPos = 1; } + + if ( $i % 2 == 0 ) + { + imagefilledrectangle($this->Layers[0],1,$YPos,$LayerWidth-1,$LastY,$C_Rectangle); + } + } + imagecopymerge($this->Picture,$this->Layers[0],$this->GArea_X1,$this->GArea_Y1,0,0,$LayerWidth,$LayerHeight,$Alpha); + imagedestroy($this->Layers[0]); + } + + /* Horizontal lines */ + $YPos = $this->GArea_Y2 - $this->DivisionHeight; + for($i=1;$i<=$this->DivisionCount;$i++) + { + if ( $YPos > $this->GArea_Y1 && $YPos < $this->GArea_Y2 ) + $this->drawDottedLine($this->GArea_X1,$YPos,$this->GArea_X2,$YPos,$LineWidth,$R,$G,$B); + + $YPos = $YPos - $this->DivisionHeight; + } + + /* Vertical lines */ + if ( $this->GAreaXOffset == 0 ) + { $XPos = $this->GArea_X1 + $this->DivisionWidth + $this->GAreaXOffset; $ColCount = $this->DataCount-2; } + else + { $XPos = $this->GArea_X1 + $this->GAreaXOffset; $ColCount = $this->DataCount; } + + for($i=1;$i<=$ColCount;$i++) + { + if ( $XPos > $this->GArea_X1 && $XPos < $this->GArea_X2 ) + $this->drawDottedLine(floor($XPos),$this->GArea_Y1,floor($XPos),$this->GArea_Y2,$LineWidth,$R,$G,$B); + $XPos = $XPos + $this->DivisionWidth; + } + } + + /* retrieve the legends size */ + function getLegendBoxSize($DataDescription) + { + if ( !isset($DataDescription["Description"]) ) + return(-1); + + /* <-10->[8]<-4->Text<-10-> */ + $MaxWidth = 0; $MaxHeight = 8; + foreach($DataDescription["Description"] as $Key => $Value) + { + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Value,$bogus); + $TextWidth = $Position[2]-$Position[0]; + $TextHeight = $Position[1]-$Position[7]; + if ( $TextWidth > $MaxWidth) { $MaxWidth = $TextWidth; } + $MaxHeight = $MaxHeight + $TextHeight + 4; + } + $MaxHeight = $MaxHeight - 3; + $MaxWidth = $MaxWidth + 32; + + return(array($MaxWidth,$MaxHeight)); + } + + /* Draw the data legends */ + function drawLegend($XPos,$YPos,&$DataDescription,$R,$G,$B,$Rs=-1,$Gs=-1,$Bs=-1) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawLegend",$DataDescription); + + if ( !isset($DataDescription["Description"]) ) + return(-1); + + $C_TextColor = imagecolorallocate($this->Picture,0,0,0); + + /* <-10->[8]<-4->Text<-10-> */ + $MaxWidth = 0; $MaxHeight = 8; + foreach($DataDescription["Description"] as $Key => $Value) + { + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Value,$bogus); + $TextWidth = $Position[2]-$Position[0]; + $TextHeight = $Position[1]-$Position[7]; + if ( $TextWidth > $MaxWidth) { $MaxWidth = $TextWidth; } + $MaxHeight = $MaxHeight + $TextHeight + 4; + } + $MaxHeight = $MaxHeight - 5; + $MaxWidth = $MaxWidth + 32; + + if ( $Rs == -1 || $Gs == -1 || $Bs == -1 ) + { $Rs = $R-30; $Gs = $G-30; $Bs = $B-30; } + + $this->drawFilledRoundedRectangle($XPos+1,$YPos+1,$XPos+$MaxWidth+1,$YPos+$MaxHeight+1,5,$Rs,$Gs,$Bs); + $this->drawFilledRoundedRectangle($XPos,$YPos,$XPos+$MaxWidth,$YPos+$MaxHeight,5,$R,$G,$B); + + $YOffset = 4 + $this->FontSize; $ID = 0; + foreach($DataDescription["Description"] as $Key => $Value) + { + $this->drawFilledRoundedRectangle($XPos+10,$YPos+$YOffset-4,$XPos+14,$YPos+$YOffset-4,2,$this->Palette[$ID]["R"],$this->Palette[$ID]["G"],$this->Palette[$ID]["B"]); + imagettftext($this->Picture,$this->FontSize,0,$XPos+22,$YPos+$YOffset,$C_TextColor,$this->FontName,$Value); + + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Value,$bogus); + $TextHeight = $Position[1]-$Position[7]; + + $YOffset = $YOffset + $TextHeight + 4; + $ID++; + } + } + + /* Draw the data legends */ + function drawPieLegend($XPos,$YPos,&$Data,&$DataDescription,$R,$G,$B) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawPieLegend",$DataDescription,FALSE); + $this->validateData("drawPieLegend",$Data); + + if ( !isset($DataDescription["Position"]) ) + return(-1); + + $C_TextColor = imagecolorallocate($this->Picture,0,0,0); + + /* <-10->[8]<-4->Text<-10-> */ + $MaxWidth = 0; $MaxHeight = 8; + foreach($Data as $Key => $Value) + { + $Value2 = $Value[$DataDescription["Position"]]; + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Value2,$bogus); + $TextWidth = $Position[2]-$Position[0]; + $TextHeight = $Position[1]-$Position[7]; + if ( $TextWidth > $MaxWidth) { $MaxWidth = $TextWidth; } + + $MaxHeight = $MaxHeight + $TextHeight + 4; + } + $MaxHeight = $MaxHeight - 3; + $MaxWidth = $MaxWidth + 32; + + $this->drawFilledRoundedRectangle($XPos+1,$YPos+1,$XPos+$MaxWidth+1,$YPos+$MaxHeight+1,5,$R-30,$G-30,$B-30); + $this->drawFilledRoundedRectangle($XPos,$YPos,$XPos+$MaxWidth,$YPos+$MaxHeight,5,$R,$G,$B); + + $YOffset = 4 + $this->FontSize; $ID = 0; + foreach($Data as $Key => $Value) + { + $Value2 = $Value[$DataDescription["Position"]]; + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Value2,$bogus); + $TextHeight = $Position[1]-$Position[7]; + $this->drawFilledRectangle($XPos+10,$YPos+$YOffset-6,$XPos+14,$YPos+$YOffset-2,$this->Palette[$ID]["R"],$this->Palette[$ID]["G"],$this->Palette[$ID]["B"]); + + imagettftext($this->Picture,$this->FontSize,0,$XPos+22,$YPos+$YOffset,$C_TextColor,$this->FontName,$Value2); + $YOffset = $YOffset + $TextHeight + 4; + $ID++; + } + } + + /* Draw the graph title */ + function drawTitle($XPos,$YPos,$Value,$R,$G,$B,$XPos2 = -1, $YPos2 = -1) + { + $C_TextColor = imagecolorallocate($this->Picture,$R,$G,$B); + + if ( $XPos2 != -1 ) + { + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Value,$bogus); + $TextWidth = $Position[2]-$Position[0]; + $XPos = floor(( $XPos2 - $XPos - $TextWidth ) / 2 ) + $XPos; + } + + if ( $YPos2 != -1 ) + { + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Value,$bogus); + $TextHeight = $Position[5]-$Position[3]; + $YPos = floor(( $YPos2 - $YPos - $TextHeight ) / 2 ) + $YPos; + } + + imagettftext($this->Picture,$this->FontSize,0,$XPos,$YPos,$C_TextColor,$this->FontName,$Value); + } + + /* Draw a text box with text align & alpha properties */ + function drawTextBox($X1,$Y1,$X2,$Y2,$Text,$Angle=0,$R=255,$G=255,$B=255,$Align=ALIGN_LEFT,$Shadow=TRUE,$BgR=-1,$BgG=-1,$BgB=-1,$Alpha=100) + { + $Position = imageftbbox($this->FontSize,$Angle,$this->FontName,$Text,$bogus); + $TextWidth = $Position[2]-$Position[0]; + $TextHeight = $Position[5]-$Position[3]; + $AreaWidth = $X2 - $X1; + $AreaHeight = $Y2 - $Y1; + + if ( $BgR != -1 && $BgG != -1 && $BgB != -1 ) + $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,$BgR,$BgG,$BgB,FALSE,$Alpha); + + if ( $Align == ALIGN_TOP_LEFT ) { $X = $X1+1; $Y = $Y1+$this->FontSize+1; } + if ( $Align == ALIGN_TOP_CENTER ) { $X = $X1+($AreaWidth/2)-($TextWidth/2); $Y = $Y1+$this->FontSize+1; } + if ( $Align == ALIGN_TOP_RIGHT ) { $X = $X2-$TextWidth-1; $Y = $Y1+$this->FontSize+1; } + if ( $Align == ALIGN_LEFT ) { $X = $X1+1; $Y = $Y1+($AreaHeight/2)-($TextHeight/2); } + if ( $Align == ALIGN_CENTER ) { $X = $X1+($AreaWidth/2)-($TextWidth/2); $Y = $Y1+($AreaHeight/2)-($TextHeight/2); } + if ( $Align == ALIGN_RIGHT ) { $X = $X2-$TextWidth-1; $Y = $Y1+($AreaHeight/2)-($TextHeight/2); } + if ( $Align == ALIGN_BOTTOM_LEFT ) { $X = $X1+1; $Y = $Y2-1; } + if ( $Align == ALIGN_BOTTOM_CENTER ) { $X = $X1+($AreaWidth/2)-($TextWidth/2); $Y = $Y2-1; } + if ( $Align == ALIGN_BOTTOM_RIGHT ) { $X = $X2-$TextWidth-1; $Y = $Y2-1; } + + $C_TextColor = imagecolorallocate($this->Picture,$R,$G,$B); + $C_ShadowColor = imagecolorallocate($this->Picture,0,0,0); + if ( $Shadow ) + imagettftext($this->Picture,$this->FontSize,$Angle,$X+1,$Y+1,$C_ShadowColor,$this->FontName,$Text); + + imagettftext($this->Picture,$this->FontSize,$Angle,$X,$Y,$C_TextColor,$this->FontName,$Text); + } + + /* Compute and draw the scale */ + function drawTreshold($Value,$R,$G,$B,$ShowLabel=FALSE,$ShowOnRight=FALSE,$TickWidth=4,$FreeText=NULL) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $C_TextColor = imagecolorallocate($this->Picture,$R,$G,$B); + $Y = $this->GArea_Y2 - ($Value - $this->VMin) * $this->DivisionRatio; + + if ( $Y <= $this->GArea_Y1 || $Y >= $this->GArea_Y2 ) + return(-1); + + if ( $TickWidth == 0 ) + $this->drawLine($this->GArea_X1,$Y,$this->GArea_X2,$Y,$R,$G,$B); + else + $this->drawDottedLine($this->GArea_X1,$Y,$this->GArea_X2,$Y,$TickWidth,$R,$G,$B); + + if ( $ShowLabel ) + { + if ( $FreeText == NULL ) + { $Label = $Value; } else { $Label = $FreeText; } + + if ( $ShowOnRight ) + imagettftext($this->Picture,$this->FontSize,0,$this->GArea_X2+2,$Y+($this->FontSize/2),$C_TextColor,$this->FontName,$Label); + else + imagettftext($this->Picture,$this->FontSize,0,$this->GArea_X1+2,$Y-($this->FontSize/2),$C_TextColor,$this->FontName,$Label); + } + } + + /* This function put a label on a specific point */ + function setLabel(&$Data,&$DataDescription,$SerieName,$ValueName,$Caption,$R=210,$G=210,$B=210) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("setLabel",$DataDescription); + $this->validateData("setLabel",$Data); + + $C_Label = imagecolorallocate($this->Picture,$R,$G,$B); + $C_Shadow = imagecolorallocate($this->Picture,$R-30,$G-30,$B-30); + $C_TextColor = imagecolorallocate($this->Picture,0,0,0); + + $Cp = 0; $Found = FALSE; + foreach ( $Data as $Key => $Value ) + { + if ( $Data[$Key][$DataDescription["Position"]] == $ValueName ) + { $NumericalValue = $Data[$Key][$SerieName]; $Found = TRUE; } + if ( !$Found ) + $Cp++; + } + + $XPos = $this->GArea_X1 + $this->GAreaXOffset + ( $this->DivisionWidth * $Cp ) + 2; + $YPos = $this->GArea_Y2 - ($NumericalValue - $this->VMin) * $this->DivisionRatio; + + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Caption,$bogus); + $TextHeight = $Position[3] - $Position[5]; + $TextWidth = $Position[2]-$Position[0]; + $TextOffset = floor($TextHeight/2); + + // Shadow + $Poly = array($XPos+1,$YPos+1,$XPos + 9,$YPos - $TextOffset,$XPos + 8,$YPos + $TextOffset + 2); + imagefilledpolygon($this->Picture,$Poly,3,$C_Shadow); + $this->drawLine($XPos,$YPos+1,$XPos + 9,$YPos - $TextOffset - 1,$R-30,$G-30,$B-30); + $this->drawLine($XPos,$YPos+1,$XPos + 9,$YPos + $TextOffset + 3,$R-30,$G-30,$B-30); + $this->drawFilledRectangle($XPos + 9,$YPos - $TextOffset,$XPos + 13 + $TextWidth,$YPos + $TextOffset + 2,$R-30,$G-30,$B-30); + + // Label background + $Poly = array($XPos,$YPos,$XPos + 8,$YPos - $TextOffset - 1,$XPos + 8,$YPos + $TextOffset + 1); + imagefilledpolygon($this->Picture,$Poly,3,$C_Label); + $this->drawLine($XPos-1,$YPos,$XPos + 8,$YPos - $TextOffset - 2,$R,$G,$B); + $this->drawLine($XPos-1,$YPos,$XPos + 8,$YPos + $TextOffset + 2,$R,$G,$B); + $this->drawFilledRectangle($XPos + 8,$YPos - $TextOffset - 1,$XPos + 12 + $TextWidth,$YPos + $TextOffset + 1,$R,$G,$B); + + imagettftext($this->Picture,$this->FontSize,0,$XPos + 10,$YPos + $TextOffset,$C_TextColor,$this->FontName,$Caption); + } + + /* This function draw a line graph */ + function drawPlotGraph(&$Data,&$DataDescription,$BigRadius=5,$SmallRadius=2,$R2=-1,$G2=-1,$B2=-1) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawPlotGraph",$DataDescription); + $this->validateData("drawPlotGraph",$Data); + + $GraphID = 0; + + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + $R = $this->Palette[$ColorID]["R"]; + $G = $this->Palette[$ColorID]["G"]; + $B = $this->Palette[$ColorID]["B"]; + + if ( isset($DataDescription["Symbol"][$ColName]) ) + { + //$Is_Alpha = ((ord ( file_get_contents ($DataDescription["Symbol"][$ColName], false, null, 25, 1)) & 6) & 4) == 4; + $Is_Alpha = ((ord ( file_get_contents ($DataDescription["Symbol"][$ColName], false)) & 6) & 4) == 4; + + $Infos = getimagesize($DataDescription["Symbol"][$ColName]); + $ImageWidth = $Infos[0]; + $ImageHeight = $Infos[1]; + $Symbol = imagecreatefromgif($DataDescription["Symbol"][$ColName]); + } + + $XPos = $this->GArea_X1 + $this->GAreaXOffset; + $Hsize = round($BigRadius/2); + foreach ( $Data as $Key => $Values ) + { + $Value = $Data[$Key][$ColName]; + $YPos = $this->GArea_Y2 - (($Value-$this->VMin) * $this->DivisionRatio); + + /* Save point into the image map if option activated */ + if ( $this->BuildMap ) + $this->addToImageMap($XPos-$Hsize,$YPos-$Hsize,$XPos+1+$Hsize,$YPos+$Hsize+1,$DataDescription["Description"][$ColName],$Data[$Key][$ColName].$DataDescription["Unit"]["Y"],"Plot"); + + if ( is_numeric($Value) ) + { + if ( !isset($DataDescription["Symbol"][$ColName]) ) + { + $this->drawFilledCircle($XPos+1,$YPos+1,$BigRadius,$R,$G,$B); + + if ( $R2 !=-1 && $G2 !=-1 && $B2 !=-1 ) + $this->drawFilledCircle($XPos+1,$YPos+1,$SmallRadius,$R2,$G2,$B2); + else + { + $R = $this->Palette[$ColorID]["R"]-5; if ( $R < 0 ) { $R = 0; } + $G = $this->Palette[$ColorID]["G"]-5; if ( $G < 0 ) { $G = 0; } + $B = $this->Palette[$ColorID]["B"]-5; if ( $B < 0 ) { $B = 0; } + + $this->drawFilledCircle($XPos+1,$YPos+1,$SmallRadius,$R,$G,$B); + } + } + else + { + imagecopymerge($this->Picture,$Symbol,$XPos+1-$ImageWidth/2,$YPos+1-$ImageHeight/2,0,0,$ImageWidth,$ImageHeight,100); + } + } + + $XPos = $XPos + $this->DivisionWidth; + } + $GraphID++; + } + } + + + /* This function draw an area between two series */ + function drawArea(&$Data,$Serie1,$Serie2,$R,$G,$B,$Alpha = 50) + { + /* Validate the Data and DataDescription array */ + $this->validateData("drawArea",$Data); + + $LayerWidth = $this->GArea_X2-$this->GArea_X1; + $LayerHeight = $this->GArea_Y2-$this->GArea_Y1; + + $this->Layers[0] = imagecreatetruecolor($LayerWidth,$LayerHeight); + $C_White = imagecolorallocate($this->Layers[0],255,255,255); + imagefilledrectangle($this->Layers[0],0,0,$LayerWidth,$LayerHeight,$C_White); + imagecolortransparent($this->Layers[0],$C_White); + + $C_Graph = imagecolorallocate($this->Layers[0],$R,$G,$B); + + $XPos = $this->GAreaXOffset; + $LastXPos = -1; + foreach ( $Data as $Key => $Values ) + { + $Value1 = $Data[$Key][$Serie1]; + $Value2 = $Data[$Key][$Serie2]; + $YPos1 = $LayerHeight - (($Value1-$this->VMin) * $this->DivisionRatio); + $YPos2 = $LayerHeight - (($Value2-$this->VMin) * $this->DivisionRatio); + + if ( $LastXPos != -1 ) + { + $Points = ""; + $Points[] = $LastXPos; $Points[] = $LastYPos1; + $Points[] = $LastXPos; $Points[] = $LastYPos2; + $Points[] = $XPos; $Points[] = $YPos2; + $Points[] = $XPos; $Points[] = $YPos1; + + imagefilledpolygon($this->Layers[0],$Points,4,$C_Graph); + } + + $LastYPos1 = $YPos1; + $LastYPos2 = $YPos2; + $LastXPos = $XPos; + + $XPos = $XPos + $this->DivisionWidth; + } + + imagecopymerge($this->Picture,$this->Layers[0],$this->GArea_X1,$this->GArea_Y1,0,0,$LayerWidth,$LayerHeight,$Alpha); + imagedestroy($this->Layers[0]); + } + + + /* This function write the values of the specified series */ + function writeValues(&$Data,&$DataDescription,$Series) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("writeValues",$DataDescription); + $this->validateData("writeValues",$Data); + + if ( !is_array($Series) ) { $Series = array($Series); } + + foreach($Series as $Key => $Serie) + { + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $Serie ) { $ColorID = $ID; }; $ID++; } + + $XPos = $this->GArea_X1 + $this->GAreaXOffset; + $XLast = -1; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$Serie]) && is_numeric($Data[$Key][$Serie])) + { + $Value = $Data[$Key][$Serie]; + $YPos = $this->GArea_Y2 - (($Value-$this->VMin) * $this->DivisionRatio); + + $Positions = imagettfbbox($this->FontSize,0,$this->FontName,$Value); + $Width = $Positions[2] - $Positions[6]; $XOffset = $XPos - ($Width/2); + $Height = $Positions[3] - $Positions[7]; $YOffset = $YPos - 4; + + $C_TextColor = imagecolorallocate($this->Picture,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + imagettftext($this->Picture,$this->FontSize,0,$XOffset,$YOffset,$C_TextColor,$this->FontName,$Value); + } + $XPos = $XPos + $this->DivisionWidth; + } + + } + } + + /* This function draw a line graph */ + function drawLineGraph(&$Data,&$DataDescription,$SerieName="") + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawLineGraph",$DataDescription); + $this->validateData("drawLineGraph",$Data); + + $GraphID = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + if ( $SerieName == "" || $SerieName == $ColName ) + { + $XPos = $this->GArea_X1 + $this->GAreaXOffset; + $XLast = -1; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + { + $Value = $Data[$Key][$ColName]; + $YPos = $this->GArea_Y2 - (($Value-$this->VMin) * $this->DivisionRatio); + + /* Save point into the image map if option activated */ + if ( $this->BuildMap ) + $this->addToImageMap($XPos-3,$YPos-3,$XPos+3,$YPos+3,$DataDescription["Description"][$ColName],$Data[$Key][$ColName].$DataDescription["Unit"]["Y"],"Line"); + + if (!is_numeric($Value)) { $XLast = -1; } + if ( $XLast != -1 ) + $this->drawLine($XLast,$YLast,$XPos,$YPos,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"],TRUE); + + $XLast = $XPos; + $YLast = $YPos; + if (!is_numeric($Value)) { $XLast = -1; } + } + $XPos = $XPos + $this->DivisionWidth; + } + $GraphID++; + } + } + } + + /* This function draw a cubic curve */ + function drawCubicCurve(&$Data,&$DataDescription,$Accuracy=.1,$SerieName="") + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawCubicCurve",$DataDescription); + $this->validateData("drawCubicCurve",$Data); + + $GraphID = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + if ( $SerieName == "" || $SerieName == $ColName ) + { + $XIn = ""; $Yin = ""; $Yt = ""; $U = ""; + $XIn[0] = 0; $YIn[0] = 0; + + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + $Index = 1; + $XLast = -1; $Missing = ""; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName]) ) + { + $Value = $Data[$Key][$ColName]; + $XIn[$Index] = $Index; + $YIn[$Index] = $Value; + if ( !is_numeric($Value) ) { $Missing[$Index] = TRUE; } + $Index++; + } + } + $Index--; + + $Yt[0] = 0; + $Yt[1] = 0; + $U[1] = 0; + for($i=2;$i<=$Index-1;$i++) + { + $Sig = ($XIn[$i] - $XIn[$i-1]) / ($XIn[$i+1] - $XIn[$i-1]); + $p = $Sig * $Yt[$i-1] + 2; + $Yt[$i] = ($Sig - 1) / $p; + $U[$i] = ($YIn[$i+1] - $YIn[$i]) / ($XIn[$i+1] - $XIn[$i]) - ($YIn[$i] - $YIn[$i-1]) / ($XIn[$i] - $XIn[$i-1]); + $U[$i] = (6 * $U[$i] / ($XIn[$i+1] - $XIn[$i-1]) - $Sig * $U[$i-1]) / $p; + } + + $qn = 0; + $un = 0; + $Yt[$Index] = ($un - $qn * $U[$Index-1]) / ($qn * $Yt[$Index-1] + 1); + + for($k=$Index-1;$k>=1;$k--) + $Yt[$k] = $Yt[$k] * $Yt[$k+1] + $U[$k]; + + $XPos = $this->GArea_X1 + $this->GAreaXOffset; + for($X=1;$X<=$Index;$X=$X+$Accuracy) + { + $klo = 1; + $khi = $Index; + $k = $khi - $klo; + while($k > 1) + { + $k = $khi - $klo; + If ( $XIn[$k] >= $X ) + $khi = $k; + else + $klo = $k; + } + $klo = $khi - 1; + + $h = $XIn[$khi] - $XIn[$klo]; + $a = ($XIn[$khi] - $X) / $h; + $b = ($X - $XIn[$klo]) / $h; + $Value = $a * $YIn[$klo] + $b * $YIn[$khi] + (($a*$a*$a - $a) * $Yt[$klo] + ($b*$b*$b - $b) * $Yt[$khi]) * ($h*$h) / 6; + + $YPos = $this->GArea_Y2 - (($Value-$this->VMin) * $this->DivisionRatio); + + if ( $XLast != -1 && !isset($Missing[floor($X)]) && !isset($Missing[floor($X+1)]) ) + $this->drawLine($XLast,$YLast,$XPos,$YPos,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"],TRUE); + + $XLast = $XPos; + $YLast = $YPos; + $XPos = $XPos + $this->DivisionWidth * $Accuracy; + } + + // Add potentialy missing values + $XPos = $XPos - $this->DivisionWidth * $Accuracy; + if ( $XPos < ($this->GArea_X2 - $this->GAreaXOffset) ) + { + $YPos = $this->GArea_Y2 - (($YIn[$Index]-$this->VMin) * $this->DivisionRatio); + $this->drawLine($XLast,$YLast,$this->GArea_X2-$this->GAreaXOffset,$YPos,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"],TRUE); + } + + $GraphID++; + } + } + } + + /* This function draw a filled cubic curve */ + function drawFilledCubicCurve(&$Data,&$DataDescription,$Accuracy=.1,$Alpha=100,$AroundZero=FALSE) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawFilledCubicCurve",$DataDescription); + $this->validateData("drawFilledCubicCurve",$Data); + + $LayerWidth = $this->GArea_X2-$this->GArea_X1; + $LayerHeight = $this->GArea_Y2-$this->GArea_Y1; + $YZero = $LayerHeight - ((0-$this->VMin) * $this->DivisionRatio); + if ( $YZero > $LayerHeight ) { $YZero = $LayerHeight; } + + $GraphID = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + $XIn = ""; $Yin = ""; $Yt = ""; $U = ""; + $XIn[0] = 0; $YIn[0] = 0; + + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + $Index = 1; + $XLast = -1; $Missing = ""; + foreach ( $Data as $Key => $Values ) + { + $Value = $Data[$Key][$ColName]; + $XIn[$Index] = $Index; + $YIn[$Index] = $Value; + if ( !is_numeric($Value) ) { $Missing[$Index] = TRUE; } + $Index++; + } + $Index--; + + $Yt[0] = 0; + $Yt[1] = 0; + $U[1] = 0; + for($i=2;$i<=$Index-1;$i++) + { + $Sig = ($XIn[$i] - $XIn[$i-1]) / ($XIn[$i+1] - $XIn[$i-1]); + $p = $Sig * $Yt[$i-1] + 2; + $Yt[$i] = ($Sig - 1) / $p; + $U[$i] = ($YIn[$i+1] - $YIn[$i]) / ($XIn[$i+1] - $XIn[$i]) - ($YIn[$i] - $YIn[$i-1]) / ($XIn[$i] - $XIn[$i-1]); + $U[$i] = (6 * $U[$i] / ($XIn[$i+1] - $XIn[$i-1]) - $Sig * $U[$i-1]) / $p; + } + + $qn = 0; + $un = 0; + $Yt[$Index] = ($un - $qn * $U[$Index-1]) / ($qn * $Yt[$Index-1] + 1); + + for($k=$Index-1;$k>=1;$k--) + $Yt[$k] = $Yt[$k] * $Yt[$k+1] + $U[$k]; + + $Points = ""; + $Points[] = $this->GAreaXOffset; + $Points[] = $LayerHeight; + + $this->Layers[0] = imagecreatetruecolor($LayerWidth,$LayerHeight); + $C_White = imagecolorallocate($this->Layers[0],255,255,255); + imagefilledrectangle($this->Layers[0],0,0,$LayerWidth,$LayerHeight,$C_White); + imagecolortransparent($this->Layers[0],$C_White); + + $YLast = NULL; + $XPos = $this->GAreaXOffset; $PointsCount = 2; + for($X=1;$X<=$Index;$X=$X+$Accuracy) + { + $klo = 1; + $khi = $Index; + $k = $khi - $klo; + while($k > 1) + { + $k = $khi - $klo; + If ( $XIn[$k] >= $X ) + $khi = $k; + else + $klo = $k; + } + $klo = $khi - 1; + + $h = $XIn[$khi] - $XIn[$klo]; + $a = ($XIn[$khi] - $X) / $h; + $b = ($X - $XIn[$klo]) / $h; + $Value = $a * $YIn[$klo] + $b * $YIn[$khi] + (($a*$a*$a - $a) * $Yt[$klo] + ($b*$b*$b - $b) * $Yt[$khi]) * ($h*$h) / 6; + + $YPos = $LayerHeight - (($Value-$this->VMin) * $this->DivisionRatio); + + if ( $YLast != NULL && $AroundZero && !isset($Missing[floor($X)]) && !isset($Missing[floor($X+1)])) + { + $aPoints = ""; + $aPoints[] = $XLast; + $aPoints[] = $YLast; + $aPoints[] = $XPos; + $aPoints[] = $YPos; + $aPoints[] = $XPos; + $aPoints[] = $YZero; + $aPoints[] = $XLast; + $aPoints[] = $YZero; + + $C_Graph = imagecolorallocate($this->Layers[0],$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + imagefilledpolygon($this->Layers[0],$aPoints,4,$C_Graph); + } + + if ( !isset($Missing[floor($X)]) || $YLast == NULL ) + { + $PointsCount++; + $Points[] = $XPos; + $Points[] = $YPos; + } + else + { + $PointsCount++; $Points[] = $XLast; $Points[] = $LayerHeight; + } + + $YLast = $YPos; $XLast = $XPos; + $XPos = $XPos + $this->DivisionWidth * $Accuracy; + } + + // Add potentialy missing values + $XPos = $XPos - $this->DivisionWidth * $Accuracy; + if ( $XPos < ($LayerWidth-$this->GAreaXOffset) ) + { + $YPos = $LayerHeight - (($YIn[$Index]-$this->VMin) * $this->DivisionRatio); + + if ( $YLast != NULL && $AroundZero ) + { + $aPoints = ""; + $aPoints[] = $XLast; + $aPoints[] = $YLast; + $aPoints[] = $LayerWidth-$this->GAreaXOffset; + $aPoints[] = $YPos; + $aPoints[] = $LayerWidth-$this->GAreaXOffset; + $aPoints[] = $YZero; + $aPoints[] = $XLast; + $aPoints[] = $YZero; + + $C_Graph = imagecolorallocate($this->Layers[0],$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + imagefilledpolygon($this->Layers[0],$aPoints,4,$C_Graph); + } + + if ( $YIn[$klo] != "" && $YIn[$khi] != "" || $YLast == NULL ) + { + $PointsCount++; + $Points[] = $LayerWidth-$this->GAreaXOffset; + $Points[] = $YPos; + } + } + + $Points[] = $LayerWidth-$this->GAreaXOffset; + $Points[] = $LayerHeight; + + if ( !$AroundZero ) + { + $C_Graph = imagecolorallocate($this->Layers[0],$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + imagefilledpolygon($this->Layers[0],$Points,$PointsCount,$C_Graph); + } + + imagecopymerge($this->Picture,$this->Layers[0],$this->GArea_X1,$this->GArea_Y1,0,0,$LayerWidth,$LayerHeight,$Alpha); + imagedestroy($this->Layers[0]); + + $this->drawCubicCurve($Data,$DataDescription,$Accuracy,$ColName); + + $GraphID++; + } + } + + /* This function draw a filled line graph */ + function drawFilledLineGraph(&$Data,&$DataDescription,$Alpha=100,$AroundZero=FALSE) + { + $Empty = -2147483647; + + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawFilledLineGraph",$DataDescription); + $this->validateData("drawFilledLineGraph",$Data); + + $LayerWidth = $this->GArea_X2-$this->GArea_X1; + $LayerHeight = $this->GArea_Y2-$this->GArea_Y1; + + $GraphID = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + $aPoints = ""; + $aPoints[] = $this->GAreaXOffset; + $aPoints[] = $LayerHeight; + + $this->Layers[0] = imagecreatetruecolor($LayerWidth,$LayerHeight); + $C_White = imagecolorallocate($this->Layers[0],255,255,255); + imagefilledrectangle($this->Layers[0],0,0,$LayerWidth,$LayerHeight,$C_White); + imagecolortransparent($this->Layers[0],$C_White); + + $XPos = $this->GAreaXOffset; + $XLast = -1; $PointsCount = 2; + $YZero = $LayerHeight - ((0-$this->VMin) * $this->DivisionRatio); + if ( $YZero > $LayerHeight ) { $YZero = $LayerHeight; } + + $YLast = $Empty; + foreach ( $Data as $Key => $Values ) + { + $Value = $Data[$Key][$ColName]; + $YPos = $LayerHeight - (($Value-$this->VMin) * $this->DivisionRatio); + + /* Save point into the image map if option activated */ + if ( $this->BuildMap ) + $this->addToImageMap($XPos-3,$YPos-3,$XPos+3,$YPos+3,$DataDescription["Description"][$ColName],$Data[$Key][$ColName].$DataDescription["Unit"]["Y"],"FLine"); + + if ( !is_numeric($Value) ) + { + $PointsCount++; + $aPoints[] = $XLast; + $aPoints[] = $LayerHeight; + + $YLast = $Empty; + } + else + { + $PointsCount++; + if ( $YLast <> $Empty ) + { $aPoints[] = $XPos; $aPoints[] = $YPos; } + else + { $PointsCount++; $aPoints[] = $XPos; $aPoints[] = $LayerHeight; $aPoints[] = $XPos; $aPoints[] = $YPos; } + + if ($YLast <> $Empty && $AroundZero) + { + $Points = ""; + $Points[] = $XLast; $Points[] = $YLast; + $Points[] = $XPos; + $Points[] = $YPos; + $Points[] = $XPos; + $Points[] = $YZero; + $Points[] = $XLast; + $Points[] = $YZero; + + $C_Graph = imagecolorallocate($this->Layers[0],$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + imagefilledpolygon($this->Layers[0],$Points,4,$C_Graph); + } + $YLast = $YPos; + } + + $XLast = $XPos; + $XPos = $XPos + $this->DivisionWidth; + } + $aPoints[] = $LayerWidth - $this->GAreaXOffset; + $aPoints[] = $LayerHeight; + + if ( $AroundZero == FALSE ) + { + $C_Graph = imagecolorallocate($this->Layers[0],$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + imagefilledpolygon($this->Layers[0],$aPoints,$PointsCount,$C_Graph); + } + + imagecopymerge($this->Picture,$this->Layers[0],$this->GArea_X1,$this->GArea_Y1,0,0,$LayerWidth,$LayerHeight,$Alpha); + imagedestroy($this->Layers[0]); + $GraphID++; + $this->drawLineGraph($Data,$DataDescription,$ColName); + } + } + + /* This function draw a bar graph */ + function drawOverlayBarGraph(&$Data,&$DataDescription,$Alpha=50) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawOverlayBarGraph",$DataDescription); + $this->validateData("drawOverlayBarGraph",$Data); + + $LayerWidth = $this->GArea_X2-$this->GArea_X1; + $LayerHeight = $this->GArea_Y2-$this->GArea_Y1; + + $GraphID = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + $this->Layers[$GraphID] = imagecreatetruecolor($LayerWidth,$LayerHeight); + $C_White = imagecolorallocate($this->Layers[$GraphID],255,255,255); + $C_Graph = imagecolorallocate($this->Layers[$GraphID],$this->Palette[$GraphID]["R"],$this->Palette[$GraphID]["G"],$this->Palette[$GraphID]["B"]); + imagefilledrectangle($this->Layers[$GraphID],0,0,$LayerWidth,$LayerHeight,$C_White); + imagecolortransparent($this->Layers[$GraphID],$C_White); + + $XWidth = $this->DivisionWidth / 4; + $XPos = $this->GAreaXOffset; + $YZero = $LayerHeight - ((0-$this->VMin) * $this->DivisionRatio); + $XLast = -1; $PointsCount = 2; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName]) ) + { + $Value = $Data[$Key][$ColName]; + if ( is_numeric($Value) ) + { + $YPos = $LayerHeight - (($Value-$this->VMin) * $this->DivisionRatio); + + imagefilledrectangle($this->Layers[$GraphID],$XPos-$XWidth,$YPos,$XPos+$XWidth,$YZero,$C_Graph); + + $X1 = floor($XPos - $XWidth + $this->GArea_X1); $Y1 = floor($YPos+$this->GArea_Y1) + .2; + $X2 = floor($XPos + $XWidth + $this->GArea_X1); $Y2 = $this->GArea_Y2 - ((0-$this->VMin) * $this->DivisionRatio); + if ( $X1 <= $this->GArea_X1 ) { $X1 = $this->GArea_X1 + 1; } + if ( $X2 >= $this->GArea_X2 ) { $X2 = $this->GArea_X2 - 1; } + + /* Save point into the image map if option activated */ + if ( $this->BuildMap ) + $this->addToImageMap($X1,min($Y1,$Y2),$X2,max($Y1,$Y2),$DataDescription["Description"][$ColName],$Data[$Key][$ColName].$DataDescription["Unit"]["Y"],"oBar"); + + $this->drawLine($X1,$Y1,$X2,$Y1,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"],TRUE); + } + } + $XPos = $XPos + $this->DivisionWidth; + } + + $GraphID++; + } + + for($i=0;$i<=($GraphID-1);$i++) + { + imagecopymerge($this->Picture,$this->Layers[$i],$this->GArea_X1,$this->GArea_Y1,0,0,$LayerWidth,$LayerHeight,$Alpha); + imagedestroy($this->Layers[$i]); + } + } + + /* This function draw a bar graph */ + function drawBarGraph(&$Data,&$DataDescription,$Shadow=FALSE,$Alpha=100) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawBarGraph",$DataDescription); + $this->validateData("drawBarGraph",$Data); + + $GraphID = 0; + $Series = count($DataDescription["Values"]); + $SeriesWidth = $this->DivisionWidth / ($Series+1); + $SerieXOffset = $this->DivisionWidth / 2 - $SeriesWidth / 2; + + $YZero = $this->GArea_Y2 - ((0-$this->VMin) * $this->DivisionRatio); + if ( $YZero > $this->GArea_Y2 ) { $YZero = $this->GArea_Y2; } + + $SerieID = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + $XPos = $this->GArea_X1 + $this->GAreaXOffset - $SerieXOffset + $SeriesWidth * $SerieID; + $XLast = -1; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + { + if ( is_numeric($Data[$Key][$ColName]) ) + { + $Value = $Data[$Key][$ColName]; + $YPos = $this->GArea_Y2 - (($Value-$this->VMin) * $this->DivisionRatio); + + /* Save point into the image map if option activated */ + if ( $this->BuildMap ) + { + $this->addToImageMap($XPos+1,min($YZero,$YPos),$XPos+$SeriesWidth-1,max($YZero,$YPos),$DataDescription["Description"][$ColName],$Data[$Key][$ColName].$DataDescription["Unit"]["Y"],"Bar"); + } + + if ( $Shadow && $Alpha == 100 ) + $this->drawRectangle($XPos+1,$YZero,$XPos+$SeriesWidth-1,$YPos,25,25,25,TRUE,$Alpha); + + $this->drawFilledRectangle($XPos+1,$YZero,$XPos+$SeriesWidth-1,$YPos,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"],TRUE,$Alpha); + } + } + $XPos = $XPos + $this->DivisionWidth; + } + $SerieID++; + } + } + + /* This function draw a stacked bar graph */ + function drawStackedBarGraph(&$Data,&$DataDescription,$Alpha=50) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawBarGraph",$DataDescription); + $this->validateData("drawBarGraph",$Data); + + $GraphID = 0; + $Series = count($DataDescription["Values"]); + $SeriesWidth = $this->DivisionWidth * .8; + + $YZero = $this->GArea_Y2 - ((0-$this->VMin) * $this->DivisionRatio); + if ( $YZero > $this->GArea_Y2 ) { $YZero = $this->GArea_Y2; } + + $SerieID = 0; $LastValue = ""; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + $XPos = $this->GArea_X1 + $this->GAreaXOffset - $SeriesWidth / 2; + $XLast = -1; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + { + if ( is_numeric($Data[$Key][$ColName]) ) + { + $Value = $Data[$Key][$ColName]; + + if ( isset($LastValue[$Key]) ) + { + $YPos = $this->GArea_Y2 - ((($Value+$LastValue[$Key])-$this->VMin) * $this->DivisionRatio); + $YBottom = $this->GArea_Y2 - (($LastValue[$Key]-$this->VMin) * $this->DivisionRatio); + $LastValue[$Key] += $Value; + } + else + { + $YPos = $this->GArea_Y2 - (($Value-$this->VMin) * $this->DivisionRatio); + $YBottom = $YZero; + $LastValue[$Key] = $Value; + } + + /* Save point into the image map if option activated */ + if ( $this->BuildMap ) + $this->addToImageMap($XPos+1,min($YBottom,$YPos),$XPos+$SeriesWidth-1,max($YBottom,$YPos),$DataDescription["Description"][$ColName],$Data[$Key][$ColName].$DataDescription["Unit"]["Y"],"sBar"); + + $this->drawFilledRectangle($XPos+1,$YBottom,$XPos+$SeriesWidth-1,$YPos,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"],TRUE,$Alpha); + } + } + $XPos = $XPos + $this->DivisionWidth; + } + $SerieID++; + } + } + + /* This function draw a limits bar graphs */ + function drawLimitsGraph(&$Data,&$DataDescription,$R=0,$G=0,$B=0) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawLimitsGraph",$DataDescription); + $this->validateData("drawLimitsGraph",$Data); + + $XWidth = $this->DivisionWidth / 4; + $XPos = $this->GArea_X1 + $this->GAreaXOffset; + + foreach ( $Data as $Key => $Values ) + { + $Min = $Data[$Key][$DataDescription["Values"][0]]; + $Max = $Data[$Key][$DataDescription["Values"][0]]; + $GraphID = 0; $MaxID = 0; $MinID = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + if ( isset($Data[$Key][$ColName]) ) + { + if ( $Data[$Key][$ColName] > $Max && is_numeric($Data[$Key][$ColName])) + { $Max = $Data[$Key][$ColName]; $MaxID = $GraphID; } + } + if ( isset($Data[$Key][$ColName]) && is_numeric($Data[$Key][$ColName])) + { + if ( $Data[$Key][$ColName] < $Min ) + { $Min = $Data[$Key][$ColName]; $MinID = $GraphID; } + $GraphID++; + } + } + + $YPos = $this->GArea_Y2 - (($Max-$this->VMin) * $this->DivisionRatio); + $X1 = floor($XPos - $XWidth); $Y1 = floor($YPos) - .2; + $X2 = floor($XPos + $XWidth); + if ( $X1 <= $this->GArea_X1 ) { $X1 = $this->GArea_X1 + 1; } + if ( $X2 >= $this->GArea_X2 ) { $X2 = $this->GArea_X2 - 1; } + + $YPos = $this->GArea_Y2 - (($Min-$this->VMin) * $this->DivisionRatio); + $Y2 = floor($YPos) + .2; + + $this->drawLine(floor($XPos)-.2,$Y1+1,floor($XPos)-.2,$Y2-1,$R,$G,$B,TRUE); + $this->drawLine(floor($XPos)+.2,$Y1+1,floor($XPos)+.2,$Y2-1,$R,$G,$B,TRUE); + $this->drawLine($X1,$Y1,$X2,$Y1,$this->Palette[$MaxID]["R"],$this->Palette[$MaxID]["G"],$this->Palette[$MaxID]["B"],FALSE); + $this->drawLine($X1,$Y2,$X2,$Y2,$this->Palette[$MinID]["R"],$this->Palette[$MinID]["G"],$this->Palette[$MinID]["B"],FALSE); + + $XPos = $XPos + $this->DivisionWidth; + } + } + + /* This function draw radar axis centered on the graph area */ + function drawRadarAxis(&$Data,&$DataDescription,$Mosaic=TRUE,$BorderOffset=10,$A_R=60,$A_G=60,$A_B=60,$S_R=200,$S_G=200,$S_B=200,$MaxValue=-1) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawRadarAxis",$DataDescription); + $this->validateData("drawRadarAxis",$Data); + + $C_TextColor = imagecolorallocate($this->Picture,$A_R,$A_G,$A_B); + + /* Draw radar axis */ + $Points = count($Data); + $Radius = ( $this->GArea_Y2 - $this->GArea_Y1 ) / 2 - $BorderOffset; + $XCenter = ( $this->GArea_X2 - $this->GArea_X1 ) / 2 + $this->GArea_X1; + $YCenter = ( $this->GArea_Y2 - $this->GArea_Y1 ) / 2 + $this->GArea_Y1; + + /* Search for the max value */ + if ( $MaxValue == -1 ) + { + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + if ( $Data[$Key][$ColName] > $MaxValue ) { $MaxValue = $Data[$Key][$ColName]; } + } + } + } + + /* Draw the mosaic */ + if ( $Mosaic ) + { + $RadiusScale = $Radius / $MaxValue; + for ( $t=1; $t<=$MaxValue-1; $t++) + { + $TRadius = $RadiusScale * $t; + $LastX1 = -1; + + for ( $i=0; $i<=$Points; $i++) + { + $Angle = -90 + $i * 360/$Points; + $X1 = cos($Angle * 3.1418 / 180 ) * $TRadius + $XCenter; + $Y1 = sin($Angle * 3.1418 / 180 ) * $TRadius + $YCenter; + $X2 = cos($Angle * 3.1418 / 180 ) * ($TRadius+$RadiusScale) + $XCenter; + $Y2 = sin($Angle * 3.1418 / 180 ) * ($TRadius+$RadiusScale) + $YCenter; + + if ( $t % 2 == 1 && $LastX1 != -1) + { + $Plots = ""; + $Plots[] = $X1; $Plots[] = $Y1; + $Plots[] = $X2; $Plots[] = $Y2; + $Plots[] = $LastX2; $Plots[] = $LastY2; + $Plots[] = $LastX1; $Plots[] = $LastY1; + + $C_Graph = imagecolorallocate($this->Picture,250,250,250); + imagefilledpolygon($this->Picture,$Plots,(count($Plots)+1)/2,$C_Graph); + } + + $LastX1 = $X1; $LastY1= $Y1; + $LastX2 = $X2; $LastY2= $Y2; + } + } + } + + + /* Draw the spider web */ + for ( $t=1; $t<=$MaxValue; $t++) + { + $TRadius = ( $Radius / $MaxValue ) * $t; + $LastX = -1; + + for ( $i=0; $i<=$Points; $i++) + { + $Angle = -90 + $i * 360/$Points; + $X = cos($Angle * 3.1418 / 180 ) * $TRadius + $XCenter; + $Y = sin($Angle * 3.1418 / 180 ) * $TRadius + $YCenter; + + if ( $LastX != -1 ) + $this->drawDottedLine($LastX,$LastY,$X,$Y,4,$S_R,$S_G,$S_B); + + $LastX = $X; $LastY= $Y; + } + } + + /* Draw the axis */ + for ( $i=0; $i<=$Points; $i++) + { + $Angle = -90 + $i * 360/$Points; + $X = cos($Angle * 3.1418 / 180 ) * $Radius + $XCenter; + $Y = sin($Angle * 3.1418 / 180 ) * $Radius + $YCenter; + + $this->drawLine($XCenter,$YCenter,$X,$Y,$A_R,$A_G,$A_B); + + $XOffset = 0; $YOffset = 0; + if (isset($Data[$i][$DataDescription["Position"]])) + { + $Label = $Data[$i][$DataDescription["Position"]]; + + $Positions = imagettfbbox($this->FontSize,0,$this->FontName,$Label); + $Width = $Positions[2] - $Positions[6]; + $Height = $Positions[3] - $Positions[7]; + + if ( $Angle >= 0 && $Angle <= 90 ) + $YOffset = $Height; + + if ( $Angle > 90 && $Angle <= 180 ) + { $YOffset = $Height; $XOffset = -$Width; } + + if ( $Angle > 180 && $Angle <= 270 ) + { $XOffset = -$Width; } + + imagettftext($this->Picture,$this->FontSize,0,$X+$XOffset,$Y+$YOffset,$C_TextColor,$this->FontName,$Label); + } + } + + /* Write the values */ + for ( $t=1; $t<=$MaxValue; $t++) + { + $TRadius = ( $Radius / $MaxValue ) * $t; + + $Angle = -90 + 360 / $Points; + $X1 = $XCenter; + $Y1 = $YCenter - $TRadius; + $X2 = cos($Angle * 3.1418 / 180 ) * $TRadius + $XCenter; + $Y2 = sin($Angle * 3.1418 / 180 ) * $TRadius + $YCenter; + + $XPos = floor(($X2-$X1)/2) + $X1; + $YPos = floor(($Y2-$Y1)/2) + $Y1; + + $Positions = imagettfbbox($this->FontSize,0,$this->FontName,$t); + $X = $XPos - ( $X+$Positions[2] - $X+$Positions[6] ) / 2; + $Y = $YPos + $this->FontSize; + + $this->drawFilledRoundedRectangle($X+$Positions[6]-2,$Y+$Positions[7]-1,$X+$Positions[2]+4,$Y+$Positions[3]+1,2,240,240,240); + $this->drawRoundedRectangle($X+$Positions[6]-2,$Y+$Positions[7]-1,$X+$Positions[2]+4,$Y+$Positions[3]+1,2,220,220,220); + imagettftext($this->Picture,$this->FontSize,0,$X,$Y,$C_TextColor,$this->FontName,$t); + } + } + + /* This function draw a radar graph centered on the graph area */ + function drawRadar(&$Data,&$DataDescription,$BorderOffset=10,$MaxValue=-1) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawRadar",$DataDescription); + $this->validateData("drawRadar",$Data); + + $Points = count($Data); + $Radius = ( $this->GArea_Y2 - $this->GArea_Y1 ) / 2 - $BorderOffset; + $XCenter = ( $this->GArea_X2 - $this->GArea_X1 ) / 2 + $this->GArea_X1; + $YCenter = ( $this->GArea_Y2 - $this->GArea_Y1 ) / 2 + $this->GArea_Y1; + + /* Search for the max value */ + if ( $MaxValue == -1 ) + { + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + if ( $Data[$Key][$ColName] > $MaxValue ) { $MaxValue = $Data[$Key][$ColName]; } + } + } + } + + $GraphID = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + $Angle = -90; + $XLast = -1; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + { + $Value = $Data[$Key][$ColName]; + $Strength = ( $Radius / $MaxValue ) * $Value; + + $XPos = cos($Angle * 3.1418 / 180 ) * $Strength + $XCenter; + $YPos = sin($Angle * 3.1418 / 180 ) * $Strength + $YCenter; + + if ( $XLast != -1 ) + $this->drawLine($XLast,$YLast,$XPos,$YPos,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + + if ( $XLast == -1 ) + { $FirstX = $XPos; $FirstY = $YPos; } + + $Angle = $Angle + (360/$Points); + $XLast = $XPos; + $YLast = $YPos; + } + } + $this->drawLine($XPos,$YPos,$FirstX,$FirstY,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + $GraphID++; + } + } + + /* This function draw a radar graph centered on the graph area */ + function drawFilledRadar(&$Data,&$DataDescription,$Alpha=50,$BorderOffset=10,$MaxValue=-1) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawFilledRadar",$DataDescription); + $this->validateData("drawFilledRadar",$Data); + + $Points = count($Data); + $LayerWidth = $this->GArea_X2-$this->GArea_X1; + $LayerHeight = $this->GArea_Y2-$this->GArea_Y1; + $Radius = ( $this->GArea_Y2 - $this->GArea_Y1 ) / 2 - $BorderOffset; + $XCenter = ( $this->GArea_X2 - $this->GArea_X1 ) / 2; + $YCenter = ( $this->GArea_Y2 - $this->GArea_Y1 ) / 2; + + /* Search for the max value */ + if ( $MaxValue == -1 ) + { + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + if ( $Data[$Key][$ColName] > $MaxValue && is_numeric($Data[$Key][$ColName])) { $MaxValue = $Data[$Key][$ColName]; } + } + } + } + + $GraphID = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + $ID = 0; + foreach ( $DataDescription["Description"] as $keyI => $ValueI ) + { if ( $keyI == $ColName ) { $ColorID = $ID; }; $ID++; } + + $Angle = -90; + $XLast = -1; + $Plots = ""; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + { + $Value = $Data[$Key][$ColName]; + if ( !is_numeric($Value) ) { $Value = 0; } + $Strength = ( $Radius / $MaxValue ) * $Value; + + $XPos = cos($Angle * 3.1418 / 180 ) * $Strength + $XCenter; + $YPos = sin($Angle * 3.1418 / 180 ) * $Strength + $YCenter; + + $Plots[] = $XPos; + $Plots[] = $YPos; + + $Angle = $Angle + (360/$Points); + $XLast = $XPos; + $YLast = $YPos; + } + } + + if (isset($Plots[0])) + { + $Plots[] = $Plots[0]; + $Plots[] = $Plots[1]; + + $this->Layers[0] = imagecreatetruecolor($LayerWidth,$LayerHeight); + $C_White = imagecolorallocate($this->Layers[0],255,255,255); + imagefilledrectangle($this->Layers[0],0,0,$LayerWidth,$LayerHeight,$C_White); + imagecolortransparent($this->Layers[0],$C_White); + + $C_Graph = imagecolorallocate($this->Layers[0],$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + imagefilledpolygon($this->Layers[0],$Plots,(count($Plots)+1)/2,$C_Graph); + + imagecopymerge($this->Picture,$this->Layers[0],$this->GArea_X1,$this->GArea_Y1,0,0,$LayerWidth,$LayerHeight,$Alpha); + imagedestroy($this->Layers[0]); + + for($i=0;$i<=count($Plots)-4;$i=$i+2) + $this->drawLine($Plots[$i]+$this->GArea_X1,$Plots[$i+1]+$this->GArea_Y1,$Plots[$i+2]+$this->GArea_X1,$Plots[$i+3]+$this->GArea_Y1,$this->Palette[$ColorID]["R"],$this->Palette[$ColorID]["G"],$this->Palette[$ColorID]["B"]); + } + + $GraphID++; + } + } + + /* This function draw a flat pie chart */ + function drawBasicPieGraph(&$Data,&$DataDescription,$XPos,$YPos,$Radius=100,$DrawLabels=PIE_NOLABEL,$R=255,$G=255,$B=255,$Decimals=0) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawBasicPieGraph",$DataDescription,FALSE); + $this->validateData("drawBasicPieGraph",$Data); + + /* Determine pie sum */ + $Series = 0; $PieSum = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + if ( $ColName != $DataDescription["Position"] ) + { + $Series++; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + $PieSum = $PieSum + $Data[$Key][$ColName]; $iValues[] = $Data[$Key][$ColName]; $iLabels[] = $Data[$Key][$DataDescription["Position"]]; + } + } + } + + /* Validate serie */ + if ( $Series != 1 ) + RaiseFatal("Pie chart can only accept one serie of data."); + + $SpliceRatio = 360 / $PieSum; + $SplicePercent = 100 / $PieSum; + + /* Calculate all polygons */ + $Angle = 0; $TopPlots = ""; + foreach($iValues as $Key => $Value) + { + $TopPlots[$Key][] = $XPos; + $TopPlots[$Key][] = $YPos; + + /* Process labels position & size */ + if ( !($DrawLabels == PIE_NOLABEL) ) + { + $TAngle = $Angle+($Value*$SpliceRatio/2); + if ($DrawLabels == PIE_PERCENTAGE) + $Caption = (round($Value * pow(10,$Decimals) * $SplicePercent)/pow(10,$Decimals))."%"; + elseif ($DrawLabels == PIE_LABELS) + $Caption = $iLabels[$Key]; + $TX = cos(($TAngle) * 3.1418 / 180 ) * ($Radius + 10)+ $XPos; + $TY = sin(($TAngle) * 3.1418 / 180 ) * ($Radius+ 10) + $YPos + 4; + + if ( $TAngle > 90 && $TAngle < 270 ) + { + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Caption,$bogus); + $TextWidth = $Position[2]-$Position[0]; + $TX = $TX - $TextWidth; + } + + $C_TextColor = imagecolorallocate($this->Picture,70,70,70); + imagettftext($this->Picture,$this->FontSize,0,$TX,$TY,$C_TextColor,$this->FontName,$Caption); + } + + /* Process pie slices */ + for($iAngle=$Angle;$iAngle<=$Angle+$Value*$SpliceRatio;$iAngle=$iAngle+.5) + { + $TopX = cos($iAngle * 3.1418 / 180 ) * $Radius + $XPos; + $TopY = sin($iAngle * 3.1418 / 180 ) * $Radius + $YPos; + + $TopPlots[$Key][] = $TopX; + $TopPlots[$Key][] = $TopY; + } + + $TopPlots[$Key][] = $XPos; + $TopPlots[$Key][] = $YPos; + + $Angle = $iAngle; + } + $PolyPlots = $TopPlots; + + /* Set array values type to float --- PHP Bug with imagefilledpolygon casting to integer */ + foreach ($TopPlots as $Key => $Value) + { foreach ($TopPlots[$Key] as $Key2 => $Value2) { settype($TopPlots[$Key][$Key2],"float"); } } + + /* Draw Top polygons */ + foreach ($PolyPlots as $Key => $Value) + { + $C_GraphLo = imagecolorallocate($this->Picture,$this->Palette[$Key]["R"],$this->Palette[$Key]["G"],$this->Palette[$Key]["B"]); + imagefilledpolygon($this->Picture,$PolyPlots[$Key],(count($PolyPlots[$Key])+1)/2,$C_GraphLo); + } + + $this->drawCircle($XPos-.5,$YPos-.5,$Radius,$R,$G,$B); + $this->drawCircle($XPos-.5,$YPos-.5,$Radius+.5,$R,$G,$B); + + /* Draw Top polygons */ + foreach ($TopPlots as $Key => $Value) + { + for($j=0;$j<=count($TopPlots[$Key])-4;$j=$j+2) + $this->drawLine($TopPlots[$Key][$j],$TopPlots[$Key][$j+1],$TopPlots[$Key][$j+2],$TopPlots[$Key][$j+3],$R,$G,$B); + } + } + + /* This function draw a flat pie chart */ + function drawFlatPieGraph(&$Data,&$DataDescription,$XPos,$YPos,$Radius=100,$DrawLabels=PIE_NOLABEL,$SpliceDistance=0,$Decimals = 0) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawFlatPieGraph",$DataDescription,FALSE); + $this->validateData("drawFlatPieGraph",$Data); + + /* Determine pie sum */ + $Series = 0; $PieSum = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + if ( $ColName != $DataDescription["Position"] ) + { + $Series++; + foreach ( $Data as $Key => $Values ) + { + if ( isset($Data[$Key][$ColName])) + $PieSum = $PieSum + $Data[$Key][$ColName]; $iValues[] = $Data[$Key][$ColName]; $iLabels[] = $Data[$Key][$DataDescription["Position"]]; + } + } + } + + /* Validate serie */ + if ( $Series != 1 ) + RaiseFatal("Pie chart can only accept one serie of data."); + + $SpliceDistanceRatio = $SpliceDistance; + $SpliceRatio = (360 - $SpliceDistanceRatio * count($iValues) ) / $PieSum; + $SplicePercent = 100 / $PieSum; + + /* Calculate all polygons */ + $Angle = 0; $TopPlots = ""; + foreach($iValues as $Key => $Value) + { + $XCenterPos = cos(($Angle+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * $SpliceDistance + $XPos; + $YCenterPos = sin(($Angle+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * $SpliceDistance + $YPos; + + $TopPlots[$Key][] = $XCenterPos; + $TopPlots[$Key][] = $YCenterPos; + + /* Process labels position & size */ + if ( !($DrawLabels == PIE_NOLABEL) ) + { + $TAngle = $Angle+($Value*$SpliceRatio/2); + if ($DrawLabels == PIE_PERCENTAGE) + $Caption = (round($Value * pow(10,$Decimals) * $SplicePercent)/pow(10,$Decimals))."%"; + elseif ($DrawLabels == PIE_LABELS) + $Caption = $iLabels[$Key]; + $TX = cos(($TAngle) * 3.1418 / 180 ) * ($Radius+10+$SpliceDistance)+$XPos; + $TY = sin(($TAngle) * 3.1418 / 180 ) * ($Radius+10+$SpliceDistance) + $YPos + 4; + + if ( $TAngle > 90 && $TAngle < 270 ) + { + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Caption,$bogus); + $TextWidth = $Position[2]-$Position[0]; + $TX = $TX - $TextWidth; + } + + $C_TextColor = imagecolorallocate($this->Picture,70,70,70); + imagettftext($this->Picture,$this->FontSize,0,$TX,$TY,$C_TextColor,$this->FontName,$Caption); + } + + /* Draw borders to correct imagefilledpolygon bug */ + $BMax = 2; + for($i=-1;$i<=$BMax;$i++) + { + $BorderX1 = cos(($Angle+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * ($SpliceDistance+$i) + $XPos; + $BorderY1 = sin(($Angle+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * ($SpliceDistance+$i) + $YPos; + $BorderX2 = cos(($Angle+$i*.5) * 3.1418 / 180 ) * (($Radius+$BMax)+$SpliceDistance) + $XPos; + $BorderY2 = sin(($Angle+$i*.5) * 3.1418 / 180 ) * (($Radius+$BMax)+$SpliceDistance) + $YPos; + $this->drawLine($BorderX1,$BorderY1,$BorderX2,$BorderY2,$this->Palette[$Key]["R"],$this->Palette[$Key]["G"],$this->Palette[$Key]["B"]); + + $BorderX1 = cos(($Angle+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * ($SpliceDistance+$i) + $XPos; + $BorderY1 = sin(($Angle+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * ($SpliceDistance+$i) + $YPos; + $BorderX2 = cos(($Angle-$i*.5+$Value*$SpliceRatio) * 3.1418 / 180 ) * (($Radius+$BMax)+$SpliceDistance) + $XPos; + $BorderY2 = sin(($Angle-$i*.5+$Value*$SpliceRatio) * 3.1418 / 180 ) * (($Radius+$BMax)+$SpliceDistance) + $YPos; + $this->drawLine($BorderX1,$BorderY1,$BorderX2,$BorderY2,$this->Palette[$Key]["R"],$this->Palette[$Key]["G"],$this->Palette[$Key]["B"]); + } + + /* Process pie slices */ + for($iAngle=$Angle;$iAngle<=$Angle+$Value*$SpliceRatio;$iAngle=$iAngle+.5) + { + $TopX = cos($iAngle * 3.1418 / 180 ) * ($Radius+$SpliceDistance) + $XPos; + $TopY = sin($iAngle * 3.1418 / 180 ) * ($Radius+$SpliceDistance) + $YPos; + + $TopPlots[$Key][] = $TopX; + $TopPlots[$Key][] = $TopY; + + if ( $iAngle != $Angle ) + { + for($i=-1;$i<=2;$i++) + { + $BorderX1 = cos(($iAngle-.5) * 3.1418 / 180 ) * (($Radius+$i)+$SpliceDistance) + $XPos; + $BorderY1 = sin(($iAngle-.5) * 3.1418 / 180 ) * (($Radius+$i)+$SpliceDistance) + $YPos; + $BorderX2 = cos($iAngle * 3.1418 / 180 ) * (($Radius+$i)+$SpliceDistance) + $XPos; + $BorderY2 = sin($iAngle * 3.1418 / 180 ) * (($Radius+$i)+$SpliceDistance) + $YPos; + + $this->drawLine($BorderX1,$BorderY1,$BorderX2,$BorderY2,$this->Palette[$Key]["R"],$this->Palette[$Key]["G"],$this->Palette[$Key]["B"]); + } + } + } + + $TopPlots[$Key][] = $XCenterPos; + $TopPlots[$Key][] = $YCenterPos; + + $Angle = $iAngle + $SpliceDistanceRatio; + } + $PolyPlots = $TopPlots; + + /* Set array values type to float --- PHP Bug with imagefilledpolygon casting to integer */ + foreach ($TopPlots as $Key => $Value) + { foreach ($TopPlots[$Key] as $Key2 => $Value2) { settype($TopPlots[$Key][$Key2],"float"); } } + + /* Draw Top polygons */ + foreach ($TopPlots as $Key => $Value) + { + $C_GraphLo = imagecolorallocate($this->Picture,$this->Palette[$Key]["R"],$this->Palette[$Key]["G"],$this->Palette[$Key]["B"]); + imagefilledpolygon($this->Picture,$PolyPlots[$Key],(count($PolyPlots[$Key])+1)/2,$C_GraphLo); + } + } + + /* This function draw a pseudo-3D pie chart */ + function drawPieGraph(&$Data,&$DataDescription,$XPos,$YPos,$Radius=100,$DrawLabels=PIE_NOLABEL,$EnhanceColors=TRUE,$Skew=60,$SpliceHeight=20,$SpliceDistance=0,$Decimals=0) + { + /* Validate the Data and DataDescription array */ + $this->validateDataDescription("drawPieGraph",$DataDescription,FALSE); + $this->validateData("drawPieGraph",$Data); + + /* Determine pie sum */ + $Series = 0; $PieSum = 0; $rPieSum = 0; + foreach ( $DataDescription["Values"] as $Key2 => $ColName ) + { + if ( $ColName != $DataDescription["Position"] ) + { + $Series++; + foreach ( $Data as $Key => $Values ) + if ( isset($Data[$Key][$ColName])) + { + if ( $Data[$Key][$ColName] == 0 ) + { $PieSum++; $iValues[] = 1; $rValues[] = 0; } + else + { $PieSum += $Data[$Key][$ColName]; $iValues[] = $Data[$Key][$ColName]; $iLabels[] = $Data[$Key][$DataDescription["Position"]]; $rValues[] = $Data[$Key][$ColName]; $rPieSum += $Data[$Key][$ColName];} + } + } + } + + /* Validate serie */ + if ( $Series != 1 ) + RaiseFatal("Pie chart can only accept one serie of data."); + + $SpliceDistanceRatio = $SpliceDistance; + $SkewHeight = ($Radius * $Skew) / 100; + $SpliceRatio = (360 - $SpliceDistanceRatio * count($iValues) ) / $PieSum; + $SplicePercent = 100 / $PieSum; + $rSplicePercent = 100 / $rPieSum; + + /* Calculate all polygons */ + $Angle = 0; $TopPlots = ""; $BotPlots = ""; $CDev = 5; + foreach($iValues as $Key => $Value) + { + $XCenterPos = cos(($Angle-$CDev+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * $SpliceDistance + $XPos; + $YCenterPos = sin(($Angle-$CDev+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * $SpliceDistance + $YPos; + $XCenterPos2 = cos(($Angle+$CDev+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * $SpliceDistance + $XPos; + $YCenterPos2 = sin(($Angle+$CDev+($Value*$SpliceRatio+$SpliceDistanceRatio)/2) * 3.1418 / 180 ) * $SpliceDistance + $YPos; + + $TopPlots[$Key][] = $XCenterPos; $BotPlots[$Key][] = $XCenterPos; + $TopPlots[$Key][] = $YCenterPos; $BotPlots[$Key][] = $YCenterPos + $SpliceHeight; + + /* Process labels position & size */ + if ( !($DrawLabels == PIE_NOLABEL) ) + { + $TAngle = $Angle+($Value*$SpliceRatio/2); + if ($DrawLabels == PIE_PERCENTAGE) + $Caption = (round($rValues[$Key] * pow(10,$Decimals) * $rSplicePercent)/pow(10,$Decimals))."%"; + elseif ($DrawLabels == PIE_LABELS) + $Caption = $iLabels[$Key]; + + $TX = cos(($TAngle) * 3.1418 / 180 ) * ($Radius + 10)+ $XPos; + + if ( $TAngle > 0 && $TAngle < 180 ) + $TY = sin(($TAngle) * 3.1418 / 180 ) * ($SkewHeight + 10) + $YPos + $SpliceHeight + 4; + else + $TY = sin(($TAngle) * 3.1418 / 180 ) * ($SkewHeight + 10) + $YPos + 4; + + if ( $TAngle > 90 && $TAngle < 270 ) + { + $Position = imageftbbox($this->FontSize,0,$this->FontName,$Caption,$bogus); + $TextWidth = $Position[2]-$Position[0]; + $TX = $TX - $TextWidth; + } + + $C_TextColor = imagecolorallocate($this->Picture,70,70,70); + imagettftext($this->Picture,$this->FontSize,0,$TX,$TY,$C_TextColor,$this->FontName,$Caption); + } + + /* Process pie slices */ + for($iAngle=$Angle;$iAngle<=$Angle+$Value*$SpliceRatio;$iAngle=$iAngle+.5) + { + $TopX = cos($iAngle * 3.1418 / 180 ) * $Radius + $XPos; + $TopY = sin($iAngle * 3.1418 / 180 ) * $SkewHeight + $YPos; + + $TopPlots[$Key][] = $TopX; $BotPlots[$Key][] = $TopX; + $TopPlots[$Key][] = $TopY; $BotPlots[$Key][] = $TopY + $SpliceHeight; + } + + $TopPlots[$Key][] = $XCenterPos2; $BotPlots[$Key][] = $XCenterPos2; + $TopPlots[$Key][] = $YCenterPos2; $BotPlots[$Key][] = $YCenterPos2 + $SpliceHeight; + + $Angle = $iAngle + $SpliceDistanceRatio; + } + + /* Draw Bottom polygons */ + foreach($iValues as $Key => $Value) + { + $C_GraphLo = $this->AllocateColor($this->Picture,$this->Palette[$Key]["R"],$this->Palette[$Key]["G"],$this->Palette[$Key]["B"],-20); + imagefilledpolygon($this->Picture,$BotPlots[$Key],(count($BotPlots[$Key])+1)/2,$C_GraphLo); + + for($j=0;$j<=count($BotPlots[$Key])-4;$j=$j+2) + $this->drawLine($BotPlots[$Key][$j],$BotPlots[$Key][$j+1],$BotPlots[$Key][$j+2],$BotPlots[$Key][$j+3],$this->Palette[$Key]["R"]-20,$this->Palette[$Key]["G"]-20,$this->Palette[$Key]["B"]-20); + } + + /* Draw pie layers */ + if ( $EnhanceColors ) { $ColorRatio = 30 / $SpliceHeight; } else { $ColorRatio = 25 / $SpliceHeight; } + for($i=$SpliceHeight-1;$i>=1;$i--) + { + foreach($iValues as $Key => $Value) + { + $C_GraphLo = $this->AllocateColor($this->Picture,$this->Palette[$Key]["R"],$this->Palette[$Key]["G"],$this->Palette[$Key]["B"],-10); + $Plots = ""; $Plot = 0; + foreach($TopPlots[$Key] as $Key2 => $Value2) + { + $Plot++; + if ( $Plot % 2 == 1 ) + $Plots[] = $Value2; + else + $Plots[] = $Value2+$i; + } + imagefilledpolygon($this->Picture,$Plots,(count($Plots)+1)/2,$C_GraphLo); + + $Index = count($Plots); + $ColorFactor = -20 + ($SpliceHeight - $i) * $ColorRatio; + $this->drawAntialiasPixel($Plots[0],$Plots[1],$this->Palette[$Key]["R"]+$ColorFactor,$this->Palette[$Key]["G"]+$ColorFactor,$this->Palette[$Key]["B"]+$ColorFactor); + $this->drawAntialiasPixel($Plots[2],$Plots[3],$this->Palette[$Key]["R"]+$ColorFactor,$this->Palette[$Key]["G"]+$ColorFactor,$this->Palette[$Key]["B"]+$ColorFactor); + $this->drawAntialiasPixel($Plots[$Index-4],$Plots[$Index-3],$this->Palette[$Key]["R"]+$ColorFactor,$this->Palette[$Key]["G"]+$ColorFactor,$this->Palette[$Key]["B"]+$ColorFactor); + } + } + + /* Draw Top polygons */ + for($Key=count($iValues)-1;$Key>=0;$Key--) + { + $C_GraphLo = $this->AllocateColor($this->Picture,$this->Palette[$Key]["R"],$this->Palette[$Key]["G"],$this->Palette[$Key]["B"]); + imagefilledpolygon($this->Picture,$TopPlots[$Key],(count($TopPlots[$Key])+1)/2,$C_GraphLo); + + if ( $EnhanceColors ) { $En = 10; } else { $En = 5; } + for($j=0;$j<=count($TopPlots[$Key])-4;$j=$j+2) + $this->drawLine($TopPlots[$Key][$j],$TopPlots[$Key][$j+1],$TopPlots[$Key][$j+2],$TopPlots[$Key][$j+3],$this->Palette[$Key]["R"]+$En,$this->Palette[$Key]["G"]+$En,$this->Palette[$Key]["B"]+$En); + } + } + + /* This function can be used to set the background color */ + function drawBackground($R,$G,$B) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $C_Background = imagecolorallocate($this->Picture,$R,$G,$B); + imagefilledrectangle($this->Picture,0,0,$this->XSize,$this->YSize,$C_Background); + } + + /* This function can be used to set the background color */ + function drawGraphAreaGradient($R,$G,$B,$Decay,$Target=TARGET_GRAPHAREA) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + if ( $Target == TARGET_GRAPHAREA ) { $X1 = $this->GArea_X1+1; $X2 = $this->GArea_X2-1; $Y1 = $this->GArea_Y1+1; $Y2 = $this->GArea_Y2; } + if ( $Target == TARGET_BACKGROUND ) { $X1 = 0; $X2 = $this->XSize; $Y1 = 0; $Y2 = $this->YSize; } + + $YStep = ($Y2 - $Y1 - 2) / $Decay; + for($i=0;$i<=$Decay;$i++) + { + $R-=1;$G-=1;$B-=1; + $Yi1 = $Y1 + ( $i * $YStep ); + $Yi2 = ceil( $Yi1 + ( $i * $YStep ) + $YStep ); + if ( $Yi2 >= $Yi2 ) { $Yi2 = $Y2-1; } + + $C_Background = $this->AllocateColor($this->Picture,$R,$G,$B); + imagefilledrectangle($this->Picture,$X1,$Yi1,$X2,$Yi2,$C_Background); + } + } + + /* This function create a rectangle with antialias */ + function drawRectangle($X1,$Y1,$X2,$Y2,$R,$G,$B) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $C_Rectangle = imagecolorallocate($this->Picture,$R,$G,$B); + + $X1=$X1-.2;$Y1=$Y1-.2; + $X2=$X2+.2;$Y2=$Y2+.2; + $this->drawLine($X1,$Y1,$X2,$Y1,$R,$G,$B); + $this->drawLine($X2,$Y1,$X2,$Y2,$R,$G,$B); + $this->drawLine($X2,$Y2,$X1,$Y2,$R,$G,$B); + $this->drawLine($X1,$Y2,$X1,$Y1,$R,$G,$B); + } + + /* This function create a filled rectangle with antialias */ + function drawFilledRectangle($X1,$Y1,$X2,$Y2,$R,$G,$B,$DrawBorder=TRUE,$Alpha=100) + { + if ( $X2 > $X1 ) { list($X1, $X2) = array($X2, $X1); } + if ( $Y2 > $Y1 ) { list($Y1, $Y2) = array($Y2, $Y1); } + + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + if ( $Alpha == 100 ) + { + $C_Rectangle = imagecolorallocate($this->Picture,$R,$G,$B); + imagefilledrectangle($this->Picture,$X1,$Y1,$X2,$Y2,$C_Rectangle); + } + else + { + $LayerWidth = abs($X2-$X1)+2; + $LayerHeight = abs($Y2-$Y1)+2; + + $this->Layers[0] = imagecreatetruecolor($LayerWidth,$LayerHeight); + $C_White = imagecolorallocate($this->Layers[0],255,255,255); + imagefilledrectangle($this->Layers[0],0,0,$LayerWidth,$LayerHeight,$C_White); + imagecolortransparent($this->Layers[0],$C_White); + + $C_Rectangle = imagecolorallocate($this->Layers[0],$R,$G,$B); + imagefilledrectangle($this->Layers[0],1,1,$LayerWidth-1,$LayerHeight-1,$C_Rectangle); + + imagecopymerge($this->Picture,$this->Layers[0],min($X1,$X2)-1,min($Y1,$Y2)-1,0,0,$LayerWidth,$LayerHeight,$Alpha); + imagedestroy($this->Layers[0]); + } + + if ( $DrawBorder ) + $this->drawRectangle($X1,$Y1,$X2,$Y2,$R,$G,$B); + } + + /* This function create a rectangle with rounded corners and antialias */ + function drawRoundedRectangle($X1,$Y1,$X2,$Y2,$Radius,$R,$G,$B) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $C_Rectangle = imagecolorallocate($this->Picture,$R,$G,$B); + + $Step = 90 / ((3.1418 * $Radius)/2); + + for($i=0;$i<=90;$i=$i+$Step) + { + $X = cos(($i+180)*3.1418/180) * $Radius + $X1 + $Radius; + $Y = sin(($i+180)*3.1418/180) * $Radius + $Y1 + $Radius; + $this->drawAntialiasPixel($X,$Y,$R,$G,$B); + + $X = cos(($i-90)*3.1418/180) * $Radius + $X2 - $Radius; + $Y = sin(($i-90)*3.1418/180) * $Radius + $Y1 + $Radius; + $this->drawAntialiasPixel($X,$Y,$R,$G,$B); + + $X = cos(($i)*3.1418/180) * $Radius + $X2 - $Radius; + $Y = sin(($i)*3.1418/180) * $Radius + $Y2 - $Radius; + $this->drawAntialiasPixel($X,$Y,$R,$G,$B); + + $X = cos(($i+90)*3.1418/180) * $Radius + $X1 + $Radius; + $Y = sin(($i+90)*3.1418/180) * $Radius + $Y2 - $Radius; + $this->drawAntialiasPixel($X,$Y,$R,$G,$B); + } + + $X1=$X1-.2;$Y1=$Y1-.2; + $X2=$X2+.2;$Y2=$Y2+.2; + $this->drawLine($X1+$Radius,$Y1,$X2-$Radius,$Y1,$R,$G,$B); + $this->drawLine($X2,$Y1+$Radius,$X2,$Y2-$Radius,$R,$G,$B); + $this->drawLine($X2-$Radius,$Y2,$X1+$Radius,$Y2,$R,$G,$B); + $this->drawLine($X1,$Y2-$Radius,$X1,$Y1+$Radius,$R,$G,$B); + } + + /* This function create a filled rectangle with rounded corners and antialias */ + function drawFilledRoundedRectangle($X1,$Y1,$X2,$Y2,$Radius,$R,$G,$B) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $C_Rectangle = imagecolorallocate($this->Picture,$R,$G,$B); + + $Step = 90 / ((3.1418 * $Radius)/2); + + for($i=0;$i<=90;$i=$i+$Step) + { + $Xi1 = cos(($i+180)*3.1418/180) * $Radius + $X1 + $Radius; + $Yi1 = sin(($i+180)*3.1418/180) * $Radius + $Y1 + $Radius; + + $Xi2 = cos(($i-90)*3.1418/180) * $Radius + $X2 - $Radius; + $Yi2 = sin(($i-90)*3.1418/180) * $Radius + $Y1 + $Radius; + + $Xi3 = cos(($i)*3.1418/180) * $Radius + $X2 - $Radius; + $Yi3 = sin(($i)*3.1418/180) * $Radius + $Y2 - $Radius; + + $Xi4 = cos(($i+90)*3.1418/180) * $Radius + $X1 + $Radius; + $Yi4 = sin(($i+90)*3.1418/180) * $Radius + $Y2 - $Radius; + + imageline($this->Picture,$Xi1,$Yi1,$X1+$Radius,$Yi1,$C_Rectangle); + imageline($this->Picture,$X2-$Radius,$Yi2,$Xi2,$Yi2,$C_Rectangle); + imageline($this->Picture,$X2-$Radius,$Yi3,$Xi3,$Yi3,$C_Rectangle); + imageline($this->Picture,$Xi4,$Yi4,$X1+$Radius,$Yi4,$C_Rectangle); + + $this->drawAntialiasPixel($Xi1,$Yi1,$R,$G,$B); + $this->drawAntialiasPixel($Xi2,$Yi2,$R,$G,$B); + $this->drawAntialiasPixel($Xi3,$Yi3,$R,$G,$B); + $this->drawAntialiasPixel($Xi4,$Yi4,$R,$G,$B); + } + + imagefilledrectangle($this->Picture,$X1,$Y1+$Radius,$X2,$Y2-$Radius,$C_Rectangle); + imagefilledrectangle($this->Picture,$X1+$Radius,$Y1,$X2-$Radius,$Y2,$C_Rectangle); + + $X1=$X1-.2;$Y1=$Y1-.2; + $X2=$X2+.2;$Y2=$Y2+.2; + $this->drawLine($X1+$Radius,$Y1,$X2-$Radius,$Y1,$R,$G,$B); + $this->drawLine($X2,$Y1+$Radius,$X2,$Y2-$Radius,$R,$G,$B); + $this->drawLine($X2-$Radius,$Y2,$X1+$Radius,$Y2,$R,$G,$B); + $this->drawLine($X1,$Y2-$Radius,$X1,$Y1+$Radius,$R,$G,$B); + } + + /* This function create a circle with antialias */ + function drawCircle($Xc,$Yc,$Height,$R,$G,$B,$Width=0) + { + if ( $Width == 0 ) { $Width = $Height; } + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $C_Circle = imagecolorallocate($this->Picture,$R,$G,$B); + $Step = 360 / (2 * 3.1418 * max($Width,$Height)); + + for($i=0;$i<=360;$i=$i+$Step) + { + $X = cos($i*3.1418/180) * $Height + $Xc; + $Y = sin($i*3.1418/180) * $Width + $Yc; + $this->drawAntialiasPixel($X,$Y,$R,$G,$B); + } + } + + /* This function create a filled circle/ellipse with antialias */ + function drawFilledCircle($Xc,$Yc,$Height,$R,$G,$B,$Width=0) + { + if ( $Width == 0 ) { $Width = $Height; } + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $C_Circle = imagecolorallocate($this->Picture,$R,$G,$B); + $Step = 360 / (2 * 3.1418 * max($Width,$Height)); + + for($i=90;$i<=270;$i=$i+$Step) + { + $X1 = cos($i*3.1418/180) * $Height + $Xc; + $Y1 = sin($i*3.1418/180) * $Width + $Yc; + $X2 = cos((180-$i)*3.1418/180) * $Height + $Xc; + $Y2 = sin((180-$i)*3.1418/180) * $Width + $Yc; + + $this->drawAntialiasPixel($X1-1,$Y1-1,$R,$G,$B); + $this->drawAntialiasPixel($X2-1,$Y2-1,$R,$G,$B); + + if ( ($Y1-1) > $Yc - max($Width,$Height) ) + imageline($this->Picture,$X1,$Y1-1,$X2-1,$Y2-1,$C_Circle); + } + } + + /* This function will draw a filled ellipse */ + function drawEllipse($Xc,$Yc,$Height,$Width,$R,$G,$B) + { $this->drawCircle($Xc,$Yc,$Height,$R,$G,$B,$Width); } + + /* This function will draw an ellipse */ + function drawFilledEllipse($Xc,$Yc,$Height,$Width,$R,$G,$B) + { $this->drawFilledCircle($Xc,$Yc,$Height,$R,$G,$B,$Width); } + + /* This function create a line with antialias */ + function drawLine($X1,$Y1,$X2,$Y2,$R,$G,$B,$GraphFunction=FALSE) + { + if ( $this->LineDotSize > 1 ) { $this->drawDottedLine($X1,$Y1,$X2,$Y2,$this->LineDotSize,$R,$G,$B,$GraphFunction); return(0); } + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $Distance = sqrt(($X2-$X1)*($X2-$X1)+($Y2-$Y1)*($Y2-$Y1)); + if ( $Distance == 0 ) + return(-1); + $XStep = ($X2-$X1) / $Distance; + $YStep = ($Y2-$Y1) / $Distance; + + for($i=0;$i<=$Distance;$i++) + { + $X = $i * $XStep + $X1; + $Y = $i * $YStep + $Y1; + + if ( ($X >= $this->GArea_X1 && $X <= $this->GArea_X2 && $Y >= $this->GArea_Y1 && $Y <= $this->GArea_Y2) || !$GraphFunction ) + { + if ( $this->LineWidth == 1 ) + $this->drawAntialiasPixel($X,$Y,$R,$G,$B); + else + { + $StartOffset = -($this->LineWidth/2); $EndOffset = ($this->LineWidth/2); + for($j=$StartOffset;$j<=$EndOffset;$j++) + $this->drawAntialiasPixel($X+$j,$Y+$j,$R,$G,$B); + } + } + } + } + + /* This function create a line with antialias */ + function drawDottedLine($X1,$Y1,$X2,$Y2,$DotSize,$R,$G,$B,$GraphFunction=FALSE) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $Distance = sqrt(($X2-$X1)*($X2-$X1)+($Y2-$Y1)*($Y2-$Y1)); + + $XStep = ($X2-$X1) / $Distance; + $YStep = ($Y2-$Y1) / $Distance; + + $DotIndex = 0; + for($i=0;$i<=$Distance;$i++) + { + $X = $i * $XStep + $X1; + $Y = $i * $YStep + $Y1; + + if ( $DotIndex <= $DotSize) + { + if ( ($X >= $this->GArea_X1 && $X <= $this->GArea_X2 && $Y >= $this->GArea_Y1 && $Y <= $this->GArea_Y2) || !$GraphFunction ) + { + if ( $this->LineWidth == 1 ) + $this->drawAntialiasPixel($X,$Y,$R,$G,$B); + else + { + $StartOffset = -($this->LineWidth/2); $EndOffset = ($this->LineWidth/2); + for($j=$StartOffset;$j<=$EndOffset;$j++) + $this->drawAntialiasPixel($X+$j,$Y+$j,$R,$G,$B); + } + } + } + + $DotIndex++; + if ( $DotIndex == $DotSize * 2 ) + $DotIndex = 0; + } + } + + /* Load a PNG file and draw it over the chart */ + function drawFromPNG($FileName,$X,$Y,$Alpha=100) + { $this->drawFromPicture(1,$FileName,$X,$Y,$Alpha); } + + /* Load a GIF file and draw it over the chart */ + function drawFromGIF($FileName,$X,$Y,$Alpha=100) + { $this->drawFromPicture(2,$FileName,$X,$Y,$Alpha); } + + /* Load a JPEG file and draw it over the chart */ + function drawFromJPG($FileName,$X,$Y,$Alpha=100) + { $this->drawFromPicture(3,$FileName,$X,$Y,$Alpha); } + + /* Generic loader function for external pictures */ + function drawFromPicture($PicType,$FileName,$X,$Y,$Alpha=100) + { + if ( file_exists($FileName)) + { + $Infos = getimagesize($FileName); + $Width = $Infos[0]; + $Height = $Infos[1]; + if ( $PicType == 1 ) { $Raster = imagecreatefrompng($FileName); } + if ( $PicType == 2 ) { $Raster = imagecreatefromgif($FileName); } + if ( $PicType == 3 ) { $Raster = imagecreatefromjpeg($FileName); } + + imagecopymerge($this->Picture,$Raster,$X,$Y,0,0,$Width,$Height,$Alpha); + imagedestroy($Raster); + } + } + + /* Draw an alpha pixel */ + function drawAlphaPixel($X,$Y,$Alpha,$R,$G,$B) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + if ( $X < 0 || $Y < 0 || $X >= $this->XSize || $Y >= $this->YSize ) + return(-1); + + $RGB2 = imagecolorat($this->Picture, $X, $Y); + $R2 = ($RGB2 >> 16) & 0xFF; + $G2 = ($RGB2 >> 8) & 0xFF; + $B2 = $RGB2 & 0xFF; + + $iAlpha = (100 - $Alpha)/100; + $Alpha = $Alpha / 100; + + $Ra = floor($R*$Alpha+$R2*$iAlpha); + $Ga = floor($G*$Alpha+$G2*$iAlpha); + $Ba = floor($B*$Alpha+$B2*$iAlpha); + + $C_Aliased = imagecolorallocate($this->Picture,$Ra,$Ga,$Ba); + imagesetpixel($this->Picture,$X,$Y,$C_Aliased); + } + + /* Color helper */ + function AllocateColor($Picture,$R,$G,$B,$Factor=0) + { + $R = $R + $Factor; + $G = $G + $Factor; + $B = $B + $Factor; + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + return(imagecolorallocate($Picture,$R,$G,$B)); + } + + /* Add a border to the picture */ + function addBorder($Size=3,$R=0,$G=0,$B=0) + { + $Width = $this->XSize+2*$Size; + $Height = $this->YSize+2*$Size; + + $Resampled = imagecreatetruecolor($Width,$Height); + $C_Background = imagecolorallocate($Resampled,$R,$G,$B); + imagefilledrectangle($Resampled,0,0,$Width,$Height,$C_Background); + + imagecopy($Resampled,$this->Picture,$Size,$Size,0,0,$this->XSize,$this->YSize); + imagedestroy($this->Picture); + + $this->XSize = $Width; + $this->YSize = $Height; + + $this->Picture = imagecreatetruecolor($this->XSize,$this->YSize); + $C_White = imagecolorallocate($this->Picture,255,255,255); + imagefilledrectangle($this->Picture,0,0,$this->XSize,$this->YSize,$C_White); + imagecolortransparent($this->Picture,$C_White); + imagecopy($this->Picture,$Resampled,0,0,0,0,$this->XSize,$this->YSize); + } + + /* Render the current picture to a file */ + function Render($FileName) + { + if ( $this->ErrorReporting ) + $this->printErrors($this->ErrorInterface); + + /* Save image map if requested */ + if ( $this->BuildMap ) + $this->SaveImageMap(); + + imagepng($this->Picture,$FileName); + } + + /* Render the current picture to STDOUT */ + function Stroke() + { + if ( $this->ErrorReporting ) + $this->printErrors("GD"); + + /* Save image map if requested */ + if ( $this->BuildMap ) + $this->SaveImageMap(); + + header('Content-type: image/png'); + imagepng($this->Picture); + } + + /* Private functions for internal processing */ + function drawAntialiasPixel($X,$Y,$R,$G,$B) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $Plot = ""; + $Xi = floor($X); + $Yi = floor($Y); + + if ( $Xi == $X && $Yi == $Y) + { + /* $this->drawAlphaPixel($Xi,$Yi,0,$R,$G,$B); */ + $C_Aliased = imagecolorallocate($this->Picture,$R,$G,$B); + imagesetpixel($this->Picture,$X,$Y,$C_Aliased); + } + else + { + $Alpha1 = (1 - ($X - floor($X))) * (1 - ($Y - floor($Y))) * 100; + if ( $Alpha1 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi,$Yi,$Alpha1,$R,$G,$B); } + + $Alpha2 = ($X - floor($X)) * (1 - ($Y - floor($Y))) * 100; + if ( $Alpha2 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi+1,$Yi,$Alpha2,$R,$G,$B); } + + $Alpha3 = (1 - ($X - floor($X))) * ($Y - floor($Y)) * 100; + if ( $Alpha3 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi,$Yi+1,$Alpha3,$R,$G,$B); } + + $Alpha4 = ($X - floor($X)) * ($Y - floor($Y)) * 100; + if ( $Alpha4 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi+1,$Yi+1,$Alpha4,$R,$G,$B); } + } + } + + /* Validate data contained in the description array */ + function validateDataDescription($FunctionName,&$DataDescription,$DescriptionRequired=TRUE) + { + if (!isset($DataDescription["Position"])) + { + $this->Errors[] = "[Warning] ".$FunctionName." - Y Labels are not set."; + $DataDescription["Position"] = "Name"; + } + + if ( $DescriptionRequired ) + { + if (!isset($DataDescription["Description"])) + { + $this->Errors[] = "[Warning] ".$FunctionName." - Series descriptions are not set."; + foreach($DataDescription["Values"] as $key => $Value) + { + $DataDescription["Description"][$Value] = $Value; + } + } + + if (count($DataDescription["Description"]) < count($DataDescription["Values"])) + { + $this->Errors[] = "[Warning] ".$FunctionName." - Some series descriptions are not set."; + foreach($DataDescription["Values"] as $key => $Value) + { + if ( !isset($DataDescription["Description"][$Value])) + $DataDescription["Description"][$Value] = $Value; + } + } + } + } + + /* Validate data contained in the data array */ + function validateData($FunctionName,&$Data) + { + $DataSummary = ""; + + foreach($Data as $key => $Values) + { + foreach($Values as $key2 => $Value) + { + if (!isset($DataSummary[$key2])) + $DataSummary[$key2] = 1; + else + $DataSummary[$key2]++; + } + } + + if ( max($DataSummary) == 0 ) + $this->Errors[] = "[Warning] ".$FunctionName." - No data set."; + + foreach($DataSummary as $key => $Value) + { + if ($Value < max($DataSummary)) + { + $this->Errors[] = "[Warning] ".$FunctionName." - Missing data in serie ".$key."."; + } + } + } + + /* Print all error messages on the CLI or graphically */ + function printErrors($Mode="CLI") + { + if (count($this->Errors) == 0) + return(0); + + if ( $Mode == "CLI" ) + { + foreach($this->Errors as $key => $Value) + echo $Value."\r\n"; + } + elseif ( $Mode == "GD" ) + { + $this->setLineStyle($Width=1); + $MaxWidth = 0; + foreach($this->Errors as $key => $Value) + { + $Position = imageftbbox($this->ErrorFontSize,0,$this->ErrorFontName,$Value,$bogus); + $TextWidth = $Position[2]-$Position[0]; + if ( $TextWidth > $MaxWidth ) { $MaxWidth = $TextWidth; } + } + $this->drawFilledRoundedRectangle($this->XSize-($MaxWidth+20),$this->YSize-(20+(($this->ErrorFontSize+4)*count($this->Errors))),$this->XSize-10,$this->YSize-10,6,233,185,185); + $this->drawRoundedRectangle($this->XSize-($MaxWidth+20),$this->YSize-(20+(($this->ErrorFontSize+4)*count($this->Errors))),$this->XSize-10,$this->YSize-10,6,193,145,145); + + $C_TextColor = imagecolorallocate($this->Picture,133,85,85); + $YPos = $this->YSize - (18 + (count($this->Errors)-1) * ($this->ErrorFontSize + 4)); + foreach($this->Errors as $key => $Value) + { + imagettftext($this->Picture,$this->ErrorFontSize,0,$this->XSize-($MaxWidth+15),$YPos,$C_TextColor,$this->ErrorFontName,$Value); + $YPos = $YPos + ($this->ErrorFontSize + 4); + } + } + } + + /* Activate the image map creation process */ + function setImageMap($Mode=TRUE,$GraphID="MyGraph") + { + $this->BuildMap = $Mode; + $this->MapID = $GraphID; + } + + /* Add a box into the image map */ + function addToImageMap($X1,$Y1,$X2,$Y2,$SerieName,$Value,$CallerFunction) + { + if ( $this->MapFunction == NULL || $this->MapFunction == $CallerFunction ) + { + $this->ImageMap[] = round($X1).",".round($Y1).",".round($X2).",".round($Y2).",".$SerieName.",".$Value; + $this->MapFunction = $CallerFunction; + } + } + + /* Load and cleanup the image map from disk */ + function getImageMap($MapName,$Flush=TRUE) + { + /* Strip HTML query strings */ + $Values = $this->tmpFolder.$MapName; + $Value = split("\?",$Values); + $FileName = $Value[0]; + + if ( file_exists($FileName) ) + { + $Handle = fopen($FileName, "r"); + $MapContent = fread($Handle, filesize($FileName)); + fclose($Handle); + echo $MapContent; + + if ( $Flush ) + unlink($FileName); + + exit(); + } + else + { + header("HTTP/1.0 404 Not Found"); + exit(); + } + } + + /* Save the image map to the disk */ + function SaveImageMap() + { + if ( !$this->BuildMap ) { return(-1); } + + if ( $this->ImageMap == NULL ) + { + $this->Errors[] = "[Warning] SaveImageMap - Image map is empty."; + return(-1); + } + + $Handle = fopen($this->tmpFolder.$this->MapID, 'w'); + if ( !$Handle ) + { + $this->Errors[] = "[Warning] SaveImageMap - Cannot save the image map."; + return(-1); + } + else + { + foreach($this->ImageMap as $Key => $Value) + fwrite($Handle, htmlentities($Value)."\r"); + } + fclose ($Handle); + } + + /* Convert seconds to a time format string */ + function ToTime($Value) + { + $Hour = floor($Value/3600); + $Minute = floor(($Value - $Hour*3600)/60); + $Second = floor($Value - $Hour*3600 - $Minute*60); + + if (strlen($Hour) == 1 ) { $Hour = "0".$Hour; } + if (strlen($Minute) == 1 ) { $Minute = "0".$Minute; } + if (strlen($Second) == 1 ) { $Second = "0".$Second; } + + return($Hour.":".$Minute.":".$Second); + } + + /* Convert to metric system */ + function ToMetric($Value) + { + $Go = floor($Value/1000000000); + $Mo = floor(($Value - $Go*1000000000)/1000000); + $Ko = floor(($Value - $Go*1000000000 - $Mo*1000000)/1000); + $o = floor($Value - $Go*1000000000 - $Mo*1000000 - $Ko*1000); + + if ($Go != 0) { return($Go.".".$Mo."g"); } + if ($Mo != 0) { return($Mo.".".$ko."m"); } + if ($Ko != 0) { return($Ko.".".$o)."k"; } + return($o); + } + + /* Set date format for axis labels */ + function setDateFormat($Format) + { + $this->DateFormat = $Format; + } + + /* Convert TS to a date format string */ + function ToDate($Value) + { + return(date($this->DateFormat,$Value)); + } + } + + function RaiseFatal($Message) + { + echo "[FATAL] ".$Message."\r\n"; + exit(); + } +?> diff --git a/clients/GD/FSMon/pChart/pData.class b/clients/GD/FSMon/pChart/pData.class new file mode 100644 index 0000000..8e1938d --- /dev/null +++ b/clients/GD/FSMon/pChart/pData.class @@ -0,0 +1,260 @@ +. + + Class initialisation : + pData() + Data populating methods : + ImportFromCSV($FileName,$Delimiter=",",$DataColumns=-1,$HasHeader=FALSE,$DataName=-1) + AddPoint($Value,$Serie="Serie1",$Description="") + Series manipulation methods : + AddSerie($SerieName="Serie1") + AddAllSeries() + RemoveSerie($SerieName="Serie1") + SetAbsciseLabelSerie($SerieName = "Name") + SetSerieName($Name,$SerieName="Serie1") + + SetSerieSymbol($Name,$Symbol) + SetXAxisName($Name="X Axis") + SetYAxisName($Name="Y Axis") + SetXAxisFormat($Format="number") + SetYAxisFormat($Format="number") + SetXAxisUnit($Unit="") + SetYAxisUnit($Unit="") + removeSerieName($SerieName) + removeAllSeries() + Data retrieval methods : + GetData() + GetDataDescription() + */ + + /* pData class definition */ + class pData + { + var $Data; + var $DataDescription; + + function pData() + { + $this->Data = ""; + $this->DataDescription = ""; + $this->DataDescription["Position"] = "Name"; + $this->DataDescription["Format"]["X"] = "number"; + $this->DataDescription["Format"]["Y"] = "number"; + $this->DataDescription["Unit"]["X"] = NULL; + $this->DataDescription["Unit"]["Y"] = NULL; + } + + function ImportFromCSV($FileName,$Delimiter=",",$DataColumns=-1,$HasHeader=FALSE,$DataName=-1) + { + $handle = @fopen($FileName,"r"); + if ($handle) + { + $HeaderParsed = FALSE; + while (!feof($handle)) + { + $buffer = fgets($handle, 4096); + $buffer = str_replace(chr(10),"",$buffer); + $buffer = str_replace(chr(13),"",$buffer); + $Values = split($Delimiter,$buffer); + + if ( $buffer != "" ) + { + if ( $HasHeader == TRUE && $HeaderParsed == FALSE ) + { + if ( $DataColumns == -1 ) + { + $ID = 1; + foreach($Values as $key => $Value) + { $this->SetSerieName($Value,"Serie".$ID); $ID++; } + } + else + { + $SerieName = ""; + + foreach($DataColumns as $key => $Value) + $this->SetSerieName($Values[$Value],"Serie".$Value); + } + $HeaderParsed = TRUE; + } + else + { + if ( $DataColumns == -1 ) + { + $ID = 1; + foreach($Values as $key => $Value) + { $this->AddPoint(intval($Value),"Serie".$ID); $ID++; } + } + else + { + $SerieName = ""; + if ( $DataName != -1 ) + $SerieName = $Values[$DataName]; + + foreach($DataColumns as $key => $Value) + $this->AddPoint($Values[$Value],"Serie".$Value,$SerieName); + } + } + } + } + fclose($handle); + } + } + + function AddPoint($Value,$Serie="Serie1",$Description="") + { + if (is_array($Value) && count($Value) == 1) + $Value = $Value[0]; + + $ID = 0; + for($i=0;$i<=count($this->Data);$i++) + { if(isset($this->Data[$i][$Serie])) { $ID = $i+1; } } + + if ( count($Value) == 1 ) + { + $this->Data[$ID][$Serie] = $Value; + if ( $Description != "" ) + $this->Data[$ID]["Name"] = $Description; + elseif (!isset($this->Data[$ID]["Name"])) + $this->Data[$ID]["Name"] = $ID; + } + else + { + foreach($Value as $key => $Val) + { + $this->Data[$ID][$Serie] = $Val; + if (!isset($this->Data[$ID]["Name"])) + $this->Data[$ID]["Name"] = $ID; + $ID++; + } + } + } + + function AddSerie($SerieName="Serie1") + { + if ( !isset($this->DataDescription["Values"]) ) + { + $this->DataDescription["Values"][] = $SerieName; + } + else + { + $Found = FALSE; + foreach($this->DataDescription["Values"] as $key => $Value ) + if ( $Value == $SerieName ) { $Found = TRUE; } + + if ( !$Found ) + $this->DataDescription["Values"][] = $SerieName; + } + } + + function AddAllSeries() + { + unset($this->DataDescription["Values"]); + + if ( isset($this->Data[0]) ) + { + foreach($this->Data[0] as $Key => $Value) + { + if ( $Key != "Name" ) + $this->DataDescription["Values"][] = $Key; + } + } + } + + function RemoveSerie($SerieName="Serie1") + { + if ( !isset($this->DataDescription["Values"]) ) + return(0); + + $Found = FALSE; + foreach($this->DataDescription["Values"] as $key => $Value ) + { + if ( $Value == $SerieName ) + unset($this->DataDescription["Values"][$key]); + } + } + + function SetAbsciseLabelSerie($SerieName = "Name") + { + $this->DataDescription["Position"] = $SerieName; + } + + function SetSerieName($Name,$SerieName="Serie1") + { + $this->DataDescription["Description"][$SerieName] = $Name; + } + + function SetXAxisName($Name="X Axis") + { + $this->DataDescription["Axis"]["X"] = $Name; + } + + function SetYAxisName($Name="Y Axis") + { + $this->DataDescription["Axis"]["Y"] = $Name; + } + + function SetXAxisFormat($Format="number") + { + $this->DataDescription["Format"]["X"] = $Format; + } + + function SetYAxisFormat($Format="number") + { + $this->DataDescription["Format"]["Y"] = $Format; + } + + function SetXAxisUnit($Unit="") + { + $this->DataDescription["Unit"]["X"] = $Unit; + } + + function SetYAxisUnit($Unit="") + { + $this->DataDescription["Unit"]["Y"] = $Unit; + } + + function SetSerieSymbol($Name,$Symbol) + { + $this->DataDescription["Symbol"][$Name] = $Symbol; + } + + function removeSerieName($SerieName) + { + if ( isset($this->DataDescription["Description"][$SerieName]) ) + unset($this->DataDescription["Description"][$SerieName]); + } + + function removeAllSeries() + { + foreach($this->DataDescription["Values"] as $Key => $Value) + unset($this->DataDescription["Values"][$Key]); + } + + function GetData() + { + return($this->Data); + } + + function GetDataDescription() + { + return($this->DataDescription); + } + } +?> \ No newline at end of file diff --git a/clients/GD/FSMon/testgraph.php b/clients/GD/FSMon/testgraph.php new file mode 100644 index 0000000..f52de98 --- /dev/null +++ b/clients/GD/FSMon/testgraph.php @@ -0,0 +1,62 @@ +AddPoint (0, "Free", 1); +// $DataSet->AddPoint (0, "Used", 1); +// $DataSet->AddPoint (70, "Free", 2); +// $DataSet->AddPoint (30, "Used", 2); +// $DataSet->AddPoint (80, "Free", 3); +// $DataSet->AddPoint (20, "Used", 3); +// $DataSet->AddPoint (90, "Free", 4); +// $DataSet->AddPoint (10, "Used", 4); + +// Used first +$DataSet->AddPoint (0, "Used", 1); +$DataSet->AddPoint (70, "Used", 2); +$DataSet->AddPoint (80, "Used", 3); +$DataSet->AddPoint (90, "Used", 4); +$DataSet->AddPoint (0, "Free", 1); +$DataSet->AddPoint (30, "Free", 2); +$DataSet->AddPoint (20, "Free", 3); +$DataSet->AddPoint (10, "Free", 4); + +$DataSet->AddAllSeries(); +$DataSet->SetAbsciseLabelSerie(); + +// Initialise the graph +$Test = new pChart (700, 280); + +$Test->setColorPalette (1, 0, 255, 0); +$Test->setColorPalette (0, 255, 0, 0); + +$Test->drawGraphAreaGradient (100, 150, 175, 100, TARGET_BACKGROUND); +$Test->setFontProperties ("$fonts/tahoma.ttf", 8); +$Test->setGraphArea (50, 30, 680, 200); +$Test->drawRoundedRectangle (5, 5, 695, 275, 5, 230, 230, 230); +$Test->drawGraphAreaGradient (162, 183, 202, 50); +$Test->drawScale ($DataSet->GetData (), $DataSet->GetDataDescription (), SCALE_ADDALL, 200, 200, 200, true, 70, 2, true); +$Test->drawGrid (4, true, 230, 230, 230, 50); + +// Draw the 0 line +$Test->setFontProperties ("$fonts/tahoma.ttf", 6); +$Test->drawTreshold (0, 143, 55, 72, true, true); + +// Draw the bar graph +$Test->drawStackedBarGraph ($DataSet->GetData (), $DataSet->GetDataDescription (), 75); + +// Finish the graph +$Test->setFontProperties ("$fonts/tahoma.ttf",8); +$Test->drawLegend (610, 35, $DataSet->GetDataDescription (), 130, 180, 205); +$Test->setFontProperties ("$fonts/tahoma.ttf", 10); +$Test->drawTitle (50, 22, "$system:$mount", 255, 255, 255, 675); +$Test->Stroke (); +?> \ No newline at end of file diff --git a/clients/GD/cqtool.tar.gz b/clients/GD/cqtool.tar.gz new file mode 100644 index 0000000..8c82abd Binary files /dev/null and b/clients/GD/cqtool.tar.gz differ diff --git a/clients/GD/cqtool/CreateHelpDeskUI.pm b/clients/GD/cqtool/CreateHelpDeskUI.pm new file mode 100644 index 0000000..d3bb60d --- /dev/null +++ b/clients/GD/cqtool/CreateHelpDeskUI.pm @@ -0,0 +1,627 @@ +############################################################################## +# +# Name: CreateHelpDeskUI.pm +# +# Description: CreateHelpDeskUI.pm is a Perl module that encapsulates +# a Perl/Tk application to create a Help Desk +# ticket. This application was developed for a few +# reasons. First ucmwb needs to be able to create Help +# Desk tickets. The approach was to use IBM/Rational's +# cqtool (/opt/rational/clearquest/bin/cqtool) but there +# is two problems with this. First IBM/Rational's cqtool +# is unsupported and documented. Secondly IBM/Rational's +# cqtool is going away as of Clearquest 7.0. +# +# Another problem is that while IBM/Rational's cqtool +# would work, it does not return the ID of the Help Desk ticket +# created! +# +# So this Perl/Tk module was created to create Help Desk +# tickets. Perl interfaces with Clearquest to call the +# appropraite Clearquest action hooks and the like. Note +# that only the basic information is asked for. If you +# really want to create or modify a full Help Desk ticket +# use Clearquest. This Perl/Tk app's main customer is +# ucmwb. +# +# Author: Andrew@ClearSCM.com +# +# (c) Copyright 2007, General Dynamics, all rights reserved +# +############################################################################## +use strict; +use warnings; + +package CreateHelpDeskUI; + use Tk; + use Tk::Dialog; + use Tk::BrowseEntry; + + use Display; + use Tk::MyText; + use CQTool; + + use base "Exporter"; + + my $ME = "CreateHelpDesk"; + my $VERSION = "1.1"; + + # Colors + my ($EDIT_FOREGROUND, $EDIT_BACKGROUND); + + our %hd; + + our @EXPORT = qw ( + createHelpDeskUI + %hd + ); + + # Globals + my $_createHelpDeskUI; + + # Dropdowns + my ( + $_requestor, + $_location, + $_category, + $_related_version, + $_platform, + $_requestor_priority, + ); + + # Choice lists + my ( + @_requestors, + @_locations, + @_categories, + @_related_versions, + @_platforms, + @_requested_priorities, + ); + + # Buttons + my $_submit; + + ############################################################################ + # Subroutines + ############################################################################ + + #--------------------------------------------------------------------------- + # _helpAbout (): Puts up the Help: About dialog box + #--------------------------------------------------------------------------- + sub _helpAbout () { + my $text = "$ME v$VERSION\n"; + + $text .= < of ClearSCM, Inc. +END + + my $desc = $_createHelpDeskUI->Dialog ( + -title => "About $ME", + -text => $text, + -buttons => [ "OK" ], + ); + + $desc->Show; + } # _helpAbout + + #--------------------------------------------------------------------------- + # _displayValues (): Displays the contents for %hd hash + #--------------------------------------------------------------------------- + sub _displayValues () { + foreach (keys %hd) { + if ($hd{$_}) { + display "$_: $hd{$_}"; + } else { + display "$_: undef"; + } # if + } # foreach + } # _displayValues + + #--------------------------------------------------------------------------- + # _getChoices (): For a given $entity and $fieldname, this routine returns + # the given choice list from Clearquest. + #--------------------------------------------------------------------------- + sub _getChoices ($$) { + my ($entity, $fieldname) = @_; + + return @{$entity->GetFieldChoiceList ($fieldname)}; + } # _getChoices + + #--------------------------------------------------------------------------- + # _destroyHelpDeskUI (): Destroys the current HelpDesk UI recycling Tk + # objects + #--------------------------------------------------------------------------- + sub _destroyHelpDeskUI () { + # Destroy all globals created + destroy $_submit; + destroy $_requestor; + destroy $_location; + destroy $_category; + destroy $_related_version; + destroy $_platform; + destroy $_requestor_priority; + destroy $_createHelpDeskUI; + + $_requestor = + $_location = + $_category = + $_related_version = + $_platform = + $_requestor_priority = + $_submit = + $_createHelpDeskUI = undef; + + %hd = (); + } # _destroyHelpDeskUI + + #--------------------------------------------------------------------------- + # _submit (): Actually creates the WOR given the filled out %hd hash. + #--------------------------------------------------------------------------- + sub _submit () { + debug "Creating Help Desk Ticket..."; + + # Change requestor from a format of "lastname, firstname (badge)" -> badge + if ($hd{requestor} =~ /\((\w*)\)$/) { + $hd{requestor} = $1; + } # if + + _displayValues if get_debug; + + my $new_id = CQTool::submitHelpDesk ($CQTool::entity, %hd); + + display $new_id if $new_id; + + _destroyHelpDeskUI; + + return $new_id; + } # _submit + + #--------------------------------------------------------------------------- + # _setSubmitButton (): Sets the submit button to active only if all required + # fields have values. + #--------------------------------------------------------------------------- + sub _setSubmitButton (;$) { + my ($headline) = @_; + + return if !$_submit; + + # Check to see if we can activate the submit button + my $state = "normal"; + + foreach (@CQTool::hd_required_fields) { + if ($_ eq "headline") { + if (defined $headline) { + if ($headline eq "") { + $state = "disable"; + last; + } else { + next; + } # if + } # if + } # if + + if (!$hd{$_} or $hd{$_} eq "") { + $state = "disable"; + last; + } # if + } # foreach + + $_submit->configure ( + -state => $state, + ); + } # _setSubmitButton + + #--------------------------------------------------------------------------- + # _validateText (): Gets the text from the MyText widget and sets the submit + # button + #--------------------------------------------------------------------------- + sub _validatetext { + my ($text) = @_; + + $hd{description} = $text->get_text; + chomp $hd{description}; + + _setSubmitButton $text; + + return 1; + } # _validatetext + + #--------------------------------------------------------------------------- + # _validateEntry (): Gets the text from the headline widget and sets the + # submit button + #--------------------------------------------------------------------------- + sub _validateentry { + my ($entry) = @_; + + _setSubmitButton $entry; + + return 1; + } # _validateentry + + #--------------------------------------------------------------------------- + # _createDropDown (): Creates a dropdown widget in $parent in a grid at the + # $x, $y coordinates with a $label and a $value, using + # dropdown @values and a $refresh procedure. + #--------------------------------------------------------------------------- + sub _createDropDown ($$$$$$@) { + my ($parent, $x, $y, $label, $refresh, $value, @values) = @_; + + $parent->Label ( + -width => length $label, + -text => "$label:", + )->grid ( + -row => $x, + -column => $y, + -sticky => "e", + ); + + return $parent->Optionmenu ( + -activeforeground => $EDIT_FOREGROUND, + -activebackground => $EDIT_BACKGROUND, + -command => \&$refresh, + -variable => $value, + -options => \@values, + )->grid ( + -row => $x, + -column => $y + 1, + -sticky => "w", + ); + } # _createDropDown + + #--------------------------------------------------------------------------- + # _createBrowseEntry (): Creates a dropdown like widget which drops down a + # scrollable list in $parent with a $label, $refresh + # procedure, setting $value with the choice from + # @values. + #--------------------------------------------------------------------------- + sub _createBrowseEntry ($$$$$$@) { + my ($parent, $x, $y, $label, $refresh, $value, @values) = @_; + + $parent->Label ( + -width => length $label, + -text => "$label:", + )->grid ( + -row => $x, + -column => $y, + -sticky => "e", + ); + + my $longest_item = 0; + + foreach (@values) { + $longest_item = length $_ if length $_ > $longest_item; + } # if + + my $browse_entry = $parent->BrowseEntry ( + -browsecmd => \&$refresh, + -variable => $value, + -width => $longest_item, + )->grid ( + -row => $x, + -column => $y + 1, + -sticky => "w", + ); + + my $i = 0; + + foreach (@values) { + $browse_entry->insert ($i++, $_); + } # foreach + + return $browse_entry; + } # _createBrowseEntry + + #--------------------------------------------------------------------------- + # _createTextField (): Creates a text field widget in $parent with a $label + # and a $value, using a $maxlen and a $validate + # procedure. + #--------------------------------------------------------------------------- + sub _createTextField ($$$$$) { + my ($parent, $label, $value, $maxlen, $validate) = @_; + + $parent->Label ( + -text => "$label:", + -justify => "right", + -width => 10, + )->pack ( + -side => "left", + -anchor => "e", + ); + + $parent->Entry ( + -foreground => $EDIT_FOREGROUND, + -background => $EDIT_BACKGROUND, + -width => $maxlen, + -justify => "left", + -textvariable => $value, + -validate => "key", + -validatecommand => \&$validate, + )->pack ( + -side => "left", + -padx => 5, + -anchor => "e", + ); + } # _createTextField + + #--------------------------------------------------------------------------- + # _createText (): Creates a multiline text field widget in $parent with a + # $label and a $value, using the specified $rows and $cols + # and a $validate procedure. + #--------------------------------------------------------------------------- + sub _createText ($$$$$$) { + my ($parent, $label, $value, $rows, $cols, $validate) = @_; + + $parent->Label ( + -text => "$label:", + -justify => "right", + -width => 10, + )->pack ( + -side => "left",+ + -anchor => "n", + -pady => 5, + ); + + $parent->MyText ( + -foreground => $EDIT_FOREGROUND, + -background => $EDIT_BACKGROUND, + -height => $rows, + -width => $cols, + -modified => \&$validate, + -text => $value, + )->pack ( + -side => "left", + -pady => 5, + -anchor => "s", + ); + } # _createText + + #--------------------------------------------------------------------------- + # _createButton (): Creates a pushbutton widget in $parent with a $label and + # an $action. + #--------------------------------------------------------------------------- + sub _createButton ($$$) { + my ($parent, $label, $action) = @_; + + $parent->Button ( + -activeforeground => $EDIT_FOREGROUND, + -activebackground => $EDIT_BACKGROUND, + -text => $label, + -width => length $label, + -command => \$action + )->pack ( + -side => "left", + -padx => 5 + ); + } # _createButton + + #--------------------------------------------------------------------------- + # _changeDropDown (): Refreshes the values in the dropdown menu. + #--------------------------------------------------------------------------- + sub _changeDropDown ($@) { + my ($dropdown, @values) = @_; + + if ($dropdown) { + my $menu = $dropdown->menu; + + if ($menu) { + $dropdown->menu->delete (0, "end"); + } # if + + $dropdown->addOptions (@values); + } # if + } # _changeDropDown + + #--------------------------------------------------------------------------- + # _refresh (): Refreshes the application by getting news values from + # Clearquest. Note a change in one dropdown may change others, + # so we re-get all of them through this procedure. + #--------------------------------------------------------------------------- + sub _refresh () { + my $fieldname; + + $fieldname = "category"; + @_categories = _getChoices $CQTool::entity, $fieldname; + $hd{$fieldname} = $_categories[0] if !$hd{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $hd{$fieldname}); + + $fieldname = "related_version"; + @_related_versions = _getChoices $CQTool::entity, $fieldname; + $hd{$fieldname} = $_related_versions[0] if !$hd{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $hd{$fieldname}); + + $fieldname = "platform"; + @_platforms = _getChoices $CQTool::entity, $fieldname; + $hd{$fieldname} = $_platforms[0] if !$hd{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $hd{$fieldname}); + + $fieldname = "requestedpriority"; + @_requested_priorities = _getChoices $CQTool::entity, $fieldname; + $hd{$fieldname} = $_requested_priorities[0] if !$hd{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $hd{$fieldname}); + + _changeDropDown $_category, @_categories; + _changeDropDown $_related_version, @_related_versions; + _changeDropDown $_platform, @_platforms; + _changeDropDown $_requestor_priority, @_requested_priorities; + + _setSubmitButton; + } # _refresh + + #--------------------------------------------------------------------------- + # _getNames (): Translates an array of badge numbers into a hash of names + # as the key and badge numbers as the value. + #--------------------------------------------------------------------------- + sub _getNames (@) { + my (@badges) = @_; + + my %names; + + foreach (@badges) { + my $query = $CQTool::session->BuildQuery ("users"); + + $query->BuildField ("fullname"); + + my $filter = $query->BuildFilterOperator ($CQPerlExt::CQ_BOOL_OP_AND); + + # Clearquest requires values to be in an array + my @badge = $_; + + $filter->BuildFilter ("login_name", $CQPerlExt::CQ_COMP_OP_EQ, \@badge); + + my $result = $CQTool::session->BuildResultSet ($query); + + $result->Execute; + + my $status = $result->MoveNext; + + my $fullname; + + while ($status == $CQPerlExt::CQ_SUCCESS) { + $fullname = $result->GetColumnValue (1); + $status = $result->MoveNext; + } # while + + $names{$fullname ? $fullname : ""} = $_; + } # foreach + + return %names; + } # _getNames + + #--------------------------------------------------------------------------- + # _darken (): Returns a slightly darker color than the passed in color + #--------------------------------------------------------------------------- + sub _darken ($) { + my ($color) = @_; + + # Get the RGB values + my ($r, $g, $b) = $_createHelpDeskUI->rgb($color); + + # Set them to $DARKEN % of their previous values + my $DARKEN = .8; + my $rhex = sprintf "%x", $r * $DARKEN; + my $ghex = sprintf "%x", $g * $DARKEN; + my $bhex = sprintf "%x", $b * $DARKEN; + + # Return a color string + return "\#$rhex$ghex$bhex"; + } # _darken + + #--------------------------------------------------------------------------- + # _createHelpDeskUI (): This is the main and exported routine that creates + # and handles the entire Perl/Tk application for + # creating a Help Desk ticket. + #--------------------------------------------------------------------------- + sub createHelpDeskUI () { + $_createHelpDeskUI = MainWindow->new; + + $EDIT_FOREGROUND = $_createHelpDeskUI->optionGet ("foreground", "Foreground"); + $EDIT_BACKGROUND = _darken ($_createHelpDeskUI->optionGet ("background", "Background")); + + $hd{id} = "None" if !$hd{id}; + + $_createHelpDeskUI->title ("Submit Helpdesk $hd{id}"); + + my $frame0 = $_createHelpDeskUI->Frame->pack (-pady => 2); + my $frame1 = $_createHelpDeskUI->Frame->pack; + my $frame2 = $_createHelpDeskUI->Frame->pack; + my $frame3 = $_createHelpDeskUI->Frame->pack; + my $frame4 = $_createHelpDeskUI->Frame->pack; + my $frame5 = $_createHelpDeskUI->Frame->pack; + my $frame6 = $_createHelpDeskUI->Frame->pack; + + _createTextField + $frame1, + "Headline", + \$hd{headline}, + 100, + \&_validateentry; + + _createText + $frame2, + "Description", + \$hd{description}, + 24, 100, + \&_validatetext; + + @_categories = _getChoices $CQTool::entity, "category"; + @_related_versions = _getChoices $CQTool::entity, "related_version"; + @_platforms = _getChoices $CQTool::entity, "platform"; + @_requested_priorities = _getChoices $CQTool::entity, "requestedpriority"; + @_requestors = _getChoices $CQTool::entity, "requestor"; + + my %requestor_names = _getNames @_requestors; + + @_requestors = (); + + foreach (sort keys %requestor_names) { + if ($_ eq "") { + push @_requestors, ""; + } else { + push @_requestors, "$_ ($requestor_names{$_})"; + } # if + } # foreach + + @_locations = _getChoices $CQTool::entity, "requestorlocation"; + + $_requestor = _createBrowseEntry + $frame3, + 0, 0, + "Requestor", + \&_refresh, + \$hd{requestor}, + @_requestors; + $_location = _createDropDown + $frame3, + 0, 3, + "Location", + \&_refresh, + \$hd{location}, + @_locations; + + $_category = _createDropDown + $frame4, + 0, 0, + "Category", + \&_refresh, + \$hd{category}, + @_categories; + $_related_version = _createDropDown + $frame4, + 0, 3, + "Related Version", + \&_refresh, + \$hd{related_version}, + @_related_versions; + + $_platform = _createDropDown + $frame5, + 0, 0, + "Platform", + \&_refresh, + \$hd{platform}, + @_platforms; + $_requestor_priority = _createDropDown + $frame5, + 0, 3, + "Requested Priority", + \&_refresh, + \$hd{requestedpriority}, + @_requested_priorities; + + $_submit = _createButton $frame6, "Submit", \&_submit; + + $_submit->configure ( + -state => "disabled", + ); + + _createButton $frame6, "Display", \&_displayValues if (get_debug); + _createButton $frame6, "About", \&_helpAbout; + _createButton $frame6, "Exit", sub { _destroyHelpDeskUI }; + } # createHelpDeskUI + +1; diff --git a/clients/GD/cqtool/CreateWORUI.pm b/clients/GD/cqtool/CreateWORUI.pm new file mode 100644 index 0000000..8a62a86 --- /dev/null +++ b/clients/GD/cqtool/CreateWORUI.pm @@ -0,0 +1,575 @@ +############################################################################## +# +# Name: CreateWORUI.pm +# +# Description: CreateWORUI.pm is a Perl module that encapsulates a +# Perl/Tk application to create a WOR. This application +# was developed for a few reasons. First ucmwb needs to +# be able to create WORs. The approach was to use +# IBM/Rational's cqtool +# (/opt/rational/clearquest/bin/cqtool) but there is two +# problems with this. First IBM/Rational's cqtool is +# unsupported and documented. Secondly IBM/Rational's +# cqtool is going away as of Clearquest 7.0. +# +# Another problem is that while IBM/Rational's cqtool +# would work, it does not return the ID of the WOR +# created! +# +# So this Perl/Tk module was created to create WORs. Perl +# interfaces with Clearquest to call the appropraite +# Clearquest action hooks and the like. Note that only +# the basic information is asked for. If you really want +# to create or modify a full WOR use Clearquest. This +# Perl/Tk app's main customer is ucmwb. +# +# Author: Andrew@ClearSCM.com +# +# (c) Copyright 2007, General Dynamics, all rights reserved +# +############################################################################## +use strict; +use warnings; + +package CreateWORUI; + use Tk; + use Tk::Dialog; + use Tk::MyText; + + use Display; + use CQTool; + + use base "Exporter"; + + my $ME = "CreateWOR"; + my $VERSION = "1.1"; + + # Colors + my ($EDIT_FOREGROUND, $EDIT_BACKGROUND); + + our %wor; + + our @EXPORT = qw ( + createWORUI + %wor + ); + + # Globals + my $_createWORUI; + + # Dropdowns + my ( + $_projects, + $_rclcs, + $_prod_arch1s, + $_prod_arch2s, + $_engr_targets, + $_work_codes, + $_work_products, + $_wor_classes, + ); + + # Choice lists + my ( + @_projects, + @_rclcs, + @_prod_arch1s, + @_prod_arch2s, + @_engr_targets, + @_work_codes, + @_work_products, + @_wor_classes, + ); + + # Buttons + my $_submit; + + ############################################################################ + # Subroutines + ############################################################################ + + #--------------------------------------------------------------------------- + # _helpAbout (): Puts up the Help: About dialog box + #--------------------------------------------------------------------------- + sub _helpAbout () { + my $text = "$ME v$VERSION\n"; + + $text .= < of ClearSCM, Inc. +END + + my $desc = $_createWORUI->Dialog ( + -title => "About $ME", + -text => $text, + -buttons => [ "OK" ], + ); + + $desc->Show (); + } # _helpAbout + + #--------------------------------------------------------------------------- + # _displayValues (): Displays the contents for %wor hash + #--------------------------------------------------------------------------- + sub _displayValues () { + foreach (keys %wor) { + if ($wor{$_}) { + display ("$_: $wor{$_}"); + } else { + display ("$_: undef"); + } # if + } # foreach + } # _displayValues + + #--------------------------------------------------------------------------- + # _getChoices (): For a given $entity and $fieldname, this routine returns + # the given choice list from Clearquest. + #--------------------------------------------------------------------------- + sub _getChoices ($$) { + my ($entity, $fieldname) = @_; + + return @{$entity->GetFieldChoiceList ($fieldname)}; + } # _getChoices + + #--------------------------------------------------------------------------- + # _destroyCreateWORUI (): Destroys the current WOR UI recycling Tk objects + #--------------------------------------------------------------------------- + sub _destroyCreateWORUI () { + # Destroy all globals created + destroy $_submit; + destroy $_projects; + destroy $_rclcs; + destroy $_prod_arch1s; + destroy $_prod_arch2s; + destroy $_engr_targets; + destroy $_work_codes; + destroy $_work_products; + destroy $_createWORUI; + + $_submit = + $_projects = + $_rclcs = + $_prod_arch1s = + $_prod_arch2s = + $_engr_targets = + $_work_codes = + $_work_products = + $_wor_classes = + $_createWORUI = undef; + + %wor = (); + } # _destroyCreateWORUI + + #--------------------------------------------------------------------------- + # _submit (): Actually creates the WOR given the filled out %wor hash. + #--------------------------------------------------------------------------- + sub _submit () { + debug "Creating WOR..."; + _displayValues if get_debug; + my $new_id = CQTool::submitWOR ($CQTool::entity, %wor); + + display ($new_id) if $new_id; + + _destroyCreateWORUI; + + return $new_id; + } # _submit + + #--------------------------------------------------------------------------- + # _setSubmitButton (): Sets the submit button to active only if all required + # fields have values. + #--------------------------------------------------------------------------- + sub _setSubmitButton (;$) { + my ($headline) = @_; + + return if !$_submit; + + # Check to see if we can activate the submit button + my $state = "normal"; + + foreach (@CQTool::wor_required_fields) { + if ($_ eq "headline") { + if (defined $headline) { + if ($headline eq "") { + $state = "disable"; + last; + } else { + next; + } # if + } # if + } # if + + if (!$wor{$_} or $wor{$_} eq "") { + $state = "disable"; + last; + } # if + } # foreach + + $_submit->configure ( + -state => $state, + ); + } # _setSubmitButton + + #--------------------------------------------------------------------------- + # _validateText (): Gets the text from the MyText widget and sets the submit + # button + #--------------------------------------------------------------------------- + sub _validateText { + my ($text) = @_; + + $wor{description} = $text->get_text; + chomp $wor{description}; + + _setSubmitButton $text; + + return 1; + } # _validateText + + #--------------------------------------------------------------------------- + # _validateEntry (): Gets the text from the headline widget and sets the + # submit button + #--------------------------------------------------------------------------- + sub _validateEntry { + my ($entry) = @_; + + _setSubmitButton $entry; + + return 1; + } # _validateEntry + + #--------------------------------------------------------------------------- + # _createDropDown (): Creates a dropdown widget in $parent in a grid at the + # $x, $y coordinates with a $label and a $value, using + # dropdown @values and a $refresh procedure. + #--------------------------------------------------------------------------- + sub _createDropDown ($$$$$$@) { + my ($parent, $x, $y, $label, $refresh, $value, @values) = @_; + + $parent->Label ( + -width => length $label, + -text => "$label:", + )->grid ( + -row => $x, + -column => $y, + -sticky => "e", + ); + + # Color the active foreground otherwise it's defaulted to ugly grey! + return $parent->Optionmenu ( + -activeforeground => $EDIT_FOREGROUND, + -activebackground => $EDIT_BACKGROUND, + -command => \&$refresh, + -variable => $value, + -options => \@values, + )->grid ( + -row => $x, + -column => $y + 1, + -sticky => "w", + ); + } # _createDropDown + + #--------------------------------------------------------------------------- + # _createTextField (): Creates a text field widget in $parent with a $label + # and a $value, using a $maxlen and a $validate + # procedure. + #--------------------------------------------------------------------------- + sub _createTextField ($$$$$) { + my ($parent, $label, $value, $maxlen, $validate) = @_; + + $parent->Label ( + -text => "$label:", + -justify => "right", + -width => 10, + )->pack ( + -side => "left", + -anchor => "e", + ); + + $parent->Entry ( + -foreground => $EDIT_FOREGROUND, + -background => $EDIT_BACKGROUND, + -width => $maxlen, + -justify => "left", + -textvariable => $value, + -validate => "key", + -validatecommand => \&$validate, + )->pack ( + -side => "left", + -padx => 5, + -anchor => "e", + ); + } # _createTextField + + #--------------------------------------------------------------------------- + # _createText (): Creates a multiline text field widget in $parent with a + # $label and a $value, using the specified $rows and $cols + # and a $validate procedure. + #--------------------------------------------------------------------------- + sub _createText ($$$$$$) { + my ($parent, $label, $value, $rows, $cols, $validate) = @_; + + $parent->Label ( + -text => "$label:", + -justify => "right", + -width => 10, + )->pack ( + -side => "left",+ + -anchor => "n", + -pady => 5, + ); + + $parent->MyText ( + -foreground => $EDIT_FOREGROUND, + -background => $EDIT_BACKGROUND, + -height => $rows, + -width => $cols, + -modified => \&$validate, + -text => $value, + )->pack ( + -side => "left", + -pady => 5, + -anchor => "s", + ); + } # _createText + + #--------------------------------------------------------------------------- + # _createButton (): Creates a pushbutton widget in $parent with a $label and + # an $action. + #--------------------------------------------------------------------------- + sub _createButton ($$$) { + my ($parent, $label, $action) = @_; + + $parent->Button ( + -activeforeground => $EDIT_FOREGROUND, + -activebackground => $EDIT_BACKGROUND, + -text => $label, + -width => length $label, + -command => \$action + )->pack ( + -side => "left", + -padx => 5 + ); + } # _createButton + + #--------------------------------------------------------------------------- + # _changeDropDown (): Refreshes the values in the dropdown menu. + #--------------------------------------------------------------------------- + sub _changeDropDown ($@) { + my ($dropdown, @values) = @_; + + if ($dropdown) { + my $menu = $dropdown->menu; + + if ($menu) { + $dropdown->menu->delete (0, "end"); + } # if + + $dropdown->addOptions (@values); + } # if + } # _changeDropDown + + #--------------------------------------------------------------------------- + # _refresh (): Refreshes the application by getting news values from + # Clearquest. Note a change in one dropdown may change others, + # so we re-get all of them through this procedure. + #--------------------------------------------------------------------------- + sub _refresh () { + my $fieldname; + + $fieldname = "project"; + my %projects = CQTool::getProjects $CQTool::session; + $wor{$fieldname} = $_projects[0] if !$wor{fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $wor{$fieldname}); + + $fieldname = "prod_arch1"; + @_prod_arch1s = _getChoices $CQTool::entity, $fieldname; + $wor{$fieldname} = $_prod_arch1s[0] if !$wor{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $wor{$fieldname}); + + $fieldname = "prod_arch2"; + @_prod_arch2s = _getChoices $CQTool::entity, $fieldname; + $wor{$fieldname} = $_prod_arch2s[0] if !$wor{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $wor{$fieldname}); + + $fieldname = "rclc_name"; + @_rclcs = @{$projects{$wor{project}}}; + $wor{$fieldname} = $_rclcs[0] if !$wor{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $wor{$fieldname}); + + $fieldname = "engr_target"; + @_engr_targets = _getChoices $CQTool::entity, $fieldname; + $wor{$fieldname} = $_engr_targets[0] if !$wor{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $wor{$fieldname}); + + $fieldname = "work_code_name"; + @_work_codes = _getChoices $CQTool::entity, $fieldname; + $wor{$fieldname} = $_work_codes[0] if !$wor{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $wor{$fieldname}); + + $fieldname = "work_product_name"; + @_work_products = _getChoices $CQTool::entity, $fieldname; + $wor{$fieldname} = $_work_products[0] if !$wor{$fieldname}; + $CQTool::entity->SetFieldValue ($fieldname, $wor{$fieldname}); + + _changeDropDown ($_projects, keys %projects); + _changeDropDown ($_rclcs, @_rclcs); + _changeDropDown ($_prod_arch1s, @_prod_arch1s); + _changeDropDown ($_prod_arch2s, @_prod_arch2s); + _changeDropDown ($_engr_targets, @_engr_targets); + _changeDropDown ($_work_codes, @_work_codes); + _changeDropDown ($_work_products, @_work_products); + + _setSubmitButton (); + } # _refresh + + #--------------------------------------------------------------------------- + # _darken (): Returns a slightly darker color than the passed in color + #--------------------------------------------------------------------------- + sub _darken ($) { + my ($color) = @_; + + # Get the RGB values + my ($r, $g, $b) = $_createWORUI->rgb($color); + + # Set them to $DARKEN % of their previous values + my $DARKEN = .8; + my $rhex = sprintf "%x", $r * $DARKEN; + my $ghex = sprintf "%x", $g * $DARKEN; + my $bhex = sprintf "%x", $b * $DARKEN; + + # Return a color string + return "\#$rhex$ghex$bhex"; + } # _darken + + #--------------------------------------------------------------------------- + # createWORUI (): This is the main and exported routine that creates and + # handles the entire Perl/Tk application for creating a + # WOR. + #--------------------------------------------------------------------------- + sub createWORUI () { + $_createWORUI = MainWindow->new; + + $EDIT_FOREGROUND = $_createWORUI->optionGet ("foreground", "Foreground"); + $EDIT_BACKGROUND = _darken ($_createWORUI->optionGet ("background", "Background")); + + $wor{id} = "None" if !$wor{id}; + + $_createWORUI->title ("Submit WOR $wor{id}"); + + my $frame0 = $_createWORUI->Frame->pack (-pady => 2); + my $frame1 = $_createWORUI->Frame->pack; + my $frame2 = $_createWORUI->Frame->pack; + my $frame3 = $_createWORUI->Frame->pack; + my $frame4 = $_createWORUI->Frame->pack; + + _createTextField ( + $frame1, + "Headline", + \$wor{headline}, + 100, + \&_validateEntry + ); + + _createText ( + $frame2, + "Description", + \$wor{description}, + 24, 100, + \&_validateText + ); + + my %projects = CQTool::getProjects ($CQTool::session); + @_projects = keys %projects; + + $_projects = _createDropDown ( + $frame3, + 0, 0, + "Project", + \&_refresh, + \$wor{project}, + @_projects + ); + $_rclcs = _createDropDown ( + $frame3, + 0, 3, + "Revision Control Life Cycle", + \&_refresh, + \$wor{rclc_name}, + @_rclcs + ); + + $_prod_arch1s = _createDropDown ( + $frame3, + 2, 0, + "Product Architecture 1", + \&_refresh, + \$wor{prod_arch1}, + @_prod_arch1s + ); + $_engr_targets = _createDropDown ( + $frame3, + 2, 3, + "Engineering Target", + \&_refresh, + \$wor{engr_target}, + @_engr_targets + ); + + $_prod_arch2s = _createDropDown ( + $frame3, + 4, 0, + "Product Architecture 2", + \&_refresh, + \$wor{prod_arch2}, + @_prod_arch2s + ); + $_work_codes = _createDropDown ( + $frame3, + 4, 3, + "Work Code", + \&_refresh, + \$wor{work_code_name}, + @_work_codes + ); + + $_work_products = _createDropDown ( + $frame3, + 6, 0, + "Work Product", + \&_refresh, + \$wor{work_product_name}, + @_work_products + ); + + my $fieldname = "wor_class"; + @_wor_classes = _getChoices $CQTool::entity, $fieldname; + $wor{$fieldname} = "Worker"; + $CQTool::entity->SetFieldValue ($fieldname, $wor{$fieldname}); + + $_wor_classes = _createDropDown ( + $frame3, + 6, 3, + "WOR Class", + sub {}, + \$wor{wor_class}, + @_wor_classes + ); + + # Default WOR Class to Worker + $_wor_classes->setOption ("Worker"); + + $_submit = _createButton ($frame4, "Submit", \&_submit); + + $_submit->configure ( + -state => "disabled", + ); + + _createButton ($frame4, "Display", \&_displayValues) if (get_debug); + _createButton ($frame4, "About", \&_helpAbout); + _createButton ($frame4, "Exit", \&_destroyCreateWORUI); + } # createWORUI + +1; diff --git a/clients/GD/cqtool/cqtool.pl b/clients/GD/cqtool/cqtool.pl new file mode 100755 index 0000000..3c85914 --- /dev/null +++ b/clients/GD/cqtool/cqtool.pl @@ -0,0 +1,780 @@ +#!/usr/bin/env /opt/rational/clearquest/bin/cqperl +############################################################################## +# +# Name: cqtool +# +# Description: cqtool is an interface to Clearquest to perform some simple +# actions to the RANCQ database. It is used primarily by ucmwb +# but it also supports a command line interface. +# +# The following commands are supported: +# +# activate : +# Activate WOR +# assign : +# Assign the WOR +# clone : +# Clones a WOR +# comment +# Add a comment to the Notes_Entry field for the WOR +# complete : +# Complete WOR +# createhd: +# Create a new Help Desk Ticket +# createwor: +# Create a new WOR +# effort : +# Update the WOR's actual hours +# exit|quit: +# Exits cqtool +# help: +# This display +# link : +# Link a parent WOR to a child WOR +# resolve : +# Resolve WOR +# set +# Set to for the +# usage: +# Displays command line usage +# version: +# Displays version of cqtool +# +# Many of these commands simply perform actions on a wor. Two +# of these commands, createwor and createhd have Perl/Tk GUI +# interfaces. +# +# Command line usage: +# +# Usage: cqtool\t[-usage|help] [-verbose] [-debug] +# [-userid ] [-password ] [] +# +# Where: +# +# -usage|help: Display usage +# -verbose: Turn on verbose mode +# -debug: Turn on debug mode +# -userid: User ID to log into Clearquest database as +# -password: Password to use +# If specified then cqtool executes and +# exits +# +# Environment: cqtool supports the following environment variables +# that are used mostly for tesing purposes +# +# CQ_DBSET: Clearquest DBSET to open (e.g. XTST3 for testing - +# default RANCQ) +# CQ_USER: User name to log into the $CQ_DBSET database with +# CQ_PASSWORD: Password to use to log into the $CQ_DBSET with. +# +# Author: Andrew@DeFaria.com +# +# (c) Copyright 2007, General Dynamics, all rights reserved +# +############################################################################## +use strict; +use warnings; + +use CQPerlExt; +use FindBin; +use Getopt::Long; +use Term::ANSIColor qw (:constants); + +use lib ("$FindBin::Bin", "$FindBin::Bin/../lib"); + +use SCCM::Misc; +use Display; +use CQTool; +use CreateWORUI; +use CreateHelpDeskUI; +use Logger; + +my $VERSION = BOLD GREEN . "1.1" . RESET; +my $PROMPT = BOLD YELLOW . ">>" . RESET; +my $UCMWB_PROMPT = ">>"; +my $DESC = BOLD RED . "$FindBin::Script" . + RESET " Version " . + $VERSION . + CYAN ": Program to talk to Clearquest" . + RESET; + +# Globals +my $_userid = $ENV{CQ_USER} ? $ENV{CQ_USER} : $ENV{USER}; +my $_password = $ENV{CQ_PASSWORD}; +my $_db_name = $ENV{CQ_DBSET} ? $ENV{CQ_DBSET} : "RANCQ"; +my $_ucmwb; + +my $_log; + +if (get_debug) { + $_log = new Logger ( + path => "/tmp", + append => 1, + ); +} # if + +my %_commands = ( + activate => \&activate, + assign => \&assign, + clone => \&clone, + comment => \&comment, + complete => \&complete, + createhd => \&createHelpDesk, + createwor => \&createWOR, + effort => \&effort, + exit => \&shutdown, + help => \&help, + link => \&linkParentWor2ChildWor, + quit => \&shutdown, + resolve => \&resolve, + set => \&set, + usage => \&usage, + version => \&announce, +); + +############################################################################## +# Forwards +############################################################################## +sub commandLoop (@); + +############################################################################## +# Main +############################################################################## +MAIN: { + GetOptions ( + "usage" => sub { usage () }, + "verbose" => sub { set_verbose () }, + "debug" => sub { set_debug () }, + "userid=s" => \$_userid, + "password=s" => \$_password, + "database=s" => \$_db_name, + "ucmwb" => \$_ucmwb, + ) || usage (); + + exit (commandLoop(@ARGV)); +} # MAIN + +############################################################################## +# Subroutines +############################################################################## + +#----------------------------------------------------------------------------- +# shutdown (): Ends program +#----------------------------------------------------------------------------- +sub shutdown () { + exit (0); +} # exit + +#----------------------------------------------------------------------------- +# help (): Displays help +#----------------------------------------------------------------------------- +sub help () { + display ($DESC); + display < : + Activate WOR +assign : + Assign the WOR +clone : + Clones a WOR +comment + Add a comment to the Notes_Entry field for the WOR +complete : + Complete WOR +createhd: + Create a new Help Desk Ticket +createwor: + Create a new WOR +effort : + Update the WOR's actual hours +exit|quit: + Exits $FindBin::Script +help: + This display +link : + Link a parent WOR to a child WOR +resolve : + Resolve WOR +set + Set to for the +usage: + Displays command line usage +version: + Displays version of $FindBin::Script +END +} # help + +#----------------------------------------------------------------------------- +# announce (): Announce ourselves +#----------------------------------------------------------------------------- +sub announce () { + display ($DESC); +} # Announce + +#----------------------------------------------------------------------------- +# dberror ($): Handle errors when talking to Clearquest. Note we need to reset +# the database connection if an error happens. +#----------------------------------------------------------------------------- +sub dberror ($) { + my ($msg) = @_; + + # Need to not only report the error but to reopen the + # database. Something gets corruppted if we don't! + error ($msg); + + closeDB (); + + openDB ($_userid, $_password, $_db_name); +} # DBError + +#----------------------------------------------------------------------------- +# getEntity ($$): Get an entity from Clearquest +#----------------------------------------------------------------------------- +sub getEntity ($$) { + my ($recordname, $wor) = @_; + + my $entity; + + eval { + $entity = $CQTool::session->GetEntity ($recordname, $wor); + }; + + if ($@) { + chomp $@; + dberror ($@); + return undef; + } else { + return $entity; + } # if +} # getEntity + +#----------------------------------------------------------------------------- +# set ($$$): Set $field to $value for $wor +#----------------------------------------------------------------------------- +sub set ($$@) { + my ($wor, $field, $value) = @_; + + if (!$wor or $wor eq "") { + error ("WOR is required"); + return 1; + } # if + + if (!$field or $field eq "") { + error ("Field is required"); + return 1; + } # if + + my $entity = getEntity ("WOR", $wor); + + return 1 if !$entity; + + $session->EditEntity ($entity, "modify"); + + $_log->msg ("Modifying $field to \"$value\"") if get_debug; + eval { + $entity->SetFieldValue ($field, $value); + }; + + if ($@) { + dberror ("$field set failed for WOR $wor:\n$@"); + return 2; + } # if + + my $status = $entity->Validate (); + + if ($status ne "") { + $entity->Revert (); + error ("$field validate failed for WOR $wor:\n$status"); + return 2; + } # if + + $status = $entity->Commit (); + + if ($status ne "") { + error ("$field update failed during Submit for $wor:\n$status"); + return 2; + } # if + + return 0; +} # set + +#----------------------------------------------------------------------------- +# clone ($): Clone a WOR +#----------------------------------------------------------------------------- +sub clone ($) { + my ($wor) = @_; + + if (!$wor) { + error ("WOR not specified!"); + return 1; + } # if + + $entity = getEntity ("WOR", $wor); + + return 1 if !$entity; + + # Check state + my $state = $entity->GetFieldValue ("state")->GetValue (); + + if ($state ne "Closed") { + error ("WOR $wor not closed - Unable to clone!"); + return 1; + } # if + + verbose ("Cloning WOR $wor..."); + + my $result = 0; + + eval { + # Currently Clone doesn't return a proper result but eventually... + $result = $CQTool::session->FireRecordScriptAlias ($entity, "Clone"); + }; + + if ($@) { + chomp $@; + dberror ($@); + return 1; + } # if + + return $result; +} # clone + +#----------------------------------------------------------------------------- +# effort ($$): Update actual hours for a WOR +#----------------------------------------------------------------------------- +sub effort ($$) { + my ($wor, $actualHrs) = @_; + + return set $wor, "ActualEffort", $actualHrs; +} # effort + +#----------------------------------------------------------------------------- +# comment (): Update the Notes_Entry comment field for a WOR +#----------------------------------------------------------------------------- +sub comment ($) { + my ($wor) = @_; + + if (!$wor) { + error "WOR not defined in call to comment!"; + return 1; + } # if + + if (!$_ucmwb) { + display ("Enter comments below. When finished, enter \".\" on a line by itself or hit ^D:"); + } else { + # We still need to prompt for the comments however signal UCMWB + # that command is ready for more input. + display_nolf ($UCMWB_PROMPT); + } # if + + my $comments; + + while () { + last if $_ eq ".\n"; + $comments .= $_; + } # while + + chomp $comments; + + $_log->msg ("Comments:\n$comments") if get_debug; + + return set $wor, "Note_Entry", $comments; +} # Comment + +#----------------------------------------------------------------------------- +# linkParentWor2ChildWor ($$): Link a child WOR to a parent WOR +#----------------------------------------------------------------------------- +sub linkParentWor2ChildWor ($$) { + my ($parentWor, $childWor) = @_; + + my $status; + + verbose ("Linking $parentWor -> $childWor..."); + + my $childentity = getEntity ("WOR", $childWor); + my $parententity = getEntity ("WOR", $parentWor); + + return 1 unless $childentity and $parententity; + + $session->EditEntity ($parententity, "modify"); + + $parententity->AddFieldValue ("wor_children", $childWor); + + $status = $parententity->Validate (); + + if ($status ne "") { + $parententity->Revert (); + error ("Validation failed while attempting to add child WOR $childWor to parent WOR $parentWor:\n$status"); + return 1; + } # if + + eval { + $status = $parententity->Commit (); + }; + + $status = $@ if $@; + + if ($status ne "") { + (error "Commit failed while trying to add child WOR $childWor to parent WOR $parentWor:\n$status"); + return 2; + } # if + + debug "Modifying child $childWor..."; + $session->EditEntity ($childentity, "modify"); + + $childentity->SetFieldValue ("wor_parent", $parentWor); + + $status = $childentity->Validate (); + + if ($status ne "") { + $childentity->Revert (); + error "Validation failed while attempting to add parent WOR $parentWor to child WOR $childWor:\n$status"; + return 1; + } # if + + eval { + $status = $childentity->Commit (); + }; + + $status = $@ if $@; + + if ($status ne "") { + error "Commit failed while trying to add parent WOR $parentWor to child WOR $childWor:\n$status"; + return 2; + } # if + + return 0; +} # linkParentWor2ChildWor + +#----------------------------------------------------------------------------- +# assign ($$$$): Assign a WOR +#----------------------------------------------------------------------------- +sub assign ($$$$$) { + my ($wor, $assignee, $project, $plannedHrs, $startDate) = @_; + + if (!$wor or $wor eq "") { + error ("WOR is required"); + return 1; + } # if + + if (!$assignee or $assignee eq "") { + error ("Assignee must be specified"); + return 1; + } # if + + if (!$project or $project eq "") { + error ("UCM Project is required"); + return 1; + } # if + + if (!$startDate or $startDate eq "") { + error ("Planned Start Date is required"); + return 1; + } # if + + my $entity = getEntity ("WOR", $wor); + + return 1 if !$entity; + + my $state = $entity->GetFieldValue ("state")->GetValue (); + + if ($state ne "Submitted") { + error ("WOR $wor is not in Submitted state!\nState: $state"); + return 2; + } # if + + $session->EditEntity ($entity, "assign"); + + $entity->SetFieldValue ("ucm_project", $project) if $project ne ""; + $entity->SetFieldValue ("PlannedStart", $startDate) if $startDate ne ""; + $entity->SetFieldValue ("PlannedEffort", $plannedHrs) if $plannedHrs ne ""; + $entity->SetFieldValue ("Owner", $assignee) if $assignee ne ""; + + my $status = $entity->Validate (); + + if ($status ne "") { + $entity->Revert (); + error ("Assign failed for WOR $wor:\n$status"); + return 2; + } # if + + $status = $entity->Commit (); + + if ($status ne "") { + error ("Assign failed during Submit for WOR $wor:\n$status"); + return 2; + } # if + + return 0; +} # assign + +#----------------------------------------------------------------------------- +# activate (): Activate a WOR +#----------------------------------------------------------------------------- +sub activate ($$$$$) { + my ($wor, $project, $estHrs, $startDate, $endDate) = @_; + + if (!$wor or $wor eq "") { + error ("WOR is required"); + return 1; + } # if + + if (!$project or $project eq "") { + error ("UCM Project is required"); + return 1; + } # if + + if (!$startDate or $startDate eq "") { + error ("Planned Start Date is required"); + return 1; + } # if + + if (!$endDate or $endDate eq "") { + error ("Planned End Date is required"); + return 1; + } # if + + my $entity = getEntity ("WOR", $wor); + + return 1 if !$entity; + + my $state = $entity->GetFieldValue ("state")->GetValue (); + + if ($state ne "Assessing") { + error ("WOR $wor is not in Assessing state!\nstate: $state"); + return 2; + } # if + + $session->EditEntity ($entity, "activate"); + + $entity->SetFieldValue ("ucm_project", $project) if $project ne ""; + $entity->SetFieldValue ("EstimatedEffort", $estHrs) if $estHrs ne ""; + $entity->SetFieldValue ("PlannedStart", $startDate) if $startDate ne ""; + $entity->SetFieldValue ("PlannedEnd", $endDate) if $endDate ne ""; + + my $status = $entity->Validate (); + + if ($status ne "") { + $entity->Revert (); + error ("Activate failed for WOR $wor:\n$status"); + return 2; + } # if + + $status = $entity->Commit (); + + if ($status ne "") { + error ("Activate failed during Submit for WOR $wor:\n$status"); + return 2; + } # if + + return 0; +} # activate + +#----------------------------------------------------------------------------- +# resolve ($): Resolve a WOR +#----------------------------------------------------------------------------- +sub resolve ($) { + my ($wor) = @_; + + if (!$wor or $wor eq "") { + error ("WOR is required"); + return 1; + } # if + + my $entity = getEntity ("WOR", $wor); + + return 1 if !$entity; + + my $state = $entity->GetFieldValue ("state")->GetValue (); + + if ($state ne "Working") { + error ("WOR $wor is not in Working state!\nState: $state"); + return 2; + } # if + + $session->EditEntity ($entity, "resolve"); + + my $status = $entity->Validate (); + + if ($status ne "") { + $entity->Revert (); + error ("Resolve failed for WOR $wor:\n$status"); + return 2; + } # if + + $status = $entity->Commit (); + + if ($status ne "") { + error ("Resolve failed during Submit for WOR $wor:\n$status"); + return 2; + } # if + + return 0; +} # resolve + +#----------------------------------------------------------------------------- +# complete ($$): Complete a WOR +#----------------------------------------------------------------------------- +sub complete ($$) { + my ($wor, $actualHrs) = @_; + + if (!$wor or $wor eq "") { + error ("WOR is required"); + return 1; + } # if + + if (!$wor or $wor eq "") { + error ("Actual Hours are required"); + return 1; + } # if + + my $entity = getEntity ("WOR", $wor); + + return 1 if !$entity; + + my $state = $entity->GetFieldValue ("state")->GetValue (); + + if ($state ne "Verifying") { + error ("WOR $wor is not in Verifying state!\nState:$state"); + return 2; + } # if + + $session->EditEntity ($entity, "complete"); + $entity->SetFieldValue ("ActualEffort", $actualHrs) if $actualHrs ne ""; + + my $status = $entity->Validate (); + + if ($status ne "") { + $entity->Revert (); + error ("Complete failed for WOR $wor:\n$status"); + return 2; + } # if + + $status = $entity->Commit (); + + if ($status ne "") { + error ("Complete failed during Submit for WOR $wor:\n$status"); + return 2; + } # if + + return 0; +} # Complete + +#----------------------------------------------------------------------------- +# executeCommand (@): Executes a cqtool command +#----------------------------------------------------------------------------- +sub executeCommand (@) { + my (@args) = @_; + + my $cmd = lc shift @args; + + return if $cmd eq ""; + + if ($_commands{$cmd}) { + if (!$CQTool::session) { + if ( # Commands that do not require a database connection + !($cmd eq "exit" or + $cmd eq "quit" or + $cmd eq "help" or + $cmd eq "usage" or + $cmd eq "verbose")) { + verbose "Opening $_db_name as $_userid..."; + + if (!$_password) { + display_nolf ("${_userid}'s password:"); + `stty -echo`; + $_password = ; + chomp $_password; + display (""); + `stty echo`; + } # if + + openDB ($_userid, $_password, $_db_name); + } # if + } # if + + # Treat args: Args that are enclosed in quotes must be + # combined. For simplicity's sake we will only support matched + # pairs of double quotes. Anything else results in undefined + # behavior. + my (@new_args); + + foreach (@args) { + # Quoted argument starting + if (/^\"(.*)\"$/s) { + push @new_args, $1; + } else { + push @new_args, $_; + } # if + } # foreach + + $_log->msg ("$cmd (" . join (",", @new_args) . ")") if get_debug; + + return $_commands{$cmd} (@new_args); + } else { + error ("Unknown command \"$cmd\" (try help)"); + return 1; + } # if +} # executeCommand + +#----------------------------------------------------------------------------- +# commandLoop (@): This is the interactive command loop +#----------------------------------------------------------------------------- +sub commandLoop (@) { + my (@args) = @_; + + # For single, command line, commands... + return executeCommand (@args) if @args; + + announce if !$_ucmwb; + + while () { + if (!$_ucmwb) { + display_nolf ($PROMPT . RESET . UNDERLINE); + } else { + display_nolf ($UCMWB_PROMPT); + } # if + + # Read command into $_ + $_ = ; + chomp; + + # If we are not being called by ucmwb, display RESET to stop the + # UNDERLINE we were using. This keeps the output from being + # underlined. In ucmwb mode we are not using any of the terminal + # sequences. + display_nolf (RESET) if !$_ucmwb; + + # If the user hit Control-d then a ^D is displayed but we remain + # on the same line. So output a carriage return and exit 0. + if (!$_) { + display (""); + exit 0; + } # if + + # Special handling for set command since we want to take + # everything after to be a value, and we may get long + # values that are space separated and space significant + # (e.g. description?) + if (/^\s*(\w+)\s+(\w+)\s+(\w+)\s+(.*)/) { + if (lc $1 eq "set") { + my $cmd = $1; + my $wor = $2; + my $field = $3; + my $value = $4; + + # Change "\n"'s back to \n's + $value =~ s/\\n/\n/g; + + executeCommand ($cmd, $wor, $field, "\"$value\""); + } else { + executeCommand (split); + } # if + } else { + executeCommand (split); + } # if + } # while +} # commandLoop diff --git a/clients/GD/rexec b/clients/GD/rexec new file mode 100644 index 0000000..cd35cc4 --- /dev/null +++ b/clients/GD/rexec @@ -0,0 +1,329 @@ +#!/usr/local/bin/perl +################################################################################ +# +# File: $RCSfile: $ +# Revision: $Revision: $ +# Description: Remotely run processes on other machines +# Author: Andrew@DeFaria.com +# Created: Tue Jan 8 15:57:27 MST 2008 +# Modified: $Date: $ +# Language: perl +# +# (c) Copyright 2008, ClearSCM, Inc., all rights reserved +# +################################################################################ +use strict; +use warnings; + +use FindBin; +use Getopt::Long; +use Term::ANSIColor qw(:constants); +use POSIX ":sys_wait_h"; + +my $libs; + +BEGIN { + $libs = $ENV{SITE_PERLLIB} ? $ENV{SITE_PERLLIB} : "$FindBin::Bin/../lib"; + + die "Unable to find libraries\n" if !$libs and !-d $libs; +} + +use lib "$FindBin::Bin/../lib"; +use lib $libs; + +use Display; +use Logger; +use Machines; +use Rexec; +use Utils; + +our $_host; +our $_skip = 0; +our $_currentHost; + +my $_log = 0; +my $_quiet = 0; +my $_alternateFile; +my $_parallel = 0; + +my $_totalMachines = 0; +my $_totalExecutions = 0; +my $_totalFailures = 0; +my $_totalConnectFailures = 0; +my $_totalSkips = 0; + +my (%_workerStatuses, %_workerNames); + +sub Usage { + my $msg = shift; + + display "ERROR: $msg\n" if defined $msg; + + display "rexec\t[-v] [-d] [-u] "; + display "\t-v\tTurn on verbose mode"; + display "\t-d\tTurn on debug mode"; + display "\t-u\tThis usage message"; + display "\tCommand to execute remotely"; + + exit 1; +} # Usage + +sub printStats { + display YELLOW . "Machines: " . RESET . "$_totalMachines " . + MAGENTA . "Executions/Failures: " . RESET . "($_totalExecutions/$_totalFailures) " . + BLUE . "Connect Failures/Skips: " . RESET . "($_totalConnectFailures/$_totalSkips)"; +} # printStats + +sub Interrupted { + use Term::ReadKey; + + display BLUE . "\nInterrupted execution on $_host" . RESET; + + printStats; + + display_nolf "Executing on " . YELLOW . $_host . RESET . " - " + . GREEN . BOLD . "S" . RESET . GREEN . "kip" . RESET . ", " + . CYAN . BOLD . "C" . RESET . CYAN . "ontinue" . RESET . " or " + . MAGENTA . BOLD . "A" . RESET . MAGENTA . "bort run" . RESET . " (" + . GREEN . BOLD . "s" . RESET . "/" + . CYAN . BOLD . "C" . RESET . "/" + . MAGENTA . BOLD . "a" . RESET . ")?"; + + ReadMode ("cbreak"); + my $answer = ReadKey (0); + ReadMode ("normal"); + + if ($answer eq "\n") { + display "c"; + } else { + display $answer; + } # if + + $answer = lc $answer; + + if ($answer eq "s") { + *STDOUT->flush; + display "Skipping $_host"; + $_skip = 1; + $_totalSkips++; + } elsif ($answer eq "a") { + display RED . "Aborting run". RESET; + printStats; + exit; + } else { + display "Continuing..."; + $_skip = 0; + } # if +} # Interrupted + +sub workerDeath { + while ((my $worker = waitpid (-1, WNOHANG)) > 0) { + my $status = $?; + + # Ignore all child deaths except for processes we started + next if !exists $_workerStatuses{$worker}; + + $_workerStatuses{$worker} = $status; + } # while + + $SIG{CHLD} = \&workerDeath; +} # workerDeath + +sub execute ($$$) { + my ($cmd, $host, $prompt) = @_; + + my @lines; + + verbose_nolf "Connecting to machine $host..."; + + eval { + $_currentHost = new Rexec ( + host => $host, + prompt => $prompt, + ); + }; + + # Problem with creating Rexec object. Log error if logging and return. + if ($@ or !$_currentHost) { + if ($_log) { + my $log = new Logger (name => $_host); + + $log->err ("Unable to connect to $host to execute command\n$cmd"); + } # if + + $_totalConnectFailures++; + + return (1, ()); + } # if + + verbose " connected"; + + display YELLOW . "$host:" . RESET . UNDERLINE . "$cmd" . RESET unless $_quiet; + + @lines = $_currentHost->exec ($cmd); + + if ($_skip) { + # Kick current connection + kill INT => $_currentHost->{handle}->pid; + } # if + + if ($_parallel != 0) { + if ($_log) { + my $log = new Logger (name => $_host); + + $log->err ("Unable to connect to $host to execute command\n$cmd"); + } # if + + $_totalConnectFailures++; + } # if + + verbose "Disconnected from $host"; + + my $status = $_currentHost->status; + + undef $_currentHost; + + return ($status, @lines); +} # execute + +sub parallelize ($%) { + my ($cmd, %machines) = @_; + + my $thread_count = 1; + + foreach $_host (sort keys %machines) { + if ($thread_count <= $_parallel) { + debug "Processing $_host ($thread_count)"; + $thread_count++; + + if (my $pid = fork) { + # In parent process - record this host and its status + $_workerNames{$pid} = $_host; + } else { + # In spawned child... + $pid = $$; + + debug "Starting process for $_host [$pid]"; + + $_workerNames{$pid} = $_host; + + my ($status, @lines) = execute $cmd, $_host, $machines{$_host}; + + my $log = new Logger (name => $_host); + + $log->log ($_) foreach (@lines); + + exit $status; + } # if + } else { + # Wait for somebody to finish; + debug "Waiting for somebody to exit..."; + my $reaped = wait; + + debug "Reaped $_workerNames{$reaped} [$reaped] (Status: $?)"; + $_workerStatuses{$reaped} = $? >> 8 if $reaped != -1; + + $thread_count--; + } # if + } # foreach + + # Wait for all kids + my %threads = %_workerNames; + + foreach (keys %threads) { + if (waitpid ($_, 0) == -1) { + delete $threads{$_}; + } else { + $_workerStatuses{$_} = $? >> 8; + debug "$threads{$_} [$_] exited with a status of $_workerStatuses{$_}"; + } # if + } # foreach + + debug "All processed completed - Status:"; + + if (get_debug) { + foreach (sort keys %_workerStatuses) { + debug "$_workerNames{$_}\t[$_]:\tStatus: $_workerStatuses{$_}"; + } # foreach + } # if + + # Gather output... + display "Output of all executions"; + foreach $_host (sort keys %machines) { + if (-f "$_host.log") { + display "$_host:$_" foreach (ReadFile ("$_host.log")); + + #unlink "$_host.log"; + } else { + warning "Unable to find output for $_host ($_host.log missing)"; + } # if + } # foreach +} # parallelize + +# Print the totals if interrupted +$SIG{INT} = \&Interrupted; + +# Get our options +GetOptions ( + "usage" => sub { Usage "" }, + "verbose" => sub { set_verbose }, + "debug" => sub { set_debug }, + "log" => \$_log, + "quiet" => \$_quiet, + "file=s" => \$_alternateFile, + "parallel:i" => \$_parallel, +) || Usage "Unknown parameter"; + +my $cmd = join " ", @ARGV; + +error "No command specified", 1 if !$cmd; + +my $machines = Machines->new (file => $_alternateFile); +my %machines = $machines->all (); + +if ($_parallel > 0) { + parallelize ($cmd, %machines); + printStats; + exit; +} # if + +display "NOTE: Logging output to .log" if $_log; + +foreach $_host (sort keys (%machines)) { + $_totalMachines++; + + my ($status, @lines) = execute $cmd, $_host, $machines{$_host}; + + if ($_skip) { + $_skip = 0; + next; + } # if + + if (defined $status) { + if ($status == 0) { + $_totalExecutions++; + } else { + if ($_log) { + my $log = new Logger (name => $_host); + + $log->log ("Host: $_host\nCommand: $cmd\nStatus: $status\nOutput:\n"); + $log->log ($_) foreach (@lines); + } # if + + $_totalFailures++; + + next; + } # if + } # if + + if ($_log) { + my $log = new Logger (name => $_host); + + $log->log ("Host: $_host\nCommand: $cmd\nStatus: $status\nOutput:\n"); + $log->log ($_) foreach (@lines); + } else { + display $_ foreach (@lines); + } # if +} # foreach + +printStats; diff --git a/clients/HP/bin/SCS b/clients/HP/bin/SCS new file mode 100644 index 0000000..55dfe36 --- /dev/null +++ b/clients/HP/bin/SCS @@ -0,0 +1,878 @@ +#!/bin/sh +############################################# +# @(#)scs 1.45 +# system characterization script +# "scs" collects data from Atria +# customer sites for analysis by +# engineering. +###################################### + +######################### +# For Solaris 5.x systems +######################### +nddit() +{ +for i in tcp udp ip hme +do + /usr/sbin/ndd /dev/$i \? | /bin/awk '{print $1}' | \ + /bin/egrep -v '\?|directed|respond|status|hash' > /tmp/$$ + for j in `/bin/cat /tmp/$$` + do + /bin/printf "%-30s %s\n" $j `/usr/sbin/ndd /dev/$i $j ` + done + /bin/rm /tmp/$$ + echo "--------" +done +} + +solaris() +{ +show "Uptime" /bin/uptime +show "System Device Configuration" /usr/sbin/prtconf -vP +show "System Configuration" /usr/sbin/sysdef -i +show "System Customization" '/bin/cat /etc/system | \ + /bin/grep -v "^\*" | /bin/grep -v "^$"' +show "Network Configuration" nddit +show "System Messages" /bin/dmesg +show "Patches" /bin/showrev -p +# /usr/kvm/prtconf check and use +#show "fpversion" /opt/SUNWspro/bin/fpversion + +show "Processes" '/usr/ucb/ps auxww | /bin/fold -80' +show "Network Configuration" /usr/sbin/ifconfig -a +show "Network Utilization Summary" /bin/netstat -i +show "Network Protocol Statistics" /bin/netstat -s +show "Network Mbuf Statistics" /bin/netstat -m +show "VM Statistics" /bin/vmstat -s +show "Cache Flush Statistics" /bin/vmstat -c +show "Interrupts" /bin/vmstat -i +show "NFS Statistics" /bin/nfsstat +show "NFS Responses" /bin/nfsstat -m + +show "CPU Utilization" /bin/sar -u 1 10 +show "Buffer Activity" /bin/sar -b 1 10 +show "Block Device Activity" /bin/sar -d 1 10 +show "Disk Device Activity" iostat -x 1 10 +show "Paging In Activity" /bin/sar -p 1 5 +show "Paging Out Activity" /bin/sar -g 1 5 +show "Free Memory" /bin/sar -r 1 5 +show "vmstat snapshot" /bin/vmstat 2 10 +show "Kernel Memory Allocation Activity" /bin/sar -k 1 5 +show "KMA statistics" 'echo kmastat | /usr/sbin/crash' +echo "" +show "Swap space" /usr/sbin/swap -s +echo "" +} + +####################### +# For SUNOS 4.x systems +####################### +sunos() +{ + +show "Memory " '/etc/dmesg | grep mem' +show "System Messages" /etc/dmesg +show "Processes" '/bin/ps auxww | /usr/ucb/fold -80' +show "Network Utilization Summary" /usr/ucb/netstat -i +show "Network Protocol Statistics" /usr/ucb/netstat -s +show "Network Mbuf Statistics" /usr/ucb/netstat -m +show "VM Statistics" /usr/ucb/vmstat -s +show "Cache Flush Statistics" /usr/ucb/vmstat -c +show "Interrupts" /usr/ucb/vmstat -i +show "NFS Statistics" /usr/etc/nfsstat + +show "Disk Device Activity" /bin/iostat -D 1 10 +show "CPU Activity" /usr/ucb/vmstat 1 10 +show "Tables" /etc/pstat -T +show "vmstat snapshot" /usr/ucb/vmstat 2 10 + +} + + +####################### +# For AIX +####################### +aix() +{ + +show "Processes" '/usr/bin/ps -elf ' +show "Network Utilization Summary" /bin/netstat -i +show "Network Protocol Statistics" /bin/netstat -s +show "Network Mbuf Statistics" /bin/netstat -m +show "Network Configurables" /usr/sbin/no -a +show "NFS Statistics" /usr/sbin/nfsstat + +show "System Attributes" /usr/sbin/lsattr -E -l sys0 +show "CPU Utilization" sar -u 1 10 +show "Buffer Activity" sar -b 1 10 +show "Disk Activity" /bin/iostat 1 10 +show "Paging Stats" sar -r 1 5 +show "Network Monitor for 30s" '/bin/netpmon -v -o /tmp/$$; sleep 30; trcstop' +echo "" +} + +####################### +# For OSF1 +####################### +osf1() +{ +show "Boot Messages" 'echo "";echo ""; echo "";uerf -r 300 | tail -100' +show "Processes" '/usr/bin/ps glww | fold -80' +show "Network Utilization Summary" /usr/sbin/netstat -i +show "Network Protocol Statistics" /usr/sbin/netstat -s +show "Network Mbuf Statistics" /usr/sbin/netstat -m +show "NFS Statistics" /usr/bin/nfsstat +show "Kernel memory usage" /usr/bin/vmstat -M +show "vmstat snapshopt" /usr/bin/vmstat 2 10 +show "Disk Device snapshot" /bin/iostat 2 10 + +} + +####################### +# For IRIX 6.x +####################### +irix6() +{ +show "Uptime" /usr/bsd/uptime +show "System Device Configuration" /usr/sbin/sysconf +show "System Hardware Configuration" /usr/bin/hinv +show "System Software Configuration" /etc/chkconfig +show "Patches" '/usr/sbin/versions | grep Patch' +show "Disk Usage" /usr/sbin/df -l -k +show "System Customization" '/bin/cat /var/sysgen/stune | \ + /bin/grep -v "^\*" | /bin/grep -v "^$"' + +show "Processes" '/usr/bin/ps -elf | /bin/fold -80' +show "Network Utilization Summary" /usr/etc/netstat -i +show "Network Protocol Statistics" /usr/etc/netstat -s +show "Network Mbuf Statistics" /usr/etc/netstat -m +show "NFS Statistics" /usr/etc/nfsstat + +show "CPU Utilization" sar -u 1 10 +show "Buffer Activity" sar -b 1 10 +show "Block Device Activity" sar -d 1 10 +show "Paging In Activity" sar -p 1 5 +show "Paging Out Activity" sar -g 1 5 +show "Free Memory" sar -r 1 5 +echo "" +} + + +####################### +# For IRIX 5.x +####################### +irix() +{ +show "Uptime" /usr/bsd/uptime +show "System Device Configuration" /usr/sbin/sysconf +show "System Hardware Configuration" /usr/bin/hinv +show "System Software Configuration" /etc/chkconfig +show "Disk Usage" /usr/sbin/df -l -k +show "System Customization" '/bin/cat /var/sysgen/stune | \ + /bin/grep -v "^\*" | /bin/grep -v "^$"' + +show "Processes" '/usr/bin/ps -elf | /bin/fold -80' +show "Network Utilization Summary" /usr/etc/netstat -i +show "Network Protocol Statistics" /usr/etc/netstat -s +show "Network Mbuf Statistics" /usr/etc/netstat -m +show "NFS Statistics" /usr/etc/nfsstat + +show "CPU Utilization" sar -u 1 10 +show "Buffer Activity" sar -b 1 10 +show "Block Device Activity" sar -d 1 10 +show "Paging In Activity" sar -p 1 5 +show "Paging Out Activity" sar -g 1 5 +show "Free Memory" sar -r 1 5 +echo "" +} + + +##################### +# For HP-UX 9/800 systems +##################### +hpux98() +{ +show "Memory " grep "mem =" /usr/adm/*syslog +#first the shared info +hpux +# now the system specific +show "System definition" /etc/sysdef +show "CPU Utilization" /usr/bin/sar -u 1 10 +show "Buffer Activity" /usr/bin/sar -b 1 10 +show "Block Device Activity" /usr/bin/sar -d 1 10 +} +##################### +# For HP-UX 9/700 systems +##################### +hpux97() +{ +show "Memory " grep Physical /usr/adm/messages +# just the shared info +hpux +} +##################### +# For All HP-UX 9 systems +##################### +hpux() +{ +show "Uptime" /usr/bin/uptime +show "System Messages" /etc/dmesg +show "Swap Space" /etc/swapinfo +show "Patches" ls -ld /system/PH* +show "IO devices" /etc/ioscan -f + +show "Processes" '/bin/ps -elf | /usr/bin/fold -80' +show "Network Utilization Summary" /usr/bin/netstat -i +show "Network Protocol Statistics" /usr/bin/netstat -s +show "Network Mbuf Statistics" /usr/bin/netstat -m +show "VM Statistics" /usr/bin/vmstat -s +show "NFS Statistics" /usr/etc/nfsstat +show "Network errors" /etc/netfmt -t 30 -f /usr/adm/nettl.LOG00 + +show "Disk Utilization" /usr/bin/bdf -l +show "vmstat snapshot" /usr/bin/vmstat 2 10 +} + +##################### +# For HP-UX 10 systems +##################### +hpux10() +{ + +show "Memory " grep Physical /var/adm/syslog/syslog.log +show "System DMessages" /usr/sbin/dmesg +show "System definition" /usr/sbin/sysdef +show "Messages" "tail -100 /usr/adm/syslog/syslog.log" +show "IO status" /etc/ioscan -f +show "Patches" '/usr/sbin/swlist -l product | grep PH' + +show "Processes" '/usr/bin/ps -elf | /usr/bin/fold -80' +show "Network Utilization Summary" /usr/bin/netstat -i +show "Network Protocol Statistics" /usr/bin/netstat -s +show "Network Mbuf Statistics" /usr/bin/netstat -m +show "VM Statistics" /usr/bin/vmstat -s +show "NFS Statistics" /usr/bin/nfsstat + +show "CPU Utilization" /usr/bin/sar -u 1 10 +show "Buffer Activity" /usr/bin/sar -b 1 10 +show "Block Device Activity" /usr/bin/sar -d 1 10 +show "vmstat snapshot" /usr/bin/vmstat 2 10 +} +##################### +# For Unixware systems +##################### +unixware() +{ +show "Memory size" /sbin/memsize +show "Message log" cat /usr/adm/log/osmlog +show "System Configuration" /usr/sbin/sysdef +show "Processes" '/usr/bin/ps -elf ' +show "Network Utilization Summary" /bin/netstat -i +show "Network Protocol Statistics" /bin/netstat -s +show "NFS Statistics" /usr/sbin/nfsstat + +show "CPU Utilization" /sbin/sar -u 1 10 +show "Buffer Activity" /sbin/sar -b 1 10 +show "Block Device Activity" /sbin/sar -d 1 10 +show "Paging In Activity" /sbin/sar -p 1 5 +show "Paging Out Activity" /sbin/sar -g 1 5 +show "Free Memory" /sbin/sar -r 1 5 +show "Historical sar data" /sbin/sar -A +echo "" +} + + +#################################### +# display informationin a uniform way +#################################### +show() { + echo "----------------------------------------------------" + echo $1 + echo "----------------------------------------------------" + shift + eval "$@" + echo "" +} +################################################## +# check uw network - works for Unixware +################################################## +check_uw_network() { + +netstat -i $interface +sleep 10 +netstat -i $interface +} + +################################################## +# check network - works for HP-UX and SUNOS 5.x +################################################## +check_network() { + printf "%8s %8s %8s %8s %8s %8s \n" time inpkts inerrs \ + outpkts outerrs colls + netstat -i -I $interface $interval | ( + (line ; line ; line) > /dev/null + t_inpkts=0 # initialize counter + t_inerrs=0 # initialize counter + t_outpkts=0 # initialize counter + t_outerrs=0 # initialize counter + t_colls=0 # initialize counter + i=0 + while test $i -lt $count ; do # for each of the lines + time=`date +%T` + /bin/echo $time \\c + set -- `line` # get the line + printf "%8s %8s %8s %8s %8s\n" $1 $2 $3 $4 $5 + t_inpkts=`expr $1 + $t_inpkts` # accumulate in packets + shift + t_inerrs=`expr $1 + $t_inerrs` # accumulate in errors + shift + t_outpkts=`expr $1 + $t_outpkts` # accumulate out packets + shift + t_outerrs=`expr $1 + $t_outerrs` # accumulate out errors + shift + t_colls=`expr $1 + $t_colls` # accumulate collisions + i=`expr $i + 1 ` + done + printf "\n%8s %8s %8s %8s %8s %8s \n" \ + total $t_inpkts $t_inerrs $t_outpkts $t_outerrs $t_colls +# now check error and collision rate. +# Use awk to get floating point accuracy + echo $t_colls $t_outpkts $t_inerrs $t_inpkts | awk '$2 != 0 { + collision_rate = $1 / $2; + printf("\n\ncollision rate ( %g %% )", (collision_rate * 100.0)); + if ( collision_rate > 0.05 ) + printf(" too high. Add subnets.\n"); + else + printf("\n")} + $4 != 0 { + error_rate = $3 / $4; + printf(" error rate ( %g %% )", (error_rate * 100.0)); + if (error_rate > 0.00025) + printf(" too high. Check cabling.\n"); + else + printf("\n")}' + + ) +} + +################################################## +# check fddi - for sun +################################################## +check_fddi_sol() { +/opt/*conn/*nf/utilities/nf_stat $interface 3 5 +/opt/*conn/*nf/utilities/nf_stat -m 3 5 +/opt/*fddi/fddistat -l +} + +################################################## +# check fddi - for HPs +################################################## +check_fddi_hp() { +/usr/bin/fddistat /dev/$interface +} + +################################################## +# check network - works for SUNOS 4.x +################################################## +check_network1() { + echo " time inpkts inerrs outpkts outerrs colls" + netstat -i -I $interface $interval | ( + (line ; line ; line) > /dev/null + t_inpkts=0 # initialize counter + t_inerrs=0 # initialize counter + t_outpkts=0 # initialize counter + t_outerrs=0 # initialize counter + t_colls=0 # initialize counter + i=0 + while test $i -lt $count ; do # for each of the lines + time=`date +%T` + /bin/echo -n $time + set -- `line` # get the line + echo " $1 $2 $3 $4 $5" + t_inpkts=`expr $1 + $t_inpkts` # accumulate in packets + shift + t_inerrs=`expr $1 + $t_inerrs` # accumulate in errors + shift + t_outpkts=`expr $1 + $t_outpkts` # accumulate out packets + shift + t_outerrs=`expr $1 + $t_outerrs` # accumulate out errors + shift + t_colls=`expr $1 + $t_colls` # accumulate collisions + i=`expr $i + 1 ` + done + echo -n "total " + echo -n "$t_inpkts $t_inerrs $t_outpkts " + echo " $t_outerrs $t_colls" +# now check error and collision rate. +# Use awk to get floating point accuracy + echo $t_colls $t_outpkts $t_inerrs $t_inpkts | awk '$2 != 0 { + collision_rate = $1 / $2; + printf("\n\ncollision rate ( %g %% )", (collision_rate * 100.0)); + if ( collision_rate > 0.05 ) + printf(" - too many collisions. \n"); + else + printf("\n")} + $4 != 0 { + error_rate = $3 / $4; + printf(" error rate ( %g %% )", (error_rate * 100.0)); + if (error_rate > 0.00025) + printf(" - too many errors. \n"); + else + printf("\n")}' + + ) +} + +######################################################## +# get disk layout and performance data +######################################################## +do_ssaadm() +{ +#need to add logic here to select a configured controller +#and only do an ssaadm if relevant. We'll live with the errors +# for now.... +for i in `(cd /dev/rdsk; ls | cut -d't' -f 1 | uniq)` +do + ssaadm display $i 2>/dev/null + ssaadm display -p $i 2>/dev/null +done +} + +######################################################## +# attempt to get Sparc Storage Array configuration +######################################################## +do_arrays() +{ +SSAS=`/usr/sbin/prtconf -vP | grep soc | grep instance | wc -l` +show "SSAs" echo "$SSAS SparcStorage Arrays attached" + +if [ $SSAS = 0 ] ; then + return +fi + +#else lets print out information + +show "SSA Disks and Performance" do_ssaadm +show "State and Configuration of Array Disks" /usr/sbin/vxprint -ht +show "Disk utilization" /usr/sbin/vxstat -i 2 -c 5 +show "Disk utilization" /usr/sbin/vxstat -i 2 -c 5 -s + +} + +######################################################## +# establish file partition -> disk device mapping for solaris +# how do I do this for other platforms? +######################################################## +do_discs() +{ +df -F ufs -k +show "Disk Device Mapping" echo ' ' +df -F ufs | cut -f1 -d: | awk '{print $2}' | sed 's/(//' |\ + sed 's/)//' > /tmp/lll +for i in `cat /tmp/lll` +do + ls -l $i +done +rm /tmp/lll + +show "path_to_inst file" cat /etc/path_to_inst +} + +######################################################## +# calculate the size (in bytes) of all VOB database on this host +######################################################## +check_vobs() +{ +if [ ! -f $ATRIAHOME/bin/cleartool ] ; then + echo this is not a ClearCase host + exit +fi +# list all vobs on this host and extract the +# VOB storage directory. +$ATRIAHOME/bin/cleartool lsvob -host $HOST +$ATRIAHOME/bin/cleartool lsvob -host $HOST | \ +awk '$1 == "*" {print $3 } \ + $1 != "*" {print $2 }' >/tmp/list.$$ +# count the vobs +vobs=`wc -l /tmp/list.$$ | awk '{print $1}'` +echo "Number of vobs : $vobs" +if [ $vobs = 0 ] ; then + return +fi +# now count all the bytes in the database data and key files +for i in `cat /tmp/list.$$` +do + if [ ! -d $i/db ] ; then + echo no db subdirectory for $i + continue + fi + cd $i/db + $LSL vob_db.d0? vob_db.k0? | \ + awk 'BEGIN {sum=0} \ + {sum = sum + $5/(1024.0*1024.0)} \ + END {printf " %8.3f Mb\t", sum}' + echo `basename $i` +done | tee -a /tmp/list1.$$ + +awk 'BEGIN {sum=0} \ +{sum = sum + $1} \ +END {printf "%9.3f Mb\tTOTAL", sum}' < /tmp/list1.$$ + +rm /tmp/list.$$ /tmp/list1.$$ +} + +######################################################## +# check the view characteristics +######################################################## +check_views() +{ +if [ ! -f $ATRIAHOME/bin/cleartool ] ; then + echo this is not a ClearCase host + exit +fi +$ATRIAHOME/bin/cleartool lsview -host $HOST | \ +awk '$1 == "*" {print $3,$2 } \ + $1 != "*" {print $2,$1 }' >/tmp/list.$$ +# count the views +views=`wc -l /tmp/list.$$ | awk '{print $1}'` +echo "Number of views : $views" +if [ $views = 0 ] ; then + return +fi +cat /tmp/list.$$ | ( +i=1 +while [ $i -le $views ] +do + set -- `line`; + size=`grep -s cache $1/.view | awk '{print $2}'` + if [ a$size = a ]; then + size=default + fi + echo "$size $2" | awk '{printf "%8s\t%-16s\n", $1, $2}' + i=`expr $i + 1` +done +) +rm /tmp/list.$$ +} + +######################################################## +# check the MVFS cache on this system +######################################################## +check_mvfs() +{ +/usr/atria/etc/mvfsstat -iclrh 2>&1 +} + +######################################################## +# obtain lockmgr parameters +######################################################## +get_lockmgr() +{ +if [ -f $ATRIAHOME/etc/init.d/atria ] ; then + grep lockmgr $ATRIAHOME/etc/init.d/atria | egrep '\-u' | \ + sed 's/.*}//' | sed 's/>>.*//' +elif [ -f $ATRIAHOME/etc/rc.atria ] ; then + grep lockmgr $ATRIAHOME/etc/rc.atria | egrep '\-u' | \ + sed 's/.*}//' | sed 's/>>.*//' +#for V3 +elif [ -f $ATRIAHOME/etc/atria_start ] ; then + grep lockmgr $ATRIAHOME/etc/atria_start | egrep '\-u' | \ + sed 's/.*}//' | sed 's/>>.*//' +fi +} + +######################################################## +# obtain lockmgr parameters +######################################################## +get_vob_counts() +{ +VSL=$VAR/adm/atria/log/vob_scrubber_log +if [ ! -f $VSL ] ; then + echo no data available +else + egrep 'Started|element|branch|version|derived|hyperlink' $VSL +fi + +} + +######################################################## +# check clearcase things +######################################################## +check_cc() +{ +ATRIAHOME=${ATRIAHOME:-/usr/atria} + show "VOB sizes" check_vobs + show "Views" check_views + show "MVFS" check_mvfs + show "Cleartool Version" $ATRIAHOME/bin/cleartool -ver + show "Lock Manager Configuration" get_lockmgr + show "VOB Characteristics" get_vob_counts + show "License Host" cat $VAR/adm/atria/config/license_host + show "Registry Host and Region" cat $VAR/adm/atria/rgy/rgy*.conf +} + +######################################################## +# obtain mvs parameters +######################################################## + +get_mvfs_sun4() +{ +adb -k /var/adm/atria/vmunix_mvfs /dev/mem </dev/null </dev/null < -fullname " + print -u2 "\t-employeetype -employeenumber +" + print -u2 "\t-manager -mailserver " + exit 1 +} # usage + +function email_postmaster { + notify="postmaster pdl-support" + mailx -s "Please setup email for $fullname" $notify < $message_file +} # email_postmaster + +message_file=$tmp_prefix.msg.$$ +username= +fullname= +employeetype= +employeenumber= +manager= +mailserver= + +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -username) + if [ $# -le 1 ]; then + error "Username not specified!" + usage + fi + shift + username="$1" + ;; + + -fullname) + if [ $# -le 1 ]; then + error "Full name not specified!" + usage + fi + shift + fullname="$1" + ;; + + -employeetype) + if [ $# -le 1 ]; then + error "Employee type not specified!" + usage + fi + shift + employeetype="$1" + + case "$employeetype" in + Employee|SEED|Contractor) + ;; + *) + error "Employeetype must be one of \"Employee\", \"SEED\" or \"Contractor\"" + exit 1 + ;; + esac + ;; + + -employeenumber) + if [ $# -gt 1 ]; then + shift + employeenumber="$1" + fi + ;; + + -manager) + if [ $# -le 1 ]; then + error "Manager name not specified!" + usage + fi + shift + manager="$1" + ;; + + -mailserver) + if [ $# -le 1 ]; then + error "Mail server not specified!" + usage + fi + shift + mailserver="$1" + ;; + + *) + error "Unknown parameter encounter: \"$1\"" + usage + ;; + esac + shift +done + +if [ "_$username" = "_" -o \ + "_$fullname" = "_" -o \ + "_$employeetype" = "_" -o \ + "_$manager" = "_" -o \ + "_$mailserver" = "_" ]; then + error "Missing parameter" + usage +fi + +case "$employeetype" in + Contractor) + if [ "_$employeenumber" != "_" ]; then + error "Contractors should not have an HP Employee number" + exit 1 + fi + ;; + *) # already verified that employeetype is correct + if [ "_$employeenumber" = "_" ]; then + error "Employee number is required for HP Employees and SEEDs" + exit 1 + fi + ;; +esac + +firstname=$(print $fullname | awk '{print $1}') + +cat > $message_file <> $message_file <> $message_file < -fullname " + print -u2 "\t-phone -homeserver -shell " + exit 1 +} # usage + +function add_to_moa { + cd $admin_root/lib + co -q -l $master_passwd + + if [ $? -ne 0 ]; then + error "Unable to checkout $master_passwd" + exit $? + fi + + trap cancel_checkout INT ERR + + if [ "$shell" = "tcsh" ]; then + shell="/app/tcsh" + else + shell="/bin/$shell" + fi + + uid=$(/app/newuid) # generate unique uid + print "$username:*:$uid:$gid:$fullname,42U,$phone,_MoA_:/nfs/$homeserver/data/home/$username:$shell" >> $master_passwd + + if [ $? -ne 0 ]; then + error "Unable to add entry to $master_passwd" + exit $? + fi + + ci -u -q -m"Added $fullname" $master_passwd + if [ $? -ne 0 ]; then + error "Unable to check in new master password file!" + exit $? + fi + + trap INT ERR + + cd $OLDPWD +} # add_to_moa + +function cancel_checkout { + info "Canceling checkout" + rcs -q -u $master_passwd + chmod -w $master_passwd + co -q $master_passwd + exit 1 +} # cancel_checkout +A +function user_exists { + grep -ve "^#" $master_passwd | cut -f1 -d: | + grep "$username" >/dev/null 2>&1 + return $? +} # user_exists + +# Find admin root +if [ -d /net/bismol/app/admin ]; then + admin_root=/net/bismol/app/admin +elif [ -d /net/hpclbis/app/admin ]; then + admin_root=/net/hpclbis/app/admin +elif [ -d /nfs/bismol/app/admin ]; then + admin_root=/nfs/bismol/app/admin +elif [ -d /nfs/hpclbis/app/admin ]; then + admin_root=/nfs/hpclbis/app/admin +elif [ -d /nfs/hpclbis/root/app/admin ]; then + admin_root=/nfs/hpclbis/root/app/admin +else + error "Internal error: Unable to ascertain admin_root!" + exit 1 +fi + +master_passwd=$admin_root/lib/master_passwd +gid=191 # lang group +username= +fullname= +phone= +homeserver= +shell= + +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -username) + if [ $# -le 1 ]; then + error "Username not specified!" + usage + fi + shift + username="$1" + ;; + + -fullname) + if [ $# -le 1 ]; then + error "Full name not specified!" + usage + fi + shift + fullname="$1" + ;; + + -phone) + if [ $# -le 1 ]; then + error "Phone not specified!" + usage + fi + shift + phone="$1" + ;; + + -homeserver) + if [ $# -le 1 ]; then + error "Home machine not specified!" + usage + fi + shift + homeserver="$1" + ;; + + -shell) + if [ $# -le 1 ]; then + error "Shell not specified!" + usage + fi + shift + shell="$1" + ;; + + *) + error "Unknown parameter encounter: \"$1\"" + usage + ;; + esac + shift +done + +if [ "_$username" = "_" -o \ + "_$fullname" = "_" -o \ + "_$phone" = "_" -o \ + "_$homeserver" = "_" -o \ + "_$shell" = "_" ]; then + error "Missing parameter" + usage +fi + +#if $(user_exists); then + #error "$username already exists in the master password file" +#else + add_to_moa + if [ $? -eq 0 ]; then + info "Account for $fullname has been successfully created" + else + error "Problems encountered trying to create account for $fullname" + fi +#fi diff --git a/clients/HP/bin/add_postnote b/clients/HP/bin/add_postnote new file mode 100644 index 0000000..483231e --- /dev/null +++ b/clients/HP/bin/add_postnote @@ -0,0 +1,182 @@ +#!/bin/ksh +################################################################################ +# +# File: add_postnote +# RCS: $Header: add_postnote,v 1.1 97/05/27 15:35:32 defaria Exp $ +# Description: This script adds a new person to the postnote addressbook +# Author: Andrew DeFaria, California Language Labs +# Created: Mon May 19 15:56:06 PDT 1997 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved. +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +function usage { + print -u2 "Usage: $me -username -fullname " + print -u2 "\t-phone -hostname " + print -u2 "\t-displayname " + exit 1 +} # usage + +function add_to_postnote { + cd $postnote_dir + check_out_file=$postnote_addressbook + co -q -l $check_out_file + + if [ $? -ne 0 ]; then + error "Unable to checkout $check_out_file" + exit $? + fi + + trap cancel_checkout INT ERR + + print "S:$fullname = Phone: $phonenumber = +($hostname,$displayname:0,$username@cup.hp.com,F,$xterm)" >> $check_out_file + + if [ $? -ne 0 ]; then + error "Unable to add entry to $check_out_file" + exit $? + fi + + ci -u -q -m"Added $fullname" $check_out_file + if [ $? -ne 0 ]; then + error "Unable to check in $check_out_file!" + exit $? + fi + + trap INT ERR + + cd $OLDPWD +} # add_to_postnote + +function cancel_checkout { + info "Canceling checkout" + rcs -q -u $check_out_file + chmod -w $check_out_file + co -q $check_out_file + exit 1 +} # cancel_checkout + +# Find AppServer's data directory +if [ -d /net/bismol/app/data ]; then + appserver_data=/net/bismol/app/data +elif [ -d /net/hpclbis/app/data ]; then + appserver_data=/net/hpclbis/app/data +elif [ -d /nfs/bismol/app/data ]; then + appserver_data=/nfs/bismol/app/data +elif [ -d /nfs/hpclbis/app/data ]; then + appserver_data=/nfs/hpclbis/app/data +elif [ -d /nfs/hpclbis/root/app/data ]; then + appserver_data=/nfs/hpclbis/root/app/data +else + error "Internal error: Unable to ascertain appserver_data!" + exit 1 +fi + +postnote_dir=$appserver_data +postnote_addressbook=$postnote_dir/pn_addressbook +username= +fullname= +phonenumber="????" +hostname= +displayserver= +xterm= +check_out_file= + +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -username) + if [ $# -le 1 ]; then + error "Username not specified!" + usage + fi + shift + username="$1" + ;; + + -fullname) + if [ $# -le 1 ]; then + error "Full name not specified!" + usage + fi + shift + fullname="$1" + ;; + -phone) + if [ $# -le 1 ]; then + error "Phone not specified!" + usage + fi + shift + phonenumber="$1" + ;; + + -hostname) + if [ $# -le 1 ]; then + error "Hostname not specified!" + usage + fi + shift + hostname="$1" + ;; + + -displayname) + if [ $# -le 1 ]; then + error "Displayname not specified!" + usage + fi + shift + displayname="$1" + ;; + + *) + error "Unknown parameter encounter: \"$1\"" + usage + ;; + esac + shift +done + +if [ "_$username" = "_" -o \ + "_$fullname" = "_" -o \ + "_$hostname" = "_" ]; then + error "Missing parameter" + usage +fi + +if [ "_$displayname" = "_" ]; then + displayname=$hostname:0.0 +elif [ "$displayname" != "$hostname" ]; then + xterm="T" +else + xterm="F" +fi + +add_to_postnote + +if [ $? -eq 0 ]; then + info "$fullname has been added to PostNote addressbook" + if [ "$xterm" = "T" ]; then + info "X Terminal Server: $hostname; X Terminal Display Name: +$displayname" + fi +else + error "Problems encountered trying to create PostNote entry for $fullname" +fi diff --git a/clients/HP/bin/add_sharedx b/clients/HP/bin/add_sharedx new file mode 100644 index 0000000..b8d6f9b --- /dev/null +++ b/clients/HP/bin/add_sharedx @@ -0,0 +1,187 @@ +#!/bin/ksh +################################################################################ +# +# File: add_sharedx +# RCS: $Header: add_sharedx,v 1.1 97/05/27 15:35:33 defaria Exp $ +# Description: This script adds a new person to the SharedX addressbook +# Author: Andrew DeFaria, California Language Labs +# Created: Mon May 19 15:56:06 PDT 1997 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +function usage { + print -u2 "Usage: $me -username -fullname " + print -u2 "\t-phone -hostname " + print -u2 "\t-displayname " + exit 1 +} # usage + +function add_to_sharedx { + cd $sharedx_dir + check_out_file=$sharedx_addressbook + co -q -l $check_out_file + + if [ $? -ne 0 ]; then + error "Unable to checkout $check_out_file" + exit $? + fi + + trap cancel_checkout INT ERR + + if [ "$xterm" = "T" ]; then + print "$displayname:0\t$fullname\t$phonenumber $username\t$hostname" >> +$check_out_file + else + print "$displayname:0\t$fullname\t$phonenumber $username" >> +$check_out_file + fi + + if [ $? -ne 0 ]; then + error "Unable to add entry to $check_out_file" + exit $? + fi + + ci -u -q -m"Added $fullname" $check_out_file + if [ $? -ne 0 ]; then + error "Unable to check in $check_out_file!" + exit $? + fi + + trap INT ERR + + cd $OLDPWD +} # add_to_sharedx + +function cancel_checkout { + info "Canceling checkout" + rcs -q -u $check_out_file + chmod -w $check_out_file + co -q $check_out_file + exit 1 +} # cancel_checkout + +# Find AppServer's data directory +if [ -d /net/bismol/app/data ]; then + appserver_data=/net/bismol/app/data +elif [ -d /net/hpclbis/app/data ]; then + appserver_data=/net/hpclbis/app/data +elif [ -d /nfs/bismol/app/data ]; then + appserver_data=/nfs/bismol/app/data +elif [ -d /nfs/hpclbis/app/data ]; then + appserver_data=/nfs/hpclbis/app/data +elif [ -d /nfs/hpclbis/root/app/data ]; then + appserver_data=/nfs/hpclbis/root/app/data +else + error "Internal error: Unable to ascertain appserver_data!" + exit 1 +fi + +sharedx_dir=$appserver_data/SharedX/address_books +sharedx_addressbook=$sharedx_dir/CLL +username= +fullname= +phonenumber="????" +hostname= +displayserver= +xterm= +check_out_file= + +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -username) + if [ $# -le 1 ]; then + error "Username not specified!" + usage + fi + shift + username="$1" + ;; + + -fullname) + if [ $# -le 1 ]; then + error "Full name not specified!" + usage + fi + shift + fullname="$1" + ;; + -phone) + if [ $# -le 1 ]; then + error "Phone not specified!" + usage + fi + shift + phonenumber="$1" + ;; + + -hostname) + if [ $# -le 1 ]; then + error "Hostname not specified!" + usage + fi + shift + hostname="$1" + ;; + + -displayname) + if [ $# -le 1 ]; then + error "Displayname not specified!" + usage + fi + shift + displayname="$1" + ;; + + *) + error "Unknown parameter encounter: \"$1\"" + usage + ;; + esac + shift +done + +if [ "_$username" = "_" -o \ + "_$fullname" = "_" -o \ + "_$displayname" = "_" ]; then + error "Missing parameter" + usage +fi + +if [ "_$hostname" = "_" ]; then + hostname=$displayname +elif [ "$displayname" != "$hostname" ]; then + xterm="T" +else + xterm="F" +fi + +add_to_sharedx + +if [ $? -eq 0 ]; then + info "$fullname has been added to Shared/X addressbook" + if [ "$xterm" = "T" ]; then + info "X Terminal Server: $hostname; X Terminal Display Name: +$displayname" + fi +else + error "Problems encountered trying to create Shared/X entry for $fullname" +fi diff --git a/clients/HP/bin/add_synchronize b/clients/HP/bin/add_synchronize new file mode 100644 index 0000000..803a92d --- /dev/null +++ b/clients/HP/bin/add_synchronize @@ -0,0 +1,195 @@ +#!/bin/ksh +################################################################################ +# +# File: add_synchronize +# RCS: $Header: add_synchronize,v 1.2 97/05/27 15:35:51 defaria Exp +$ +# Description: This script adds a new person to synchronize +# Author: Andrew DeFaria, California Language Labs +# Created: Mon May 19 15:56:06 PDT 1997 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +function usage { + print -u2 "Usage: $me -username -fullname " + print -u2 "\t-groupname " + exit 1 +} # usage + +function add_to_synchronize { + cd $synchro_db + check_out_file=$synchro_users + co -q -l $check_out_file + + if [ $? -ne 0 ]; then + error "Unable to checkout $check_out_file" + exit $? + fi + + trap cancel_checkout INT ERR + + print "$fullname,\t$username,\t$username@cup.hp.com" >> $check_out_file + + if [ $? -ne 0 ]; then + error "Unable to add entry to $check_out_file" + exit $? + fi + + ci -u -q -m"Added $fullname" $check_out_file + if [ $? -ne 0 ]; then + error "Unable to check in $check_out_file!" + exit $? + fi + + trap INT ERR + + cd $OLDPWD +} # add_to_synchronize + +function add_to_synchronize_group { + cd $synchro_db/GroupTemplates + check_out_file=$groupname + co -q -l $check_out_file + + if [ $? -ne 0 ]; then + error "Unable to checkout $check_out_file" + exit $? + fi + + trap cancel_checkout INT ERR + + print "$fullname" >> $check_out_file + + if [ $? -ne 0 ]; then + error "Unable to add entry to $check_out_file" + exit $? + fi + + ci -u -q -m"Added $fullname to $check_out_file" $check_out_file + if [ $? -ne 0 ]; then + error "Unable to check in $check_out_file!" + exit $? + fi + + trap INT ERR + + make > make.out 2>&1 + + if [ $? -ne 0 ]; then + error "Rebuilding of Synchronize groups failed" + exit $? + fi + + cd $OLDPWD +} # add_to_synchronize_group + +function cancel_checkout { + info "Canceling checkout" + rcs -q -u $check_out_file + chmod -w $check_out_file + co -q $check_out_file + exit 1 +} # cancel_checkout + +function user_exists { + grep -ve "^#" $synchro_users | cut -f1 -d',' | + grep "^$username$" >/dev/null 2>&1 + return $? +} # user_exists + +# Find synchro_dir +if [ -d /net/cllapp/opt/synchronize ]; then + synchro_dir=/net/cllapp/opt/synchronize +else + error "Internal error: Unable to ascertain synchro_dir!" + exit 1 +fi + +synchro_db=$synchro_dir/db +synchro_users=$synchro_db/users +username= +fullname= +groupname= +check_out_file= + +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -username) + if [ $# -le 1 ]; then + error "Username not specified!" + usage + fi + shift + username="$1" + ;; + + -fullname) + if [ $# -le 1 ]; then + error "Full name not specified!" + usage + fi + shift + fullname="$1" + ;; + -groupname) + if [ $# -le 1 ]; then + error "Groupname not specified!" + usage + fi + shift + groupname="$1" + ;; + + *) + error "Unknown parameter encounter: \"$1\"" + usage + ;; + esac + shift +done + +if [ "_$username" = "_" -o \ + "_$fullname" = "_" -o \ + "_$groupname" = "_" ]; then + error "Missing parameter" + usage +fi + +if $(user_exists); then + error "$username already exists in the Synchronize database" +elif [ ! -f $synchro_db/GroupTemplates/$groupname ]; then + error "Unknown Synchronize group $groupname" +else + add_to_synchronize + if [ $? -eq 0 ]; then + info "$fullname has been added as a Synchronize user" + else + error "Problems encountered trying to create Synchronize user for +$fullname" + fi + add_to_synchronize_group + if [ $? -eq 0 ]; then + info "$fullname has been successfully added to $groupname" + else + error "Problems encountered trying to add $fullname to $groupname" + fi +fi diff --git a/clients/HP/bin/add_user b/clients/HP/bin/add_user new file mode 100644 index 0000000..f9c2e9e --- /dev/null +++ b/clients/HP/bin/add_user @@ -0,0 +1,497 @@ +#!/bin/ksh +################################################################################ +# +# File: add_user +# Description: This script adds a user +# Author: Andrew DeFaria +# Language: Korn Shell +# Modified: +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Parameters +employeenumber= +employeetype= +fullname= +groupname= +manager= +phone= +username= +workstation= +shell= +hostname= +homeserver= +displayname= + +# fieldvalue is used when prompting for non-supplied fields +fieldvalue= + +# Logfile +logfile=$TMPDIR/add_user.$$.log + +## Set global env variables +# Set me +me=${0##*/} + +function error { + print -u2 "$me: Error: $1" +} # error + +function warning { + print -u2 "$me: Warning: $1" +} # warning + +function display { + print "$1" +} # display + +function info { + display "$me: Info: $1" +} # info + +function verbose { + if [ ! -z "$verbose" ]; then + display "$1" + fi +} # verbose + +function debug { + if [ ! -z "$debug" ]; then + print -u2 "$me: Debug: $1" + fi +} # debug + +function usage { + display "$me [-v|verbose] [-d|debug] [-usage]" + display " -v|verbose: Turns on verbose mode" + display " -d|debug: Turns on debug mode" + display " -usage: Print this usage message" + display + display "The following options will be prompted for if not supplied on the" + display "command line. If any command line parameter has spaces in it then" + display "you need to surround it in quotes (e.g. -owners_fullname" + display "\"Andrew DeFaria\". Note: Do NOT use quotes when responding to" + display "prompts for missing information." + display + display " -employeenumber Specify the Employee \#" + display " -employeetype One of Employee, SEED or Contractor" + display " -fullname The employee's full name" + display " -groupname Synchronize group name" + display " -manager Full name of manager" + display " -phone In the format of 7-XXXX (the t-44 will" + display " be prepended)" + display " -username Unix/NT username for this new user" + display " -workstation One of Unix|X Terminal|Win NT" + display " -shell One of ksh|sh|csh|tcsh" + display " -hostname Name of workstation host or X Terminal" + display " server" + display " -homeserver Name of machine where \$HOME will be" + display " created" + display " -displayname Name of DISPLAY" + + error "$1" + exit 1 +} # usage + +function prompt_for_field { + fieldname="$1" + fieldvalue= + + while [ ! -n "$fieldvalue" ]; do + display "Enter the value for $fieldname:\c" + read fieldvalue + + if [ ! -n "$fieldvalue" ]; then + error "Must specify $fieldname!" + fi + done +} # prompt_for_field + +function display_parms { + display "New user:" + display "------------------------------------------------------" + display "employeenumber = $employeenumber" + display "employeetype = $employeetype" + display "fullname = $fullname" + display "groupname = $groupname" + display "manager = $manager" + display "phone = $phone" + display "username = $username" + display "workstation = $workstation" + display "shell = $shell" + display "hostname = $hostname" + display "homeserver = $homeserver" + display "displayname = $displayname" + display + display "Command line equivalent:" + display + display "$me -employeenumber $employeenumber \\" + display " -employeetype $employeetype \\" + display " -fullname \"$fullname\" \\" + display " -groupname $groupname \\" + display " -manager \"$manager\" \\" + display " -phone $phone \\" + display " -username $username \\" + display " -workstation $workstation \\" + display " -shell $shell \\" + display " -hostname $hostname \\" + display " -homeserver $homeserver \\" + display " -displayname $displayname" + display "Are the parameters correct [Y|n]?\c" + read answer + case "$answer" in + Y|y) + : OK! + ;; + *) + exit + esac +} # display_parms + +# Get parameters +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + -employeenumber) + if [ $# -gt 1 ]; then + shift + employeenumber="$1" + fi + ;; + + -employeetype) + if [ $# -gt 1 ]; then + shift + employeetype="$1" + fi + ;; + + -fullname) + if [ $# -gt 1 ]; then + shift + fullname="$1" + fi + ;; + + -groupname) + if [ $# -gt 1 ]; then + shift + groupname="$1" + fi + ;; + + -manager) + if [ $# -gt 1 ]; then + shift + manager="$1" + fi + ;; + + -phone) + if [ $# -gt 1 ]; then + shift + phone="$1" + fi + ;; + + -username) + if [ $# -gt 1 ]; then + shift + username="$1" + fi + ;; + + -workstation) + if [ $# -gt 1 ]; then + shift + workstation="$1" + fi + ;; + + -shell) + if [ $# -gt 1 ]; then + shift + shell="$1" + fi + ;; + + -hostname) + if [ $# -gt 1 ]; then + shift + hostname="$1" + fi + ;; + + -homeserver) + if [ $# -gt 1 ]; then + shift + homeserver="$1" + fi + ;; + + -displayname) + if [ $# -gt 1 ]; then + shift + displayname="$1" + fi + ;; + + *) + usage "Unrecognized parameter $1" + ;; + esac + shift +done + +if [ "_$employeenumber" = "_" ]; then + verbose "Employee Number was not specified!" + prompt_for_field "Employee Number" + employeenumber="$fieldvalue" +fi + +if [ "_$employeetype" = "_" ]; then + verbose "Employee Type was not specified!" + prompt_for_field "Employee Type" + employeetype="$fieldvalue" +fi + +while true; do + case "$employeetype" in + Employee|SEED|Contractor) + break + ;; + + *) + error "Employee Type was not one of \"Employee\", \"SEED\" or \"Contractor\"!" + prompt_for_field "Employee Type" + employeetype="$fieldvalue" + ;; + esac +done + +if [ "_$fullname" = "_" ]; then + verbose "Employee Name was not specified!" + prompt_for_field "Employee Name" + fullname="$fieldvalue" +fi + +if [ "_$groupname" = "_" ]; then + verbose "Project Name was not specified!" + prompt_for_field "Project Name" + groupname="$fieldvalue" +fi + +while true; do + if [ -f "/net/cllapp/opt/synchronize/db/GroupTemplates/$groupname" ]; + then + break + else + verbose "Project name \"$groupname\" is not valid!" + display + display "Valid Project names are:" + cd /net/cllapp/opt/synchronize/db/groups/Projects + ls * + cd $OLDPWD + display + prompt_for_field "Project Name" + groupname="$fieldvalue" + fi +done + +if [ "_$manager" = "_" ]; then + verbose "Project Manager was not specified!" + prompt_for_field "Project Manager" + manager="$fieldvalue" +fi + +if [ "_$phone" = "_" ]; then + verbose "Phone was not specified!" + prompt_for_field "Phone" + phone="$fieldvalue" +fi + +if [ "_$username" = "_" ]; then + verbose "Username was not specified!" + prompt_for_field "Username" + username="$fieldvalue" +fi + +if [ "_$workstation" = "_" ]; then + verbose "Workstation was not specified!" + prompt_for_field "Workstation" + workstation="$fieldvalue" +fi + +while true; do + case "$workstation" in + Unix|"X Terminal"|"Win NT") + break + ;; + + *) + error "Workstation was not one of Unix|X Terminal|Win NT!" + prompt_for_field "Workstation" + workstation="$fieldvalue" + ;; + esac +done + +if [ "_$shell" = "_" ]; then + verbose "Shell was not specified!" + prompt_for_field "Shell" + shell="$fieldvalue" +fi + +while true; do + case "$shell" in + ksh|sh|csh|tcsh) + break + ;; + + *) + error "Shell was not one of ksh, sh, csh or tcsh!" + prompt_for_field "Shell" + shell="$fieldvalue" + ;; + esac +done + +if [ "_$hostname" = "_" ]; then + verbose "Hostname was not specified!" + prompt_for_field "Hostname" + hostname="$fieldvalue" +fi + +if [ "$workstation" != "Win NT" ]; then + if [ "_$homeserver" = "_" ]; then + verbose "Home Server was not specified!" + prompt_for_field "Home Server" + homeserver="$fieldvalue" + fi +fi + +if [ "$workstation" = "Unix" ]; then + if [ "_$displayname" = "_" ]; then + displayname=$hostname + fi +elif [ "$workstation" = "X Terminal" ]; then + if [ "$displayname" = "$hostname" ]; then + verbose "Display name cannot be the same as hostname for an X Terminal" + prompt_for_field "Display name" + displayname="$fieldvalue" + fi + if [ "_$displayname" = "_" ]; then + prompt_for_field "Display name" + displayname="$fieldvalue" + fi +fi + +display_parms + +export PATH=$PATH:/app/admin/bin + +print "Add MOA Entry (Y/n)?\c" +read answer +answer=$(print "$answer" | tr [:upper:] [:lower:]) + +case $answer in + y|yes) + add_moa -username $username \ + -fullname "$fullname" \ + -phone $phone \ + -homeserver $homeserver \ + -shell $shell + ;; + *) + print "$fullname not added to MOA" + ;; +esac + +if [ "$employeetype" != "Contractor" ]; then + print "Add Synchronize Entry (Y/n)?\c" + read answer + answer=$(print "$answer" | tr [:upper:] [:lower:]) + + case $answer in + y|yes) + add_synchronize -username $username \ + -fullname "$fullname" \ + -groupname $groupname + ;; + *) + print "$fullname not added to Synchronize" + ;; + esac +fi + +print "Add Postnote Entry (Y/n)?\c" +read answer +answer=$(print "$answer" | tr [:upper:] [:lower:]) + +case $answer in + y|yes) + add_postnote -username $username \ + -fullname "$fullname" \ + -phone $phone \ + -hostname $hostname \ + -displayname $displayname + ;; + *) + print "$fullname not added to Postnote" + ;; +esac + +print "Add Shared/X Entry (Y/n)?\c" +read answer +answer=$(print "$answer" | tr [:upper:] [:lower:]) + +case $answer in + y|yes) + add_sharedx -username $username \ + -fullname "$fullname" \ + -phone $phone \ + -hostname $hostname \ + -displayname $displayname + ;; + *) + print "$fullname not added to Shared/X" + ;; +esac + +print "Send request for email account for $fullname (Y/n)?\c" +read answer +answer=$(print "$answer" | tr [:upper:] [:lower:]) + +case $answer in + y|yes) + if [ "$employeetype" != "Contractor" ]; then + add_email -username $username \ + -fullname "$fullname" \ + -employeetype $employeetype \ + -employeenumber $employeenumber \ + -manager "$manager" \ + -mailserver cllmail + else + add_email -username $username \ + -fullname "$fullname" \ + -employeetype $employeetype \ + -manager "$manager" \ + -mailserver cllmail + fi + ;; + *) + print "$fullname not added to email" + ;; +esac diff --git a/clients/HP/bin/adl-config b/clients/HP/bin/adl-config new file mode 100644 index 0000000..d879a8c --- /dev/null +++ b/clients/HP/bin/adl-config @@ -0,0 +1,437 @@ +#!/usr/bin/ksh +################################################################################ +# +# File: adl-config +# Description: ADL system configuration script +# To run this script you must have the adl-config.src parameter +# file located in root. It is important that the source parameter +# file be read and understood before running the script. +# See below for useful comments. +# Author: Kevin Lister - kel@cup.hp.com +# Date 3.11.99 +# Language: Korn Shell +# +# (c) Copyright 1991, Hewlett-Packard Company, all rights reserved. +# +# Revision History +# 3.25.99 kel Changed the name of the Clearcase install script in shell +# archive, so it had to be changed here as well. Added an +# eclipse install script to the shell archive, so a line to +# to remove it if Clearcase is not installed had to be added +# here as well. +# 4.1.99 kel Added code to determine if the installed system is going to have +# a graphics console. If yes, then the /etc/dt/config/Xservers +# file needs to have the console server line uncommented. +# Also added absolute paths to the unix commands. +# +################################################################################ +# Useful (hopefully) Comments Section +# +# This script will configure a system to operate nicely in the ADL +# infrastructure. This script requires the adl-config.src file in order to +# run. The adl-config.src file contains variables that determine exactly +# what type of optional software to install, which patch bundle to install, +# configures various system files, etc. +# +# Here is a brief description of what this script will do: +# +# 1) Check that the script is run as root +# 2) Check that the architecture is correct. The script will run on most +# hardware. The architecture is really only important when trying to +# determine which 100Mbit drivers to install. +# 3) Sources the input parameter source file. +# 4) Determine if script is run intereactive or not. +# 5) Determine if 100Mbit drivers are to be installed +# 6) If intereactive, greet the user and display the parameter settings. +# 7) Modify the kernel system file located in /stand/system +# 8) Download the shell archive file from the anonymous ftp server and unpack. +# The shell archive contains many files and symlinks and will not be +# listed here. See the README in the ahell archive build area and the shell +# archive itself for more details. One can also look through the "root" +# directory that is used to build the archive to see which files and +# symlinks are included. +# 9) Modify the /etc/rc.config.d files. (turn off unused stuff) +# 10) Modify the /etc/issue, /etc/gettydefs and /etc/motd files. +# 11) Modify miscellaneous files. +# 12) Perform miscellaneous setup procedures: +# a) Run /net/bismol/App/admin/bin/setup +# b) Run /usr/local/bin/ninstall -h bismol lp adm net3 +# c) Run /usr/adm/netdist/netdaemon.dy +# d) Run /usr/sbin/catman -w +# 13) Set the system up for ClearCase installation upon automatic reboot. +# 14) Install optional software and patches from the specified depot server. +# +# END of Useful Comments Section +################################################################################ + +# +## +### Variables +## +# + +SRC_FILE=/adl-config.src + +BASE=${0##*/} +HOST=`/bin/uname -n` +ARCH=`/bin/uname -m` +OS=`/bin/uname -r | /usr/bin/cut -c 3-4` +integer INDEX=0 + +# +## +### Functions +## +# + +function error { + print -u2 "\t$BASE: Error: $1" +} + +function warning { + print -u2 "\t$BASE: Warning: $1" +} + +function display { + print "\t$1" +} + +function usage { + display "\t$BASE [-usage]" + display " -usage: Print this usage message" + display " " + error "$1" + exit 1 +} + +function step { + let INDEX=INDEX+1 + display "\tStep #$INDEX: $@" +} + +function get_shar { +step "Get shell archive from ftp server and unpack" + cd / + ftp -n $FTP_SERVER <<@EOD +user $FTP_USER $FTP_PASSWD +cd $SHAR_DIR +get $SHAR_FILE +quit +@EOD +if [ $? -ne 0 ]; then + error "Unable to ftp $SHAR_FILE from $FTP_SERVER" + exit 1 +fi +sh $SHAR_FILE >> $LOGFILE 2>&1 +if [ $? -ne 0 ]; then + error "Cannot unpack shell archive." + exit 1 +fi +/bin/rm -f $SHAR_FILE +} + +function clearcase_setup { + if [ "$CLEARCASE" = "NO" ]; then + /bin/rm -f /sbin/rc3.d/S998install_clearcase + /bin/rm -f /sbin/rc3.d/S999install_eclipse + fi +} + +function chk_uid { + if [ $(id -u) -ne 0 ]; then + error "Must be root to execute this command... Exiting!" + exit 1 + fi +} + +function chk_arch { + case $ARCH in + 9000/7[1-3]*|9000/755|9000/7[7-8]*|9000/8**) + continue + ;; + + *) + warning "\tUnknown machine type $ARCH, Exiting!" + exit 1 + ;; + esac +} + +function read_src { + if [ -a $SRC_FILE ]; then + . $SRC_FILE + case "$CLEARCASE" in + y|Y|yes|YES|Yes|1) + CLEARCASE=yes + ;; + *) + CLEARCASE=no + ;; + esac + case "$SWINSTALL" in + y|Y|yes|YES|Yes|1) + SWINSTALL=yes + ;; + *) + SWINSTALL=no + ;; + esac + else + error "Source file does not exist!" + exit 1 + fi +} + +function set_mode { + case "$INTERACTIVE" in + y|Y|yes|YES|Yes|1) + INTERACTIVE=yes + ;; + *) + INTERACTIVE=no + ;; + esac +} + +function fast_enet { + if [ "_$ENET_DRVRS" = "_" ]; then + FAST_ENET=no + else + FAST_ENET=yes + fi +} + +function mod_kernel { + step "Modify /stand/system file." + grep -v -E 'maxswapchunks|default_disk_ir|nstrpty' /stand/system \ + > /stand/system.new + /bin/mv /stand/system /stand/system.orig + /bin/mv /stand/system.new /stand/system + + case $ARCH in + 9000/7[1-5]*) + echo "create_fastlinks 1" >> /stand/system + echo "dbc_max_pct 25" >> /stand/system + echo "default_disk_ir 1" >> /stand/system + echo "fs_async 1" >> /stand/system + echo "maxdsiz (256*1024*1024)" >> /stand/system + echo "maxfiles 256" >> /stand/system + echo "maxfiles_lim 2048" >> /stand/system + echo "maxssiz (80*1024*1024)" >> /stand/system + echo "maxswapchunks 4096" >> /stand/system + echo "maxuprc 500" >> /stand/system + echo "maxusers 150" >> /stand/system + echo "netmemmax 0" >> /stand/system + echo "nfile 7000" >> /stand/system + echo "nflocks 400" >> /stand/system + echo "ninode 20000" >> /stand/system + echo "nproc 1500" >> /stand/system + echo "npty 512" >> /stand/system + echo "nstrpty 512" >> /stand/system + echo "semmns 200" >> /stand/system + if [ "$OS" = "10" ]; then + echo "large_ncargs_enabled 1" >> /stand/system + fi + ;; + + 9000/7[7-8]*|9000/8**) + echo "create_fastlinks 1" >> /stand/system + echo "dbc_max_pct 25" >> /stand/system + echo "default_disk_ir 1" >> /stand/system + echo "fs_async 1" >> /stand/system + echo "maxdsiz (512*1024*1024)" >> /stand/system + echo "maxfiles 256" >> /stand/system + echo "maxfiles_lim 2048" >> /stand/system + echo "maxssiz (80*1024*1024)" >> /stand/system + echo "maxswapchunks 4096" >> /stand/system + echo "maxuprc 1000" >> /stand/system + echo "maxusers 256" >> /stand/system + echo "netmemmax 0" >> /stand/system + echo "nfile 14000" >> /stand/system + echo "nflocks 800" >> /stand/system + echo "ninode 40000" >> /stand/system + echo "nproc 3000" >> /stand/system + echo "npty 512" >> /stand/system + echo "nstrpty 512" >> /stand/system + echo "semmns 400" >> /stand/system + if [ "$OS" = "10" ]; then + echo "large_ncargs_enabled 1" >> /stand/system + fi + ;; + + *) + warning "Unknown machine model $ARCH!" + warning "Leaving kernel parameters as default" + /bin/mv /stand/system.orig /stand/system + ;; + esac +} # mod_kernel + +function greet { + display "\tADL System Configuration script." + display + display "\tYou are about to install and modify various system files," + display "\tinstall system patches, install optional software and," + display "\tif you elected to do so, install ClearCase 3.2." + display + display "\tIf you wish to modify the parameters below exit the install" + display "\tand modify the parameters in the $SRC_FILE file." + display + display "\tMachine Name:\t\t\t$MACHINE_NAME" + display "\tMachine Usage:\t\t\t$MACHINE_USAGE" + display "\tMacine Location:\t\t$LOCATION" + display "\tOwner's Fullname:\t\t$OWNER_NAME" + display "\tOwner's Email:\t\t\t$OWNER_EMAIL" + display "\tOwner's Extension:\t\t$OWNER_EXTENSION" + display "\tInstall ClearCase?:\t\t$CLEARCASE" + display "\tInstall 100Mbit Drivers?:\t$FAST_ENET" + if [ "$SWINSTALL" = "yes" ]; then + display "\tThe following products will be installed from $DEPOT:" + display "\t$PRODUCTS" + display + else + display + fi + if [ "$INTERACTIVE" = "yes" ]; then + display "\tContinue installation with these parameters (Y|n)?\c" + display + answer=y + read answer + case "$answer" in + y|Y|yes|Yes|YES|"") + continue + ;; + *) + display + display "\tYou have chosen NOT to run the $BASE setup script... +Exiting" + exit 1 + ;; + esac + fi +} # greet + +function mod_rc_files { + /usr/sbin/ch_rc -ap AUDIO_SERVER=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap LIST_TEMPS=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap CLEAR_TMP=1 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap HPARRAY_START_STOP=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NIS_CLIENT=1 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NIS_DOMAIN=adl >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap START_LLBD=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NTPDATE_SERVER=cupertino.ntp.hp.com >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap XNTPD=1 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NETTL=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NUM_NFSIOD=16 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap VTDAEMON_START=0 >> $LOGFILE 2>&1 + if [ "$OS" = "10" ]; then + /usr/sbin/ch_rc -ap WAIT_FOR_NIS_SERVER=FALSE >> $LOGFILE 2>&1 + fi +} + +function mod_etc_files { + step "/etc files setup" + print "+auto.master" > /etc/auto_master + /bin/chmod 644 /etc/auto_master + /bin/chown root:root /etc/auto_master + + sed "s/GenericSysName/$MACHINE_NAME/" /etc/issue > /etc/issue-new + /bin/mv /etc/issue /etc/issue-orig + /bin/mv /etc/issue-new /etc/issue + + sed "s/Console Login:/$MACHINE_NAME Console Login:/" /etc/gettydefs \ + > /etc/gettydefs-new + /bin/mv /etc/gettydefs /etc/gettydefs-orig + /bin/mv /etc/gettydefs-new /etc/gettydefs + + /bin/banner $MACHINE_NAME > /etc/motd + /bin/uname -a >> /etc/motd + cat >> /etc/motd <<:END + +******************************************************************************* +* This is a private system operated for the Hewlett-Packard Company business. * +* Authorization from HP management is required to use this system. * +* Use by unauthorized persons is prohibited. * +******************************************************************************* +For System Support: Mon-Fri 8:00-5:00 Email (site-ux@cup.hp.com) +Phone: t-447-1212 After hours/weekend Pre-arrange: t-447-0629 +------------------------------------------------------------------------------- +Usage: $MACHINE_USAGE +Owner: $OWNER_NAME ($OWNER_EMAIL) Phone: $OWNER_EXTENSION +Location: $LOCATION +------------------------------------------------------------------------------- +:END + + sed "s/Root user/Root\@$HOST/" /etc/passwd > /tmp/passwd-new + /bin/mv /tmp/passwd-new /etc/passwd +} # mod_etc_files + +function mod_misc_files { + step "Miscellaneous file setup" + /bin/rm -f /var/adm/cron/at.allow + /bin/rm -f /var/adm/cron/cron.allow + /bin/chmod 644 /dev/lan* + case "$WORKSTATION" in + y|Y|yes|YES|Yes|1) + WORKSTATION=yes + ;; + *) + WORKSTATION=no + ;; + esac + if [ "$WORKSTATION" = "yes" ]; then + /bin/sed -e "s/# \*/ \*/" Xservers > /tmp/Xservers-new + /bin/mv /tmp/Xservers-new /etc/dt/config/Xservers + /bin/chmod 444 /etc/dt/config/Xservers + /bin/chown root:other /etc/dt/config/Xservers + fi +} + +function misc_setup { + step "Setup Application Server" + /net/bismol/App/admin/bin/setup >> $LOGFILE 2>&1 + + step "Ninstalling lp, adm and net3 packages" + /usr/local/bin/ninstall -h bismol lp adm net3 >> $LOGFILE 2>&1 + + step "Run netdaemon.dy" + /usr/adm/netdist/netdaemon.dy >> $LOGFILE 2>&1 + + step "Create the whatis database" + /usr/sbin/catman -w >> $LOGFILE 2>&1 +} + +function inst_sw { + if [ "$SWINSTALL" = "yes" ]; then + step "Installing Patches and Optional Software, be patient!" + /usr/sbin/swinstall -s $DEPOT -x $OPTIONS $PRODUCTS $ENETDRVR >> +$LOGFILE 2>&1 + else + step "Rebuilding kernel with new parameters." + /usr/sbin/mk_kernel -v -o /stand/vmunix >> $LOGFILE 2>&1 + step "Rebooting the system..." + cd / + /usr/sbin/shutdown -ry 0 + fi +} + +# +## +### Main +## +# + +chk_uid +chk_arch +read_src +set_mode +fast_enet +greet +mod_kernel +get_shar +mod_rc_files +mod_etc_files +mod_misc_files +misc_setup +clearcase_setup +inst_sw diff --git a/clients/HP/bin/adl-config.src b/clients/HP/bin/adl-config.src new file mode 100644 index 0000000..56086a6 --- /dev/null +++ b/clients/HP/bin/adl-config.src @@ -0,0 +1,163 @@ +################################################################################ +# +# File: adl-config.src +# Description: Parameter Source File for the ADL system configuration script +# adl-config. This file is required by the adl-config script +# in order to run. +# See below for useful comments. +# Author: Kevin Lister (C) - kel@cup.hp.com +# Date: 3.11.99 +# Language: Korn Shell +# +# (c) Copyright 1991, Hewlett-Packard Company, all rights reserved. +# +# Revision History +# 4.1.99 kel added the WORKSTATION variable. Setting the WORKSTATION +# variable to yes will set the machine up with a graphics console +# login using CDE. +# +################################################################################ +# Useful (hopefully) Comments Section +# +# Do not make your changes to the varibales in the comment section. Change +# the variables at the end of this file. +# +# Below you will find all of the ENV variables that the adl-config script +# will use to configure the system. +# Descriptions for these variables can be found below, read on. +# +# Set the INTERACTIVE ENV variable to yes if you wish to have a chance to +view +# the configuration parameters the script will use before proceeding. Set to +# no otherwise. +# +# INTERACTIVE=yes +# +# Set the WORKSTATION variable to yes if you are installing a system that +will +# have a graphics console monitor attached. Setting WORKSTATION to no +disbales +# CDE on the console. +# +# WORKSTATION=no +# +# You can have ClearCase 3.2 installed automatically by setting CLEARCASE +# to yes. If you do not want ClearCase, set to no. +# +# CLEARCASE=yes +# +# If you want the Patch bundle (see below) and Optional Software installed +# set SWINSTALL to yes. +# +# SWINSTALL=yes +# +# If you plan to use a 100Mbit network interface then set FAST_ENET to yes +# to have the correct drivers installed. Set to no if you don't. +# +# FAST_ENET=yes +# +# Set the location of the logfile for the configure script using the LOGFILE +# variable. +# +# LOGFILE=/adl-config.log +# +# The /etc/motd file will be set up with the information contained in the next +# several variables. The /etc/issue and /etc/gettydefs files will also be +# setup by using the MACHINE_NAME variable. You should set these to something +# that makes sense. +# +# OWNER_NAME="ADL Support" +# OWNER_EMAIL=adl-support@cup.hp.com +# OWNER_EXTENSION=t-447-5790 +# MACHINE_USAGE="X Terminal Server" +# LOCATION=RDC +# MACHINE_NAME=Generic +# +# The next several variables set up the depot server name, depot path and +# names of the software bundles and products to install. It is likely that you +# you will only need to change ENET_DRVRS. Set ENET_DRVRS to 100BT-HSC for a +# J282 (780). Set ENET_DRVRS to SX00306 for a 755. The default for XTERM_SVR +# is "". If you really don't want patches and optional software then set +# PATCHES and OPTIONAL to "". You should never need to modify PRODUCTS, DEPOT +# or OPTIONS. +# +# PATCHES=Patches-Generic +# OPTIONAL="OptionalSoftware SysMonSoftware VUEtoCDE" +# XTERM_SVR="ENWARE netstation" +# ENET_DRVRS=100BT-HSC +# ENET_DRVRS=SX00306 +# PRODUCTS="$PATCHES $OPTIONAL $XTERM_SVR $ENET_DRVRS" +# DEPOT=adliux01:/depots/10.20 +# OPTIONS="autoreboot=true" +# +# Finally, the next several variables set up the ftp server, directory and +# filename of the shell archive that the script uses to unpack all kinds +# of useful files and symlinks. You should never have to modify these. +# +# FTP_SERVER=15.0.98.138 +# FTP_USER=anonymous +# FTP_PASSWD=$LOGNAME@$(uname -n).cup.hp.com +# SHAR_DIR=productivity/adl-config +# SHAR_FILE=adl-config.shar +# +# END of Useful Comments Section +################################################################################ + +# +## +### Change these to suit your fancy. +## +# + +INTERACTIVE=yes +WORKSTATION=no +CLEARCASE=yes +SWINSTALL=yes +FAST_ENET=no +LOGFILE=/adl-config.log + +# +## +### /etc/motd setup +## +# + +OWNER_NAME="ADL Support" +OWNER_EMAIL=adl-support@cup.hp.com +OWNER_EXTENSION=t-447-5790 +MACHINE_USAGE="Change Me" +LOCATION=RDC +MACHINE_NAME=GENERIC + +# +## +### Patches and Optional Software +## +# + +PATCHES=Patches-Generic +OPTIONAL="OptionalSoftware SysMonSoftware VUEtoCDE" +XTERM_SVR="" +ENET_DRVRS="" +PRODUCTS="$PATCHES $OPTIONAL $XTERM_SVR $ENET_DRVRS" + +# +## +### Depot Server Information +## +# + +DEPOT=adliux01:/depots/10.20 +OPTIONS="autoreboot=true" + +# +## +### Shell Archive Server and Location +## +# + +FTP_SERVER=15.0.98.138 +FTP_USER=anonymous +FTP_PASSWD=$LOGNAME@$(uname -n).cup.hp.com +SHAR_DIR=productivity/adl-config +SHAR_FILE=adl-config.shar diff --git a/clients/HP/bin/allmach b/clients/HP/bin/allmach new file mode 100644 index 0000000..33d82c6 --- /dev/null +++ b/clients/HP/bin/allmach @@ -0,0 +1,111 @@ +#!/bin/ksh +################################################################################ +# +# File: allmach +# Description: Runs an arbitrary command on all machines +# Author: Andrew@DeFaria.com +# Created: Fri Apr 30 14:17:40 PDT 1999 +# Language: Korn Shell +# Modifications:Added trapping of INT so that you can abort a non-responding +# machine. +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Set machines +machines=${machines:-$adm_base/data/machines} + +if [ "$1" = "-f" ]; then + shift + machines="$1" + shift +fi + +if [ "$1" = "-r" ]; then + root_remsh=true + shift +fi + +if [ ! -f $machines ]; then + error "Unable to find $machines file!" 1 +fi + +function trap_intr { + display "${machines[i]}:$cmd interrupted" + display "(A)bort $me or (C)ontinue with next machine? \c" + read response + typeset -l response=$response + + case "$response" in + a|abort) + display "Aborting $me..." + exit + ;; + esac + display "Continuing on with the next machine..." +} # trap_intr + +# Build up data arrays. Note this is done because if we remsh while in a pipe +# Sun will not allow a simple remsh with no command (boo!) +# Column 1 Machine name +# Column 2 Model +# Column 3 OS Version +# Column 4 ClearCase Version (if applicable) +# Column 5 Owner (if known) +# Column 6 Usage (if known) +oldIFS=$IFS +IFS=":" +integer nbr_of_machines=0 +sed -e "/^#/d" $machines | + while read machine model osversion ccversion owner phone usage location; +do + machines[nbr_of_machines]=$machine + models[nbr_of_machines]=$model + #osversions[nbr_of_machines]=$osversion + #ccversions[nbr_of_machines]=$ccversion + #owners[nbr_of_machines]=$owner + #phones[nbr_of_machines]=$phone + #usages[nbr_of_machines]=$usage + #locations[nbr_of_machines]=$location + let nbr_of_machines=nbr_of_machines+1 +done +IFS="$oldIFS" + +# This loop executes the command +trap trap_intr INT +integer i=0 +while [ $i -lt $nbr_of_machines ]; do + export currmachine=${machines[i]} + # Execute command. Note if no command is given then the effect is to + # rlogin to each machine. + print -u2 "${machines[i]}\c" + print -u2 ":$@" + cmd="$@" + if [ $# -gt 0 ]; then + if [ "$root_remsh" = "true" ]; then + remsh ${machines[i]} -n -l root "$cmd" + else + remsh ${machines[i]} -n "$cmd" + fi + else + if [ "$root_remsh" = "true" ]; then + remsh ${machines[i]} -l root + else + remsh ${machines[i]} + fi + fi + let i=i+1 +done +trap - INT diff --git a/clients/HP/bin/arcserverenv b/clients/HP/bin/arcserverenv new file mode 100644 index 0000000..42f3abc --- /dev/null +++ b/clients/HP/bin/arcserverenv @@ -0,0 +1,66 @@ +#!/bin/ksh +################################################################################ +# +# File: arcservenv +# Description: Set environment variables for Arc Serve +# Author: Andrew@DeFaria.com +# Created: Fri Jul 2 14:49:22 PDT 1999 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Set machines +machines=${machines:-$adm_base/data/machines} + +if [[ "$me" = "-ksh" ]]; then + : #This script was sourced (I think, the man page is sketchy on this) +else + error "You need to invoke this script with a leading. (e.g. . $me)" 1 +fi + +me=$(basename $2) + +if [ "$VENDOR" = "Sun" ]; then + export ARC_HOME=${ARC_HOME:-/opt/ARCserve} + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/openwin/lib:$ARC_HOME:/usr/dt/lib +elif [ "$VENDOR" = "HP" ]; then + export ARC_HOME=${ARC_HOME:-/usr/ARCserve} + export SHLIB_PATH=$SHLIB_PATH:$ARC_HOME:/usr/dt/lib +else + export ARC_HOME=${ARC_HOME:-Unknown} +fi + +if [ ! -d "$ARC_HOME" ]; then + warning "$ARC_HOME does not exist!" +fi + +export PATH=$PATH:$ARC_HOME +export XFILESEARCHPATH=/usr/openwin/lib/locale/%L/%T/%N/%S:/usr/openwin/lib/%T/%N/%S +export HHHOME=$ARC_HOME +export MANPATH=$MANPATH:$ARC_HOME/man + +display "ARC Serve Environment Settings" +display - ------------------------------------------------------------------------------- +display "ARC_HOME: $ARC_HOME" +display "PATH: $PATH" +if [ "$VENDOR" = "Sun" ]; then + display "XFILESEARCHPATH: $XFILESEARCHPATH" + display "LD_LIBRARY_PATH: $LD_LIBRARY_PATH" +else + display "SHLIB_PATH: $SHLIB_PATH" +fi +display "HHHOME: $HHHOME" +display "MANPATH: $MANPATH" diff --git a/clients/HP/bin/atria.scs b/clients/HP/bin/atria.scs new file mode 100644 index 0000000..793b2b8 --- /dev/null +++ b/clients/HP/bin/atria.scs @@ -0,0 +1,727 @@ +#!/bin/sh +############################################# +# @(#)scs 1.26 +# system characterization script +# "scs" collects data from Atria +# customer sites for analysis by +# engineering. +###################################### + +######################### +# For Solaris 5.x systems +######################### +nddit() +{ +for i in tcp udp ip +do + /usr/sbin/ndd /dev/$i \? | awk '{print $1}' | \ + egrep -v '\?|directed|respond'> /tmp/$$ + for j in `cat /tmp/$$` + do + printf "%-30s %s\n" $j `/usr/sbin/ndd /dev/$i $j` + done + rm /tmp/$$ +done +} + +solaris() +{ +show "System Device Configuration" /usr/sbin/prtconf -vP +show "System Configuration" /usr/sbin/sysdef -i +show "System Customization" '/bin/cat /etc/system | \ + /bin/grep -v "^\*" | /bin/grep -v "^$"' +show "Network Configuration" nddit +show "System Messages" /bin/dmesg +show "Patches" /bin/showrev -p + +show "Processes" '/usr/ucb/ps auxww | /bin/fold -80' +show "Network Configuration" /usr/sbin/ifconfig -a +show "Network Utilization Summary" /bin/netstat -i +show "Network Protocol Statistics" /bin/netstat -s +show "Network Mbuf Statistics" /bin/netstat -m +show "VM Statistics" /bin/vmstat -s +show "Cache Flush Statistics" /bin/vmstat -c +show "Interrupts" /bin/vmstat -i +show "NFS Statistics" /bin/nfsstat +show "NFS Responses" /bin/nfsstat -m + +show "CPU Utilization" /bin/sar -u 1 10 +show "Buffer Activity" /bin/sar -b 1 10 +show "Block Device Activity" /bin/sar -d 1 10 +show "Disk Device Activity" iostat -x 1 10 +show "Paging In Activity" /bin/sar -p 1 5 +show "Paging Out Activity" /bin/sar -g 1 5 +show "Free Memory" /bin/sar -r 1 5 +show "vmstat snapshot" /bin/vmstat 2 10 +show "Kernel Memory Allocation Activity" /bin/sar -k 1 5 +show "KMA statistics" echo kmastat | /usr/sbin/crash +echo "" +} + +####################### +# For SUNOS 4.x systems +####################### +sunos() +{ + +show "Memory " '/etc/dmesg | grep mem' +show "System Messages" /etc/dmesg +show "Processes" '/bin/ps auxww | /usr/ucb/fold -80' +show "Network Utilization Summary" /usr/ucb/netstat -i +show "Network Protocol Statistics" /usr/ucb/netstat -s +show "Network Mbuf Statistics" /usr/ucb/netstat -m +show "VM Statistics" /usr/ucb/vmstat -s +show "Cache Flush Statistics" /usr/ucb/vmstat -c +show "Interrupts" /usr/ucb/vmstat -i +show "NFS Statistics" /usr/etc/nfsstat + +show "Disk Device Activity" /bin/iostat -D 1 10 +show "CPU Activity" /usr/ucb/vmstat 1 10 +show "Tables" /etc/pstat -T +show "vmstat snapshot" /usr/ucb/vmstat 2 10 + +} + + +####################### +# For AIX +####################### +aix() +{ + +show "Processes" '/usr/bin/ps -elf ' +show "Network Utilization Summary" /bin/netstat -i +show "Network Protocol Statistics" /bin/netstat -s +show "Network Mbuf Statistics" /bin/netstat -m +show "Network Configurables" /usr/sbin/no -a +show "NFS Statistics" /usr/sbin/nfsstat + +show "System Attributes" /usr/sbin/lsattr -E -l sys0 +show "CPU Utilization" sar -u 1 10 +show "Buffer Activity" sar -b 1 10 +show "Disk Activity" /bin/iostat 1 10 +show "Paging Stats" sar -r 1 5 +show "Network Monitor for 30s" '/bin/netpmon -v -o /tmp/$$; sleep 30; trcstop' +echo "" +} + +####################### +# For OSF1 +####################### +osf1() +{ +show "Boot Messages" 'echo "";echo ""; echo "";uerf -r 300 | tail -100' +show "Processes" '/usr/bin/ps glww | fold -80' +show "Network Utilization Summary" /usr/sbin/netstat -i +show "Network Protocol Statistics" /usr/sbin/netstat -s +show "Network Mbuf Statistics" /usr/sbin/netstat -m +show "NFS Statistics" /usr/bin/nfsstat +show "Kernel memory usage" /usr/bin/vmstat -M +show "vmstat snapshopt" /usr/bin/vmstat 2 10 +show "Disk Device snapshot" /bin/iostat 2 10 + +} + +####################### +# For IRIX 5.x +####################### +irix() +{ +show "System Device Configuration" /usr/sbin/sysconf +show "System Hardware Configuration" /usr/bin/hinv +show "System Software Configuration" /etc/chkconfig +show "Disk Usage" /usr/sbin/df -l -k +show "System Customization" '/bin/cat /var/sysgen/stune | \ + /bin/grep -v "^\*" | /bin/grep -v "^$"' + +show "Processes" '/usr/bin/ps -elf | /bin/fold -80' +show "Network Utilization Summary" /usr/etc/netstat -i +show "Network Protocol Statistics" /usr/etc/netstat -s +show "Network Mbuf Statistics" /usr/etc/netstat -m +show "NFS Statistics" /usr/etc/nfsstat + +show "CPU Utilization" sar -u 1 10 +show "Buffer Activity" sar -b 1 10 +show "Block Device Activity" sar -d 1 10 +show "Paging In Activity" sar -p 1 5 +show "Paging Out Activity" sar -g 1 5 +show "Free Memory" sar -r 1 5 +echo "" +} + + +##################### +# For HP-UX 9/800 systems +##################### +hpux98() +{ +#first the shared info +hpux +# now the system specific +show "System definition" /etc/sysdef +show "CPU Utilization" /usr/bin/sar -u 1 10 +show "Buffer Activity" /usr/bin/sar -b 1 10 +show "Block Device Activity" /usr/bin/sar -d 1 10 +} +##################### +# For HP-UX 9/700 systems +##################### +hpux97() +{ +# just the shared info +hpux +} +##################### +# For All HP-UX 9 systems +##################### +hpux() +{ +show "Memory " grep Physical /usr/adm/messages +show "System Messages" /etc/dmesg +show "Swap Space" /etc/swapinfo +show "Patches" ls -ld /system/PH* +show "IO devices" /etc/ioscan -f + +show "Processes" '/bin/ps -elf | /usr/bin/fold -80' +show "Network Utilization Summary" /usr/bin/netstat -i +show "Network Protocol Statistics" /usr/bin/netstat -s +show "Network Mbuf Statistics" /usr/bin/netstat -m +show "VM Statistics" /usr/bin/vmstat -s +show "NFS Statistics" /usr/etc/nfsstat +show "Network errors" /etc/netfmt -t 30 -f /usr/adm/nettl.LOG00 + +show "Disk Utilization" df -l +show "vmstat snapshot" /usr/bin/vmstat 2 10 +} + +##################### +# For HP-UX 10 systems +##################### +hpux10() +{ + +show "Memory " grep Physical /var/adm/syslog/syslog.log +show "System DMessages" /usr/sbin/dmesg +show "System definition" /usr/sbin/sysdef +show "Messages" "tail -100 /usr/adm/syslog/syslog.log" +show "IO status" /etc/ioscan -f +show "Patches" '/usr/sbin/swlist -l product | grep PH' + +show "Processes" '/usr/bin/ps -elf | /usr/bin/fold -80' +show "Network Utilization Summary" /usr/bin/netstat -i +show "Network Protocol Statistics" /usr/bin/netstat -s +show "Network Mbuf Statistics" /usr/bin/netstat -m +show "VM Statistics" /usr/bin/vmstat -s +show "NFS Statistics" /usr/bin/nfsstat + +show "CPU Utilization" /usr/bin/sar -u 1 10 +show "Buffer Activity" /usr/bin/sar -b 1 10 +show "Block Device Activity" /usr/bin/sar -d 1 10 +show "vmstat snapshot" /usr/bin/vmstat 2 10 +} +##################### +# For Unixware systems +##################### +unixware() +{ +show "Memory size" /sbin/memsize +show "Message log" cat /usr/adm/log/osmlog +show "System Configuration" /usr/sbin/sysdef +show "Processes" '/usr/bin/ps -elf ' +show "Network Utilization Summary" /bin/netstat -i +show "Network Protocol Statistics" /bin/netstat -s +show "NFS Statistics" /usr/sbin/nfsstat + +show "CPU Utilization" /sbin/sar -u 1 10 +show "Buffer Activity" /sbin/sar -b 1 10 +show "Block Device Activity" /sbin/sar -d 1 10 +show "Paging In Activity" /sbin/sar -p 1 5 +show "Paging Out Activity" /sbin/sar -g 1 5 +show "Free Memory" /sbin/sar -r 1 5 +show "Historical sar data" /sbin/sar -A +echo "" +} + + +#################################### +# display informationin a uniform way +#################################### +show() { + echo "----------------------------------------------------" + echo $1 + echo "----------------------------------------------------" + shift + eval "$@" + echo "" +} +################################################## +# check uw network - works for Unixware +################################################## +check_uw_network() { + +netstat -i $interface +sleep 10 +netstat -i $interface +} + +################################################## +# check network - works for HP-UX and SUNOS 5.x +################################################## +check_network() { + printf "%8s %8s %8s %8s %8s %8s \n" time inpkts inerrs \ + outpkts outerrs colls + netstat -i -I $interface $interval | ( + (line ; line ; line) > /dev/null + t_inpkts=0 # initialize counter + t_inerrs=0 # initialize counter + t_outpkts=0 # initialize counter + t_outerrs=0 # initialize counter + t_colls=0 # initialize counter + i=0 + while test $i -lt $count ; do # for each of the lines + time=`date +%T` + /bin/echo $time \\c + set -- `line` # get the line + printf "%8s %8s %8s %8s %8s\n" $1 $2 $3 $4 $5 + t_inpkts=`expr $1 + $t_inpkts` # accumulate in packets + shift + t_inerrs=`expr $1 + $t_inerrs` # accumulate in errors + shift + t_outpkts=`expr $1 + $t_outpkts` # accumulate out packets + shift + t_outerrs=`expr $1 + $t_outerrs` # accumulate out errors + shift + t_colls=`expr $1 + $t_colls` # accumulate collisions + i=`expr $i + 1 ` + done + printf "\n%8s %8s %8s %8s %8s %8s \n" \ + total $t_inpkts $t_inerrs $t_outpkts $t_outerrs $t_colls +# now check error and collision rate. +# Use awk to get floating point accuracy + echo $t_colls $t_outpkts $t_inerrs $t_inpkts | awk '$2 != 0 { + collision_rate = $1 / $2; + printf("\n\ncollision rate ( %g %% )", (collision_rate * 100.0)); + if ( collision_rate > 0.05 ) + printf(" too high. Add subnets.\n"); + else + printf("\n")} + $4 != 0 { + error_rate = $3 / $4; + printf(" error rate ( %g %% )", (error_rate * 100.0)); + if (error_rate > 0.00025) + printf(" too high. Check cabling.\n"); + else + printf("\n")}' + + ) +} + +################################################## +# check network - works for SUNOS 4.x +################################################## +check_network1() { + echo " time inpkts inerrs outpkts outerrs colls" + netstat -i -I $interface $interval | ( + (line ; line ; line) > /dev/null + t_inpkts=0 # initialize counter + t_inerrs=0 # initialize counter + t_outpkts=0 # initialize counter + t_outerrs=0 # initialize counter + t_colls=0 # initialize counter + i=0 + while test $i -lt $count ; do # for each of the lines + time=`date +%T` + /bin/echo -n $time + set -- `line` # get the line + echo " $1 $2 $3 $4 $5" + t_inpkts=`expr $1 + $t_inpkts` # accumulate in packets + shift + t_inerrs=`expr $1 + $t_inerrs` # accumulate in errors + shift + t_outpkts=`expr $1 + $t_outpkts` # accumulate out packets + shift + t_outerrs=`expr $1 + $t_outerrs` # accumulate out errors + shift + t_colls=`expr $1 + $t_colls` # accumulate collisions + i=`expr $i + 1 ` + done + echo -n "total " + echo -n "$t_inpkts $t_inerrs $t_outpkts " + echo " $t_outerrs $t_colls" +# now check error and collision rate. +# Use awk to get floating point accuracy + echo $t_colls $t_outpkts $t_inerrs $t_inpkts | awk '$2 != 0 { + collision_rate = $1 / $2; + printf("\n\ncollision rate ( %g %% )", (collision_rate * 100.0)); + if ( collision_rate > 0.05 ) + printf(" too high. Add subnets.\n"); + else + printf("\n")} + $4 != 0 { + error_rate = $3 / $4; + printf(" error rate ( %g %% )", (error_rate * 100.0)); + if (error_rate > 0.00025) + printf(" too high. Check cabling.\n"); + else + printf("\n")}' + + ) +} + +######################################################## +# establish file partition -> disk device mapping for solaris +# how do I do this for other platforms? +######################################################## +do_discs() +{ +df -F ufs +df -F ufs | cut -f1 -d: | awk '{print $2}' | sed 's/(//' |\ + sed 's/)//' > /tmp/lll +for i in `cat /tmp/lll` +do + ls -l $i +done +rm /tmp/lll +cat /etc/path_to_inst +} + +######################################################## +# calculate the size (in bytes) of all VOB database on this host +######################################################## +check_vobs() +{ +if [ ! -f $ATRIAHOME/bin/cleartool ] ; then + echo this is not a ClearCase host + exit +fi +# list all vobs on this host and extract the +# VOB storage directory. +$ATRIAHOME/bin/cleartool lsvob -host $HOST +$ATRIAHOME/bin/cleartool lsvob -host $HOST | \ +awk '$1 == "*" {print $3 } \ + $1 != "*" {print $2 }' >/tmp/list.$$ +# count the vobs +vobs=`wc -l /tmp/list.$$ | awk '{print $1}'` +echo "Number of vobs : $vobs" +if [ $vobs = 0 ] ; then + return +fi +# now count all the bytes in the database data and key files +for i in `cat /tmp/list.$$` +do + cd $i/db + $LSL vob_db.d0? vob_db.k0? | \ + awk 'BEGIN {sum=0} \ + {sum = sum + $5} \ + END {printf "%12d\t", sum}' + echo `basename $i` +done | tee -a /tmp/list1.$$ + +awk 'BEGIN {sum=0} \ +{sum = sum + $1} \ +END {printf "%12d\tTOTAL", sum}' < /tmp/list1.$$ + +rm /tmp/list.$$ /tmp/list1.$$ +} + +######################################################## +# check the view characteristics +######################################################## +check_views() +{ +if [ ! -f $ATRIAHOME/bin/cleartool ] ; then + echo this is not a ClearCase host + exit +fi +$ATRIAHOME/bin/cleartool lsview -host $HOST | \ +awk '$1 == "*" {print $3,$2 } \ + $1 != "*" {print $2,$1 }' >/tmp/list.$$ +# count the views +views=`wc -l /tmp/list.$$ | awk '{print $1}'` +echo "Number of views : $views" +if [ $views = 0 ] ; then + return +fi +cat /tmp/list.$$ | ( +i=1 +while [ $i -le $views ] +do + set -- `line`; + size=`grep -s cache $1/.view | awk '{print $2}'` + if [ a$size = a ]; then + size=default + fi + echo "$size $2" | awk '{printf "%8s\t%-16s\n", $1, $2}' + i=`expr $i + 1` +done +) +rm /tmp/list.$$ +} + +######################################################## +# check the MVFS cache on this system +######################################################## +check_mvfs() +{ +/usr/atria/etc/mvfsstat -iclrh 2>&1 +} + +######################################################## +# check clearcase things +######################################################## +check_cc() +{ +ATRIAHOME=${ATRIAHOME:-/usr/atria} + show "VOB sizes" check_vobs + show "Views" check_views + show "MVFS" check_mvfs + show "Cleartool Version" $ATRIAHOME/bin/cleartool -ver +} + +######################################################## +# obtain mvs parameters +######################################################## + +get_mvfs_sun4() +{ +adb -k /var/adm/atria/vmunix_mvfs /dev/mem </dev/null < by Andrew@DeFaria.com +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +function usage { + print "usage: $me: [ -verbose | -v ] [ -size | -s n ] [ ]" + print "\t\t[ -top n | -t n ] [ -notop | -not ]\n" + print "Where:" + print " -size | -s n\tShow only files bigger then n Meg (default 1 Meg)" + print " -verbose | -v\tTurn on verbose mode (default verbose off)" + print " -top | -t n\tPrint out only the top n largest files (default LINES - 1)" + print " -notop|not\tPrint out all files (default top LINES - 1)" + print " \tFilesystems to check (default all hfs filesystems)" + exit +} # usage + +filesystems= +verbose=off +integer top_n +lines=${LINES:-25} +let top_n=$lines-1 +bytes_in_meg=1048576 +block_size=512 + +# Now get parms +integer size_in_meg=1 +integer size=$size_in_meg*$bytes_in_meg/$block_size + +while [ $# -gt 0 ]; do + case "$1" in + -size|-s) + shift + size_in_meg=$1 + # Convert size to 512 blocks + size=$size_in_meg*$bytes_in_meg/$block_size + shift + ;; + + -usage) + usage + ;; + + -top|-t) + shift + top_n=$1 + shift + ;; + + -notop|-not) + top_n=0 + shift + ;; + + -verbose|-v) + verbose=on + shift + ;; + + -*) + print -u2 "$me: Error: Unknown option $1" + print + usage + ;; + + *) + filesystems="$filesystems $1" + shift + ;; + esac +done + +if [ "_$filesystems" = "_" ]; then + i=1 + df -k -F ufs | while read line; do + if [ $i -gt 1 ]; then + filesystems="$filesystems $(echo $line | awk '{print $6}')" + fi + let i=$i+1 + done +fi + +# Now do the find +if [ $verbose = "on" ]; then + print "Filesystems:\t$filesystems" + print "Size:\t\t$size_in_meg Meg ($size blocks)" + print "Top:\t\t$top_n" +fi + +if [ $top_n -eq 0 ]; then + head_cmd="cat" +else + head_cmd="head -$top_n" +fi + +find $filesystems -xdev -size +$size -exec ls -l {} \; |\ + sort +nr5 | awk '{ printf ("%.3f %s\t%s\n", $5/(1024*1024), $3, $9) }' | + $head_cmd diff --git a/clients/HP/bin/buildservers b/clients/HP/bin/buildservers new file mode 100644 index 0000000..0eb3072 --- /dev/null +++ b/clients/HP/bin/buildservers @@ -0,0 +1,39 @@ +#!/bin/ksh +################################################################################ +# +# File: buildservers +# RCS: $Header: buildservers,v 1.3 98/01/28 12:21:43 defaria Exp $ +# Description: A script to execute a command on all build servers. +# Author: Andrew DeFaria, California Language Labs +# Created: Wed Mar 5 16:31:13 PST 1997 +# Modified: Fri Jan 16 13:51:43 PST 1998 +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +PATH=/adm/bin:$PATH + +if [ "$1" = "-r" ]; then + root=yes + shift +fi + +for buildserver in $(get_info server_names buildserver); do + # Execute command. Note if no command is given then the effect is to + # rlogin to each machine. + print "$buildserver:$@" + if [ $# -gt 0 ]; then + if [ -z "$root" ]; then + remsh $buildserver -n "$@" + else + root remsh $buildserver -n "$@" + fi + else + if [ -z "$root" ]; then + remsh $buildserver + else + root remsh $buildserver + fi + fi +done diff --git a/clients/HP/bin/check_security b/clients/HP/bin/check_security new file mode 100644 index 0000000..b20008c --- /dev/null +++ b/clients/HP/bin/check_security @@ -0,0 +1,93 @@ +#! /bin/ksh +USAGE='USAGE: check_security + + This script checks for some security problems. It does + not fix anything. It only prints messages about possible + problems. + + Author: Michael Coulter +' + +# Set parameters + + PASSWD_FILE=/etc/passwd + +# Check for execution by root + + WHOAMI=$(whoami) + if [ "$WHOAMI" != "root" ] + then + echo "It is recommended that you run this script as root" + fi + +# Parse all the lines in $PASSWD_FILE + + OLD_IFS="$IFS" + IFS=":" + cat "$PASSWD_FILE" | while read USER PASSWORD UID GID COMMENT HOME SHELL REST + do + # Checks for users who shouldn't log-in, i.e. PASSWORD is "*" + + if [ "$PASSWORD" = '*' ] + then + # If the PASSWORD is "*", there should not be a .rhosts or hosts.equiv + # in the home directory or .forward + if [ -f "${HOME}/.rhosts" ] + then + echo "$USER has a .rhosts file in $HOME" + fi + if [ -f "${HOME}/.forward" ] + then + echo "$USER has a .forward file in $HOME" + fi + + + + # There should not be a crontab or atjob for the user + + if [ -f "/usr/spool/cron/crontabs/${USER}" ] + then + echo "$USER has a crontab file in /usr/spool/cron/crontabs" + fi + if [ -f "/usr/spool/cron/atjobs/${USER}" ] + then + echo "$USER has a crontab file in /usr/spool/cron/atjobs" + fi + + fi # End of * password checks + + if [ "$PASSWORD" = "" ] + then + echo "$USER has a NULL password." + fi + + # No wildcards in $HOME/.rhosts or /etc/host.equiv + LINES="$(sed -e "/^#/d" $HOME/.rhosts | grep "+" 2> /dev/null | wc -l)" + if [ "$LINES" -ne 0 ] + then + echo "$USER has + in $HOME/.rhosts" + fi + + done + # read USER PASSWORD UID GID COMMENT HOME SHELL REST + +# Checks that are only done once + +# Check no wildcards in /etc/host.equiv + + LINES="$(grep -- "+" /etc/host.equiv 2> /dev/null | wc -l)" + if [ "$LINES" -ne 0 ] + then + echo "System has + in /etc/host.equiv" + fi + + if [ ! -f "/usr/adm/inetd.sec" ] + then + echo "No /usr/adm/inetd.sec file. " + fi + + if [ -f "/etc/hosts.equiv" ] + then + echo "System has a /etc/hosts.equiv file" + fi + diff --git a/clients/HP/bin/cleantmps b/clients/HP/bin/cleantmps new file mode 100644 index 0000000..fc9a35f --- /dev/null +++ b/clients/HP/bin/cleantmps @@ -0,0 +1,59 @@ +#!/bin/ksh +# +# $Header: cleantmps,v 1.14 97/07/24 12:17:34 root Exp $ +# +# +# This is a shell script to clean up files that clutter the tmp directories +# and garbage files that take up a lot of space (e.g., core files). +# +# +# Clean up specific garbage files, old log files +# +find /tmp -mountstop -mtime +1 -name "sh[1-9]*.[1-9]*" -exec rm {} \; +find /tmp -mountstop -mtime +3 -name "*~" -exec rm {} \; +find /tmp -mountstop -mtime +3 -name "eXT*" -exec rm {} \; +find /tmp -mountstop -mtime +3 -name "clr*" -exec rm {} \; +find /var/tmp -mountstop -mtime +3 -name "*~" -exec rm {} \; +find /tmp -mountstop -mtime +7 -name "crout*" -exec rm {} \; +find /var/tmp -mountstop -mtime +7 -name "cscope[0-9]*" -exec rm {} \; + +# +# Delete crash core dumps and kernel backups (leave behind INDEX (log) file) +# +find /var/adm/crash -type f -name "core.*" -exec rm {} \; +find /var/adm/crash -type f -name "vmunix*" -exec rm {} \; + +# +# General aging of everything in /tmp +# + +# Preserve sockets and certain files which I don't want to age away +find /tmp -mountstop -depth -mtime +7 ! -type d ! -type s ! -type p | + egrep -v "\.log$|\.X11-unix" | xargs -n25 rm + +# Try to remove directories -- only empty ones will actually get removed. +find /tmp -mountstop -depth -type d ! -name lost+found -print | + xargs -i -n25 rmdir -f {} 2>/dev/null + +# +# Search entire filesystem for files which are automatically cleaned up. +# +# Remove #* and core files. Exclude *.flc (emacs font-lock (fast-lock) +# files, which can start with '#'). +# +find / \( -fsonly hfs -o -fsonly vxfs \) -mtime +3 -type f \ +\( -name "#*" -o -name "core" \) ! -name "*.flc" | xargs rm -f + +# PJJ NOTE ON THE ABOVE COMMAND: +# +# By including only hfs and vxfs filesystems, we avoid descending NFS or +MVFS +# (ClearCase) mount points. We don't use "! -fstype nfs" -- that would +still +# descend NFS mounts, looking for HFS/VxFS mounted underneath. One could +# argue that it's preferable to do something like +# +# find / \( -fstype nfs -o -fstype mvfs \) -prune -o -mtime +3 ... +# +# (i.e., only list filesystem types to exclude), but the mention of mvfs +# would cause the command to fail on hosts which don't have ClearCase. diff --git a/clients/HP/bin/config_disk_array b/clients/HP/bin/config_disk_array new file mode 100644 index 0000000..528aff9 --- /dev/null +++ b/clients/HP/bin/config_disk_array @@ -0,0 +1,189 @@ +#!/usr/bin/ksh +################################################################################ +# +# File: config_disk_array +# RCS: $Header: config_disk_array,v 1.2 97/04/21 13:27:19 defaria Exp $ +# Description: A script to configure a NIKE Model 20 Disk Array +# Author: Andrew DeFaria, California Language Labs +# Created: Tue Jan 28 15:59:11 PST 1997 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: Must be root to execute this command!" + exit 1 +fi + +# Get parametes +primary_disk= +mirror_disk= +while [ $# -ge 1 ]; do + case "$1" in + -p) + if [ $# -le 1 ]; then + print -u2 "$me: Error: Primary disk not specified" + fi + shift + primary_disk="$1" + ;; + + -m) + if [ $# -le 1 ]; then + print -u2 "$me: Error: Mirror disk not specified" + fi + shift + mirror_disk="$1" + ;; + + -d|-debug) + debug=yes + ;; + + *) + print -u2 "$me: Error: Unknown parameter found ($1)" + exit 1 + ;; + esac + shift +done + +print "This script will configure the NIKE Model 20 Disk Array" + +if [ "_$primary_disk" != "_" ]; then + print "The primary disk is at: /dev/dsk/$primary_disk" +fi + +if [ "_$mirror_disk" != "_" ]; then + print "The mirror disk is at: /dev/dsk/$mirror_disk" +fi + +print + +if [ "_$primary_disk" = "_" -a "_$mirror_disk" = "_" ]; then + print -u2 "Nothing to do!" + exit 1 +fi + +answer=y +print "Are these settings correct (Y/n)?\c" +read answer + +if [ "$answer" != "y" -a "$answer" != "Y" ]; then + print -u2 "Nothing done" + exit 1 +fi + +# First create the mirror disk +if [ "_$mirror_disk" != "_" ]; then + print "Creating the mirror disk" + /sbin/pvcreate -f /dev/rdsk/$mirror_disk + status=$? + + if [ $status -eq 0 ]; then + print "Mirror disk created" + else + print "Unable to create mirror disk (Status: $status)" + exit 1 + fi +fi + +# Create Physical Volume Groups +if [ "_$primary_disk" != "_" ]; then + print "Creating Physical Volume Groups" + /sbin/vgextend -g primary /dev/vgvobs /dev/dsk/$primary_disk + status=$? + + # Ignore the warning about the volume already being created (Status: 2) + if [ $status -eq 0 -o $status -eq 2 ]; then + print "Physical Volume Group \"primary\" created" + else + print "Unable to create Physical Volume Group \"primary\" (Status: $status)" + exit 1 + fi +fi + +if [ "_$mirror_disk" != "_" ]; then + /sbin/vgextend -g mirror /dev/vgvobs /dev/dsk/$mirror_disk + status=$? + + if [ $status -eq 0 ]; then + print "Physical Volume Group \"mirror\" created" + else + print "Unable to create Physical Volume Group \"mirror\" (Status: $status)" + exit 1 + fi +fi + +if [ "_$primary_disk" = "_" ]; then + exit +fi + +# Create CLO logical volume +print "Creating CLO Logical Volume" + +if [ "_$mirror_disk" = "_" ]; then + /sbin/lvcreate -l 3004 -n CLO -r y -C n -s y -p w -d p vgvobs +else + /sbin/lvcreate -l 3004 -n CLO -m 1 -r y -C n -M y -s g -p w -d p vgvobs +fi + +status=$? + +if [ $status -eq 0 ]; then + print "CLO Logical Volume created" +else + print "Unable to create CLO Logical Volume (Status: $status)" + exit 1 +fi + +# Create the file system +print "Creating file system on CLO Logical Volume" +/usr/sbin/newfs -F hfs -L -i 6144 -m 5 /dev/vgvobs/rCLO +status=$? + +if [ $status -eq 0 ]; then + print "File system for CLO Logical Volume created" +else + print "Unable to create file system for CLO Logical Volume (Status: $status)" + exit 1 +fi + +# Mount the new CLO logical volume +print "Mounting CLO Logical Volume" +mkdir -p /CLO +/usr/sbin/mount -o rw,suid, -F hfs /dev/vgvobs/CLO /CLO +status=$? + +if [ $status -eq 0 ]; then + print "CLO Logical Volume mounted" +else + print "Unable to mount CLO Logical Volume (Status: $status)" + exit 1 +fi + +# Add the /etc/fstab entry +print "/dev/vgvobs/CLO /CLO hfs rw,suid 0 2" >> /etc/fstab +print "Added CLO Logical Volume to /etc/fstab" + +# Add the /etc/exports entry +print "/CLO -async" >> /etc/exports +print "Added CLO Logical Volume to /etc/exports as -async" + +# Export /CLO +print "Exporting CLO Logical Volume" +/usr/sbin/exportfs -a +status=$? + +if [ $status -eq 0 ]; then + print "CLO Logical Volume exported" +else + print "Unable to export CLO Logical Volume (Status: $status)" + exit 1 +fi + +print "Done" diff --git a/clients/HP/bin/configure_machine b/clients/HP/bin/configure_machine new file mode 100644 index 0000000..7adc6aa --- /dev/null +++ b/clients/HP/bin/configure_machine @@ -0,0 +1,325 @@ +#!/bin/ksh +################################################################################ +# +# File: configure_machine +# Description: A script to set up the "admin" environment +# Author: Andrew@DeFaria.com +# Created: Tue Apr 15 14:20:02 PDT 1997 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +if [ ! -d /adm ]; then + if [ ! -d "$adm_base" ]; then + print -u2 "$me: Error: Unable to find \"adm\" path! - Exiting" + exit 1 + fi +fi + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Source in tmpfiles function +tmpprefix=${TMPDIR:-/tmp}/configure_machine.$$ +. $adm_fpath/tmpfiles +arm_trap + +verbose= +debug= +mode=check + +function usage { + info "$ME [-v|verbose] [-d|debug] [-usage]" + info " -v|verbose: Turns on verbose mode" + info " -d|debug: Turns on debug mode" + info " -f|ix: Turns on fix mode" + info " -c|heck: Turns on check mode (default)" + info " -usage: Print this usage message\n" + + error "$1" 1 +} # usage + +function symlink { + debug "ENTER symlink" + from="$1" + to="$2" + + if [ ! -h "$from" ]; then + if [ $mode = "fix" ]; then + verbose "Setting up symlink from $from -> $to" + ln -s "$to" "$from" + else + warning "$from link is not setup properly" 0 + fi + else + verbose "$from link is OK" + fi + + debug "EXIT symlink" +} # symlink + +function setup_symlinks { + debug "ENTER setup_symlinks" + + symlinks="\ +/adm $adm_base\ +" + print $symlinks | while read from to; do + symlink $from $to + done + + debug "EXIT setup_symlinks" +} # setup_symlinks + +function check_and_replace_file { + debug "ENTER check_and_replace_file" + master_file="$1" + check_file="$2" + permissions="$3" + owner_group="$4" + + if ! cmp -s $master_file $check_file; then + if [ $mode = "fix" ]; then + verbose "Fixing $check_file" + cp $master_file $check_file + chmod $permissions $check_file + chown $owner_group $check_file + else + warning "$check_file is not setup properly" 0 + fi + else + verbose "$check_file is OK" + fi + + debug "EXIT check_and_replace_file" +} # check_and_replace_file + +function check_nsswitch_conf { + debug "ENTER check_nsswitch_conf" + + sed 's/automount: files nis/automount: nis files/' \ + /etc/nsswitch.conf > $tmpprefix.nsswitch.conf + + check_and_replace_file $tmpprefix.nsswitch.conf /etc/nsswitch.conf 444 +root:adm + + debug "EXIT check_nsswitch_conf" +} # check_nsswitch_conf + +function check_automount_maps { + debug "ENTER check_automount_maps" + + for map in master home direct indirect; do + check_and_replace_file /adm/etc/auto_$map /etc/auto_$map 444 root:adm + done + + debug "EXIT check_automount_maps" +} # check_automount_maps + +function setup_rcfiles { + debug "ENTER setup_rcfiles" + local_src=$ADM_PATH/etc/init.d/local + local_dest=/etc/init.d/local + local_symlink=/etc/rc3.d/S99local + + if [ ! -x $local_dest ]; then + if [ $mode = "fix" ]; then + verbose "Creating $local_dest" + cp "$local_src" $local_dest + chown root:adm $local_dest + chmod 555 $local_dest + else + warning "$local_dest does not exist!" 0 + fi + else + verbose "$local_dest is OK" + fi + + if [ ! -h $local_symlink ]; then + if [ $mode = "fix" ]; then + verbose "Setting up $local_symlink" + ln -s $local_dest $local_symlink + else + warning "$local_symlink does not exist!" 0 + fi + else + verbose "$local_symlink is OK" + fi + + if [ ! -d /etc/Startup ]; then + if [ $mode = "fix" ]; then + verbose "Creating /etc/Startup directory" + mkdir /etc/Startup + chown root:adm /etc/Startup + # Note: Security would be better if this was 775... + chmod 777 /etc/Startup + else + warning "/etc/Startup does not exist!" 0 + fi + else + verbose "/etc/Startup is OK" + fi + + start_views_src=$ADM_PATH/clearcase/start_views + start_views_dest=/etc/Startup/start_views + + if [ ! -x $start_views_dest ]; then + if [ $mode = "fix" ]; then + verbose "Creating $start_views_dest" + cp "$start_views_src" $start_views_dest + chown root:adm $start_views_dest + chmod 555 $start_views_dest + else + warning "$start_views_dest does not exist!" 0 + fi + else + verbose "$start_views_dest is OK" + fi + + views_to_start_src=$ADM_PATH/clearcase/views_to_start + views_to_start_dest=/etc/views_to_start + + if [ ! -f $views_to_start_dest ]; then + if [ $mode = "fix" ]; then + verbose "Creating $views_to_start_dest" + cp "$views_to_start_src" $views_to_start_dest + chown root:adm $views_to_start_dest + chmod 555 $views_to_start_dest + else + warning "$views_to_start_dest does not exist!" 0 + fi + else + verbose "$views_to_start_dest is OK" + fi + + debug "EXIT setup_rcfiles" +} # setup_rcfiles + +function setup_root_rhosts { + debug "ENTER setup_root_rhosts" + root_rhosts_src="$ADM_PATH/etc/root_rhosts" + root_rhosts_dest="/.rhosts" + + if [ ! -f $root_rhosts_dest ]; then + if [ $mode = "fix" ]; then + verbose "Creating $root_rhosts_dest" + cp "$root_rhosts_src" $root_rhosts_dest + chown root:adm $root_rhosts_dest + chmod 400 $root_rhosts_dest + else + warning "$root_rhosts_dest does not exist!" 0 + fi + else + if is_root; then + if ! cmp -s $root_rhosts_src $root_rhosts_dest; then + if [ $mode = "fix" ]; then + verbose "Updating $root_rhosts_dest" + cp "$root_rhosts_src" $root_rhosts_dest + chown root:adm $root_rhosts_dest + chmod 400 $root_rhosts_dest + else + warning "Contents of $root_rhosts_dest is non standard!" 0 + fi + fi + else + verbose "$root_rhosts_dest is present" + verbose "Contents not check since you're not running as root" + fi + fi + + debug "EXIT setup_root_rhosts" +} # setup_root_rhosts + +function setup_root_profile { + debug "ENTER setup_root_profile" + if [ "$VENDOR" = "HP" ]; then + debug "RETURN setup_root_profile (Skip HP machines)" + return + fi + root_profile_src="$ADM_PATH/etc/root_profile" + root_profile_dest="/.profile" + + if [ ! -f $root_profile_dest ]; then + if [ $mode = "fix" ]; then + verbose "Creating $root_profile_dest" + cp "$root_profile_src" $root_profile_dest + chown root:adm $root_profile_dest + chmod 444 $root_profile_dest + else + warning "$root_profile_dest does not exist!" 0 + fi + else + if is_root; then + if ! cmp -s $root_profile_src $root_profile_dest; then + if [ $mode = "fix" ]; then + verbose "Updating $root_profile_dest" + cp "$root_profile_src" $root_profile_dest + chown root:adm $root_profile_dest + chmod 400 $root_profile_dest + else + warning "Contents of $root_profile_dest is non standard!" 0 + fi + fi + else + verbose "$root_profile_dest is present" + verbose "Contents not check since you're not running as root" + fi + fi + + debug "EXIT setup_root_profile" +} # setup_root_rhosts + +# Get parameters +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + -f|-fix) + mode=fix + ;; + + -c|-check) + mode=check + ;; + + *) + usage "Unrecognized parameter $1" + ;; + esac + shift +done + +if [ "$mode" = "fix" ]; then + if ! is_root; then + error "Must be root to execute this command in fix mode!" 2 + fi +fi + +verbose "Starting $me..." +setup_symlinks +check_nsswitch_conf +check_automount_maps +setup_rcfiles +setup_root_rhosts +setup_root_profile +verbose "$me completed" diff --git a/clients/HP/bin/cpucount b/clients/HP/bin/cpucount new file mode 100644 index 0000000..fab8e65 --- /dev/null +++ b/clients/HP/bin/cpucount @@ -0,0 +1,34 @@ +#!/usr/bin/ksh + +cpus=1 + +top -d 1 > /tmp/jwhzxz + +grep -q "\[B 1" /tmp/jwhzxz +if [ $? -eq 0 ]; then + cpus=2 +else + grep -q "\[B 2" /tmp/jwhzxz + if [ $? -eq 0 ]; then + cpus=3 + else + grep -q "\[B 3" /tmp/jwhzxz + if [ $? -eq 0 ]; then + cpus=4 + else + grep -q "\[B 4" /tmp/jwhzxz + if [ $? -eq 0 ]; then + cpus=5 + else + grep -q "\[B 5" /tmp/jwhzxz + if [ $? -eq 0 ]; then + cpus=6 + fi + fi + fi + fi +fi + +rm /tmp/jwhzxz + +echo $cpus diff --git a/clients/HP/bin/cygwin_setup b/clients/HP/bin/cygwin_setup new file mode 100644 index 0000000..d013848 --- /dev/null +++ b/clients/HP/bin/cygwin_setup @@ -0,0 +1,241 @@ +#!/bin/bash +################################################################################ +# +# File: cygwin_setup +# Description: This script will perform additional setup to configure the +# local machine into the cygwin enviornment for Salira +# Author: Andrew@DeFaria.com +# Created: Fri Oct 5 15:30:16 2001 +# Modified: +# Language: Bash Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Global variables +commonserver=sonscentral +commonarea=common +adm=//$commonserver/$commonarea/adm +homeserver=sonscentral +homeshare=users +ccserver=sons-clearcase +anonymous_ftp_server=sons-clearcase +viewshare=views +printerserver=sons-mrp +printers="\ + LJ4050PCL6\ + LJ45500-Color\ + LJ8150\ +" +defaultprinter=LJ8150 + +# Current machine's OS. +OS=$(uname -s | cut -f2 -d-) + +# Current machine's hostname +hostname=$(echo $(hostname) | tr [:upper:] [:lower:]) + +# Setup standard mounts +# +# Home directory +echo "Step 1 of 10: Setting up /home mount point" +mount -tsf //$homeserver/$homeshare /home + +# Clearcase views +echo "Step 2 of 10: Setting up /view mount point" +if [ $hostname = $ccserver ]; then + mount -tsf C:/ClearCaseStorage/Views /view +else + mount -tsf //$ccserver/$viewshare /view +fi + +# Set cygdrive prefix to /dev +echo "Step 3 of 10: Setting cygdrive-prefix to /dev" +mount -s --change-cygdrive-prefix /dev + +# Remove user level cygdrive-prefix (Need to do this with regedit +regedit /s \\\\$commonserver\\$commonarea\\FixCygwin.reg + +# Link passwd file +echo "Step 4 of 10: Create common password file" +if [ ! -f /etc/passwd.local ]; then + if [ ! -L /etc/passwd ]; then + cp /etc/passwd /etc/passwd.local + fi +fi + +if [ ! -L /etc/passwd ]; then + if [ "$OS" != "4.0" ]; then + rm /etc/passwd + ln -s //$commonserver/$commonarea/passwd /etc/passwd + else + cp //$commonserver/$commonarea/passwd /etc/passwd + fi +else + if [ "$OS" = "4.0" ]; then + # Fix up NT 4.0 machines (they don't like symlinked /etc/passwd files!) + rm /etc/passwd + cp //$commonserver/$commonarea/passwd /etc/passwd + fi +fi + +# Link group file +echo "Step 5 of 10: Create common group file" +if [ ! -f /etc/group.local ]; then + if [ ! -L /etc/group ]; then + cp /etc/group /etc/group.local + fi +fi + +if [ ! -L /etc/group ]; then + rm /etc/group + ln -s //$commonserver/$commonarea/group /etc/group +fi + +# Link /etc/profile +echo "Step 6 of 10: Linking /etc/profile to common profile file" +if [ ! -f /etc/profile.orig ]; then + if [ ! -L /etc/profile ]; then + cp /etc/profile /etc/profile.orig + fi +fi + +if [ ! -L /etc/profile ]; then + rm /etc/profile + ln -s //$commonserver/$commonarea/profile /etc/profile +fi + +# Setup printer mount +echo "Step 7 of 10: Setting up printers" +for printer in $printers; do + mount -bsf //$printerserver/$printer /dev/$printer +done + +# Mount default printer +mount -bsf //$printerserver/$defaultprinter /dev/lp + +# Install internet services +echo "Step 8 of 10: Installing internet services" + +# First save any pre-existing /etc/motd +if [ -f /etc/motd ]; then + cp /etc/motd /etc/motd.$$ +fi + +rm -f /etc/ftpusers /etc/ftpwelcome /etc/inetd.conf /etc/motd /etc/shells +iu-config > /dev/null + +# In order to allow anonymous ftp access we need to clear /etc/ftpusers. +# Do this only for the $anonymous_ftp_server for now +if [ $hostname = $anonymous_ftp_server ]; then + cat /dev/null > /etc/ftpusers +fi + +# Now replace that saved /etc/motd if it existed, otherwise remove the boring +# /etc/motd that iu-config creates. First check to see if the user has a +# personalized /etc/motd in /etc/motd.save +if [ -f /etc/motd.save ]; then + # User had a personalized motd so move it into place and remove any prior + # copies + mv /etc/motd.save /etc/motd + rm -f /etc/motd.$$ +elif [ -f /etc/motd.$$ ]; then + # Reinstall previous motd + # First update uname -a line + uname -a > /etc/motd + + # Remove old uname -a line if present + grep -ve "^cygwin" /etc/motd.$$ >> /etc/motd.$$ + + # Cleanup + rm -f /etc/motd.$$ +else + # No saved motd or previous motd. Remove /etc/motd which will cause us + # to prompt for the information later. + rm /etc/motd +fi + +# Need to hardlink /usr/bin/cygwin1.dll & /usr/sbin/cygwin1.dll +# 12/17/2001: Stopped hardlinking cygwin1.dll. Enforcing having Windows system +# environment variables instead. For this we need Cygwin's bin in the path. +# User should also set CYGWIN=ntsec in a Windows system environment variable. +if [ -f /usr/sbin/cygwin1.dll ]; then + rm -f /usr/sbin/cygwin1.dll + #ln /usr/bin/cygwin1.dll /usr/sbin/cygwin1.dll + echo "Warning: Please make sure that you have a Windows *SYSTEM* environment" + echo " variable named CYGWIN set to the value of \"ntsec\" and that" + echo " you have \bin inserted into the Windows *SYSTEM*" + echo " environment variable named PATH" +fi + +# Set up anonymous ftp iff we are on the $anonymous_ftp_server +if [ $hostname = $anonymous_ftp_server ]; then + # Toggle on write access to ~ftp/bin + chmod +w ~ftp/bin + + # Remove old copies of ls and cygwin1.dll + rm -f ~ftp/bin/ls.exe + rm -f ~ftp/bin/cygwin1.dll + + # Install new copies (Note hardlinks will not work here since ~ftp/bin is + # on another file system. Doing an ln simply does a copy anyway) + # 12/17/2001: Skipping copying of cygwin1.dll as noted above + cp /bin/cygwin1.dll ~ftp/bin/cygwin1.dll + cp /bin/ls.exe ~ftp/bin/ls.exe + + # Set security + chmod 555 ~ftp/bin/cygwin1.dll + chmod 111 ~ftp/bin/ls.exe + chown Administrator ~ftp/bin/cygwin1.dll + chown Administrator ~ftp/bin/ls.exe + chmod -w ~ftp/bin +fi + +# Install inetd as a service +/usr/sbin/inetd --install-as-service + +# Start inetd service +inetd_started=$(net start | grep -i inetd) + +if [ -z "$inetd_started" ]; then + net start inetd +fi + +# Setup SMTP +$adm/bin/setup_ssmtp + +# Setup cron +$adm/bin/setup_cron + +# Create /etc/motd +echo "Step 9 of 10: Gathering machine specific information" +if [ ! -f /etc/motd ]; then + $adm/bin/make_motd + made_motd=true +else + echo "Skipped: Machine info already gathered" +fi + +# Fixup /etc/ftpwelcome +host=$(hostname | tr [:upper:] [:lower:]) +echo "Welcome to $host's ftp service" > /etc/ftpwelcome + +# Update machines file +echo "Step 10 of 10: Registering this machine (This takes a few seconds)" +if [ ! -z "$made_motd" ]; then + $adm/bin/update_machine_info +else + echo "Skipped: Machine already registered" +fi + +# Sneaky other fixes... +# Link /bin/more.exe -> /bin/less.exe +if [ ! -L /bin/more.exe ]; then + ln -s /bin/less.exe /bin/more.exe +fi + +# Finished +echo "Done" diff --git a/clients/HP/bin/daily b/clients/HP/bin/daily new file mode 100644 index 0000000..ae93e19 --- /dev/null +++ b/clients/HP/bin/daily @@ -0,0 +1,151 @@ +#!/bin/ksh +################################################################################ +# +# File: daily +# Description: This is the daily cronjob for root +# Author: Andrew@DeFaria.com +# Created: Wed Jul 21 12:12:28 PDT 1999 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Add $adm_base/bin and $adm_base/clearcase PATH +export PATH=$adm_base/bin:$adm_base/clearcase:$PATH + +# Source in tmpfiles function +tmpprefix=${TMPDIR:-/tmp}/$me.$$ +tmpfile=$tmpprefix +. $adm_fpath/tmpfiles +arm_trap + +# Where logs are kept +logs=$adm_host/logs + +# Define admin_host. Admin_host is the machine where checks for the network +# as a whole are run (such as check_view_storage) +admin_host=dreamcicle # For now... + +verbose= +debug= + +function usage { + display "$me [-v|verbose] [-d|debug] [-u|usage] [-n|notify ]" + display " -v|verbose: Turns on verbose mode" + display " -d|debug: Turns on debug mode" + display " -u|usage: Print this usage message\n" + display " -n|notify: Who to notify of problems (default root)" + + error "$1" 1 +} # usage + +lab_admin=cdsadmin # For now +local_admin=cdsadmin + +function notify { + debug "ENTER notify" + who=$1 + logfile=$2 + + cat > $tmpfile <> $tmpfile + + mailx -s "Notice: $me cronjob discovered the following problems" $who < +$tmpfile + debug "EXIT notify" +} # notify + +# Get parameters +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + -n|-notify) + shift + if [ $# -lt 1 ]; then + error "Notify email address was unspecified!" 1 + fi + local_admin="$1" + ;; + + *) + usage "Unrecognized parameter $1" + ;; + esac + shift +done + +## Main +# Some common portions of log filenames: +host=$(uname -n) # System's name +date=$(date +%d) # Note we keep one month of rolling logs + +if [ "$host" = "$admin_host" ]; then + network_diskspace_log=$logs/network.diskspace.$date.log + verbose "Diskspace Report -> $network_diskspace_log" + diskspace -network > $network_diskspace_log 2>&1 + + if [ -s $network_diskspace_log ]; then + notify $lab_admin $network_diskspace_log + fi + + view_storage_log=$logs/viewstorage.$date.log + verbose "View Storage Report -> $view_storage_log" + check_view_storage > $view_storage_log 2>&1 + + if [ -s $view_storage_log ]; then + notify $lab_admin $view_storage_log + fi + + # Produce a viewspace report for all production view servers + viewservers="cds-sundev-rem canon" + + for viewserver in $viewservers; do + viewspace_log=$logs/$viewserver.viewspace.$date.log + verbose "Viewspace Report for $viewserver -> $viewspace_log" + viewspace -host $viewserver > $viewspace_log + done +fi + +# Checks run on all machines +local_diskspace_log=$logs/$host.diskspace.$date.log +verbose "Diskspace Report -> $local_diskspace_log" +diskspace -local > $local_diskspace_log 2>&1 + +if [ -s $local_diskspace_log ]; then + notify local_admin $local_diskspace_log +fi + +machine_configuration_log=$logs/$host.machine_configuration.$date.log +verbose "Machine Configuration Report -> $machine_configuration_log" 2>&1 & +configure_machine -f > $machine_configuraton_log 2>&1 + +if [ -s $machine_configuration_log ]; then + notify local_admin $machine_configuration_log +fi diff --git a/clients/HP/bin/desktopmach b/clients/HP/bin/desktopmach new file mode 100644 index 0000000..f128765 --- /dev/null +++ b/clients/HP/bin/desktopmach @@ -0,0 +1,60 @@ +#!/bin/ksh +################################################################################ +# +# File: desktopmach +# Description: A script to execute a command on all desktop class machines +# Author: Andrew@DeFaria.com +# Created: Thu May 11 11:08:24 PDT 2000 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Set machines +machines=${machines:-$adm_base/data/machines} + +if [ "$1" = "-f" ]; then + shift + machines="$1" + shift +fi + +PATH=/adm/bin:$PATH + +if [ "$1" = "-r" ]; then + root=yes + shift +fi + +for desktop_machine in $(grep -ve ^# $machines | grep :Desktop: | cut -d: +-f1); do + # Execute command. Note if no command is given then the effect is to + # rlogin to each machine. + print "$desktop_machine:$@" + if [ $# -gt 0 ]; then + if [ -z "$root" ]; then + remsh $desktop_machine -n "$@" + else + root remsh $desktop_machine -n "$@" + fi + else + if [ -z "$root" ]; then + remsh $desktop_machine + else + root remsh $desktop_machine + fi + fi +done diff --git a/clients/HP/bin/diskspace b/clients/HP/bin/diskspace new file mode 100644 index 0000000..3e2f3e2 --- /dev/null +++ b/clients/HP/bin/diskspace @@ -0,0 +1,112 @@ +#!/usr/bin/perl +################################################################################ +# +# File: diskspace +# Description: Check filesystems to see if they are becoming too full +# Author: Andrew@DeFaria.com +# Created: Fri Mar 12 10:17:44 PST 2004 +# Language: Perl +# Modifications: +# +# (c) Copyright 2004, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +use strict; +use warnings; +use File::Spec; + +my ($me, $abs_path, $lib_path, $bin_path, $log_path); + +BEGIN { + # Extract relative path and basename from script name. + $0 =~ /(.*)[\/\\](.*)/; + + $abs_path = (!defined $1) ? "." : File::Spec->rel2abs ($1); + $me = (!defined $2) ? $0 : $2; + + # Setup paths + $bin_path = "$abs_path"; + $lib_path = "$abs_path/../../lib"; + $log_path = "$abs_path/../../log"; + + # Add the appropriate path to our modules to @INC array. + unshift (@INC, "$lib_path"); +} # BEGIN + +use Display; + +my $threshold = 90; + +sub Usage { + my $msg = shift; + + display "ERROR: $msg\n" if defined $msg; + + display "$me\t[-v] [-d] [-u] [ -n | -l ]"; + display "\t-v\tTurn on verbose mode"; + display "\t-d\tTurn on debug mode"; + display "\t-u\tThis usage message"; + display "\t-t\tThreshold (0-100)"; + + exit 1; +} # Usage + +sub CheckFilesystemSpace { + my $filesystem = shift; + + # Isolate the disk usage line + my @diskusage = `df -k $filesystem`; + + # Get fields + $_ = $diskusage [1]; + my ($fs, $blocks, $used, $available, $used_percent, $mounted_on) = split; + + if ($used_percent =~ /(\d+)%/) { + $used_percent = $1; + } # if + + $available = sprintf ("%.3f", $available / 1024); + + # Check if over threshold and report + if ($used_percent <= $threshold ) { + verbose "$mounted_on is $used_percent% full - $available Megs left"; + } else { + warning "$mounted_on is $used_percent% full - $available Megs left"; + } # if +} # CheckFilesystemSpace + +sub CheckLocalFilesystems { + my @local_filesystems = `df -k`; + + @local_filesystems = grep {/^\/dev/} @local_filesystems; + + foreach (@local_filesystems) { + my ($fs, $blocks, $used, $available, $used_percent, $mounted_on) = split; + CheckFilesystemSpace $mounted_on; + } # foreach +} # CheckLocalFilesystems + +# Get parameters +while ($ARGV [0]) { + if ($ARGV [0] eq "-v") { + set_verbose; + } elsif ($ARGV [0] eq "-d") { + set_debug; + } elsif ($ARGV [0] eq "-t") { + shift (@ARGV); + if (!$ARGV [0]) { + Usage "Must specify threshold after -t"; + } else { + $threshold = $ARGV [0]; + } # if + } elsif ($ARGV [0] eq "-u") { + Usage; + } else { + Usage "Unknown argument found: " . $ARGV [0]; + } # if + + shift (@ARGV); +} # while + +debug "Theshold: $threshold"; +CheckLocalFilesystems; diff --git a/clients/HP/bin/display_path b/clients/HP/bin/display_path new file mode 100644 index 0000000..df825dc --- /dev/null +++ b/clients/HP/bin/display_path @@ -0,0 +1,32 @@ +#!/bin/bash +################################################################################ +# +# File: display_path +# Description: Displays the components in PATH +# Author: Andrew@DeFaria.com +# Language: Bash Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved. +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +declare -i i=0 + +for path_component in $(echo $PATH | tr ":" "\n"); do + let i=i+1 + if [ $i -eq 1 ]; then + display "PATH consists of the following components:\n" + fi + display "\t$i) $path_component" +done | more diff --git a/clients/HP/bin/dum b/clients/HP/bin/dum new file mode 100644 index 0000000..48e445e --- /dev/null +++ b/clients/HP/bin/dum @@ -0,0 +1,19 @@ +#!/bin/bash +################################################################################ +# +# File: dum +# Description: Outputs disk usage in Megabytes (what a concept! :-) +# Author: Andrew@DeFaria.com +# Created: Mon Nov 13 16:14:30 1995 +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +lines=${LINES:-24} +du "$@" 2> /dev/null | + sort -nr | + awk '{ + filename=substr ($0, length ($1) + 2, (length ($0) - length ($1)) - 1); + printf "%.3f%s%s\n", $1/1024, "\t", filename + }' | + head -$lines diff --git a/clients/HP/bin/fix_automounts b/clients/HP/bin/fix_automounts new file mode 100644 index 0000000..ec1ac67 --- /dev/null +++ b/clients/HP/bin/fix_automounts @@ -0,0 +1,91 @@ +#!/bin/ksh +################################################################################ +# +# File: fix_automounts +# Description: Remounts exported file systems from a machine +# Author: Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# Created: Tue Apr 21 11:59:57 PDT 1998 +# Status: Experimental (Do Not Distribute) +# Modifications: Removed the grep "(everyone)". In the past file systems were +# exported to everyone and that is no longer the case. This does +# mean that this script might attempt to mount things it can't +# but there is no easy way to ascertain if the current machine +# is allowed to mount given showmount -e output, especially if +# that output is a netgroup. I could check this via ypmatch +# but that'll take yet more smarts... +# Andrew@DeFaria.com +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: You must be root to execute this command!" + exit 1 +fi + +if [[ "$OS" = "10" ]] ; then + mount=/usr/sbin/mount +else + mount=/etc/mount +fi + +if [ $# -lt 1 ]; then + print -u2 "Usage: [ ]" + exit 1 +fi + +function remount_filesystem { + machine=$1 + mount_directory=$2 + mount_over_directory=/tmp_mnt/net/$machine$2 + if [ ! -d $mount_over_directory ]; then + print Making $mount_over_directory + mkdir -p $mount_over_directory + fi + + if [ ! -d $mount_over_directory/lost+found ]; then + print Mounting $machine:$mount_directory to $mount_over_directory + $mount $machine:$mount_directory $mount_over_directory + status=$? + if [ $status -ne 0 ]; then + print -u2 "Warning: Unable to mount $machine:$mount_directory +$mount_over_directory (Status: $?)" + fi + fi +} # remount_filesystem + +function kick_automounter { + automount_pid=$(ps -ef | grep automount | grep -v "grep automount" | grep -v "fix_automounts" | awk '{print $2}') + + print Kicking automounter \($automount_pid\) + kill -HUP $automount_pid +} # kick_automounter + +if [ "$OS" = "10" ]; then + showmount=/usr/sbin/showmount +else + showmount=/usr/etc/showmount +fi + +for remote in "$@"; do + exported_filesystems=$($showmount -e $remote | grep -v "export list" | + cut -f1 -d' ') + for filesystem in $exported_filesystems; do + remount_filesystem $remote $filesystem + done +done + +kick_automounter diff --git a/clients/HP/bin/fix_startup b/clients/HP/bin/fix_startup new file mode 100644 index 0000000..41722b2 --- /dev/null +++ b/clients/HP/bin/fix_startup @@ -0,0 +1,53 @@ +#!/bin/ksh +################################################################################ +# +# File: fixr_startup +# Description: This script will fix the local startup scripts. Thist is done +# by moving them from /sbin/rc2.d to /sbin/rc3.d where they +# really belong. +# Author: Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# First source /app/appserver +if [ -x /app/appserver ]; then + . /app/appserver +fi + +if [ $(id -u) -ne 0 ]; then + print -u2 "Error: You must be root to execute this command!" + exit 1 +fi + +if [ "$OS" = "09" ]; then + print -u2 "Error: $(basename $0) does not run on 9.x!" + exit 1 +fi + +moved_a_file=no + +if [ -x /sbin/rc2.d/S900local ]; then + print "Moving /sbin/rc2.d/S900local \-> /sbin/rc3.d/S900local" + mv /sbin/rc2.d/S900local /sbin/rc3.d/S900local + moved_a_file=yes +fi + +if [ -x /sbin/rc2.d/S920start_views ]; then + print "Moving /sbin/rc2.d/S920start_views \-> /sbin/rc3.d/S770start_views" + mv /sbin/rc2.d/S920start_views /sbin/rc3.d/S770start_views + moved_a_file=yes +fi + +if [ -x /sbin/rc2.d/S910mount_additional_vobs ]; then + print "Moving /sbin/rc2.d/S910mount_additional_vobs \-> /sbin/rc3.d/S775mount_additional_vobs" + mv /sbin/rc2.d/S910mount_additional_vobs /sbin/rc3.d/S775mount_additional_vobs + moved_a_file=yes +fi + +if [ "$moved_a_file" = "no" ]; then + print "Startup scripts already in their proper places" +else + print "Fixed startup scripts" +fi diff --git a/clients/HP/bin/fixlocalaliases b/clients/HP/bin/fixlocalaliases new file mode 100644 index 0000000..e81a80a --- /dev/null +++ b/clients/HP/bin/fixlocalaliases @@ -0,0 +1,17 @@ +#!/bin/ksh + +echo "Now on `uname -n`" +grep "root: cll-support" /etc/mail/aliases >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo " No change" + exit 0; +fi + +echo " Changing aliases.local" +sed -e "s/root\: cll-support/root\: cll-root/" \ + -e "s/paladm\: cll-support/paladm\: cll-paladm/" \ + < /etc/mail/aliases.local > /tmp/aliases.local.new +mv /etc/mail/aliases.local /etc/mail/aliases.local.`date +"%m%d%y_%H%M%S"` +mv /tmp/aliases.local.new /etc/mail/aliases.local +chmod 644 /etc/mail/aliases.local +chown root:root /etc/mail/aliases.local diff --git a/clients/HP/bin/fixntp b/clients/HP/bin/fixntp new file mode 100644 index 0000000..1ed4538 --- /dev/null +++ b/clients/HP/bin/fixntp @@ -0,0 +1,43 @@ +#!/bin/ksh +################################################################################ +# +# File: fixntp +# Description: This script will fix /etc/rc.config.d/netdaemons to set +# NTPDATE_SERVER to cupertino.ntp.hp.com +# Author: Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# Modified: +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# First source /app/appserver +if [ -x /app/appserver ]; then + . /app/appserver +fi + +if [ $(id -u) -ne 0 ]; then + print -u2 "Error: You must be root to execute this command!" + exit 1 +fi + +if [ "$OS" = "09" ]; then + print -u2 "Error: $(basename $0) does not run on 9.x!" + exit 1 +fi + +netdaemons=/etc/rc.config.d/netdaemons +netdaemons_new=/etc/rc.config.d/netdaemons.$$ + +sed 's/NTPDATE_SERVER=$/NTPDATE_SERVER=cupertino.ntp.hp.com/' \ + $netdaemons > $netdaemons_new + +if cmp -s $netdaemons $netdaemons_new; then + rm -f $netdaemons_new + print "NTPDATE_SERVER already set properly - No fix needed!" +else + mv $netdaemons_new $netdaemons + chmod 555 $netdaemons + chown bin:bin $netdaemons + print "Changed NTPDATE_SERVER to be set properly" +fi diff --git a/clients/HP/bin/fixrhosts b/clients/HP/bin/fixrhosts new file mode 100644 index 0000000..120ac6e --- /dev/null +++ b/clients/HP/bin/fixrhosts @@ -0,0 +1,65 @@ +#!/bin/ksh +################################################################################ +# +# File: fixrhosts +# Description: Generates a new ~/.rhosts file +# Author: Andrew@DeFaria.com +# Created: Fri Apr 30 14:13:56 PDT 1999 +# Modifications: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Source in tmpfiles function +tmpprefix=${TMPDIR:-/tmp}/$me.$$ +. $adm_fpath/tmpfiles +trap cleanup INT EXIT ERR + +# Check if root +if is_root; then + error "You should not run the script as root!" 1 +fi + +rhosts=$HOME/.rhosts +rhosts_loc=$HOME/.rhosts.loc + +# Generate new $rhosts + +if [ -f $rhosts_loc ]; then + cp $rhosts_loc $rhosts +else + rm -f $rhosts +fi + +# Add netgroup +print "+@all-machines $LOGNAME" >> .rhosts + +# Insure proper permissions +chmod 600 $rhosts + +# Tell user of this scripts demise +display "\t\t\t*** NOTICE ***" +display +display "Since the lab now users NIS we are employing a different solution" +display "to the issue of providing passwordless logins to sets of machines" +display "via rlogin/remsh. This solution adds the following to $rhosts:" +display +display "\t+@all-machines $LOGNAME" +display +display "Thereafter running $me is unnecessary." +display +display "I'd like to take this opportunity to thank you for your support" +display "of $me! :-) " diff --git a/clients/HP/bin/fk1 b/clients/HP/bin/fk1 new file mode 100644 index 0000000..3ded632 --- /dev/null +++ b/clients/HP/bin/fk1 @@ -0,0 +1,98 @@ +#!/bin/ksh +################################################################################ +# +# File: .tep +# RCS: $Header: .tep,v 1.5 97/10/05 22:31:46 defaria Exp $ +# Description: Wrapper script to set function keys for the TEP Console +# Concentrators. +# Author: Andrew DeFaria, California Language Labs +# Created: Thu Jun 6 08:31:57 PDT 1996 +# Modified: Thu Jun 6 08:32:13 PDT 1996 (Andrew DeFaria) defaria@spock +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) +export esc=$(print "\033") +export cr=$(print "\015") + +if [ "$TERM" = "hpterm" \ + -o "$TERM" = "hp" \ + -o "$TERM" = "2394" \ + -o "$TERM" = "70096" ]; then + # Turn: + # . Enq/Ack: No + # . RecvPace: Xon/Xoff + # . InhHndShk (G): Yes + # . Inh DC2 (H): Yes + print "${esc}&q0n1h${esc}&s1g1H\c" + + if [ "$me" = fk1 ]; then + print "\ +${esc}&f1k2a16d7L Young hpcleareQQQQT1${cr}\ +${esc}&f2k2a16d7L Loomis hpclsv1 QQQQT2${cr}\ +${esc}&f3k2a16d7L hpcll237QQQQT3${cr}\ +${esc}&f4k2a16d7L Stablerhpclear1QQQQT4${cr}\ +${esc}&f5k2a16d7L Unitas hpclear3QQQQT5${cr}\ +${esc}&f6k2a16d7L Griese hpclear5QQQQT6${cr}\ +${esc}&f7k2a16d7L Simms hpclear7QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk2 ]; then + print "\ +${esc}&f1k2a16d7LDynamitehpclldynQQQQT1${cr}\ +${esc}&f2k2a16d7L Mobius hpclang6QQQQT2${cr}\ +${esc}&f3k2a16d7L Starr hpclearnQQQQT3${cr}\ +${esc}&f4k2a16d7L hpcll208QQQQT4${cr}\ +${esc}&f5k2a16d7LTarkentnhpclear9QQQQT5${cr}\ +${esc}&f6k2a16d7L Veil QQQQT6${cr}\ +${esc}&f7k2a16d7L Kilmer hpclearkQQQQT7${cr}\ +${esc}&f8k2a16d7L hpcll207QQQQT8${cr}\c" + elif [ $me = fk3 ]; then + print "\ +${esc}&f1k2a16d7LDuchess QQQQT1${cr}\ +${esc}&f2k2a16d7LCatbert QQQQT2${cr}\ +${esc}&f3k2a16d7L Nala QQQQT3${cr}\ +${esc}&f4k2a16d7LPywacket QQQQT4${cr}\ +${esc}&f5k2a16d7L Alley QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk4 ]; then + print "\ +${esc}&f1k2a16d7L Wampus QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob01 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob02 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob03 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob04 QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk5 ]; then + print "\ +${esc}&f1k2a16d7Lcllvob05 QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob06 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob07 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob08 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob09 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllvob10 QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk6 ]; then + print "\ +${esc}&f1k2a16d7L Gideon QQQQT1${cr}\ +${esc}&f2k2a16d7L Oliver QQQQT2${cr}\ +${esc}&f3k2a16d7L Dinah QQQQT3${cr}\ +${esc}&f4k2a16d7LCheshire QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllbld01 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllbld02 QQQQT6${cr}\ +${esc}&f7k2a16d7Lcllbld03 QQQQT7${cr}\ +${esc}&f8k2a16d7Lhpcll321 QQQQT8${cr}\c" + fi + + # Turn on Function keys to see changes + print "${esc}&jB\c" +else + print -u2 "Sorry but the terminal type $TERM, is not supported" + exit 1 +fi diff --git a/clients/HP/bin/fk2 b/clients/HP/bin/fk2 new file mode 100644 index 0000000..3ded632 --- /dev/null +++ b/clients/HP/bin/fk2 @@ -0,0 +1,98 @@ +#!/bin/ksh +################################################################################ +# +# File: .tep +# RCS: $Header: .tep,v 1.5 97/10/05 22:31:46 defaria Exp $ +# Description: Wrapper script to set function keys for the TEP Console +# Concentrators. +# Author: Andrew DeFaria, California Language Labs +# Created: Thu Jun 6 08:31:57 PDT 1996 +# Modified: Thu Jun 6 08:32:13 PDT 1996 (Andrew DeFaria) defaria@spock +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) +export esc=$(print "\033") +export cr=$(print "\015") + +if [ "$TERM" = "hpterm" \ + -o "$TERM" = "hp" \ + -o "$TERM" = "2394" \ + -o "$TERM" = "70096" ]; then + # Turn: + # . Enq/Ack: No + # . RecvPace: Xon/Xoff + # . InhHndShk (G): Yes + # . Inh DC2 (H): Yes + print "${esc}&q0n1h${esc}&s1g1H\c" + + if [ "$me" = fk1 ]; then + print "\ +${esc}&f1k2a16d7L Young hpcleareQQQQT1${cr}\ +${esc}&f2k2a16d7L Loomis hpclsv1 QQQQT2${cr}\ +${esc}&f3k2a16d7L hpcll237QQQQT3${cr}\ +${esc}&f4k2a16d7L Stablerhpclear1QQQQT4${cr}\ +${esc}&f5k2a16d7L Unitas hpclear3QQQQT5${cr}\ +${esc}&f6k2a16d7L Griese hpclear5QQQQT6${cr}\ +${esc}&f7k2a16d7L Simms hpclear7QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk2 ]; then + print "\ +${esc}&f1k2a16d7LDynamitehpclldynQQQQT1${cr}\ +${esc}&f2k2a16d7L Mobius hpclang6QQQQT2${cr}\ +${esc}&f3k2a16d7L Starr hpclearnQQQQT3${cr}\ +${esc}&f4k2a16d7L hpcll208QQQQT4${cr}\ +${esc}&f5k2a16d7LTarkentnhpclear9QQQQT5${cr}\ +${esc}&f6k2a16d7L Veil QQQQT6${cr}\ +${esc}&f7k2a16d7L Kilmer hpclearkQQQQT7${cr}\ +${esc}&f8k2a16d7L hpcll207QQQQT8${cr}\c" + elif [ $me = fk3 ]; then + print "\ +${esc}&f1k2a16d7LDuchess QQQQT1${cr}\ +${esc}&f2k2a16d7LCatbert QQQQT2${cr}\ +${esc}&f3k2a16d7L Nala QQQQT3${cr}\ +${esc}&f4k2a16d7LPywacket QQQQT4${cr}\ +${esc}&f5k2a16d7L Alley QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk4 ]; then + print "\ +${esc}&f1k2a16d7L Wampus QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob01 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob02 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob03 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob04 QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk5 ]; then + print "\ +${esc}&f1k2a16d7Lcllvob05 QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob06 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob07 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob08 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob09 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllvob10 QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk6 ]; then + print "\ +${esc}&f1k2a16d7L Gideon QQQQT1${cr}\ +${esc}&f2k2a16d7L Oliver QQQQT2${cr}\ +${esc}&f3k2a16d7L Dinah QQQQT3${cr}\ +${esc}&f4k2a16d7LCheshire QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllbld01 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllbld02 QQQQT6${cr}\ +${esc}&f7k2a16d7Lcllbld03 QQQQT7${cr}\ +${esc}&f8k2a16d7Lhpcll321 QQQQT8${cr}\c" + fi + + # Turn on Function keys to see changes + print "${esc}&jB\c" +else + print -u2 "Sorry but the terminal type $TERM, is not supported" + exit 1 +fi diff --git a/clients/HP/bin/fk3 b/clients/HP/bin/fk3 new file mode 100644 index 0000000..3ded632 --- /dev/null +++ b/clients/HP/bin/fk3 @@ -0,0 +1,98 @@ +#!/bin/ksh +################################################################################ +# +# File: .tep +# RCS: $Header: .tep,v 1.5 97/10/05 22:31:46 defaria Exp $ +# Description: Wrapper script to set function keys for the TEP Console +# Concentrators. +# Author: Andrew DeFaria, California Language Labs +# Created: Thu Jun 6 08:31:57 PDT 1996 +# Modified: Thu Jun 6 08:32:13 PDT 1996 (Andrew DeFaria) defaria@spock +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) +export esc=$(print "\033") +export cr=$(print "\015") + +if [ "$TERM" = "hpterm" \ + -o "$TERM" = "hp" \ + -o "$TERM" = "2394" \ + -o "$TERM" = "70096" ]; then + # Turn: + # . Enq/Ack: No + # . RecvPace: Xon/Xoff + # . InhHndShk (G): Yes + # . Inh DC2 (H): Yes + print "${esc}&q0n1h${esc}&s1g1H\c" + + if [ "$me" = fk1 ]; then + print "\ +${esc}&f1k2a16d7L Young hpcleareQQQQT1${cr}\ +${esc}&f2k2a16d7L Loomis hpclsv1 QQQQT2${cr}\ +${esc}&f3k2a16d7L hpcll237QQQQT3${cr}\ +${esc}&f4k2a16d7L Stablerhpclear1QQQQT4${cr}\ +${esc}&f5k2a16d7L Unitas hpclear3QQQQT5${cr}\ +${esc}&f6k2a16d7L Griese hpclear5QQQQT6${cr}\ +${esc}&f7k2a16d7L Simms hpclear7QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk2 ]; then + print "\ +${esc}&f1k2a16d7LDynamitehpclldynQQQQT1${cr}\ +${esc}&f2k2a16d7L Mobius hpclang6QQQQT2${cr}\ +${esc}&f3k2a16d7L Starr hpclearnQQQQT3${cr}\ +${esc}&f4k2a16d7L hpcll208QQQQT4${cr}\ +${esc}&f5k2a16d7LTarkentnhpclear9QQQQT5${cr}\ +${esc}&f6k2a16d7L Veil QQQQT6${cr}\ +${esc}&f7k2a16d7L Kilmer hpclearkQQQQT7${cr}\ +${esc}&f8k2a16d7L hpcll207QQQQT8${cr}\c" + elif [ $me = fk3 ]; then + print "\ +${esc}&f1k2a16d7LDuchess QQQQT1${cr}\ +${esc}&f2k2a16d7LCatbert QQQQT2${cr}\ +${esc}&f3k2a16d7L Nala QQQQT3${cr}\ +${esc}&f4k2a16d7LPywacket QQQQT4${cr}\ +${esc}&f5k2a16d7L Alley QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk4 ]; then + print "\ +${esc}&f1k2a16d7L Wampus QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob01 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob02 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob03 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob04 QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk5 ]; then + print "\ +${esc}&f1k2a16d7Lcllvob05 QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob06 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob07 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob08 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob09 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllvob10 QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk6 ]; then + print "\ +${esc}&f1k2a16d7L Gideon QQQQT1${cr}\ +${esc}&f2k2a16d7L Oliver QQQQT2${cr}\ +${esc}&f3k2a16d7L Dinah QQQQT3${cr}\ +${esc}&f4k2a16d7LCheshire QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllbld01 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllbld02 QQQQT6${cr}\ +${esc}&f7k2a16d7Lcllbld03 QQQQT7${cr}\ +${esc}&f8k2a16d7Lhpcll321 QQQQT8${cr}\c" + fi + + # Turn on Function keys to see changes + print "${esc}&jB\c" +else + print -u2 "Sorry but the terminal type $TERM, is not supported" + exit 1 +fi diff --git a/clients/HP/bin/fk4 b/clients/HP/bin/fk4 new file mode 100644 index 0000000..3ded632 --- /dev/null +++ b/clients/HP/bin/fk4 @@ -0,0 +1,98 @@ +#!/bin/ksh +################################################################################ +# +# File: .tep +# RCS: $Header: .tep,v 1.5 97/10/05 22:31:46 defaria Exp $ +# Description: Wrapper script to set function keys for the TEP Console +# Concentrators. +# Author: Andrew DeFaria, California Language Labs +# Created: Thu Jun 6 08:31:57 PDT 1996 +# Modified: Thu Jun 6 08:32:13 PDT 1996 (Andrew DeFaria) defaria@spock +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) +export esc=$(print "\033") +export cr=$(print "\015") + +if [ "$TERM" = "hpterm" \ + -o "$TERM" = "hp" \ + -o "$TERM" = "2394" \ + -o "$TERM" = "70096" ]; then + # Turn: + # . Enq/Ack: No + # . RecvPace: Xon/Xoff + # . InhHndShk (G): Yes + # . Inh DC2 (H): Yes + print "${esc}&q0n1h${esc}&s1g1H\c" + + if [ "$me" = fk1 ]; then + print "\ +${esc}&f1k2a16d7L Young hpcleareQQQQT1${cr}\ +${esc}&f2k2a16d7L Loomis hpclsv1 QQQQT2${cr}\ +${esc}&f3k2a16d7L hpcll237QQQQT3${cr}\ +${esc}&f4k2a16d7L Stablerhpclear1QQQQT4${cr}\ +${esc}&f5k2a16d7L Unitas hpclear3QQQQT5${cr}\ +${esc}&f6k2a16d7L Griese hpclear5QQQQT6${cr}\ +${esc}&f7k2a16d7L Simms hpclear7QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk2 ]; then + print "\ +${esc}&f1k2a16d7LDynamitehpclldynQQQQT1${cr}\ +${esc}&f2k2a16d7L Mobius hpclang6QQQQT2${cr}\ +${esc}&f3k2a16d7L Starr hpclearnQQQQT3${cr}\ +${esc}&f4k2a16d7L hpcll208QQQQT4${cr}\ +${esc}&f5k2a16d7LTarkentnhpclear9QQQQT5${cr}\ +${esc}&f6k2a16d7L Veil QQQQT6${cr}\ +${esc}&f7k2a16d7L Kilmer hpclearkQQQQT7${cr}\ +${esc}&f8k2a16d7L hpcll207QQQQT8${cr}\c" + elif [ $me = fk3 ]; then + print "\ +${esc}&f1k2a16d7LDuchess QQQQT1${cr}\ +${esc}&f2k2a16d7LCatbert QQQQT2${cr}\ +${esc}&f3k2a16d7L Nala QQQQT3${cr}\ +${esc}&f4k2a16d7LPywacket QQQQT4${cr}\ +${esc}&f5k2a16d7L Alley QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk4 ]; then + print "\ +${esc}&f1k2a16d7L Wampus QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob01 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob02 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob03 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob04 QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk5 ]; then + print "\ +${esc}&f1k2a16d7Lcllvob05 QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob06 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob07 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob08 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob09 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllvob10 QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk6 ]; then + print "\ +${esc}&f1k2a16d7L Gideon QQQQT1${cr}\ +${esc}&f2k2a16d7L Oliver QQQQT2${cr}\ +${esc}&f3k2a16d7L Dinah QQQQT3${cr}\ +${esc}&f4k2a16d7LCheshire QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllbld01 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllbld02 QQQQT6${cr}\ +${esc}&f7k2a16d7Lcllbld03 QQQQT7${cr}\ +${esc}&f8k2a16d7Lhpcll321 QQQQT8${cr}\c" + fi + + # Turn on Function keys to see changes + print "${esc}&jB\c" +else + print -u2 "Sorry but the terminal type $TERM, is not supported" + exit 1 +fi diff --git a/clients/HP/bin/fk5 b/clients/HP/bin/fk5 new file mode 100644 index 0000000..3ded632 --- /dev/null +++ b/clients/HP/bin/fk5 @@ -0,0 +1,98 @@ +#!/bin/ksh +################################################################################ +# +# File: .tep +# RCS: $Header: .tep,v 1.5 97/10/05 22:31:46 defaria Exp $ +# Description: Wrapper script to set function keys for the TEP Console +# Concentrators. +# Author: Andrew DeFaria, California Language Labs +# Created: Thu Jun 6 08:31:57 PDT 1996 +# Modified: Thu Jun 6 08:32:13 PDT 1996 (Andrew DeFaria) defaria@spock +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) +export esc=$(print "\033") +export cr=$(print "\015") + +if [ "$TERM" = "hpterm" \ + -o "$TERM" = "hp" \ + -o "$TERM" = "2394" \ + -o "$TERM" = "70096" ]; then + # Turn: + # . Enq/Ack: No + # . RecvPace: Xon/Xoff + # . InhHndShk (G): Yes + # . Inh DC2 (H): Yes + print "${esc}&q0n1h${esc}&s1g1H\c" + + if [ "$me" = fk1 ]; then + print "\ +${esc}&f1k2a16d7L Young hpcleareQQQQT1${cr}\ +${esc}&f2k2a16d7L Loomis hpclsv1 QQQQT2${cr}\ +${esc}&f3k2a16d7L hpcll237QQQQT3${cr}\ +${esc}&f4k2a16d7L Stablerhpclear1QQQQT4${cr}\ +${esc}&f5k2a16d7L Unitas hpclear3QQQQT5${cr}\ +${esc}&f6k2a16d7L Griese hpclear5QQQQT6${cr}\ +${esc}&f7k2a16d7L Simms hpclear7QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk2 ]; then + print "\ +${esc}&f1k2a16d7LDynamitehpclldynQQQQT1${cr}\ +${esc}&f2k2a16d7L Mobius hpclang6QQQQT2${cr}\ +${esc}&f3k2a16d7L Starr hpclearnQQQQT3${cr}\ +${esc}&f4k2a16d7L hpcll208QQQQT4${cr}\ +${esc}&f5k2a16d7LTarkentnhpclear9QQQQT5${cr}\ +${esc}&f6k2a16d7L Veil QQQQT6${cr}\ +${esc}&f7k2a16d7L Kilmer hpclearkQQQQT7${cr}\ +${esc}&f8k2a16d7L hpcll207QQQQT8${cr}\c" + elif [ $me = fk3 ]; then + print "\ +${esc}&f1k2a16d7LDuchess QQQQT1${cr}\ +${esc}&f2k2a16d7LCatbert QQQQT2${cr}\ +${esc}&f3k2a16d7L Nala QQQQT3${cr}\ +${esc}&f4k2a16d7LPywacket QQQQT4${cr}\ +${esc}&f5k2a16d7L Alley QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk4 ]; then + print "\ +${esc}&f1k2a16d7L Wampus QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob01 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob02 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob03 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob04 QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk5 ]; then + print "\ +${esc}&f1k2a16d7Lcllvob05 QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob06 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob07 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob08 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob09 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllvob10 QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk6 ]; then + print "\ +${esc}&f1k2a16d7L Gideon QQQQT1${cr}\ +${esc}&f2k2a16d7L Oliver QQQQT2${cr}\ +${esc}&f3k2a16d7L Dinah QQQQT3${cr}\ +${esc}&f4k2a16d7LCheshire QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllbld01 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllbld02 QQQQT6${cr}\ +${esc}&f7k2a16d7Lcllbld03 QQQQT7${cr}\ +${esc}&f8k2a16d7Lhpcll321 QQQQT8${cr}\c" + fi + + # Turn on Function keys to see changes + print "${esc}&jB\c" +else + print -u2 "Sorry but the terminal type $TERM, is not supported" + exit 1 +fi diff --git a/clients/HP/bin/fk6 b/clients/HP/bin/fk6 new file mode 100644 index 0000000..3ded632 --- /dev/null +++ b/clients/HP/bin/fk6 @@ -0,0 +1,98 @@ +#!/bin/ksh +################################################################################ +# +# File: .tep +# RCS: $Header: .tep,v 1.5 97/10/05 22:31:46 defaria Exp $ +# Description: Wrapper script to set function keys for the TEP Console +# Concentrators. +# Author: Andrew DeFaria, California Language Labs +# Created: Thu Jun 6 08:31:57 PDT 1996 +# Modified: Thu Jun 6 08:32:13 PDT 1996 (Andrew DeFaria) defaria@spock +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) +export esc=$(print "\033") +export cr=$(print "\015") + +if [ "$TERM" = "hpterm" \ + -o "$TERM" = "hp" \ + -o "$TERM" = "2394" \ + -o "$TERM" = "70096" ]; then + # Turn: + # . Enq/Ack: No + # . RecvPace: Xon/Xoff + # . InhHndShk (G): Yes + # . Inh DC2 (H): Yes + print "${esc}&q0n1h${esc}&s1g1H\c" + + if [ "$me" = fk1 ]; then + print "\ +${esc}&f1k2a16d7L Young hpcleareQQQQT1${cr}\ +${esc}&f2k2a16d7L Loomis hpclsv1 QQQQT2${cr}\ +${esc}&f3k2a16d7L hpcll237QQQQT3${cr}\ +${esc}&f4k2a16d7L Stablerhpclear1QQQQT4${cr}\ +${esc}&f5k2a16d7L Unitas hpclear3QQQQT5${cr}\ +${esc}&f6k2a16d7L Griese hpclear5QQQQT6${cr}\ +${esc}&f7k2a16d7L Simms hpclear7QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk2 ]; then + print "\ +${esc}&f1k2a16d7LDynamitehpclldynQQQQT1${cr}\ +${esc}&f2k2a16d7L Mobius hpclang6QQQQT2${cr}\ +${esc}&f3k2a16d7L Starr hpclearnQQQQT3${cr}\ +${esc}&f4k2a16d7L hpcll208QQQQT4${cr}\ +${esc}&f5k2a16d7LTarkentnhpclear9QQQQT5${cr}\ +${esc}&f6k2a16d7L Veil QQQQT6${cr}\ +${esc}&f7k2a16d7L Kilmer hpclearkQQQQT7${cr}\ +${esc}&f8k2a16d7L hpcll207QQQQT8${cr}\c" + elif [ $me = fk3 ]; then + print "\ +${esc}&f1k2a16d7LDuchess QQQQT1${cr}\ +${esc}&f2k2a16d7LCatbert QQQQT2${cr}\ +${esc}&f3k2a16d7L Nala QQQQT3${cr}\ +${esc}&f4k2a16d7LPywacket QQQQT4${cr}\ +${esc}&f5k2a16d7L Alley QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk4 ]; then + print "\ +${esc}&f1k2a16d7L Wampus QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob01 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob02 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob03 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob04 QQQQT5${cr}\ +${esc}&f6k2a16d7L QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk5 ]; then + print "\ +${esc}&f1k2a16d7Lcllvob05 QQQQT1${cr}\ +${esc}&f2k2a16d7Lcllvob06 QQQQT2${cr}\ +${esc}&f3k2a16d7Lcllvob07 QQQQT3${cr}\ +${esc}&f4k2a16d7Lcllvob08 QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllvob09 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllvob10 QQQQT6${cr}\ +${esc}&f7k2a16d7L QQQQT7${cr}\ +${esc}&f8k2a16d5L Dis connect QQQQ${cr}\c" + elif [ $me = fk6 ]; then + print "\ +${esc}&f1k2a16d7L Gideon QQQQT1${cr}\ +${esc}&f2k2a16d7L Oliver QQQQT2${cr}\ +${esc}&f3k2a16d7L Dinah QQQQT3${cr}\ +${esc}&f4k2a16d7LCheshire QQQQT4${cr}\ +${esc}&f5k2a16d7Lcllbld01 QQQQT5${cr}\ +${esc}&f6k2a16d7Lcllbld02 QQQQT6${cr}\ +${esc}&f7k2a16d7Lcllbld03 QQQQT7${cr}\ +${esc}&f8k2a16d7Lhpcll321 QQQQT8${cr}\c" + fi + + # Turn on Function keys to see changes + print "${esc}&jB\c" +else + print -u2 "Sorry but the terminal type $TERM, is not supported" + exit 1 +fi diff --git a/clients/HP/bin/get_info b/clients/HP/bin/get_info new file mode 100644 index 0000000..db6dd58 --- /dev/null +++ b/clients/HP/bin/get_info @@ -0,0 +1,257 @@ +#! /bin/ksh +# +# Usage get_info { all_projects | +# all_members | +# all_project_members | +# member_project { asok | dgross } | +# project_attribute { Codegen vwstation} | +# member_attribute { asok phone } | +# server_names { +# buildserver | +# mailserver | +# viewserver | +# virtualws | +# vobserver | +# webserver } | +# is_project +# emit_error { error_code returned by get_info() +} +# } +# +# +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Set machines +machines=${machines:-$adm_base/data/machines} + +# Source functions +. $adm_fpath/common + +DBDIR=$adm_base/data/db/get_info +alias grep='grep -i' + +# +trap "cleanup" 1 2 3 8 15 + +####### Begin error message catalog. ############# +typeset MSG +MSG[0]="get_info:LDAP CONNECTION SUCCESSFUL" +MSG[1]="get_info:LDAP OPERATIONS ERROR" +MSG[2]="get_info:LDAP PROTOCOL ERROR" +MSG[3]="get_info:LDAP TIMELIMIT EXCEEDED" +MSG[4]="get_info:LDAP SIZELIMIT EXCEEDED" +MSG[5]="get_info:LDAP COMPARE FALSE" +MSG[6]="get_info:LDAP COMPARE TRUE" +MSG[7]="get_info:LDAP STRONG AUTH NOT SUPPORTED" +MSG[8]="get_info:LDAP STRONG AUTH REQUIRED" +MSG[9]="get_info:LDAP PARTIAL RESULTS" + +MSG[16]="get_info:LDAP NO SUCH ATTRIBUTE" +MSG[17]="get_info:LDAP UNDEFINED TYPE" +MSG[18]="get_info:LDAP INAPPROPRIATE MATCHING " +MSG[19]="get_info:LDAP CONSTRAINT VIOLATION " +MSG[20]="get_info:LDAP TYPE OR VALUE EXISTS " +MSG[21]="get_info:LDAP INVALID SYNTAX " + +MSG[32]="get_info:LDAP NO SUCH OBJECT " +MSG[33]="get_info:LDAP ALIAS PROBLEM " +MSG[34]="get_info:LDAP INVALID DN SYNTAX " +MSG[35]="get_info:LDAP IS LEAF " +MSG[36]="get_info:LDAP ALIAS DEREF PROBLEM " +MSG[37]="NAME ERROR(n) ((n & 0xf0) == 0x20)" + +MSG[48]="get_info:LDAP INAPPROPRIATE AUTH " +MSG[49]="get_info:LDAP INVALID CREDENTIALS " +MSG[50]="get_info:LDAP INSUFFICIENT ACCESS " +MSG[51]="get_info:LDAP BUSY " +MSG[52]="get_info:LDAP UNAVAILABLE " +MSG[53]="get_info:LDAP UNWILLING TO PERFORM " +MSG[54]="get_info:LDAP LOOP DETECT " + +MSG[64]="get_info:LDAP NAMING VIOLATION " +MSG[65]="get_info:LDAP OBJECT CLASS VIOLATION " +MSG[66]="get_info:LDAP NOT ALLOWED ON NONLEAF " +MSG[67]="get_info:LDAP NOT ALLOWED ON RDN " +MSG[68]="get_info:LDAP ALREADY EXISTS " +MSG[69]="get_info:LDAP NO OBJECT CLASS MODS " +MSG[70]="get_info:LDAP RESULTS TOO LARGE " + +MSG[80]="get_info:LDAP OTHER " +MSG[81]="get_info:LDAP SERVER DOWN " +MSG[82]="get_info:LDAP LOCAL ERROR " +MSG[83]="get_info:LDAP ENCODING ERROR " +MSG[84]="get_info:LDAP DECODING ERROR " +MSG[85]="get_info:LDAP TIMEOUT " +MSG[86]="get_info:LDAP AUTH UNKNOWN " +MSG[87]="get_info:LDAP FILTER ERROR " +MSG[88]="get_info:LDAP USER CANCELLED " +MSG[89]="get_info:LDAP PARAM ERROR " +MSG[90]="get_info:LDAP NO MEMORY " +MSG[91]="get_info:LDAP CONNECT ERROR " +# +# errors related to remsh or OS interface. +MSG[201]="get_info:ERROR while fixing .rhosts file in preparation for +remsh." +MSG[202]="get_info:ERROR remsh failed while invoking get_info on CLLWEB" +MSG[203]="get_info:ERROR uname returned un-supported OS." +# +# User interface errors while using get_info() +MSG[210]="get_info:ERROR insufficient arguments to get_info()" +MSG[211]="get_info:ERROR requested member project not found in data-base." +MSG[212]="get_info:ERROR requested project not found in data-base." +MSG[213]="get_info:ERROR database directory not found." +MSG[214]="get_info:ERROR gven member not found in data-base." +# +# +MSG[500]="get_info:ERROR BAD/un-implemented Error number" +####### End error message catalog. ############# + +print_error_msg() +{ +[ -z "${MSG[$1]}" ] && echo ${MSG[500]} || echo ${MSG[$1]} +exit 0 +} + +function cleanup +{ +exit $1 +} + +####################################################### +# Start processing questions . . . +# Get member project name for a given member name. +# usage# save_get_info member_project amitp +# +# This function will save information from data-base in +# a temporary file, so that cleanup can prefix this +# output with error code. This is done to pass error +# code returned by the command passed to remsh. +# +# Ex: remsh "get_info member_project amitp" +# +# remsh returns status of itself(remsh) not the status +# of "get_info". +# +save_get_info() +{ +case "$1" in +all_project_members) + # Get all members for a given project. + [ $# -ne 2 ] && cleanup 210 + [ ! -f $2.proj ] && cleanup 212 + RESULT=`grep "^project:$2" *.mem | awk -F. '{print $1}'` + ;; + +member_project) + # Get member project name for a given member name. + [ $# -ne 2 ] && cleanup 210 + [ ! -f $2.mem ] && cleanup 214 + RESULT=`grep "^project:" $2.mem | awk -F: '{print $2}'` + ;; + +project_attribute) + # Get project attribute for a given project name. + [ ! -f $2.proj ] && cleanup 212 + [ $# -eq 3 ] && RESULT=`grep "^$3:" $2.proj | awk -F: '{print $2}'` +|| RESULT=`awk -F: '{printf "%s= %s\n", $1, $2}' $2.proj` + ;; + +member_attribute) + # Get member attribute for a given member name. + [ ! -f $2.mem ] && cleanup 212 + [ $# -eq 3 ] && RESULT=`grep "^$3:" $2.mem | awk -F: '{print $2}'` +|| RESULT=`awk -F: '{printf "%s = %s\n", $1, $2}' $2.mem` + ;; + +machine_attribute) + # Get machine attribute for a given machine name. + [ ! -f $2.mach ] && cleanup 212 + [ $# -eq 3 ] && RESULT=`grep "^$3:" $2.mach | awk -F: '{print $2}'` +|| RESULT=`awk -F: '{printf "%s = %s\n", $1, $2}' $2.mach` + ;; + +is_project) + # Get project attribute for a given project name. + [ $# -ne 2 ] && cleanup 210 + [ ! -f $2.proj ] && cleanup 212 + RESULT=`grep "^project:" $2.proj | awk -d: '{print $2}'` + ;; + +all_projects) + RESULT=`/bin/ls *.proj | awk -F. '{print $1}'` + ;; + +all_members) + RESULT=`/bin/ls *.mem | awk -F. '{print $1}'` + ;; + +server_names) + [ $# -ne 2 ] && cleanup 210 + case $2 in + buildserver) + grepfor="Build Server" + ;; + mailserver) + grepfor="Mail Server" + ;; + viewserver) + grepfor="View Server" + ;; + virtualws) + grepfor="Virtual Workstation" + ;; + vobserver) + grepfor="Vob Server" + ;; + webserver) + grepfor="Web Server" + ;; + *) + cleanup 210 + ;; + esac +# RESULT=`grep "^server:$2" *.mach | awk -F. '{print $1}'` + RESULT=`grep -v "^#" $machines | grep ":Infrastructure:" | grep +"$grepfor" | awk -F: '{print $1}'` + ;; +*) + # Error in input argument. + cleanup 210 + ;; +esac +} + +######################## Main starts here ############ +# + +case $1 in +-qldap) + shift + typeset integer MULTILINE=1 + ;; +noloop) + shift + # old version compatibility + ;; + +emit_error) + [ $# -eq 2 ] && print_error_msg $2 || exit 210 # Incorrect argument +list. + ;; +*) + # go to processing outside case block + ;; +esac + +[ ! -d $DBDIR ] && cleanup 213 +cd $DBDIR +save_get_info $@ +[ $MULTILINE ] && echo "$RESULT" || echo $RESULT +cleanup 0 diff --git a/clients/HP/bin/infrastructuremach b/clients/HP/bin/infrastructuremach new file mode 100644 index 0000000..64dd505 --- /dev/null +++ b/clients/HP/bin/infrastructuremach @@ -0,0 +1,60 @@ +#!/bin/ksh +################################################################################ +# +# File: infrastructuremach +# Description: A script to execute a command on all infrastructure class machines +# Author: Andrew@DeFaria.com +# Created: Thu May 11 11:08:24 PDT 2000 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Set machines +machines=${machines:-$adm_base/data/machines} + +if [ "$1" = "-f" ]; then + shift + machines="$1" + shift +fi + +PATH=/adm/bin:$PATH + +if [ "$1" = "-r" ]; then + root=yes + shift +fi + +for infrastructure_machine in $(grep -ve ^# $machines | grep Infrastructure +| cut -d: -f1); do + # Execute command. Note if no command is given then the effect is to + # rlogin to each machine. + print "$infrastructure_machine:$@" + if [ $# -gt 0 ]; then + if [ -z "$root" ]; then + remsh $infrastructure_machine -n "$@" + else + root remsh $infrastructure_machine -n "$@" + fi + else + if [ -z "$root" ]; then + remsh $infrastructure_machine + else + root remsh $infrastructure_machine + fi + fi +done diff --git a/clients/HP/bin/insert b/clients/HP/bin/insert new file mode 100644 index 0000000..29fbda9 --- /dev/null +++ b/clients/HP/bin/insert @@ -0,0 +1,522 @@ +#!/usr/bin/ksh + +# Logfile +logfile=/new.system.1.log + +## Set global env variables +# Set me +me=${0##*/} + +# Set OS +OS=$(uname -r | cut -c3-) + +# Get configfiles from Bismol (IP address is used because the machine is not +# currently setup enough to know how to resolve bismol to an IP address) +configfiles_machine=15.0.96.154 + +# Set step_nbr +integer step_nbr=0 + +# Filename for configuration files +configfiles=${OS}configfiles.shar + +function error { + print -u2 "$me: Error: $1" +} # error + +function warning { + print -u2 "$me: Warning: $1" +} # warning + +function display { + print "$1" +} # display + +function info { + display "$me: Info: $1" +} # info + +function verbose { + if [ ! -z "$verbose" ]; then + display "$1" + fi +} # verbose + +function debug { + if [ ! -z "$debug" ]; then + print -u2 "$me: Debug: $1" + fi +} # debug + +function usage { + display "$ME -c/learcase [-v|verbose] [-d|debug] [-usage]" + display " -c/learcase Perform ClearCase installation" + display " -v|verbose: Turns on verbose mode" + display " -d|debug: Turns on debug mode" + display " -usage: Print this usage message" + display " " + display "The following options will be prompted for if not supplied on the" + display "command line. If any parameter has spaces in it then you need to" + display "surround it in quotes (e.g. -owners_fullname \"Andrew DeFaria\"." + display "You'll probably need to do this for the first 3 in the list below:" + display " " + display " -owners_fullname Specify owners full name" + display " -machine_usage Specify what this machine is to be used for" + display " -location Specify where this machine is located" + display " -owners_email Specify email address (no @cup.hp.com)" + display " -owners_extension Specify phone extenstion in the format of" + display " 7-XXXX (the t-44 will be prepended)" + display " -new_machine_name Specify the name of this system (REQUIRED)" + + error "$1" + exit 1 +} # usage + +function step { + let step_nbr=step_nbr+1 + display "Step #$step_nbr: $@" +} # step + +function get_configfiles { + user=anonymous + passwd=$LOGNAME@$(uname -n).cup.hp.com + directory=pub/Configuration + cd / + ftp -n $configfiles_machine <<@EOD +user $user $passwd +cd $directory +get $configfiles +quit +@EOD + + return $? +} # get_configfiles + +function export_disks { + # First check to see if all local disks are exported + cut -f1 -d' ' /etc/xtab > /tmp/xtab + bdf -t hfs | grep "/dev" | grep -v "/stand" | awk '{print $NF}' > +/tmp/exports + + if $(diff /tmp/exports /tmp/xtab > /dev/null 2>&1); then + verbose "All local disks exported" + else + verbose "Some local disks are not exported" + if [ "$mode" != "check" ]; then + verbose "Fixing the problem..." + cp /etc/exports /etc/exports.old + cp /tmp/exports /etc/exports + verbose "Exporting all disks..." + /usr/sbin/exportfs -a + verbose "Done" + fi + fi +} # export_disks + +function display_options { + display "Setup this machine according to the following profile:" + print - +-------------------------------------------------------------------------------- + + display "Clearcase:\t\t\c" + if [ "_$clearcase" = "_" ]; then + display "No" + else + display "Yes" + fi + + display "Verbose Mode:\t\t\c" + if [ "_$verbose" = "_" ]; then + display "Off" + else + display "On" + fi + + display "Debug Mode:\t\t\c" + if [ "_$debug" = "_" ]; then + display "Off" + else + display "On" + fi + + display "Machine Name:\t\t$new_machine_name" + display "Machine Usage:\t\t$machine_usage" + display "Macine Location:\t$location" + display "Owner's Fullname:\t$owners_fullname" + display "Owner's Email:\t\t$owners_email" + display "Owner's Extension:\t$owners_extension" +} # display_options + +# Set initial parm values +display +display "\t\tWelcome to the new system setup script" +display "\t\tThis is the first script of 4 that you" +display "\t\twill need to run to setup a new Virtual" +display "\t\tWorkstation Server or Buildpool Server." +display +clearcase= +verbose= +debug= +owners_fullname= +owners_email= +owners_extension= +machine_usage= +location= +new_machine_name= + +# Get parameters +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + -c|-clearcase) + clearcase=y + ;; + + -owners_fullname) + if [ $# -le 1 ]; then + usage "Owner's Full Name is not specified!" + fi + shift + owners_fullname="$1" + ;; + + -machine_usage) + if [ $# -le 1 ]; then + usage "Machine Usage was not specified!" + fi + shift + machine_usage="$1" + ;; + + -location) + if [ $# -le 1 ]; then + usage "Location was not specified!" + fi + shift + location="$1" + ;; + + -owners_email) + if [ $# -le 1 ]; then + usage "Owner's Email was not specified!" + fi + shift + owners_email="$1" + ;; + + -owners_extension) + if [ $# -le 1 ]; then + usage "Owner's Extention was not specified!" + fi + shift + owners_extension="$1" + ;; + + -new_machine_name) + if [ $# -le 1 ]; then + usage "New Machine Name not specified!" + fi + shift + new_machine_name="$1" + ;; + + *) + usage "Unrecognized parameter $1" + ;; + esac + shift +done + +# Prompt for options not specified on the command line + +if [ "_$clearcase" = "_" ]; then + print "Do you wish to install Clearcase?" + print "[y/n]> \c" + read clearcase + if [ "_$clearcase" = "_" ]; then + error "You must specify y or n" + exit 1 fi +fi + +if [ "_$owners_fullname" = "_" ]; then + print "Owner's Fullname" + print "> \c" + read owners_fullname + if [ "_$owners_fullname" = "_" ]; then + owners_fullname=Unknown + fi +fi + +if [ "_$machine_usage" = "_" ]; then + print "What is this machine used for?" + print "> \c" + read machine_usage + if [ "_$machine_usage" = "_" ]; then + machine_usage="This machine is used by \ for \" + fi +fi + +if [ "_$location" = "_" ]; then + print "Where is this machine located?" + print "> \c" + read location + if [ "_$location" = "_" ]; then + location="\" + fi +fi + +if [ "_$owners_email" = "_" ]; then + print "Owner's Email address:" + print "(Should be the same as username. This script will supply the cup.hp.com)" + print "> \c" + read owners_email + if [ "_$owners_email" = "_" ]; then + owners_email=Unknown + fi +fi + +if [ "_$owners_extension" = "_" ]; then + print "Owner's Phone extention:" + print "(Should be of the format 7-XXXX This script will prepend \"t-44\" to" + print "the entered extension)" + print "> \c" + read owners_extension + if [ "_$owners_extension" = "_" ]; then + owners_extension=7-XXXX + fi +fi + +until [ "_$new_machine_name" != "_" ]; do + new_machine_name="garbage" + print "New machine name:" + print "> \c" + read new_machine_name + + if [ "_$new_machine_name" = "_" ]; then + error "Must enter a new machine name" + fi +done + +if [ $(id -u) -ne 0 ]; then + error "Must be root to execute this command" + exit 1 +fi + +display_options + +display +display "Continue Installation (Y/n)?\c" +answer=y +read answer +case "$answer" in + y|Y|yes|Yes|YES|"") + continue + ;; + *) + display "Installation aborted. Rerun $me if you wish to install again" + exit 1 + ;; +esac + +function do_installation { +display_options + +step "Get configuration files" + +get_configfiles + +if [ $? -ne 0 ]; then + error "Unable to ftp $configfiles from $configfiles_machine" + exit 1 +fi + +step "Unpack configuration files" + +cd / +sh $configfiles >> $logfile 2>&1 +rm -f $configfiles + +step "Change GenericSysName in /etc/issue" + +sed "s/GenericSysName/$new_machine_name/" /etc/issue > /etc/issue.new +mv /etc/issue /etc/issue.old +mv /etc/issue.new /etc/issue + +step "Allow Access to at(1)" + +touch /var/adm/cron/at.deny +rm -f /var/adm/cron/at.allow + +step "Setup ClearCase Build Hosts File" +echo `uname -n` > /.bldhost.hppa +cat /etc/bldhost.hppa >> /.bldhost.hppa +rm /etc/bldhost.hppa + +step "Symlink /nfs -> /net" + +ln -s /net /nfs 2>> $logfile + +step "Symlink /usr/preserve -> /var/preserve" + +ln -s /var/preserve /usr/preserve 2>> $logfile + +step "Setup Application Server" + +/net/bismol/app/admin/bin/setup + +step "Setup Mother of All Passwords (AKA MoA)" + +/net/bismol/app/admin/bin/mkpass -f + +step "Create /etc/motd" + +banner $new_machine_name > /etc/motd +uname -a >> /etc/motd +cat >> /etc/motd <<:END + +******************************************************************************* +* This is a private system operated for the Hewlett-Packard Company business. * +* Authorization from HP management is required to use this system. * +* Use by unauthorized persons is prohibited. * +******************************************************************************* +For System Support: Mon-Fri 8:00-5:00 Email (site-ux@cup.hp.com) +Phone: t-447-1212 After hours/weekend Pre-arrange: t-447-0629 +------------------------------------------------------------------------------- +Usage: $machine_usage +Owner: $owners_fullname ($owners_email@cup.hp.com) Phone: +t-44$owners_extension +Location: $location +------------------------------------------------------------------------------- +:END + +step "Edit /etc/gettydefs: Change \"Console login:\" to \"$new_machine_name login:\"" + +sed "s/Console Login:/$new_machine_name Login:/" /etc/gettydefs \ + > /etc/gettydefs.new +mv /etc/gettydefs /etc/gettydefs.old +mv /etc/gettydefs.new /etc/gettydefs + +step "Ninstalling lp, adm and net3 packages" + +/usr/local/bin/ninstall -h bismol lp adm net3 >> $logfile 2>&1 + +step "Run netdaemon.dy" + +/usr/adm/netdist/netdaemon.dy 2>> $logfile + +step "Fix /usr/sbin/rlp" + +chmod +x /usr/sbin/rlp + +step "Install root crontab" + +crontab /crontab.root >> $logfile 2>&1 +rm -f /crontab.root + +step "Allow usage of crontab for ordinary users" + +touch /var/adm/cron/cron.deny +rm -f /var/adm/cron/cron.allow + +if [ "$clearcase" = "y" ]; then + step "Make symlink for the Build Environment" + + ln -s /CLO/BUILD_ENV/usr/lib /usr/shlib 2>> $logfile + + step "Symlinking clearmake for parallel build support" + + ln -s /usr/eclipse/bin/clearmake /usr/contrib/bin/clearmake +fi + +step "Adjust nfsd/biod's" + +integer nfsd=4 +integer biod=4 +case $(uname -m) in + 9000/712|9000/715) + ;; + + 9000/755) + nfsd=24 + biod=8 + ;; + + 9000/780|9000/813|9000/829|9000/849|9000/889|9000/898) + nfsd=48 + biod=16 + ;; + + *) + warning "Unknown machine model $(uname -m)!" + warning "Leaving nfsd/biod's as default" + ;; +esac + +if [ $nfsd -ne 4 ]; then + cp /etc/rc.config.d/nfsconf /etc/rc.config.d/nfsconf.old + sed "s/NUM_NFSD=4/NUM_NFSD=$nfsd/" /etc/rc.config.d/nfsconf \ + > /etc/rc.config.d/nfsconf.new + mv /etc/rc.config.d/nfsconf.new /etc/rc.config.d/nfsconf + sed "s/NUM_NFSIOD=4/NUM_NFSIOD=$biod/" /etc/rc.config.d/nfsconf \ + > /etc/rc.config.d/nfsconf.new + mv /etc/rc.config.d/nfsconf.new /etc/rc.config.d/nfsconf +fi + +step "Setting up for 9.x build environment" + +mv /usr/lib/libisamstub.1 /usr/lib/libisamstub.0 +cp /net/bismol/app/admin/lib/libisamstub.1 /usr/lib/libisamstub.1 +chmod 555 /usr/lib/libisamstub.1 +chown bin:bin /usr/lib/libisamstub.1 + +step "Setup DTS" + +ln -s /net/bismol/aspirin/DTS /usr/DTS 2>> $logfile + +step "Setup automounter to use hard mounts" + +echo "/net -hosts -intr" > /etc/auto_master + +step "Link /var/mail" + +mv /var/mail /var/mail.orig +ln -s /net/cllmail/var/mail/ /var/mail + +step "Fix Root's name entry in /etc/passwd.loc" + +sed "s/Root user/Root\@$(uname -n)/" /etc/passwd.loc > /tmp/passwd.loc +mv /tmp/passwd.loc /etc/passwd.loc + +step "Fix permissions on /dev/lan*" + +chmod 644 /dev/lan* + +step "Installing OptionalSoftware" + +display +display "This step will take several minutes and then the machine will +reboot." +display "After the machine is back up continue with new.system.2." + +/usr/sbin/swinstall + -s wampus:/Depots/$OS \ + -x autoreboot=true \ + OptionalSoftware \ +>> $logfile 2>&1 + +info "Swinstall complete, system will reboot if there were no errors" + +} # do_installation + +do_installation | tee $logfile diff --git a/clients/HP/bin/install_new_kernel b/clients/HP/bin/install_new_kernel new file mode 100644 index 0000000..ec18921 --- /dev/null +++ b/clients/HP/bin/install_new_kernel @@ -0,0 +1,65 @@ +#!/bin/ksh +# +# Move a new kernel, previously generated, into place +# +me=$(basename $0) + +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: Must be root to execute this command!" + exit 1 +fi + +OS=$(/bin/uname -r | /usr/bin/cut -f2 -d.) + +kernel_1_source= +kernel_2_source= +kernel_1_destination= +kernel_2_destination= + +case "$OS" in + 10) + kernel_1_source=/stand/build/vmunix_test + kernel_2_source=/stand/build/system.SAM + kernel_1_destination=/stand/vmunix + kernel_2_destination=/stand/system + ;; + 09) + kernel_1_source=/etc/conf/hp-ux + kernel_2_source=/etc/conf/dfile.SAM + kernel_1_destination=/hp-ux + kernel_2_destination=/etc/conf/dfile + ;; + *) + print -u2 "$me: Error: Unable to determine OS level: $OS" + exit 1 + ;; +esac + +if [ -f $kernel_1_source -a -f $kernel_2_source ]; then + answer=y + print "New kernel found, move into place (Y/n)?\c" + read answer + if [ "$answer" = "y" -o "$answer" = "Y" ]; then + print -u2 "Moving kernel into place..." + mv $kernel_1_source $kernel_1_destination + mv $kernel_2_source $kernel_2_destination + else + print "WARNING: kernel not moved into place!" + fi + + answer=y + print "Restart system (Y/n)?\c" + read answer + if [ "$answer" = "y" -o "$answer" = "Y" ]; then + cd / + /etc/shutdown -yr 0 + else + print "System not restarted" + exit + fi +else + print -u2 "$me: Error: Unable to find new kernel files:" + print -u2 "\t$kernel_1_source" + print -u2 "\t$kernel_2_source" + exit 1 +fi diff --git a/clients/HP/bin/install_pwplus b/clients/HP/bin/install_pwplus new file mode 100644 index 0000000..3004f58 --- /dev/null +++ b/clients/HP/bin/install_pwplus @@ -0,0 +1,28 @@ +#!/bin/ksh +################################################################################ +# +# File: install_pwplus +# Description: This script will install pwplus +# Author: Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# Modified: +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# First source /app/appserver +if [ -x /app/appserver ]; then + . /app/appserver +fi + +if [ $(id -u) -ne 0 ]; then + print -u2 "Error: You must be root to execute this command!" + exit 1 +fi + +if [ "$OS" = "09" ]; then + print -u2 "Error: $(basename $0) does not run on 9.x!" + exit 1 +fi + +/usr/sbin/swinstall -s medusa.corp:/var/depot/security PWplus diff --git a/clients/HP/bin/inventory b/clients/HP/bin/inventory new file mode 100644 index 0000000..c8123d2 --- /dev/null +++ b/clients/HP/bin/inventory @@ -0,0 +1,310 @@ +#!/bin/ksh +################################################################################ +# +# File: inventory +# Description: Displays information about a machine including hardware and +# software inventories +# Author: Andrew@DeFaria.com +# Created: Fri Jun 15 15:26:27 PDT 2001 +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew DeFaria, all rights reserved. +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +tmpprefix=${TMPDIR:-/tmp}/$me.$$ +tmpfile=$tmpprefix +tmpfile=~v801310/adm/data/$(hostname).sysinfo +. $adm_fpath/tmpfiles + +function usage { + print -u2 "Usage: $me -[h|ardware] -[s|oftware] -[da|emon]" + exit 1 +} # usage + +function display_inventory { + # This function displays the "inventory" for this machine. Currently + # "inventory" consists of hardware, software and daemons. + display_hardware_inventory + display_software_inventory + display_daemon_inventory +} # display_inventory + +function display_hardware_inventory { + # This function displays the hardware inventory. Only "important" hardware + # values are displayed. + # + # This function may be enhanced in the future. + debug "ENTER: $0" + + # Hostname + host=$(grep ^HOSTNAME: $tmpfile | cut -c16-) + + # OS + os=$(uname -r) + + # Model + model=$(grep ^MODEL: $tmpfile | cut -c16-) + + # CPU Speed + cpu_speed=$(grep "^CPU SPEED:" $tmpfile | cut -c16-) + + # CPUs + cpus=$(grep ^CPUS: $tmpfile | awk '{print $2}') + + # Main Memory + memory=$(grep MEMORY: $tmpfile | awk '{printf "%s %s", $2, $3}') + + # Swap + if is_root; then + swap=$(swapinfo -m -t | tail -1 | awk '{print $2}') + swap="$swap Meg" + else + swap="(Not run as root)" + fi + + # Number of disks + if is_root; then + verbose "Determining the number of disks" + nbr_disks=$(ioscan -C disk | grep -ve "^H/W" -e "^==" -e "CD-ROM" | wc -l) + else + nbr_disks="(Not run as root)" + fi + + # Volume groups and logical volumes + integer nbr_vg=0 + integer nbr_lv=0 + + verbose "Determining volume groups and logical volumes" + for vg in $(vgdisplay | grep "^VG Name" | awk '{print $NF}'); do + let nbr_vg=nbr_vg+1 + for v in $(vgdisplay -v $vg | grep " LV Name" | awk '{print $NF}'); do + let nbr_lv=nbr_lv+1 + done + done + + # Display information + display "Machine: $host" + display "OS: $os" + display "Model: $model" + display "CPUs: $cpus ($cpu_speed)" + display "Memory: $memory" + display "Swap: $swap" + display "Number of disks: $nbr_disks" + display "Volume Groups: $nbr_vg" + display "Logical Volumes: $nbr_lv" + + # Print filesystems with percentage filled in descending order: + display + bdf -l | grep -ve "^Filesystem" -e "^AFS" | + awk '{printf "%s\t%s\n", $(NF-1), $NF}' | sort -nr + debug "EXIT: $0" +} # display_hardware_inventory + +function display_software_inventory { + # This function displays the software inventory. Only "important" software + # values are displayed. Currently these are: + # + # . Certain "interesting" software registered in the SD-UX product + # database + # . Certain "interesting" 3rd party software (typically not recorded + # properly in the SD-UX product database) + # + # This function may be enhanced in the future. + debug "ENTER: $0" + + verbose "Checking for certain important software (SD-UX)" + display "\nInstalled software (SD-UX):\n" + for package in \ + Apache \ + DB2V7CAE \ + DB2V7CONN \ + DB2V7SDK \ + DB2V7WGRP \ + C-ANSI-C \ + C-Plus-Plus \ + CCASE-MVFS \ + Glance \ + Ignite-UX \ + Java-PlugIn1-2 \ + Java-Runtime1-1 \ + Java2JDK_base \ + Java2RTE_base \ + gcc \ + NscapeDir40Srv \ + NscapeFastrakSrv \ + NscapeNavGold \ + NSEntrpr36Srv \ + NSNavigator40 \ + ; do + grep "$package" $tmpfile > /dev/null 2>&1 + + if [ $? -eq 0 ]; then + if [ -n "$packages" ]; then + packages="$packages, $package" + else + packages="$package" + fi + fi + done + display "\t$packages" + + display "\nNumber of patches: \c" + grep -c "^ PH" $tmpfile + + display "\nContents of /usr/local/bin:\n\t\c" + l -F /usr/local/bin + + display "\nOther software:\n" + + for other_software_dir in \ + /sybase \ + /usr/local/flexlm \ + /opt/perl \ + /opt/perl5 \ + /opt/tuxedo \ + /opt/weblogic \ + ; do + if [ -d $other_software_dir ]; then + if [ -n "$other_software_dirs" ]; then + other_software_dirs="$other_software_dirs, $other_software_dir" + else + other_software_dirs="$other_software_dir" + fi + fi + done + + display "\t$other_software_dirs" + + debug "EXIT: $0" +} # display_software_inventory + +function display_daemon_inventory { + # This function displays the daemon inventory. Only "important" daemon + # values are displayed. + # + # This function may be enhanced in the future. + debug "ENTER: $0" + + display "\nRunning daemons on $(uname -n):\n" + + # Check to see if Oracle is running + if [ $(who | cut -f1 -d' ' | sort -u | grep -c oracle) -eq 1 ]; then + daemons="Oracle" + fi + + verbose "Checking for running daemons" + # Check other running daemons + for daemon in \ + ns-httpd \ + uxwdog \ + /opt/perf/bin/midaemon \ + /usr/afs/bin/bosserver \ + /usr/afs/bin/busserver \ + /usr/afs/bin/fileserver \ + /usr/afs/bin/kasserver \ + /usr/afs/bin/ptserver \ + /usr/afs/bin/runntp \ + /usr/afs/bin/vlserver \ + /usr/afs/bin/volserver \ + /usr/excalib/efsd \ + /usr/sbin/inetd.afs \ + /usr/vice/etc/afsd\ + ; do + integer n=$(ps -ef | grep "$daemon" | grep -v "grep $daemon" | wc -l) + + if [ $n -gt 0 ]; then + if [ -n "$daemons" ]; then + daemons="$daemons, $daemon" + else + daemons="$daemon" + fi + fi + done + display "\t$daemons" + + debug "EXIT: $0" +} # display_daemon_inventory + +# Get parms +hardware=true +softare=true +daemon=true +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + -h|-hardware) + hardware=true + ;; + + -s|-software) + software=true + ;; + + -da|-daemon) + daemon=true + ;; + + *) + error "Unknown parameter encounter: \"$1\"" + usage + ;; + esac + shift +done + +# Find sysinfo + +# First check to see if we can access our own sysinfo +sysinfo=/usr/contrib/bin/sysinfo + +if [ ! -x $sysinfo ]; then + # Next check to see if we can find sysinfo on PATH + sysinfo=$(whence sysinfo) + if [ "_$sysinfo" = "_" ]; then + error "Unable to find sysinfo!" 1 + else + warning "Using nonstandard sysinfo: $sysinfo. Results may vary" + fi +fi +verbose "Using sysinfo: $sysinfo" + +# Hack alert! During testing I'm letting $tmpfile hang around. Therefore if it +# exists already we'll simply use it assuming it contains valid output from +# a previous run. This speeds up things quite a bit +if [ ! -f $tmpfile ]; then + # Check to see if user is running as root + if is_root; then + error "You must run this as root" 1 + else + verbose "Gathering information...\c" + $sysinfo -a > $tmpfile + chown v801310:sfokt $tmpfile + chmod 666 $tmpfile + verbose " done" + fi +fi + +display_inventory diff --git a/clients/HP/bin/lpsetup b/clients/HP/bin/lpsetup new file mode 100644 index 0000000..3609c22 --- /dev/null +++ b/clients/HP/bin/lpsetup @@ -0,0 +1,156 @@ +#!/usr/bin/ksh +################################################################################ +# +# File: lpsetup +# Description: Script to recreate printer definitions +# Author: Andrew@DeFaria.com +# Created: Wed Sep 6 16:38:14 PDT 2000 +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Global variables +printer_definitions=${printer_definitions:-$adm_base/etc/printer.defs} +local_printers= + +# Commands used +accept=/usr/sbin/accept +enable=/usr/bin/enable +lpadmin=/usr/sbin/lpadmin +lpshut=/usr/sbin/lpshut +lpsched=/usr/sbin/lpsched + +function usage { + if [ "_$1" != "_" ]; then + display "$1" + display + fi + display "Usage: $me" + exit 1 +} # usage + +function remove_all_printers { + debug "ENTER: $0" + + verbose "Removing all printers" + + # First list all known printers + all_printers=$(lpstat -s | grep device | cut -f3 -d' ' | cut -f1 -d:) + + # Now determine if the printer is local. If it's local then we do not delete + # it. + for printer in $all_printers; do + if [ $(lpstat -v$printer | wc -l) -gt 1 ]; then + verbose "Removing $printer" + $lpadmin -x$printer + else + local_printers="$local_printers $printer" + verbose "$printer is local to this machine. Will not automatically remove it" + fi + done + verbose "Removed all printers" + debug "EXIT: $0" +} # remove_all_printers + +# Check for execution by root +if is_not_root; then + error "This script must be run as root" 1 +fi + +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + *) + usage "Unrecognized parameter $1" + ;; + esac + shift +done + +if [ ! -r $printer_definitions ]; then + error "Unable to find printer definitions ($printer_definitions)" 2 +fi + +if [ $(uname -r) = "B.11.11" ]; then + verbose "Prereleased OS (B.11.11) detected. No processing done" + exit 0 +fi + +# You must shutdown the spooler before making any changes +$lpshut > /dev/null 2>&1 + +if [ $? -ne 0 ]; then + error "Unable to stop LP Scheduler!" 3 +fi + +# First remove all printer definitions +remove_all_printers + +# Now add them back +verbose "Adding all printers" +grep -v "^#" $printer_definitions | grep -v "^$" | while read printer server; do + is_a_local_printer=false + for local_printer in $local_printers; do + if [ "$printer" = "$local_printer" ]; then + is_a_local_printer=true + break + fi + done + + if [ "$is_a_local_printer" = "false" ]; then + verbose "Adding $printer:$server... \c" + server=$server.cup.hp.com + $lpadmin \ + -p$printer \ + -orm$server \ + -orp$printer \ + -mrmodel \ + -v/dev/null \ + -ocmrcmodel \ + -osmrsmodel + + verbose "accepting... \c" + $accept $printer > /dev/null 2>&1 + + verbose "enabling... \c" + $enable $printer > /dev/null 2>&1 + + verbose "done" + else + verbose "Skipping local printer $printer..." + fi +done + +verbose "Added all printers" + +# Start up the print spooler +verbose "Restarting the print spooler" +$lpsched -v > /dev/null 2>&1 + +if [ $? -ne 0 ]; then + error "Unable to start LP Scheduler!" 6 +fi diff --git a/clients/HP/bin/lspatches b/clients/HP/bin/lspatches new file mode 100644 index 0000000..ca8dc86 --- /dev/null +++ b/clients/HP/bin/lspatches @@ -0,0 +1,28 @@ +#!/bin/ksh +################################################################################ +# +# File: lspatches +# RCS: $Header: lspatches,v 1.1 97/04/21 14:23:58 defaria Exp $ +# Description: Lists patches for a 10.x machine +# Author: Andrew DeFaria, California Language Labs +# Created: Mon Nov 13 16:14:30 1995 +# Modified: Mon Nov 13 16:16:56 1995 (Andrew DeFaria) defaria@spock +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# First source the appserver script +if [ -x /app/appserver ]; then + . /app/appserver +fi + +if [ $# -eq 0 ]; then + print -u2 "Patches for $(uname -n):" + /usr/sbin/swlist -l product | grep PH +else + for machine in "$@"; do + print -u2 "Patches for $machine:" + remsh $machine -n /usr/sbin/swlist -l product | grep PH + done +fi diff --git a/clients/HP/bin/lsproduct b/clients/HP/bin/lsproduct new file mode 100644 index 0000000..0b33923 --- /dev/null +++ b/clients/HP/bin/lsproduct @@ -0,0 +1,25 @@ +#!/bin/ksh +################################################################################ +# +# File: lsproduct +# RCS: $Header: lsproduct,v 1.1 96/07/24 04:01:51 defaria Exp $ +# Description: Lists products for a 10.x machine +# Author: Andrew DeFaria, California Language Labs +# Created: Wed Jul 24 04:00:36 PDT 1996 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# First source the appserver script +if [ -x /app/appserver ]; then + . /app/appserver +fi + +if [ $# -eq 0 ]; then + print -u2 "All products on $(uname -n):" + /usr/sbin/swlist -l product +else + /usr/sbin/swlist -l product "$@" +fi diff --git a/clients/HP/bin/lvs b/clients/HP/bin/lvs new file mode 100644 index 0000000..ca95ad5 --- /dev/null +++ b/clients/HP/bin/lvs @@ -0,0 +1,33 @@ +#!/bin/ksh +################################################################################ +# +# File: lvs +# RCS: $Header: lvs,v 1.1 97/04/08 15:27:22 defaria Exp $ +# Description: A script to list the LVM's and their disk devices +# Author: Jeff Bralley (Contrator), California Language Labs +# Created: Tue Apr 8 14:35:00 PDT 1997 +# Modified: Tue Apr 8 15:11:13 PDT 1997 Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +print "Mount Point\tLogical Volume\t\tPhysical Volume" +echo '--------------- ----------------------- ---------------' + +vgdisplay | + grep '^VG Name' | + awk '{print $3}' | + while read vgName; do + for volumeName in $vgName/*; do + if [ ! -b $volumeName ]; then + continue + fi + pd=$(lvdisplay -v $volumeName | grep '^[ ]*/dev/dsk' | awk '{print $1}') + mp=$(bdf $volumeName 2> /dev/null | grep -v Filesystem | awk '{print $NF}') + if [ "$mp" = "" ]; then + mp=swap + fi + print "$mp\t\t$volumeName\t\t$pd" + done +done diff --git a/clients/HP/bin/machine_info b/clients/HP/bin/machine_info new file mode 100644 index 0000000..1b1b4ce --- /dev/null +++ b/clients/HP/bin/machine_info @@ -0,0 +1,84 @@ +#!/bin/ksh +################################################################################ +# +# File: machine_info +# Description: Displays information about a machine +# Author: Andrew@DeFaria.com +# Created: Fri Apr 30 14:13:56 PDT 1999 +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Set machines +machines=${machines:-$adm_base/data/machines} + +if [ ! -f $machines ]; then + print -u2 "$me: Error: Unable to find $machines file!" + exit 1 +fi + +function display_machine_info { + machine=$1 + + ISF=" " + line=$(grep "^$machine:" $machines 2> /dev/null) + + if [ "_$line" = "_" ]; then + print -u2 "No information on machine $machine" + else + machine=$(print $line | cut -f1 -d:) + ip_address=$(print $line | cut -f2 -d:) + model=$(print $line | cut -f3 -d:) + osversion=$(print $line | cut -f4 -d:) + ccversion=$(print $line | cut -f5 -d:) + owner=$(print $line | cut -f6 -d:) + phone=$(print $line | cut -f7 -d:) + usage=$(print $line | cut -f8 -d:) + class=$(print $line | cut -f9 -d:) + location=$(print $line | cut -f10 -d:) + eclipseid=$(print $line | cut -f11 -d:) + print "Machine:\t\t$machine" + print "IP Address:\t\t$ip_address" + print "Model:\t\t\t$model" + print "OS Version:\t\t$osversion" + print "ClearCase Version:\t$ccversion" + print "Owner:\t\t\t$owner" | tr -s "(" "<" | tr -s ")" ">" + print "Phone:\t\t\t$phone" + print "Usage:\t\t\t$usage" + print "Class:\t\t\t$class" + print "Location:\t\t$location" + print "Eclipse ID:\t\t$eclipseid" + fi +} # display_machine_info + +function dump_all_machines { + grep -v "^#" $machines | cut -f1 -d: | while read machine; do + print - +-------------------------------------------------------------------------------- + display_machine_info $machine + done +} # dump_all_machines +if [ $# -eq 0 ]; then + display_machine_info $(uname -n) +else + if [ "$1" = "-all" ]; then + dump_all_machines + else + for i in $@; do + display_machine_info $i + done + fi +fi diff --git a/clients/HP/bin/machine_stats b/clients/HP/bin/machine_stats new file mode 100644 index 0000000..403244a --- /dev/null +++ b/clients/HP/bin/machine_stats @@ -0,0 +1,131 @@ +#!/bin/ksh +################################################################################ +# +# File: machine_stats +# Description: Displays statistical information about all machines +# Author: Andrew@DeFaria.com +# Created: Fri Apr 30 14:13:56 PDT 1999 +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Set machines +machines=${machines:-$adm_base/data/machines} + +if [ ! -f $machines ]; then + print -u2 "$me: Error: Unable to find $machines file!" + exit 1 +fi + +total_machines=$(grep -cv "^#" $machines) +total_infrastructure=$(grep -v "^#" $machines | grep -c ":Infrastructure:") +total_test=$(grep -v "^#" $machines | grep -c ":Test:") +total_desktop=$(grep -v "^#" $machines | grep -c ":Desktop:") +total_unknown=$(grep -v "^#" $machines | cut -f9 -d: | grep -c "Unknown") +total_5_6=$(grep -v "^#" $machines | grep -c "5\.6\:") +total_5_6_other=$(grep -v "^#" $machines | grep -c "5\.6[^:]") +total_11_00=$(grep -v "^#" $machines | grep -c "B\.11\.00") +total_11_11=$(grep -v "^#" $machines | grep -c "B\.11\.11") +total_10_30=$(grep -v "^#" $machines | grep -c "B\.10\.30") +total_10_20=$(grep -v "^#" $machines | grep -c "B\.10\.20") +total_10_10=$(grep -v "^#" $machines | grep -c "B\.10\.10") +total_10_01=$(grep -v "^#" $machines | grep -c "B\.10\.01") +total_4_0_cc=$(grep -v "^#" $machines | grep -c "4\.0\:") +total_3_2_cc=$(grep -v "^#" $machines | grep -c "3\.2\:") +total_3_2_1_cc=$(grep -v "^#" $machines | grep -c "3\.2\.1") +total_eclipse01=$(grep -v "^#" $machines | awk -F: '{print $11}' | grep -c +"01") +total_eclipse02=$(grep -v "^#" $machines | awk -F: '{print $11}' | grep -c +"02") +total_eclipse03=$(grep -v "^#" $machines | awk -F: '{print $11}' | grep -c +"03") +total_eclipseno=$(grep -v "^#" $machines | awk -F: '{print $11}' | grep -c +"No Eclipse") +let total_cc=total_4_0_cc+total_3_2_cc+total_3_2_1_cc + +print "PDL Machines" +let +hp_machines=total_11_00+total_11_11+total_10_30+total_10_20+total_10_10+total_10_01 + +if [ $hp_machines -gt 0 ]; then + print " " + print "HP-UX Versions:" + print - --------------- + if [ $total_11_00 -gt 0 ]; then + print "Total 11.00 .................. $total_11_00" + fi + if [ $total_11_11 -gt 0 ]; then + print "Total 11.11 .................. $total_11_11" + fi + if [ $total_10_30 -gt 0 ]; then + print "Total 10.30 .................. $total_10_30" + fi + if [ $total_10_20 -gt 0 ]; then + print "Total 10.20 .................. $total_10_20" + fi + if [ $total_10_10 -gt 0 ]; then + print "Total 10.10 .................. $total_10_10" + fi + if [ $total_10_01 -gt 0 ]; then + print "Total 10.01 .................. $total_10_01" + fi +fi +let sun_machines=total_5_6+total_5_6_other +if [ $sun_machines -gt 0 ]; then + print " " + print "Sun Versions:" + print - ------------- + print "5.6 .......................... $total_5_6" + print "5.6 (other) .................. $total_5_6_other" +fi +print " " +print "Total Machines ............... $total_machines" +print " " +print "ClearCase Machines:" +print - ------------------- +if [ $total_4_0_cc -gt 0 ]; then + print "4.0 .......................... $total_4_0_cc" +fi +if [ $total_3_2_cc -gt 0 ]; then + print "3.2 .......................... $total_3_2_cc" +fi +if [ $total_3_2_1_cc -gt 0 ]; then + print "3.2.1 ........................ $total_3_2_1_cc" +fi +if [ $total_eclipse01 -gt 0 ]; then + print "Eclipse 01 ................... $total_eclipse01" +fi +if [ $total_eclipse02 -gt 0 ]; then + print "Eclipse 02 ................... $total_eclipse02" +fi +if [ $total_eclipse03 -gt 0 ]; then + print "Eclipse 03 ................... $total_eclipse03" +fi +if [ $total_eclipseno -gt 0 ]; then + print "No Eclipse ................... $total_eclipseno" +fi +print " " +print "Total ClearCase Machines ..... $total_cc" + +print +print "Machine classes:" +print - ----------------- +print "Infrastructure ............... $total_infrastructure" +print "Test ......................... $total_test" +print "Desktop ...................... $total_desktop" +if [ $total_unknown -gt 0 ]; then + print "Unknown ...................... $total_unknown" +fi diff --git a/clients/HP/bin/make_motd b/clients/HP/bin/make_motd new file mode 100644 index 0000000..b3d83cd --- /dev/null +++ b/clients/HP/bin/make_motd @@ -0,0 +1,284 @@ +#!/usr/bin/ksh + +# Logfile +logfile=make_motd.log + +## Set global env variables +# Set me +me=${0##*/} + +# Set OS +OS=$(uname -r | cut -c3-) + +unames=$(uname -s) +unamen=$(uname -n) +unamer=$(uname -r) +unamev=$(uname -v) +unamem=$(model) +unamei=$(uname -i) +unamel=$(uname -l) + +# Set step_nbr +integer step_nbr=0 + +function error { + print -u2 "$me: Error: $1" +} # error + +function warning { + print -u2 "$me: Warning: $1" +} # warning + +function display { + print "$1" +} # display + +function info { + display "$me: Info: $1" +} # info + +function verbose { + if [ ! -z "$verbose" ]; then + display "$1" + fi +} # verbose + +function debug { + if [ ! -z "$debug" ]; then + print -u2 "$me: Debug: $1" + fi +} # debug + +function usage { + display "$me [-v|verbose] [-d|debug] [-usage]" + display " -v|verbose: Turns on verbose mode" + display " -d|debug: Turns on debug mode" + display " -usage: Print this usage message" + display " " + display "The following options will be prompted for if not supplied on the" + display "command line. If any parameter has spaces in it then you need to" + display "surround it in quotes (e.g. -owners_fullname \"Andrew DeFaria\"." + display "You'll probably need to do this for the first 3 in the list below:" + display " " + display " -owners_fullname Specify owners full name" + display " -machine_usage Specify what this machine is to be used for" + display " -location Specify where this machine is located" + display " -owners_email Specify email address (no @cup.hp.com)" + display " -owners_extension Specify phone extenstion in the format of" + display " 7-XXXX (the t-44 will be prepended)" + display " -new_machine_name Specify the name of this system (REQUIRED)" + + error "$1" + exit 1 +} # usage + +function step { + let step_nbr=step_nbr+1 + display "Step #$step_nbr: $@" +} # step + +function display_options { + display "Setup this machine according to the following profile:" + print - +-------------------------------------------------------------------------------- + + display "Machine Name:\t\t$new_machine_name" + display "Machine Usage:\t\t$machine_usage" + display "Macine Location:\t$location" + display "Owner's Fullname:\t$owners_fullname" + display "Owner's Email:\t\t$owners_email" + display "Owner's Extension:\t$owners_extension" +} # display_options + +# Set initial parm values +display +display "\t\tWelcome to the motd creation script" +display +verbose= +debug= +owners_fullname= +owners_email= +owners_extension= +machine_usage= +location= +new_machine_name= + +if [ $(id -u) -ne 0 ]; then + error "Must be root to create or modify /etc/motd" + exit 1 +fi + +# Get parameters +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + -owners_fullname) + if [ $# -le 1 ]; then + usage "Owner's Full Name is not specified!" + fi + shift + owners_fullname="$1" + ;; + + -machine_usage) + if [ $# -le 1 ]; then + usage "Machine Usage was not specified!" + fi + shift + machine_usage="$1" + ;; + + -location) + if [ $# -le 1 ]; then + usage "Location was not specified!" + fi + shift + location="$1" + ;; + + -owners_email) + if [ $# -le 1 ]; then + usage "Owner's Email was not specified!" + fi + shift + owners_email="$1" + ;; + + -owners_extension) + if [ $# -le 1 ]; then + usage "Owner's Extention was not specified!" + fi + shift + owners_extension="$1" + ;; + + -new_machine_name) + if [ $# -le 1 ]; then + usage "New Machine Name not specified!" + fi + shift + new_machine_name="$1" + ;; + + *) + usage "Unrecognized parameter $1" + ;; + esac + shift +done + +# Prompt for options not specified on the command line + +if [ "_$owners_fullname" = "_" ]; then + print "Owner's Fullname" + print "> \c" + read owners_fullname + if [ "_$owners_fullname" = "_" ]; then + owners_fullname=Unknown + fi +fi + +if [ "_$machine_usage" = "_" ]; then + print "What is this machine used for?" + print "> \c" + read machine_usage + if [ "_$machine_usage" = "_" ]; then + machine_usage="This machine is used by \ for \" + fi +fi + +if [ "_$location" = "_" ]; then + print "Where is this machine located?" + print "> \c" + read location + if [ "_$location" = "_" ]; then + location="\" + fi +fi + +if [ "_$owners_email" = "_" ]; then + print "Owner's Email address:" + print "(Should be the same as username. This script will supply the @cup.hp.com)" + print "> \c" + read owners_email + if [ "_$owners_email" = "_" ]; then + owners_email=Unknown + fi +fi + +if [ "_$owners_extension" = "_" ]; then + print "Owner's Phone extention:" + print "(Should be of the format 7-XXXX This script will prepend \"t-44\" to" + print "the entered extension)" + print "> \c" + read owners_extension + if [ "_$owners_extension" = "_" ]; then + owners_extension=7-XXXX + fi +fi + +until [ "_$new_machine_name" != "_" ]; do + new_machine_name="garbage" + print "New machine name:" + print "> \c" + read new_machine_name + + if [ "_$new_machine_name" = "_" ]; then + error "Must enter a new machine name" + fi +done + +display_options + +display +display "Continue Installation (Y/n)?\c" +answer=y +read answer +case "$answer" in + y|Y|yes|Yes|YES|"") + continue + ;; + *) + display "Installation aborted. Rerun $me if you wish to install again" + exit 1 + ;; +esac + +function do_installation { +#display_options + +banner $new_machine_name > /etc/motd +echo $unames $unamen $unamer $unamev $unamem $unamei $unamel >> /etc/motd +cat >> /etc/motd <<:END + +******************************************************************************* +* This is a private system operated for the Hewlett-Packard Company business. * +* Authorization from HP management is required to use this system. * +* Use by unauthorized persons is prohibited. * +******************************************************************************* +For System Support: Mon-Fri 8:00-5:00 Email (site-ux@cup.hp.com) +Phone: t-447-1212 After hours/weekend Pre-arrange: t-447-0629 +------------------------------------------------------------------------------- +Usage: $machine_usage +Owner: $owners_fullname ($owners_email@cup.hp.com) Phone: +t-44$owners_extension +Location: $location +------------------------------------------------------------------------------- +:END + +display "/etc/motd successfully created" + +} # do_installation + +do_installation | tee $logfile diff --git a/clients/HP/bin/make_resolv_conf b/clients/HP/bin/make_resolv_conf new file mode 100644 index 0000000..e01a91c --- /dev/null +++ b/clients/HP/bin/make_resolv_conf @@ -0,0 +1,49 @@ +#!/bin/ksh +################################################################################ +# +# File: make_resolv_conf +# Description: A script to create a valid /etc/resolv.conf +# Author: Andrew DeFaria, California Language Labs +# Created: Wed Jan 15 16:52:22 PST 1997 +# Modified: Wed Jan 15 16:52:22 PST 1997 (Andrew DeFaria) defaria@cup.hp.com +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +function usage { + print -u2 "$me: [ ] [ ]" + exit 1 +} # usage + +# Get parameters +primary_dns="15.28.98.95 # smildon" +secondary_dns="15.0.96.86 # masher" +trierary_dns="15.13.168.80 # hparch4" + +if [ $# -eq 2 ]; then + primary_dns="$1" + secondary_dns="$2" +elif [ $# -eq 1 ]; then + primary_dns="$1" +fi + +resolv_conf_file=/etc/resolv.conf + +# Don't copy this time... +#cp $resolv_conf_file $resolv_conf_file.old + +print "domain cup.hp.com" > $resolv_conf_file +print "search cup.hp.com hp.com ch.apollo.hp.com" >> $resolv_conf_file +print "nameserver $primary_dns" >> $resolv_conf_file +print "nameserver $secondary_dns" >> $resolv_conf_file +print "nameserver $trierary_dns" >> $resolv_conf_file + +# If machine runs cupmail (see root crontab) then we need to make a .local +# file. +cp $resolv_conf_file $resolv_conf_file.local + +print "$me: Created new $resolv_conf_file" +#print "$me: Saved old $resolv_conf_file in $resolv_conf_file.old" diff --git a/clients/HP/bin/makehome b/clients/HP/bin/makehome new file mode 100644 index 0000000..9809c83 --- /dev/null +++ b/clients/HP/bin/makehome @@ -0,0 +1,160 @@ +#!/bin/ksh +################################################################################ +# +# File: makehome +# Description: Makes a users home directory +# Author: Andrew@DeFaria.com +# Created: Thu Jun 3 17:21:24 PDT 1999 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +function usage { + display "$me: Usage: makehome [ -v|erbose ] [ -d|ebug ] -username + +\t\t\t -uid " + + exit 1 +} # usage + +function prompt_for_field { + fieldname="$1" + fieldvalue= + + while [ ! -n "$fieldvalue" ]; do + display "Enter the value for $fieldname:\c" + read fieldvalue + + if [ ! -n "$fieldvalue" ]; then + error "Must specify $fieldname!" + fi + done +} # prompt_for_field + +function show_parms { + display "$me" + display "-------------------------------------" + display "username = $username" + display "uid = $uid" + display "homedrive = $homedrive" + display "devdrive = $devdrive" + display "homepath = $homepath" + display "devpath = $devpath" + display + display "Command line equivalent:" + display + display "$me -username $username -uid $uid" + display + display "Are the parameters correct [Y|n]?\c" + read answer + case "$answer" in + Y|y) + : OK! + ;; + *) + exit + ;; + esac +} # show_parms + +if is_not_root; then + error "You must be root to use this command" 1 +fi + +case "$(hostname)" in + dreamcicle|fudgecicle) + ;; + + *) + error "Must be running on either dreamcicle or fudgecicle to execute +this command" 2 + ;; + +esac + +# Get options +debug= +verbose= + +while [ $# -ge 1 ]; do + case "$1" in + -u|usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + -username) + if [ $# -le 1 ]; then + error "Username not specified!" 0 + usage + fi + shift + username="$1" + ;; + + -uid) + if [ $# -le 1 ]; then + error "UID not specified!" 0 + usage + fi + shift + uid="$1" + ;; + + *) + error "Unknown option \"$1\" encountered" 0 + usage + ;; + + esac + shift +done + +if [ "$username" = "" ]; then + prompt_for_field "Username" + username=$fieldvalue +fi + +if [ "$uid" = "" ]; then + prompt_for_field "UID" + uid=$fieldvalue +fi + +homedrive=home1 +devdrive=dev1 +homepath=/netapp/dvd/$homedrive/$username +devpath=/netapp/dvd/$devdrive/$username + +show_parms + +mkdir -p $homepath +chown $uid:cdseng $homepath +chmod 775 $homepath +mkdir -p $devpath +chown $uid:cdseng $devpath +chmod 775 $devpath + +if [ ! -h $homepath/dev ]; then + ln -s /auto/dev/$username $homepath/dev +fi diff --git a/clients/HP/bin/makehosts b/clients/HP/bin/makehosts new file mode 100644 index 0000000..f100c9c --- /dev/null +++ b/clients/HP/bin/makehosts @@ -0,0 +1,44 @@ +#!/bin/ksh +################################################################################ +# +# File: makehosts +# Description: Makes an /etc/hosts file +# Author: Andrew@DeFaria.com +# Created: Thu Jun 3 17:21:24 PDT 1999 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +if [ $(/usr/xpg4/bin/id -u) -ne 0 ]; then + print -u2 "$me: Error: You must be root to use this command" + exit 1 +fi + +stdhosts=${stdhosts:-$adm_base/etc/stdhosts} +syshosts=${syshosts:-/etc/hosts} +localhosts=${localhosts:-/etc/hosts.local} + +current_ip=$(nslookup $(hostname) | tail -2 | awk '{print $NF}') + +cp $stdhosts $syshosts + +if ! grep $(hostname) $syshosts > /dev/null; then + print "$current_ip\t$(hostname).cisco.com\t\t$(hostname)" >> $syshosts +fi + +if [ -f $localhosts ]; then + cat $localhosts >> $syshosts +fi diff --git a/clients/HP/bin/mkpass b/clients/HP/bin/mkpass new file mode 100644 index 0000000..44caf97 --- /dev/null +++ b/clients/HP/bin/mkpass @@ -0,0 +1,238 @@ +#!/bin/ksh +################################################################################ +# +# File: mkpass +# Description: Mother of All (MoA) passwd administration script +# Author: Cory Chan (cory@cup.hp.com) +# Language: Korn Shell +# Modified: 11/18/1994 Ryan Fong (fong@cup.hp.com) Modified for 10.0 +# 07/26/1995 Andrew DeFaria (defaria@cup.hp.com) Revamped to use +# NFS mount point to avoid rcp. Script now works for both 9.0 +# and 10.0. +# 08/21/1995 Andrew DeFaria (defaria@cup.hp.com) Revamped mail +# message sending. +# 03/25/98 Michael Coulter (coulter) Changed "ch.apollo" to +# "che.hp.com" because of a domain name change for Chelmsford. +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# First source the appserver script +if [ -x /app/appserver ]; then + . /app/appserver +fi + +if [ "$OS" = "09" ]; then + /bin/cp /usr/spool/cron/crontabs/root /tmp/root-crontab + /usr/bin/crontab /tmp/root-crontab >> /nisclient.log 2>&1 + /bin/rm /tmp/root-crontab +else + /bin/cp /var/spool/cron/crontabs/root /tmp/root-crontab + /usr/bin/crontab /tmp/root-crontab >> /nisclient.log 2>&1 + /bin/rm /tmp/root-crontab +fi +exit + +# Set ADMIN_ROOT +ADMIN_ROOT=/app/admin + +# Check for force flag +FORCE="False" + +if [ "$1" = "-f" ]; then + FORCE="True" +fi + +# Whom to notify of problems. +NOTIFY=root@$(hostname) + +# Determine OS level +OS=`uname -r | cut -c 3-4` + +MASTER_PASSWD=$ADMIN_ROOT/lib/master_passwd +MASTER_PASSWD_MLL=$ADMIN_ROOT/lib/master_passwd.mll +LOCAL_PASSWD=/etc/passwd.loc +EXCLUDED_PASSWD=/etc/passwd.exc +MARKER_FILE=/etc/pass.time +PASSWD_OLD=/etc/passwd.old +PASSWD=/etc/passwd +TMP_PASSWD=/tmp/passwd.$$ +TMP_PASSWD2=/tmp/passwd2.$$ + +# Log and save old messages if there were any problems +MESSAGE_FILE=$ADMIN_ROOT/log/mkpass.$(uname -n) + +# Set file attribute +umask 022 +# Check for existance of $MASTER_PASSWD file. If missing send message and +# abort. +if [[ ! -f $MASTER_PASSWD ]]; then + mailx -s "mkpass: $MASTER_PASSWD file is missing!" $NOTIFY < /dev/null + exit 1 +fi + +# Check existence of necessary files; make when necessary. +if [[ ! -f $MARKER_FILE ]]; then + # make time marker if not exists + touch $MARKER_FILE +fi + +if [[ ! -f $EXCLUDED_PASSWD ]]; then + echo "# one login per line, no space/tab/null line#" > $EXCLUDED_PASSWD +fi + +if [[ ! -f $PASSWD_OLD ]]; then + # make old passwd file if not exists + cp $PASSWD $PASSWD_OLD +fi + +if [[ ! -f $LOCAL_PASSWD ]]; then + # no local file, notify and exit + cat > $MESSAGE_FILE < $MESSAGE_FILE < = /etc/passwd.old) +----------------------------------------------------------------------------- +!EOM + diff $PASSWD $PASSWD_OLD >> $MESSAGE_FILE + mailx -s "mkpass: $PASSWD incorrectly changed" $NOTIFY < $MESSAGE_FILE + exit 0 + fi +fi + +# Check to see if $LOCAL_PASSWD, $MASTER_PASSWD or $EXCLUDED_PASSWD is newer +# than $PASSWD. If so, combine $LOCAL_PASSWD and $MASTER_PASSWD (excluding +# entries from $EXCLUDED_PASSWD) to form new $PASSWD +if [[ $FORCE = "True" || + $LOCAL_PASSWD -nt $PASSWD || + $MASTER_PASSWD -nt $PASSWD || + $MASTER_PASSWD_MLL -nt $PASSWD || + $EXCLUDED_PASSWD -nt $PASSWD ]]; then + + # If only the $MASTER_PASSWD changed then make a note not to send email + if [[ $LOCAL_PASSWD -nt $PASSWD || + $EXCLUDED_PASSWD -nt $PASSWD ]]; then + NOTIFY_OF_CHANGE=True + else + NOTIFY_OF_CHANGE=False + fi + + # Save an old copy around + cp $PASSWD $PASSWD_OLD + + # Check root entry in $LOCAL_PASSWD + if grep -v "^#" $LOCAL_PASSWD | head -n 1 | grep "^root:" > /dev/null; then + # 1st entry root OKAY in $LOCAL_PASSWD + : + else + # 1st entry NOT root in passwd.loc + cat > $MESSAGE_FILE <> $TMP_PASSWD2 + done < $MASTER_PASSWD_MLL + + cat $LOCAL_PASSWD $MASTER_PASSWD $TMP_PASSWD2 > $TMP_PASSWD + + # Do exclusion + grep -v "^#" $EXCLUDED_PASSWD |\ + grep -vf $EXCLUDED_PASSWD $TMP_PASSWD > $TMP_PASSWD2 + + # Transform password file to 10.0 format + if [ $OS = "10" ]; then + sed -e 's/:\/nfs/:\/net/' -e 's/:\/bin/:\/usr\/bin/' \ + $TMP_PASSWD2 > $TMP_PASSWD + rm -f $TMP_PASSWD2 + else + mv $TMP_PASSWD2 $TMP_PASSWD + fi + + if [ -s $TMP_PASSWD ]; then + mv $TMP_PASSWD $PASSWD + chmod 444 $PASSWD + else + rm -f $TMP_PASSWD + mailx -s "mkpass: Error: Zero length passwd file resulted!" $NOTIFY < $MESSAGE_FILE < = /etc/passwd.old) +----------------------------------------------------------------------------- +!EOM + diff $PASSWD $PASSWD_OLD >> $MESSAGE_FILE + mailx -s "mkpass: Made new $PASSWD" $NOTIFY < $MESSAGE_FILE + fi +fi + +# Update marker file +touch -ma $MARKER_FILE + +# Update log file +echo "$PASSWD on `uname -n` is up to date as of `date`" > $MESSAGE_FILE + +exit 0 diff --git a/clients/HP/bin/mkpass-nisclient b/clients/HP/bin/mkpass-nisclient new file mode 100644 index 0000000..3c33961 --- /dev/null +++ b/clients/HP/bin/mkpass-nisclient @@ -0,0 +1,234 @@ +#!/bin/ksh +################################################################################ +# +# File: mkpass +# Description: Mother of All (MoA) passwd administration script +# Author: Cory Chan (cory@cup.hp.com) +# Language: Korn Shell +# Modified: 11/18/1994 Ryan Fong (fong@cup.hp.com) Modified for 10.0 +# 07/26/1995 Andrew DeFaria (defaria@cup.hp.com) Revamped to use +# NFS mount point to avoid rcp. Script now works for both 9.0 +# and 10.0. +# 08/21/1995 Andrew DeFaria (defaria@cup.hp.com) Revamped mail +# message sending. +# 03/25/98 Michael Coulter (coulter) Changed "ch.apollo" to +# "che.hp.com" because of a domain name change for Chelmsford. +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# First source the appserver script +if [ -x /app/appserver ]; then + . /app/appserver +fi + +if [ "$OS" = "09" ]; then + /app/admin/bin/nisclient-9.x +else + /app/admin/bin/nisclient +fi +exit + +# Set ADMIN_ROOT +ADMIN_ROOT=/app/admin + +# Check for force flag +FORCE="False" + +if [ "$1" = "-f" ]; then + FORCE="True" +fi + +# Whom to notify of problems. +NOTIFY=root@$(hostname) + +# Determine OS level +OS=`uname -r | cut -c 3-4` + +MASTER_PASSWD=$ADMIN_ROOT/lib/master_passwd +MASTER_PASSWD_MLL=$ADMIN_ROOT/lib/master_passwd.mll +LOCAL_PASSWD=/etc/passwd.loc +EXCLUDED_PASSWD=/etc/passwd.exc +MARKER_FILE=/etc/pass.time +PASSWD_OLD=/etc/passwd.old +PASSWD=/etc/passwd +TMP_PASSWD=/tmp/passwd.$$ +TMP_PASSWD2=/tmp/passwd2.$$ + +# Log and save old messages if there were any problems +MESSAGE_FILE=$ADMIN_ROOT/log/mkpass.$(uname -n) + +# Set file attribute +umask 022 +# Check for existance of $MASTER_PASSWD file. If missing send message and +# abort. +if [[ ! -f $MASTER_PASSWD ]]; then + mailx -s "mkpass: $MASTER_PASSWD file is missing!" $NOTIFY < /dev/null + exit 1 +fi + +# Check existence of necessary files; make when necessary. +if [[ ! -f $MARKER_FILE ]]; then + # make time marker if not exists + touch $MARKER_FILE +fi + +if [[ ! -f $EXCLUDED_PASSWD ]]; then + echo "# one login per line, no space/tab/null line#" > $EXCLUDED_PASSWD +fi + +if [[ ! -f $PASSWD_OLD ]]; then + # make old passwd file if not exists + cp $PASSWD $PASSWD_OLD +fi + +if [[ ! -f $LOCAL_PASSWD ]]; then + # no local file, notify and exit + cat > $MESSAGE_FILE < $MESSAGE_FILE < = /etc/passwd.old) +----------------------------------------------------------------------------- +!EOM + diff $PASSWD $PASSWD_OLD >> $MESSAGE_FILE + mailx -s "mkpass: $PASSWD incorrectly changed" $NOTIFY < $MESSAGE_FILE + exit 0 + fi +fi + +# Check to see if $LOCAL_PASSWD, $MASTER_PASSWD or $EXCLUDED_PASSWD is newer +# than $PASSWD. If so, combine $LOCAL_PASSWD and $MASTER_PASSWD (excluding +# entries from $EXCLUDED_PASSWD) to form new $PASSWD +if [[ $FORCE = "True" || + $LOCAL_PASSWD -nt $PASSWD || + $MASTER_PASSWD -nt $PASSWD || + $MASTER_PASSWD_MLL -nt $PASSWD || + $EXCLUDED_PASSWD -nt $PASSWD ]]; then + + # If only the $MASTER_PASSWD changed then make a note not to send email + if [[ $LOCAL_PASSWD -nt $PASSWD || + $EXCLUDED_PASSWD -nt $PASSWD ]]; then + NOTIFY_OF_CHANGE=True + else + NOTIFY_OF_CHANGE=False + fi + + # Save an old copy around + cp $PASSWD $PASSWD_OLD + + # Check root entry in $LOCAL_PASSWD + if grep -v "^#" $LOCAL_PASSWD | head -n 1 | grep "^root:" > /dev/null; then + # 1st entry root OKAY in $LOCAL_PASSWD + : + else + # 1st entry NOT root in passwd.loc + cat > $MESSAGE_FILE <> $TMP_PASSWD2 + done < $MASTER_PASSWD_MLL + + cat $LOCAL_PASSWD $MASTER_PASSWD $TMP_PASSWD2 > $TMP_PASSWD + + # Do exclusion + grep -v "^#" $EXCLUDED_PASSWD |\ + grep -vf $EXCLUDED_PASSWD $TMP_PASSWD > $TMP_PASSWD2 + + # Transform password file to 10.0 format + if [ $OS = "10" ]; then + sed -e 's/:\/nfs/:\/net/' -e 's/:\/bin/:\/usr\/bin/' \ + $TMP_PASSWD2 > $TMP_PASSWD + rm -f $TMP_PASSWD2 + else + mv $TMP_PASSWD2 $TMP_PASSWD + fi + + if [ -s $TMP_PASSWD ]; then + mv $TMP_PASSWD $PASSWD + chmod 444 $PASSWD + else + rm -f $TMP_PASSWD + mailx -s "mkpass: Error: Zero length passwd file resulted!" $NOTIFY < $MESSAGE_FILE < = /etc/passwd.old) +----------------------------------------------------------------------------- +!EOM + diff $PASSWD $PASSWD_OLD >> $MESSAGE_FILE + mailx -s "mkpass: Made new $PASSWD" $NOTIFY < $MESSAGE_FILE + fi +fi + +# Update marker file +touch -ma $MARKER_FILE + +# Update log file +echo "$PASSWD on `uname -n` is up to date as of `date`" > $MESSAGE_FILE + +exit 0 diff --git a/clients/HP/bin/mkpass.prenis b/clients/HP/bin/mkpass.prenis new file mode 100644 index 0000000..c2b484c --- /dev/null +++ b/clients/HP/bin/mkpass.prenis @@ -0,0 +1,227 @@ +#!/bin/ksh +################################################################################ +# +# File: mkpass +# Description: Mother of All (MoA) passwd administration script +# Author: Cory Chan (cory@cup.hp.com) +# Language: Korn Shell +# Modified: 11/18/1994 Ryan Fong (fong@cup.hp.com) Modified for 10.0 +# 07/26/1995 Andrew DeFaria (defaria@cup.hp.com) Revamped to use +# NFS mount point to avoid rcp. Script now works for both 9.0 +# and 10.0. +# 08/21/1995 Andrew DeFaria (defaria@cup.hp.com) Revamped mail +# message sending. +# 03/25/98 Michael Coulter (coulter) Changed "ch.apollo" to +# "che.hp.com" because of a domain name change for Chelmsford. +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# First source the appserver script +if [ -x /app/appserver ]; then + . /app/appserver +fi + +# Set ADMIN_ROOT +ADMIN_ROOT=/app/admin + +# Check for force flag +FORCE="False" + +if [ "$1" = "-f" ]; then + FORCE="True" +fi + +# Whom to notify of problems. +NOTIFY=root@$(hostname) + +# Determine OS level +OS=`uname -r | cut -c 3-4` + +MASTER_PASSWD=$ADMIN_ROOT/lib/master_passwd +MASTER_PASSWD_MLL=$ADMIN_ROOT/lib/master_passwd.mll +LOCAL_PASSWD=/etc/passwd.loc +EXCLUDED_PASSWD=/etc/passwd.exc +MARKER_FILE=/etc/pass.time +PASSWD_OLD=/etc/passwd.old +PASSWD=/etc/passwd +TMP_PASSWD=/tmp/passwd.$$ +TMP_PASSWD2=/tmp/passwd2.$$ + +# Log and save old messages if there were any problems +MESSAGE_FILE=$ADMIN_ROOT/log/mkpass.$(uname -n) + +# Set file attribute +umask 022 +# Check for existance of $MASTER_PASSWD file. If missing send message and +# abort. +if [[ ! -f $MASTER_PASSWD ]]; then + mailx -s "mkpass: $MASTER_PASSWD file is missing!" $NOTIFY < /dev/null + exit 1 +fi + +# Check existence of necessary files; make when necessary. +if [[ ! -f $MARKER_FILE ]]; then + # make time marker if not exists + touch $MARKER_FILE +fi + +if [[ ! -f $EXCLUDED_PASSWD ]]; then + echo "# one login per line, no space/tab/null line#" > $EXCLUDED_PASSWD +fi + +if [[ ! -f $PASSWD_OLD ]]; then + # make old passwd file if not exists + cp $PASSWD $PASSWD_OLD +fi + +if [[ ! -f $LOCAL_PASSWD ]]; then + # no local file, notify and exit + cat > $MESSAGE_FILE < $MESSAGE_FILE < = /etc/passwd.old) +----------------------------------------------------------------------------- +!EOM + diff $PASSWD $PASSWD_OLD >> $MESSAGE_FILE + mailx -s "mkpass: $PASSWD incorrectly changed" $NOTIFY < $MESSAGE_FILE + exit 0 + fi +fi + +# Check to see if $LOCAL_PASSWD, $MASTER_PASSWD or $EXCLUDED_PASSWD is newer +# than $PASSWD. If so, combine $LOCAL_PASSWD and $MASTER_PASSWD (excluding +# entries from $EXCLUDED_PASSWD) to form new $PASSWD +if [[ $FORCE = "True" || + $LOCAL_PASSWD -nt $PASSWD || + $MASTER_PASSWD -nt $PASSWD || + $MASTER_PASSWD_MLL -nt $PASSWD || + $EXCLUDED_PASSWD -nt $PASSWD ]]; then + + # If only the $MASTER_PASSWD changed then make a note not to send email + if [[ $LOCAL_PASSWD -nt $PASSWD || + $EXCLUDED_PASSWD -nt $PASSWD ]]; then + NOTIFY_OF_CHANGE=True + else + NOTIFY_OF_CHANGE=False + fi + + # Save an old copy around + cp $PASSWD $PASSWD_OLD + + # Check root entry in $LOCAL_PASSWD + if grep -v "^#" $LOCAL_PASSWD | head -n 1 | grep "^root:" > /dev/null; then + # 1st entry root OKAY in $LOCAL_PASSWD + : + else + # 1st entry NOT root in passwd.loc + cat > $MESSAGE_FILE <> $TMP_PASSWD2 + done < $MASTER_PASSWD_MLL + + cat $LOCAL_PASSWD $MASTER_PASSWD $TMP_PASSWD2 > $TMP_PASSWD + + # Do exclusion + grep -v "^#" $EXCLUDED_PASSWD |\ + grep -vf $EXCLUDED_PASSWD $TMP_PASSWD > $TMP_PASSWD2 + + # Transform password file to 10.0 format + if [ $OS = "10" ]; then + sed -e 's/:\/nfs/:\/net/' -e 's/:\/bin/:\/usr\/bin/' \ + $TMP_PASSWD2 > $TMP_PASSWD + rm -f $TMP_PASSWD2 + else + mv $TMP_PASSWD2 $TMP_PASSWD + fi + + if [ -s $TMP_PASSWD ]; then + mv $TMP_PASSWD $PASSWD + chmod 444 $PASSWD + else + rm -f $TMP_PASSWD + mailx -s "mkpass: Error: Zero length passwd file resulted!" $NOTIFY < $MESSAGE_FILE < = /etc/passwd.old) +----------------------------------------------------------------------------- +!EOM + diff $PASSWD $PASSWD_OLD >> $MESSAGE_FILE + mailx -s "mkpass: Made new $PASSWD" $NOTIFY < $MESSAGE_FILE + fi +fi + +# Update marker file +touch -ma $MARKER_FILE + +# Update log file +echo "$PASSWD on `uname -n` is up to date as of `date`" > $MESSAGE_FILE + +exit 0 diff --git a/clients/HP/bin/mkpty b/clients/HP/bin/mkpty new file mode 100644 index 0000000..79b7e2b --- /dev/null +++ b/clients/HP/bin/mkpty @@ -0,0 +1,102 @@ +#!/bin/ksh +# usage: mkpty -n number [-d dir] [ -m mastermajor ] + +# Algorithm: +# For master side, the files have a ptym/pty prefix. +# For slave side, the files have a pty/tty prefix. +# The suffix naming convention is: +# First 400: pty[p-za-ce-o] +# Next 2500: pty[p-za-ce-o] +# Last 25000: pty[p-za-ce-o] + +export OS=$(/bin/uname -r | /usr/bin/cut -f2 -d.) + +if [ "$OS" = "10" ]; then + mknod=/sbin/mknod +else + mknod=/etc/mknod +fi + +function makepty { + [[ -c $1 ]] && return 0 + $mknod $1 c $2 $3 + chmod 666 $1 && chown bin:bin $1 +} + +typeset -i major=16 slave +typeset -i npty=0 minor=0 j k +typeset -Z2 n2 +typeset -Z3 n3 +typeset -l prefix[25] hex[16] + +set -A prefix p q r s t u v w x y z a b c e f g h i j k l m n o +set -A hex 0 1 2 3 4 5 6 7 8 9 a b c d e f + +dir=/dev + +while getopts :n:Dd:m: c; do + case $c in + n) npty=$OPTARG;; + d) dir=$OPTARG;; + m) major=$OPTARG;; + D) set -x;; + :) print -u2 $OPTARG requires a value; exit 1;; + *) print -u2 Invalid argument $OPTARG; exit 1;; + esac +done + +shift OPTIND-1; + +if [[ $# -ne 0 ]]; then + print -u2 "Usage: $0 -n number [-d dir] [-m mastermajor]" + exit 1; +fi + +slave=major+1 +cd ${dir} + +mkdir -p pty ptym + +j=0;k=0 +while (( j < 25 && npty>0 )); do + name=${prefix[j]}${hex[k]} + makepty ptym/pty${name} ${major} ${minor} + makepty pty/tty${name} ${slave} ${minor} + if (( j<3 )); then + rm -f pty${name} && ln ptym/pty${name} pty${name} + rm -f tty${name} && ln pty/tty${name} tty${name} + fi + npty=npty-1 + (( (k=k+1) >= 16 )) && k=0 && j=j+1 + minor=minor+1 +done + +j=0;k=0 +while (( j < 25 && npty>0 )); do + n2=$k + name=${prefix[j]}${n2} + makepty ptym/pty${name} ${major} ${minor} + makepty pty/tty${name} ${slave} ${minor} + npty=npty-1 + (( (k=k+1) >= 100 )) && k=0 && j=j+1 + minor=minor+1 +done + +j=0;k=0 +while (( j < 25 && npty>0 )); do + n3=$k + name=${prefix[j]}${n3} + makepty ptym/pty${name} ${major} ${minor} + makepty pty/tty${name} ${slave} ${minor} + npty=npty-1 + (( (k=k+1) >= 1000 )) && k=0 && j=j+1 + minor=minor+1 +done + +if hp9000s700; then +: +elif hp9000s800; then + mknod ptym/clone c ${major} 0xffffff + chmod 666 ptym/clone + chown bin:bin ptym/clone +fi diff --git a/clients/HP/bin/monitor_taskbroker b/clients/HP/bin/monitor_taskbroker new file mode 100644 index 0000000..7c30ffe --- /dev/null +++ b/clients/HP/bin/monitor_taskbroker @@ -0,0 +1,39 @@ +#!/bin/ksh +################################################################################ +# +# File: monitor_taskbroker +# Description: Quick script to monitor the taskbroker/build pool +# Author: Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# Modified:: +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +integer day_of_week=$(date +%w) +integer sleep_time=5*60 + +talktotaskbroker=/usr/eclipse/etc/talktotaskbroker +logfile=/tmp/taskbroker$day_of_week.log + +function get_status { + print "At $(date)" + $talktotaskbroker mstatus +} # get_status + +rm -f $logfile + +print "$me started" +while true; do + if [ $day_of_week -ne $(date +%w) ]; then + day_of_week=$(date +%w) + logfile_old=$logfile + logfile=/tmp/taskbroker$day_of_week.log + print "Continuing in $logfile..." >> $logfile_old + fi + + get_status >> $logfile + sleep $sleep_time +done & diff --git a/clients/HP/bin/mount_nfs b/clients/HP/bin/mount_nfs new file mode 100644 index 0000000..59766fb --- /dev/null +++ b/clients/HP/bin/mount_nfs @@ -0,0 +1,43 @@ +#!/bin/ksh +################################################################################ +# +# File: unmount_nfs +# RCS: $Header:$ +# Description: A script to unmount all nfs mounts. Note if the automounter is +# running then this script will first shutdown the automounter. +# This script returns 0 for success or non zero if it was unable +# to umount all nfs mounts. This script must run as root. +# Author: Andrew DeFaria, California Language Labs +# Created: Fri Jun 6 10:31:51 PDT 1997 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +export me=`basename $0` +export OS=$(/bin/uname -r | /usr/bin/cut -f2 -d.) + +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: You must be root to use this command" + exit 1 +fi + +# First try to mount any nfs mounts listed in /etc/checklist +print "Re-establishing all static NFS mounts..." +if [ "$OS" = "10" ]; then + /usr/sbin/mount -aQF nfs +else + /etc/mount -at nfs +fi + +# Restart automounter if necessary +if [ -f /etc/automounter_was_here ]; then + print "Restarting automounter..." + if [ "$OS" = "10" ]; then + /usr/sbin/automount -f /etc/auto_master + else + /usr/etc/automount -f /etc/auto_master + fi + rm -f /etc/automounter_was_here +fi diff --git a/clients/HP/bin/mount_project_lvm b/clients/HP/bin/mount_project_lvm new file mode 100644 index 0000000..6fd51d8 --- /dev/null +++ b/clients/HP/bin/mount_project_lvm @@ -0,0 +1,31 @@ +#!/bin/ksh +################################################################################ +# +# File: mount_project_lvm +# Description: This script will mount all project's logical volumes +# Author: Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# Modifications: +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: You must be root to execute this command!" + exit 1 +fi + +if [ $# -ne 2 ]; then + print -u2 "Usage: $me projectID fileserver" + exit 1 +fi + +projectID=$1 +fileserver=$2 + +print Mounting $projectID LVMs on $fileserver and build servers... +/app/admin/bin/buildservers "/app/admin/bin/mountlvm $projectID $fileserver" + +print Mounting $projectID and $fileserver on virtual workstations... +/app/admin/bin/wrkservers "/app/admin/bin/mountlvm $projectID $fileserver" diff --git a/clients/HP/bin/mountlvm b/clients/HP/bin/mountlvm new file mode 100644 index 0000000..0c521a8 --- /dev/null +++ b/clients/HP/bin/mountlvm @@ -0,0 +1,54 @@ +#!/bin/ksh +################################################################################ +# +# File: mountlvm +# Description: This script will mount a project's logical volumes +# Author: Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# Modifications: +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: You must be root to execute this command!" + exit 1 +fi + +if [ $# -ne 2 ]; then + print -u2 "Usage: $me projectID fileserver" + exit 1 +fi + +projectID=$1 +fileserver=$2 + +function create_dir_and_mount { + machine=$1 + mount_directory=$2 + mount_over_directory=/tmp_mnt/net/$machine$2 + if [ ! -d $mount_over_directory ]; then + print Making $mount_over_directory + mkdir -p $mount_over_directory + fi + + if [ ! -d $mount_over_directory/lost+found ]; then + print Mounting $machine:$mount_directory to $mount_over_directory + /usr/sbin/mount $machine:$mount_directory $mount_over_directory + fi +} # create_dir_and_mount + +function kick_automounter { + automount_pid=$(/app/sj automount | awk '{print $2}') + + print Kicking automounter \($automount_pid\) + kill -HUP $automount_pid +} # kick_automounter + +create_dir_and_mount cllvu01 /CLO/Storage/Views/$projectID +create_dir_and_mount cllvu02 /CLO/Storage/Views/$projectID +create_dir_and_mount cllvu03 /CLO/Storage/Views/$projectID +create_dir_and_mount $fileserver /data/proj/$projectID + +kick_automounter diff --git a/clients/HP/bin/nisclient-11.x b/clients/HP/bin/nisclient-11.x new file mode 100644 index 0000000..f9533c3 --- /dev/null +++ b/clients/HP/bin/nisclient-11.x @@ -0,0 +1,152 @@ +#!/bin/ksh +############################################################################### +# This script sets a machine up to be an NIS client. +# Kevin Lister 10.28.98 +############################################################################### + +# Variables +logfile=/nisclient.log +me=${0##*/} + +admin=cll-support@cup.hp.com +nisdomain=cll +domainname= +namesvrs=/etc/rc.config.d/namesvrs +nsswitch=/etc/nsswitch.conf +pwfile=/etc/passwd +lclpwfile=/etc/passwd.loc +nispwfile=/etc/passwd.nis +crontab=/var/spool/cron/crontabs/root +newcrontab=/tmp/root-crontab +null=/dev/null +ypdir=/var/yp + +# Functions +function error { + print -u2 "$me: Error: $1" + /usr/bin/mailx -s "$(uname -n): NIS setup error: $1" $admin < $null + #exit 255; +} # error + +function warning { + print -u2 "$me: Warning: $1" +} # warning + +function display { + print "$1" +} # display + +function info { + display "$me: Info: $1" +} # info + +## +########## Main +## + +## +########## Check the status of the system before proceeding +## + +# Must be root to run this +if [ $(id -u) -ne 0 ]; then + error "Must be root to execute this command... Exiting." +fi + +# Check to see if this script has already been ran +if [ -a $logfile ]; then + error "$me has already been ran on $(uname -n)... Exiting" +fi + +# Check to see if domainname has been set +domainname=`/bin/domainname` +if [ "_$domainname" != "_" ]; then + error "NIS Domain name is already set to -> $domainname... Exiting." +fi + +# Are we already running NIS? +/usr/bin/ypwhich >> $logfile 2>&1 +if [ $? -eq 0 ]; then + error "This system is already running NIS... Exiting." +fi + +# Check to see if there is a name service switch config file +if [ -a $nsswitch ]; then + error "This system has a name service switch config file... Exiting." +fi + +# Check to see if /var/yp exists +if [ ! -a $ypdir ]; then + error "Directory /var/yp does not exist... Exiting" +fi + +## +########## System checks out. Set up the files and start NIS. +## + +# Set the NIS domain name - This is probably not needed +/bin/domainname $nisdomain >> $logfile 2>&1 +if [ $? -ne 0 ]; then + error "Could not set NIS domain name... Exiting." +fi + +# Setup the /etc/rc.config.d/namesvrs file +/usr/sbin/ch_rc -ap NIS_CLIENT=1 \ + -p NIS_DOMAIN=cll \ + -p YPBIND_OPTIONS="-ypsetme" + +# Email us if there are local passwd entries other than root +if [ $( /bin/wc -l $lclpwfile | /bin/cut -d " " -f 1) != "1" ]; then + /usr/bin/mailx -s "$(uname -n): passwd.loc has more than 1 line" $admin < $lclpwfile +fi + +# Create NIS passwd file +if [ -a $lclpwfile ]; then + /bin/grep "^root" $lclpwfile > $nispwfile +else + /bin/grep "^root" $pwfile > $nispwfile +fi + +/bin/cat >> $nispwfile <<:END +adm:*:4:4::/usr/adm:/usr/bin/sh +anon:*:21:5:placeholder for future:/:/usr/bin/sync +bin:*:2:2::/usr/bin:/bin/sh +daemon:*:1:5::/:/usr/bin/sh +ftp:*:500:10:anonymous ftp:/home/ftp:/usr/bin/false +lp:*:9:7:[Line Printer]:/usr/spool/lp:/usr/bin/sh +nuucp:*:6:1:0000-uucp(0000):/usr/spool/uucppublic:/usr/lib/uucp/uucico +sync:*:20:1::/:/usr/bin/sync +tftp:*:510:1:Trivial FTP user:/usr/tftpdir:/usr/bin/false +uucp:*:5:3::/usr/spool/uucppublic:/usr/lib/uucp/uucico +who:*:90:1::/:/usr/bin/who +:END + +/bin/grep -v "^root" $lclpwfile >> $nispwfile + +/bin/cat >> $nispwfile <<:END2 +-@dangerous-users ++@sysadmin ++@site-ux ++: +:END2 + +mv $pwfile $pwfile.preNIS +mv $nispwfile $pwfile +chmod 444 $pwfile +chown root:other $pwfile + +# Remove MoA from the root crontab +sed -e "/MoA/d" -e "/mkpass/d" < $crontab > $newcrontab +mv $crontab $crontab-preNIS +/usr/bin/crontab $newcrontab +chmod 444 $crontab +chown root:other $crontab + +# Start the NIS Client daemons +/sbin/init.d/nis.client start >> $logfile 2>&1 +if [ $? -ne 0 ]; then + error "Problem starting the NIS client daemons... Exiting." +fi + +# Email us that a machine was updated +/usr/bin/mailx -s "$(uname -n): NIS setup complete" $admin < $null diff --git a/clients/HP/bin/nisclient-9.x b/clients/HP/bin/nisclient-9.x new file mode 100644 index 0000000..e963f24 --- /dev/null +++ b/clients/HP/bin/nisclient-9.x @@ -0,0 +1,176 @@ +#!/bin/ksh +############################################################################### +# This script sets a machine up to be an NIS client. +# Kevin Lister 10.28.98 + +############################################################################### +# Variables +logfile=/nisclient.log +me=${0##*/} + +admin=cll-support@cup.hp.com +nisdomain=cll +domainname= +netnfsrc=/etc/netnfsrc +nsswitch=/etc/nsswitch.conf +pwfile=/etc/passwd +lclpwfile=/etc/passwd.loc +nispwfile=/etc/passwd.nis +crontab=/usr/spool/cron/crontabs/root +newcrontab=/tmp/root-crontab +null=/dev/null +ypdir=/usr/etc/yp + +# Functions +function error { + print -u2 "$me: Error: $1" + /usr/bin/mailx -s "$(uname -n): NIS setup error: $1" $admin < $null + exit 255; +} # error + +function warning { + print -u2 "$me: Warning: $1" +} # warning + +function display { + print "$1" +} # display + +function info { + display "$me: Info: $1" +} # info + +## +########## Main +## + +## +########## Check the status of the system before proceeding +## + +# Must be root to run this +if [ $(id -u) -ne 0 ]; then + error "Must be root to execute this command... Exiting." +fi + +# Check to see if this script has already been ran +if [ -a $logfile ]; then + error "$me has already been ran on $(uname -n)... Exiting" +fi + +# Check to see if domainname has been set +domainname=`/bin/domainname` +if [ "_$domainname" != "_" ]; then + error "NIS Domain name is already set to -> $domainname... Exiting." +fi + +# Are we already running NIS? +/usr/bin/ypwhich >> $logfile 2>&1 +if [ $? -eq 0 ]; then + error "This system is already running NIS... Exiting." +fi + +# Check to see if there is a name service switch config file +if [ -a $nsswitch ]; then + error "This system has a name service switch config file... +Exiting." +fi + +# Check to see if /etc/yp exists +if [ ! -a $ypdir ]; then + error "Directory /etc/yp does not exist... Exiting" +fi + +## +########## System checks out. Set up the files and start NIS. +## + +# Set the NIS domain name - This is probably not needed +/bin/domainname $nisdomain >> $logfile 2>&1 +if [ $? -ne 0 ]; then + error "Could not set NIS domain name... Exiting." +fi + +# Setup the /etc/netnfsrc file +mv $netnfsrc $netnfsrc.preNIS +cp $netnfsrc.preNIS $netnfsrc +sed -e "s/^NIS_CLIENT=0/NIS_CLIENT=1/" \ + -e "s/^NISDOMAIN=/NISDOMAIN=cll/" \ + < $netnfsrc > $netnfsrc-tmp +mv $netnfsrc-tmp $netnfsrc +chmod 544 $netnfsrc +chown bin:bin $netnfsrc + +# Email us if there are local passwd entries other than root +if [ $( /bin/wc -l $lclpwfile | /usr/bin/cut -d " " -f 1) != "1" ]; then + /usr/bin/mailx -s "$(uname -n): passwd.loc has more than 1 line" +$admin < $lclpwfile +fi + +# Create NIS passwd file +if [ -a $lclpwfile ]; then + /bin/grep "^root" $lclpwfile > $nispwfile +else + /bin/grep "^root" $pwfile > $nispwfile +fi + +/bin/cat >> $nispwfile <<:END +adm:*:4:4:,_MoA_:/usr/adm:/bin/sh +anon:*:21:5:placeholder for future,_MoA_:/:/bin/sync +bin:*:2:2:,_MoA_:/bin:/bin/sh +daemon:*:1:5:,_MoA_:/:/bin/sh +ftp:*:24:5:Anonymous &,,,_LcL_:/home/ftp:/bin/sync +ftp:*:500:10:anonymous ftp,_MoA_:/home/ftp:/bin/false +lp:*:9:7:[Line Printer],,,,_MoA_:/usr/spool/lp:/bin/sh +nuucp:*:6:1:0000-uucp(0000),_MoA_:/usr/spool/uucppublic:/usr/lib/uucp/uucico +sync:*:20:1:,_MoA_:/:/bin/sync +tftp:*:510:1:Trivial FTP user,_MoA_:/usr/tftpdir:/bin/false +uucp:*:5:3:,_MoA_:/usr/spool/uucppublic:/usr/lib/uucp/uucico +who:*:90:1:,_MoA_:/:/bin/who +:END + +/bin/grep -v "^root" $lclpwfile >> $nispwfile + +/bin/cat >> $nispwfile <<:END2 +-@dangerous-users ++@sysadmin ++@site-ux ++: +:END2 + +mv $pwfile $pwfile.preNIS +mv $nispwfile $pwfile +chmod 444 $pwfile +chown root:other $pwfile + +# Remove MoA from the root crontab +sed -e "/MoA/d" -e "/mkpass/d" < $crontab > $newcrontab +mv $crontab $crontab-preNIS +/usr/bin/crontab $newcrontab +chmod 444 $crontab +chown root:other $crontab + +# Start the NIS Client daemons +/etc/ypbind -ypset >> $logfile 2>&1 +sleep 10 +/usr/bin/ypwhich >> $logfile 2>&1 +if [ $? -ne 0 ]; then + error "Problem starting the NIS client daemons... Exiting." +fi + +# Create /net symlink if automounter is NOT running +/bin/ps -ef | /bin/grep automount | /bin/grep -v grep >> $logfile 2>&1 +if [ $? -ne 0 ]; then + /bin/ln -s /nfs /net >> $logfile 2>&1 +fi + +# Create symlinks to shells so new passwd file doesn't blow up +/bin/ln -s /bin/sh /usr/bin/sh +/bin/ln -s /bin/csh /usr/bin/csh +/bin/ln -s /bin/ksh /usr/bin/ksh + +# Create symlinks to ypdir, not required, just friendlier +/bin/ln -s /usr/etc/yp /var/yp + +# Email us that a machine was updated +/usr/bin/mailx -s "$(uname -n): NIS setup complete" $admin < $null diff --git a/clients/HP/bin/nisclient-adl b/clients/HP/bin/nisclient-adl new file mode 100644 index 0000000..c111373 --- /dev/null +++ b/clients/HP/bin/nisclient-adl @@ -0,0 +1,166 @@ +#!/bin/ksh +############################################################################### +# This script sets a machine up to be an NIS client. +# Kevin Lister 10.28.98 +############################################################################### +# Variables +logfile=/nisclient.log +me=${0##*/} + +admin=adl-support@cup.hp.com +nisdomain=adl +domainname= +namesvrs=/etc/rc.config.d/namesvrs +nsswitch=/etc/nsswitch.conf +pwfile=/etc/passwd +lclpwfile=/etc/passwd.loc +nispwfile=/etc/passwd-nis +grpfile=/etc/group +nisgrpfile=/etc/group-nis +crontab=/var/spool/cron/crontabs/root +newcrontab=/tmp/root-crontab +null=/dev/null +ypdir=/var/yp + +# Functions +function error { + print -u2 "$me: Error: $1" + /usr/bin/mailx -s "$(uname -n): NIS setup error: $1" $admin < $null + exit 255; +} # error + +function warning { + print -u2 "$me: Warning: $1" +} # warning + +function display { + print "$1" +} # display + +function info { + display "$me: Info: $1" +} # info + +## +########## Main +## + +## +########## Check the status of the system before proceeding +## + +# Must be root to run this +if [ $(id -u) -ne 0 ]; then + error "Must be root to execute this command... Exiting." +fi + +# Check to see if this script has already been ran +if [ -a $logfile ]; then + error "$me has already been ran on $(uname -n)... Exiting" +fi + +# Check to see if domainname has been set +domainname=`/bin/domainname` +if [ "_$domainname" != "_" ]; then + error "NIS Domain name is already set to -> $domainname... Exiting." +fi + +# Are we already running NIS? +/usr/bin/ypwhich >> $logfile 2>&1 +if [ $? -eq 0 ]; then + error "This system is already running NIS... Exiting." +fi + +# Check to see if there is a name service switch config file +if [ -a $nsswitch ]; then + error "This system has a name service switch config file... +Exiting." +fi + +# Check to see if /var/yp exists +if [ ! -a $ypdir ]; then + error "Directory /var/yp does not exist... Exiting" +fi + +## +########## System checks out. Set up the files and start NIS. +## + +# Set the NIS domain name - This is probably not needed +/bin/domainname $nisdomain >> $logfile 2>&1 +if [ $? -ne 0 ]; then + error "Could not set NIS domain name... Exiting." +fi + +# Setup the /etc/rc.config.d/namesvrs file +/usr/sbin/ch_rc -ap NIS_CLIENT=1 \ + -p NIS_DOMAIN=adl \ + -p WAIT_FOR_NIS_SERVER=FALSE + +# Email us if there are local passwd entries other than root +if [ $( /bin/wc -l $lclpwfile | /bin/cut -d " " -f 1) != "1" ]; then + /usr/bin/mailx -s "$(uname -n): passwd.loc has more than 1 line" +$admin < $lclpwfile +fi + +# Create NIS passwd file +if [ -a $lclpwfile ]; then + /bin/grep "^root" $lclpwfile > $nispwfile +else + /bin/grep "^root" $pwfile > $nispwfile +fi + +/bin/cat >> $nispwfile <<:END +adm:*:4:4::/usr/adm:/usr/bin/sh +anon:*:21:5:placeholder for future:/:/usr/bin/sync +bin:*:2:2::/usr/bin:/bin/sh +daemon:*:1:5::/:/usr/bin/sh +ftp:*:500:10:anonymous ftp:/home/ftp:/usr/bin/false +lp:*:9:7:[Line Printer]:/usr/spool/lp:/usr/bin/sh +nuucp:*:6:1:0000-uucp(0000):/usr/spool/uucppublic:/usr/lib/uucp/uucico +sync:*:20:1::/:/usr/bin/sync +tftp:*:510:1:Trivial FTP user:/usr/tftpdir:/usr/bin/false +uucp:*:5:3::/usr/spool/uucppublic:/usr/lib/uucp/uucico +who:*:90:1::/:/usr/bin/who +:END + +/bin/grep -v "^root" $lclpwfile >> $nispwfile + +/bin/cat >> $nispwfile <<:END2 +-@dangerous-users ++@sysadmin ++@site-ux ++: +:END2 + +mv $pwfile $pwfile.preNIS +mv $nispwfile $pwfile +chmod 444 $pwfile +chown root:other $pwfile + +/bin/cat >> $nisgrpfile <<:GRPEND +root:*:0:root +other:*:1:root,hpdb +bin:*:2:root,bin +sys:*:3:root,uucp +adm:*:4:root,adm +daemon:*:5:root,daemon +mail:*:6:root +lp::7:root,lp +nogroup:*:-2: ++: +:GRPEND + +mv $grpfile $grpfile-preNIS +mv $nisgrpfile $grpfile +chmod 444 $grpfile +chown bin:bin $grpfile + +# Start the NIS Client daemons +/sbin/init.d/nis.client start >> $logfile 2>&1 +if [ $? -ne 0 ]; then + error "Problem starting the NIS client daemons... Exiting." +fi + +# Email us that a machine was updated +/usr/bin/mailx -s "$(uname -n): NIS setup complete" $admin < $null diff --git a/clients/HP/bin/pdl-config b/clients/HP/bin/pdl-config new file mode 100644 index 0000000..7b61a64 --- /dev/null +++ b/clients/HP/bin/pdl-config @@ -0,0 +1,446 @@ +#!/usr/bin/ksh +################################################################################ +# +# File: pdl-config +# Description: ADL system configuration script +# To run this script you must have the pdl-config.src parameter +# file located in root. It is important that the source parameter +# file be read and understood before running the script. +# See below for useful comments. +# Author: Kevin Lister - kel@cup.hp.com +# Date 3.11.99 +# Language: Korn Shell +# +# (c) Copyright 1991, Hewlett-Packard Company, all rights reserved. +# +# Revision History +# 3.25.99 kel Changed the name of the Clearcase install script in shell +# archive, so it had to be changed here as well. Added an +# eclipse install script to the shell archive, so a line to +# to remove it if Clearcase is not installed had to be added +# here as well. +# 4.1.99 kel Added code to determine if the installed system is going to have +# a graphics console. If yes, then the /etc/dt/config/Xservers +# file needs to have the console server line uncommented. +# Also added absolute paths to the unix commands. +# 6.22.99 kel Added "bufpages 0" to the kernel config function. This is +# required if dynamic buffer cache sizes are being used. +# +################################################################################ +# Useful (hopefully) Comments Section +# +# This script will configure a system to operate nicely in the ADL +# infrastructure. This script requires the pdl-config.src file in order to +# run. The pdl-config.src file contains variables that determine exactly +# what type of optional software to install, which patch bundle to install, +# configures various system files, etc. +# +# Here is a brief description of what this script will do: +# +# 1) Check that the script is run as root +# 2) Check that the architecture is correct. The script will run on most +# hardware. The architecture is really only important when trying to +# determine which 100Mbit drivers to install. +# 3) Sources the input parameter source file. +# 4) Determine if script is run intereactive or not. +# 5) Determine if 100Mbit drivers are to be installed +# 6) If intereactive, greet the user and display the parameter settings. +# 7) Modify the kernel system file located in /stand/system +# 8) Download the shell archive file from the anonymous ftp server and unpack. +# The shell archive contains many files and symlinks and will not be +# listed here. See the README in the ahell archive build area and the shell +# archive itself for more details. One can also look through the "root" +# directory that is used to build the archive to see which files and +# symlinks are included. +# 9) Modify the /etc/rc.config.d files. (turn off unused stuff) +# 10) Modify the /etc/issue, /etc/gettydefs and /etc/motd files. +# 11) Modify miscellaneous files. +# 12) Perform miscellaneous setup procedures: +# a) Run /net/bismol/App/admin/bin/setup +# b) Run /usr/local/bin/ninstall -h bismol lp adm net3 +# c) Run /usr/adm/netdist/netdaemon.dy +# d) Run /usr/sbin/catman -w +# 13) Set the system up for ClearCase installation upon automatic reboot. +# 14) Install optional software and patches from the specified depot server. +# +# END of Useful Comments Section +################################################################################ +# +## +### Variables +## +# + +SRC_FILE=/pdl-config.src + +BASE=${0##*/} +HOST=`/bin/uname -n` +ARCH=`/bin/uname -m` +OS=`/bin/uname -r | /usr/bin/cut -c 3-4` +integer INDEX=0 + +# +## +### Functions +## +# + +function error { + print -u2 "\t$BASE: Error: $1" +} + +function warning { + print -u2 "\t$BASE: Warning: $1" +} + +function display { + print "\t$1" +} + +function usage { + display "\t$BASE [-usage]" + display " -usage: Print this usage message" + display " " + error "$1" + exit 1 +} + +function step { + let INDEX=INDEX+1 + display "\tStep #$INDEX: $@" +} + +function get_shar { +step "Get shell archive from ftp server and unpack" + cd / + ftp -n $FTP_SERVER <<@EOD +user $FTP_USER $FTP_PASSWD +cd $SHAR_DIR +get $SHAR_FILE +quit +@EOD +if [ $? -ne 0 ]; then + error "Unable to ftp $SHAR_FILE from $FTP_SERVER" + exit 1 +fi +sh $SHAR_FILE >> $LOGFILE 2>&1 +if [ $? -ne 0 ]; then + error "Cannot unpack shell archive." + exit 1 +fi +/bin/rm -f $SHAR_FILE +} + +function clearcase_setup { + if [ "$CLEARCASE" = "no" ]; then + /bin/rm -f /sbin/rc3.d/S998install_clearcase + /bin/rm -f /sbin/rc3.d/S999install_eclipse + fi +} + +function chk_uid { + if [ $(id -u) -ne 0 ]; then + error "Must be root to execute this command... Exiting!" + exit 1 + fi +} + +function chk_arch { + case $ARCH in + 9000/7[1-3]*|9000/755|9000/7[7-8]*|9000/8**) + continue + ;; + + *) + warning "\tUnknown machine type $ARCH, Exiting!" + exit 1 + ;; + esac +} + +function read_src { + if [ -a $SRC_FILE ]; then + . $SRC_FILE + case "$CLEARCASE" in + y|Y|yes|YES|Yes|1) + CLEARCASE=yes + ;; + *) + CLEARCASE=no + ;; + esac + case "$SWINSTALL" in + y|Y|yes|YES|Yes|1) + SWINSTALL=yes + ;; + *) + SWINSTALL=no + ;; + esac + else + error "Source file does not exist!" + exit 1 + fi +} + +function set_mode { + case "$INTERACTIVE" in + y|Y|yes|YES|Yes|1) + INTERACTIVE=yes + ;; + *) + INTERACTIVE=no + ;; + esac +} + +function fast_enet { + if [ "_$ENET_DRVRS" = "_" ]; then + FAST_ENET=no + else + FAST_ENET=yes + fi +} + +function mod_kernel { + step "Modify /stand/system file." + grep -v -E 'maxswapchunks|default_disk_ir|nstrpty' /stand/system \ + > /stand/system.new + /bin/mv /stand/system /stand/system.orig + /bin/mv /stand/system.new /stand/system + + case $ARCH in + 9000/7[1-5]*) + echo "bufpages 0" >> /stand/system + echo "create_fastlinks 1" >> /stand/system + echo "dbc_max_pct 25" >> /stand/system + echo "default_disk_ir 1" >> /stand/system + echo "fs_async 1" >> /stand/system + echo "maxdsiz (256*1024*1024)" >> /stand/system + echo "maxfiles 256" >> /stand/system + echo "maxfiles_lim 2048" >> /stand/system + echo "maxssiz (80*1024*1024)" >> /stand/system + echo "maxswapchunks 4096" >> /stand/system + echo "maxuprc 500" >> /stand/system + echo "maxusers 150" >> /stand/system + echo "netmemmax 0" >> /stand/system + echo "nfile 7000" >> /stand/system + echo "nflocks 400" >> /stand/system + echo "ninode 20000" >> /stand/system + echo "nproc 1500" >> /stand/system + echo "npty 512" >> /stand/system + echo "nstrpty 512" >> /stand/system + echo "semmns 200" >> /stand/system + if [ "$OS" = "10" ]; then + echo "large_ncargs_enabled 1" >> /stand/system + fi + ;; + + 9000/7[7-8]*|9000/8**) + echo "bufpages 0" >> /stand/system + echo "create_fastlinks 1" >> /stand/system + echo "dbc_max_pct 25" >> /stand/system + echo "default_disk_ir 1" >> /stand/system + echo "fs_async 1" >> /stand/system + echo "maxdsiz (512*1024*1024)" >> /stand/system + echo "maxfiles 256" >> /stand/system + echo "maxfiles_lim 2048" >> /stand/system + echo "maxssiz (80*1024*1024)" >> /stand/system + echo "maxswapchunks 4096" >> /stand/system + echo "maxuprc 1000" >> /stand/system + echo "maxusers 256" >> /stand/system + echo "netmemmax 0" >> /stand/system + echo "nfile 14000" >> /stand/system + echo "nflocks 800" >> /stand/system + echo "ninode 40000" >> /stand/system + echo "nproc 3000" >> /stand/system + echo "npty 512" >> /stand/system + echo "nstrpty 512" >> /stand/system + echo "semmns 400" >> /stand/system + if [ "$OS" = "10" ]; then + echo "large_ncargs_enabled 1" >> /stand/system + fi + ;; + + *) + warning "Unknown machine model $ARCH!" + warning "Leaving kernel parameters as default" + /bin/mv /stand/system.orig /stand/system + ;; + esac +} # mod_kernel + +function greet { + display "\tADL System Configuration script." + display + display "\tYou are about to install and modify various system files," + display "\tinstall system patches, install optional software and," + display "\tif you elected to do so, install ClearCase 3.2." + display + display "\tIf you wish to modify the parameters below exit the install" + display "\tand modify the parameters in the $SRC_FILE file." + display + display "\tMachine Name:\t\t\t$MACHINE_NAME" + display "\tMachine Usage:\t\t\t$MACHINE_USAGE" + display "\tMacine Location:\t\t$LOCATION" + display "\tOwner's Fullname:\t\t$OWNER_NAME" + display "\tOwner's Email:\t\t\t$OWNER_EMAIL" + display "\tOwner's Extension:\t\t$OWNER_EXTENSION" + display "\tInstall ClearCase?:\t\t$CLEARCASE" + display "\tInstall 100Mbit Drivers?:\t$FAST_ENET" + if [ "$SWINSTALL" = "yes" ]; then + display "\tThe following products will be installed from $DEPOT:" + display "\t$PRODUCTS" + display + else + display + fi + if [ "$INTERACTIVE" = "yes" ]; then + display "\tContinue installation with these parameters (Y|n)?\c" + display + answer=y + read answer + case "$answer" in + y|Y|yes|Yes|YES|"") + continue + ;; + *) + display + display "\tYou have chosen NOT to run the $BASE setup script... +Exiting" + exit 1 + ;; + esac + fi +} # greet + +function mod_rc_files { + /usr/sbin/ch_rc -ap AUDIO_SERVER=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap LIST_TEMPS=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap CLEAR_TMP=1 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap HPARRAY_START_STOP=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NIS_CLIENT=1 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NIS_DOMAIN=pdl >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap START_LLBD=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NTPDATE_SERVER=cupertino.ntp.hp.com >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap XNTPD=1 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NETTL=0 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap NUM_NFSIOD=16 >> $LOGFILE 2>&1 + /usr/sbin/ch_rc -ap VTDAEMON_START=0 >> $LOGFILE 2>&1 + if [ "$OS" = "10" ]; then + /usr/sbin/ch_rc -ap WAIT_FOR_NIS_SERVER=FALSE >> $LOGFILE 2>&1 + fi +} + +function mod_etc_files { + step "/etc files setup" + print "+auto.master" > /etc/auto_master + /bin/chmod 644 /etc/auto_master + /bin/chown root:root /etc/auto_master + + sed "s/GenericSysName/$MACHINE_NAME/" /etc/issue > /etc/issue-new + /bin/mv /etc/issue /etc/issue-orig + /bin/mv /etc/issue-new /etc/issue + + sed "s/Console Login:/$MACHINE_NAME Console Login:/" /etc/gettydefs \ + > /etc/gettydefs-new + /bin/mv /etc/gettydefs /etc/gettydefs-orig + /bin/mv /etc/gettydefs-new /etc/gettydefs + + /bin/banner $MACHINE_NAME > /etc/motd + /bin/uname -a >> /etc/motd + cat >> /etc/motd <<:END + +******************************************************************************* +* This is a private system operated for the Hewlett-Packard Company +business. * +* Authorization from HP management is required to use this system. +* +* Use by unauthorized persons is prohibited. +* + +******************************************************************************* +For System Support: Mon-Fri 8:00-5:00 Email (site-ux@cup.hp.com) +Phone: t-447-1212 After hours/weekend Pre-arrange: t-447-0629 + +------------------------------------------------------------------------------- +Usage: $MACHINE_USAGE +Owner: $OWNER_NAME ($OWNER_EMAIL) Phone: $OWNER_EXTENSION +Location: $LOCATION + +------------------------------------------------------------------------------- +:END + + sed "s/Root user/Root\@$HOST/" /etc/passwd > /tmp/passwd-new + /bin/mv /tmp/passwd-new /etc/passwd +} # mod_etc_files + +function mod_misc_files { + step "Miscellaneous file setup" + /bin/rm -f /var/adm/cron/at.allow + /bin/rm -f /var/adm/cron/cron.allow + /bin/chmod 644 /dev/lan* + case "$WORKSTATION" in + y|Y|yes|YES|Yes|1) + WORKSTATION=yes + ;; + *) + WORKSTATION=no + ;; + esac + if [ "$WORKSTATION" = "yes" ]; then + /bin/sed -e "s/# \*/ \*/" Xservers > /tmp/Xservers-new + /bin/mv /tmp/Xservers-new /etc/dt/config/Xservers + /bin/chmod 444 /etc/dt/config/Xservers + /bin/chown root:other /etc/dt/config/Xservers + fi +} + +function misc_setup { + step "Setup Application Server" + /net/bismol/App/admin/bin/setup >> $LOGFILE 2>&1 + + step "Ninstalling lp, adm and net3 packages" + /usr/local/bin/ninstall -h bismol lp adm net3 >> $LOGFILE 2>&1 + + step "Run netdaemon.dy" + /usr/adm/netdist/netdaemon.dy >> $LOGFILE 2>&1 + + step "Create the whatis database" + /usr/sbin/catman -w >> $LOGFILE 2>&1 +} + +function inst_sw { + if [ "$SWINSTALL" = "yes" ]; then + step "Installing Patches and Optional Software, be patient!" + /usr/sbin/swinstall -s $DEPOT -x $OPTIONS $PRODUCTS $ENETDRVR >> +$LOGFILE 2>&1 + else + step "Rebuilding kernel with new parameters." + /usr/sbin/mk_kernel -v -o /stand/vmunix >> $LOGFILE 2>&1 + step "Rebooting the system..." + cd / + /usr/sbin/shutdown -ry 0 + fi +} + +# +## +### Main +## +# + +chk_uid +chk_arch +read_src +set_mode +fast_enet +greet +mod_kernel +get_shar +mod_rc_files +mod_etc_files +mod_misc_files +misc_setup +clearcase_setup +inst_sw diff --git a/clients/HP/bin/pdl-config.src b/clients/HP/bin/pdl-config.src new file mode 100644 index 0000000..d215d00 --- /dev/null +++ b/clients/HP/bin/pdl-config.src @@ -0,0 +1,159 @@ +################################################################################ +# +# File: pdl-config.src +# Description: Parameter Source File for the ADL system configuration script +# pdl-config. This file is required by the pdl-config script +# in order to run. +# See below for useful comments. +# Author: Kevin Lister (C) - kel@cup.hp.com +# Date: 3.11.99 +# Language: Korn Shell +# +# (c) Copyright 1991, Hewlett-Packard Company, all rights reserved. +# +# Revision History +# 4.1.99 kel added the WORKSTATION variable. Setting the WORKSTATION +# variable to yes will set the machine up with a graphics console +# login using CDE. +# +################################################################################ +# Useful (hopefully) Comments Section +# +# Do not make your changes to the varibales in the comment section. Change +# the variables at the end of this file. +# +# Below you will find all of the ENV variables that the pdl-config script +# will use to configure the system. +# Descriptions for these variables can be found below, read on. +# +# Set the INTERACTIVE ENV variable to yes if you wish to have a chance to view +# the configuration parameters the script will use before proceeding. Set to +# no otherwise. +# +# INTERACTIVE=yes +# +# Set the WORKSTATION variable to yes if you are installing a system that will +# have a graphics console monitor attached. Setting WORKSTATION to no disbales +# CDE on the console. +# +# WORKSTATION=no +# +# You can have ClearCase 3.2 installed automatically by setting CLEARCASE +# to yes. If you do not want ClearCase, set to no. +# +# CLEARCASE=yes +# +# If you want the Patch bundle (see below) and Optional Software installed +# set SWINSTALL to yes. +# +# SWINSTALL=yes +# +# If you plan to use a 100Mbit network interface then set FAST_ENET to yes +# to have the correct drivers installed. Set to no if you don't. +# +# FAST_ENET=yes +# +# Set the location of the logfile for the configure script using the LOGFILE +# variable. +# +# LOGFILE=/pdl-config.log +# +# The /etc/motd file will be set up with the information contained in the next +# several variables. The /etc/issue and /etc/gettydefs files will also be +# setup by using the MACHINE_NAME variable. You should set these to something +# that makes sense. +# +# OWNER_NAME="ADL Support" +# OWNER_EMAIL=pdl-support@cup.hp.com +# OWNER_EXTENSION=t-447-5790 +# MACHINE_USAGE="X Terminal Server" +# LOCATION=RDC +# MACHINE_NAME=Generic +# +# The next several variables set up the depot server name, depot path and +# names of the software bundles and products to install. It is likely that you +# you will only need to change ENET_DRVRS. Set ENET_DRVRS to 100BT-HSC for a +# J282 (780). Set ENET_DRVRS to SX00306 for a 755. The default for XTERM_SVR +# is "". If you really don't want patches and optional software then set +# PATCHES and OPTIONAL to "". You should never need to modify PRODUCTS, DEPOT +# or OPTIONS. +# +# PATCHES=Patches-Generic +# OPTIONAL="OptionalSoftware SysMonSoftware VUEtoCDE" +# XTERM_SVR="ENWARE netstation" +# ENET_DRVRS=100BT-HSC +# ENET_DRVRS=SX00306 +# PRODUCTS="$PATCHES $OPTIONAL $XTERM_SVR $ENET_DRVRS" +# DEPOT=pdliux01:/depots/10.20 +# OPTIONS="autoreboot=true" +# +# Finally, the next several variables set up the ftp server, directory and +# filename of the shell archive that the script uses to unpack all kinds +# of useful files and symlinks. You should never have to modify these. +# +# FTP_SERVER=15.0.98.138 +# FTP_USER=anonymous +# FTP_PASSWD=$LOGNAME@$(uname -n).cup.hp.com +# SHAR_DIR=productivity/pdl-config +# SHAR_FILE=pdl-config.shar +# +# END of Useful Comments Section +################################################################################ +# +## +### Change these to suit your fancy. +## +# + +INTERACTIVE=yes +WORKSTATION=no +CLEARCASE=yes +SWINSTALL=yes +FAST_ENET=no +LOGFILE=/pdl-config.log + +# +## +### /etc/motd setup +## +# + +OWNER_NAME="PDL Support" +OWNER_EMAIL=pdl-support@cup.hp.com +OWNER_EXTENSION=t-447-???? +MACHINE_USAGE="Change Me" +LOCATION=RDC +MACHINE_NAME=GENERIC + +# +## +### Patches and Optional Software +## +# + +PATCHES=Patches-VUServer +OPTIONAL="OptionalSoftware SysMonSoftware VUEtoCDE" +XTERM_SVR="" +ENET_DRVRS="" +PRODUCTS="$PATCHES $OPTIONAL $XTERM_SVR $ENET_DRVRS" + +# +## +### Depot Server Information +## +# + +DEPOT=pdliux01:/depots/10.20 +OPTIONS="autoreboot=true" + +# +## +### Shell Archive Server and Location +## +# + +FTP_SERVER=15.0.98.138 +FTP_USER=anonymous +FTP_PASSWD=$LOGNAME@$(uname -n).cup.hp.com +SHAR_DIR=productivity/pdl-config +SHAR_FILE=pdl-config.shar diff --git a/clients/HP/bin/pdl-new-passwd b/clients/HP/bin/pdl-new-passwd new file mode 100644 index 0000000..a6f13e7 --- /dev/null +++ b/clients/HP/bin/pdl-new-passwd @@ -0,0 +1,63 @@ +#!/bin/ksh +################################################################################ +# +# File: newpasswd +# Description: Change the root passwd entry in /etc/passwd +# Author: Kevin Lister kel@cup.hp.com +# Language: Korn Shell +# +# (c) Copyright 1999, Hewlett-Packard Company, all rights reserved. +# +################################################################################ +# +## +### Variables +## +# + +ADMIN=pdl-support@cup.hp.com +PWFILE=/etc/passwd +PWFILENEW=/etc/passwd-new +PWFILEOLD=/etc/passwd-old +SYSNAME=$(uname -n) +BASE=${0##*/} +WHOAMI=$(id -u) +NULL=/dev/null + +# +## +### Functions +## +# + +# Functions +function error { + print -u2 "$BASE: Error: $1" +} + +# +## +### Main +## +# + +# Must be root to run this +if [ $WHOAMI -ne 0 ]; then + error "Must be root to execute this command... Exiting." + exit 0 +fi + +# Create the new passwd file +/bin/cat >> $PWFILENEW <<:NEWPW +root:u4/rTgJX35zHg:0:1:Root@$SYSNAME:/:/sbin/sh +:NEWPW +/bin/grep -v "^root" $PWFILE >> $PWFILENEW + +# Save the old passwd file, install the new one +/bin/mv $PWFILE $PWFILEOLD +/bin/mv $PWFILENEW $PWFILE +/bin/chmod 444 $PWFILE +/bin/chown root:other $PWFILE + +# Email us that a machine was updated +/usr/bin/mailx -s "$SYSNAME: Root passwd changed!" $ADMIN < $NULL diff --git a/clients/HP/bin/pingnet b/clients/HP/bin/pingnet new file mode 100644 index 0000000..9d0383f --- /dev/null +++ b/clients/HP/bin/pingnet @@ -0,0 +1,115 @@ +#!/bin/ksh +################################################################################ +# +# File: pingnet +# RCS: $Header: pingnet,v 1.3 98/03/04 00:42:49 defaria Exp $ +# Description: A script to ping all machines and report status. This script +# uses /etc/hosts and selects only machines in the IP range of +# 15.0.96.x to 15.0.99.x. +# Author: Andrew DeFaria +# Created: Sat Oct 26 10:04:28 PDT 1996 +# Modified: Sat Oct 26 12:05:26 PDT 1996 Andrew DeFaria +# Parameters: count (default 2): number of times to ping a machine before +# considering it not responding. +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +function usage { + print "$me: Usage: $me { count }" + print "\twhere count = number of times to ping a machine before +considering" + print "\tthe machine to be not responding (default count = 2)." + exit 1 +} # usage + +os= + +function get_os { + machine=$1 + # Attempt to determine the OS. First attempt to remsh to the machine and + # do a uname(1). This assumes Unix. We are unable to remsh then we'll + # assume that it's a PC (it could also be a line printer or any other of + # a number of network pingable devices!) + os=$(remsh $machine -n uname 2>&1) + + # We're gonna make some guesses here... + if [[ "$os" = "HP-UX" || + "$os" = "Linux" ]]; then + : Do nothing! + elif [[ "$os" = *Lost\ connection ]]; then + os="Linux? (Lost connection)" + elif [[ "$os" = *Permission\ denied. ]]; then + os="Linux? (Permission denied)" + elif [[ "$os" = *Login\ incorrect ]]; then + os="HP-UX? (Login incorrect)" + elif [[ "$os" = *Connection\ refused ]]; then + os="NT? (Connection refused)" + else + os="Unknown: $os" + fi +} # get_os + +integer count=2 + +if [ $# -eq 1 ]; then + count=$1 +elif [ $# -gt 1 ]; then + usage +fi + +esc=$(print "\033") + +if [ "$TERM" = "dtterm" -o -z DTTERM ]; then + export normal="$esc[39m" + export red="$esc[31m" + export green="$esc[32m" +elif [ "$TERM" = "hp" -o "$TERM" = "hpterm" ]; then + export normal="$esc&d@$esc&v0S" + export red="$esc&v1S" + export green="$esc&v2S" +fi + +# Print heading +print " Machine\t\t IP\tState\t OS" +print - "-----------------------\t-------------\t-----\t-------" + +subnet=${subnet:-15.28} +integer starting_subnet_octect=${starting_subnet_octect:-96} +integer ending_subnet_octect=${ending_subnet_octect:-103} +integer subnet_octect=starting_subnet_octect +integer starting_octect=${starting_octect:-0} +integer ending_octect=${ending_octect:-255} +integer octect=$starting_octect + +while [ $subnet_octect -le $ending_subnet_octect ]; do + while [ $octect -le $ending_octect ]; do + ip=$subnet.$subnet_octect.$octect + machine=$ip + nslookup $ip 2>&1 | grep Non-exist > /dev/null 2>&1 + if [ $? -ne 0 ]; then + machine=$(nslookup $ip | grep Name: | awk '{print $2}' | cut -f1 -d.) + fi + print "$machine\t\c" + if [ ${#machine} -lt 8 ]; then + print "\t\t\c" + elif [ ${#machine} -lt 16 ]; then + print "\t\c" + fi + print "$ip\t\c" + ping_result=$(ping $ip -n $count | tail -1 | grep "100% packet loss") + if [ -z "$ping_result" -eq 0 ]; then + print "${green}UP${normal}\t\c" + get_os $machine + print "$os" + else + print "${red}DOWN${normal}\tUnknown" + fi + let octect=octect+1 + done + let subnet_octect=subnet_octect+1 + let octect=starting_octect +done diff --git a/clients/HP/bin/reinstall_patches_bundle b/clients/HP/bin/reinstall_patches_bundle new file mode 100644 index 0000000..8f8241d --- /dev/null +++ b/clients/HP/bin/reinstall_patches_bundle @@ -0,0 +1,61 @@ +#!/bin/ksh +################################################################################ +# +# File: reinstall_patch_bundle +# RCS: $Header:$ +# Description: A script to reinstall the Patches bundle by removing it and +# reinstalling it. +# Author: Andrew DeFaria, California Language Labs +# Created: Thu May 1 23:06:48 PDT 1997 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=`basename $0` +notify=defaria@cup.hp.com +machine=`uname -n` +osver=`uname -r | cut -f2- -d.` +major_osver=`echo $osver | cut -f1 -d.` +depot="wampus:/Depots/$osver" + +if [ "$major_osver" = "10" ]; then + if [ `id -u` -ne 0 ]; then + print -u2 "$me: Error: You must be root to use this command" + exit 1 + fi + message="Reinstalling Patches bundle from $depot to $machine via $0" + mailx -s "$message" $notify < /tmp/$me.$$ 2>&1 + + if [ $? -ne 0 ]; then + message="Removal of Patches bundle failed!" + mailx -s "$message" $notify < /tmp/$me.$$ + exit 1 + fi + + # Next install the new Patches bundle. + /usr/sbin/swinstall \ + -x autoreboot=true \ + -s $depot Patches > /tmp/$me.$$ 2>&1 + + if [ $? -ne 0 ]; then + message="Installation of Patches bundle failed!" + mailx -s "$message" $notify < /tmp/$me.$$ + exit 1 + fi +else + message="Sorry but $0 only works on 10.x machines. This machine is +$major_osver." + exit 1 +fi diff --git a/clients/HP/bin/reinstall_unixsysadm b/clients/HP/bin/reinstall_unixsysadm new file mode 100644 index 0000000..058ab11 --- /dev/null +++ b/clients/HP/bin/reinstall_unixsysadm @@ -0,0 +1,80 @@ +#!/bin/ksh +################################################################################ +# +# File: reinstall_unixsysadm +# Description: Script to reinstall this package. +# Author: Andrew@DeFaria.com +# Created: Fri Sep 24 10:11:56 PDT 1999 +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +function usage { + if [ "_$1" != "_" ]; then + display "$1" + display + fi + display "Usage: $me" + exit 1 +} # usage + +# Check for execution by root +if is_not_root; then + error "This script must be run as root" 1 +fi + +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + *) + usage "Unrecognized parameter $1" + ;; + esac + shift +done + +# Currently we must swremove and swinstall this package. In the future the +# swinstall package may be made smarter and clean up older files... + +verbose "Removing old UnixSysadm package..." +/usr/sbin/swremove UnixSysadm > /tmp/swremove.log 2>&1 + +if [ $? -ne 0 ]; then + error "Unable to swremove UnixSysadm! Check /tmp/swremove.log" +else + rm /tmp/swremove.log +fi + +verbose "Reinstalling new UnixSysAdm package..." +/usr/sbin/swinstall -s pdlapp:/var/depot/adm UnixSysadm > /tmp/swinstall.log +2>&1 + +if [ $? -ne 0 ]; then + error "Unable to swinstall UnixSysadm! Check /tmp/swinstall.log" +else + rm /tmp/swinstall.log +fi diff --git a/clients/HP/bin/remount_viewserver b/clients/HP/bin/remount_viewserver new file mode 100644 index 0000000..9338ba9 --- /dev/null +++ b/clients/HP/bin/remount_viewserver @@ -0,0 +1,48 @@ +#!/bin/ksh +################################################################################ +# +# File: remount_viewserver +# Description: This script will remount a viewservers LVMs. This is handy +# when a viewserver goes down and needs to be remounted to +# the build servers. +# Author: Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# Modified: +# +# (c) Copyright 1998, Hewlett-Packard Company, all rights reserved. +# + +################################################################################ +me=$(basename $0) +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: You must be root to execute this command!" + exit 1 +fi + +if [ $# -ne 1 ]; then + print -u2 "Usage: $me viewserver" + exit 1 +fi + +viewserver=$1 + +function remount { + cd /tmp_mnt/net/$viewserver/CLO/Storage/Views + for dir in *; do + print Mounting $viewserver:/CLO/Storage/Views/$dir to $PWD/$dir + /usr/sbin/mount $viewserver:/CLO/Storage/Views/$dir $PWD/$dir 2>&1 | +grep -v "already mounted" + done + cd $OLDPWD +} # remount + +function kick_automounter { + automount_pid=$(/app/sj automount | awk '{print $2}') + + print Kicking automounter \($automount_pid\) + kill -HUP $automount_pid +} # kick_automounter + +remount $viewserver + +kick_automounter diff --git a/clients/HP/bin/restart_system b/clients/HP/bin/restart_system new file mode 100644 index 0000000..855c7fc --- /dev/null +++ b/clients/HP/bin/restart_system @@ -0,0 +1,45 @@ +#!/bin/ksh +################################################################################ +# +# File: restart_system +# Description: A script to restart a system. Used for at jobs mainly. +# Author: Andrew@DeFaria.com +# Created: Wed Apr 16 14:14:17 PDT 1997 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +# Who do notify about the restart +notify=${notify:-$LOGNAME} + +if is_not_root; then + error "This script must be run as root" 1 +fi + +message="Restarting $(hostname) ($(uname -s)) via $me" +info $message +#mailx -s "$message" $notify < User $user is \"special\"" + print "$user:$pass:$uid:$gid:$geos:$home:$shell" + ;; + + *) + # In mail mode change shell to /bin/false. Otherwise use a restricted + # shell and also set the home directory to /home/vumover. + if [ ! -z "$mailmode" ]; then + shell=/bin/false + else + shell=/usr/bin/rksh + home=/home/vumover + fi + + # Change MoA marking to Restricted + geos="$(print "$geos" | sed 's/_MoA_/_Restricted_/')" + + # Allow no other uid 0 users other than those listed above + if [ $uid -eq 0 ]; then + verbose "****> User $user is in uid 0 - skipping..." + continue + fi + + # Skip users from MLL + print $home | grep "\.ch\.apollo" > /dev/null 2>&1 + if [ $? -eq 0 ]; then + verbose "****> User $user is from Apollo - skipping..." + continue + fi + + print "$user:$pass:$uid:$gid:$geos:$home:$shell" + ;; + esac +done < /etc/passwd > /tmp/passwd.$$ + +if [ "_$outfile" = "_" ]; then + mv /etc/passwd /etc/passwd.old + mv /tmp/passwd.$$ /etc/passwd + chmod 444 /etc/passwd +else + mv /tmp/passwd.$$ $outfile +fi diff --git a/clients/HP/bin/roll_logs b/clients/HP/bin/roll_logs new file mode 100644 index 0000000..b38dc79 --- /dev/null +++ b/clients/HP/bin/roll_logs @@ -0,0 +1,115 @@ +#!/bin/ksh +################################################################################ +# +# File: roll_logs +# Description: Rolls log files +# Author: Andrew@DeFaria.com +# Created: Thu Dec 9 10:05:09 PST 1999 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Set me to command name +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common +. $adm_fpath/logs + +function usage { + if [ "_$1" != "_" ]; then + display "$1" + display + fi + display "Usage: $me -[da|aily] | -[w|eekly]" + exit 1 +} # usage + +# Check for execution by root +if is_not_root; then + error "This script must be run as root" 1 +fi + +type= +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + -da|-daily) + type=daily + ;; + + -w|-weekly) + type=weekly + ;; + + *) + usage "Unrecognized parameter $1" + ;; + esac + shift +done + +if [ "_$type" = "_" ]; then + usage "Must specify -daily or -weekly" +fi + +#Directory logfile backuplog what +dailylogs="\ +/var/adm automount.log autolog.week automount\n\ +/var/adm nettl.LOG00 nettl.week nettracelog\n\ +/var/adm ninstall.log nlog.week ninstall\n\ +/var/adm ptydaemonlog ptylog.week ptydaemon\n\ +/var/adm rpc.lockd.log rpc.lockd.week rpc.lockd\n\ +/var/adm rpc.statd.log rpc.statd.week rpc.statd\n\ +/var/adm vtdaemonlog vtlog.week vtdaemon\n\ +/var/adm/cron log log.week cron\n\ +/var/adm/lp log log.week lp\n\ +/var/adm/syslog syslog.log syslog.week syslogd" + +weeklylogs="\ +/var/adm autolog.week autolog.oldweek automount\n\ +/var/adm nettl.week nettl.oldweek nettracelog\n\ +/var/adm nlog.week nlog.oldweek ninstall\n\ +/var/adm ptylog.week ptylog.oldweek ptydaemon\n\ +/var/adm rpc.lockd.week rpc.lockd.oldweek rpc.lockd\n\ +/var/adm rpc.statd.week rpc.statd.oldweek rpc.statd\n\ +/var/adm vtlog.week vtlog.oldweek vtdaemon\n\ +/var/adm/cron log.week log.oldweek cron\n\ +/var/adm/lp log.week log.oldweek lp\n\ +/var/adm/syslog syslog.week syslog.oldweek syslogd" + +if [ "$type" = "daily" ]; then + verbose "Daily roll_logs" + logfiles="$dailylogs" +else + verbose "Weekly roll_logs" + logfiles="$weeklylogs" +fi + +print "$logfiles" | while read dir logfile backup_logfile what; do + verbose "Rolling ($what) logfile $logfile -> $backup_logfile..." + if [ "$type" = "weekly" ]; then + # Clear out oldweek file first + rm -f $backup_logfile + fi + roll_log $dir $logfile $backup_logfile $what +done diff --git a/clients/HP/bin/root b/clients/HP/bin/root new file mode 100644 index 0000000..e733b48 --- /dev/null +++ b/clients/HP/bin/root @@ -0,0 +1,43 @@ +#!/bin/bash +################################################################################ +# +# File: root +# Description: A script to go into "wizard" mode +# Author: Andrew@DeFaria.com +# Created: Mon May 17 07:35:59 PDT 1999 +# Language: Bash shell +# +# (c) Copyright 1999, Andrew DeFaria, all rights reserved. +# +################################################################################ +me=$(basename $0) + +# Set adm_base +adm_base=${adm_base:-$HOME/adm} + +# Set adm_fpath +adm_fpath=${adm_fpath:-$adm_base/functions} + +# Source functions +. $adm_fpath/common + +if [ ! -x $(type -p sudo) ]; then + warning "$me: Warning: Unable to find sudo!" + exit 1 +fi + +if [ $# -gt 0 ]; then + # Execute the commands + sudo $@ +else + # Become a "wizard"! + sudo -s + + if [ -x ~/.rc/functions ]; then + # Source in ksh functions (needed for set_title and set_prompt) + . ~/.rc/functions + # Reset title and prompt (if you can) + set_title + set_prompt + fi +fi diff --git a/clients/HP/bin/rootmail b/clients/HP/bin/rootmail new file mode 100644 index 0000000..2681dab --- /dev/null +++ b/clients/HP/bin/rootmail @@ -0,0 +1,49 @@ +#!/bin/ksh +################################################################################ +# +# File: rootmail +# RCS: $Header: rootmail,v 1.1 97/04/21 14:27:10 defaria Exp $ +# Description: Lists who receives root mail for a particular machine +# Author: Andrew DeFaria, California Language Labs +# Created: Mon Nov 13 16:14:30 1995 +# Modified: Mon Nov 13 16:16:56 1995 (Andrew DeFaria) defaria@spock +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +if [ -x /app/appserver ]; then + . /app/appserver +fi + +me=$(basename $0) + +function usage { + print -u2 "Usage: $me: hostname" + exit 1 +} # usage + +# Get parameters +if [ $# -eq 0 ]; then + host= +elif [ $# -eq 1 ]; then + host="/nfs/$1" +else + usage +fi + +path=usr/lib +if [ "_$host" = "_" ]; then + if [ "$OS" = "10" ]; then + path=etc/mail + fi +fi + +alias_file=$host/$path/aliases.local + +if [ ! -f $alias_file ]; then + print -u2 "$me: Unable to find local alias file: $alias_file" + exit 1 +fi + +grep "^root" $alias_file diff --git a/clients/HP/bin/rs b/clients/HP/bin/rs new file mode 100644 index 0000000..e912d96 --- /dev/null +++ b/clients/HP/bin/rs @@ -0,0 +1 @@ +/usr/bin/X11/resize diff --git a/clients/HP/bin/security b/clients/HP/bin/security new file mode 100644 index 0000000..2a28cea --- /dev/null +++ b/clients/HP/bin/security @@ -0,0 +1,157 @@ +#!/bin/ksh +################################################################################ +# +# File: audit +# Description: Security audit +# Author: Andrew DeFaria (defaria@cup.hp.com) +# Language: Korn Shell +# Modifications:Combined security checking scripts from Chip Chapin +# (chip@cup.hp.com) and Michael Coulter (coulter@cup.hp.com). +# +# (c) Copyright 1991, Hewlett-Packard Company, all rights reserved. +# +################################################################################ +# First source the appserver script +if [ -x /app/appserver ]; then + . /app/appserver +fi + +me=$(basename $0) + +case $OS in + 09) + crondir=/usr/spool/cron/crontabs + atdir=/usr/spool/cron/atjobs + ;; + 10) + crondir=/var/spool/cron/crontabs + atdir=/var/spool/cron/atjobs + ;; + *) + print -u2 "$me: Error: Unknown OS version: $OS" + exit 1 + ;; +esac + +function local_user { + # Determines is $user has a home directory local to this machine + first_component=$(print $home | cut -f2 -d/) + machine_component=$(print $home | cut -f3 -d/) + this_machine=$(uname -n) + + if [ "$first_component" = "nfs" -o "$first_component" = "net" ]; then + if [ $machine_component = $this_machine ]; then + return 1 + else + return 0 + fi + else + return 1 + fi +} # local_user + +function starred_out_checks { + print "$me: Warning: Non standard user \"$user\" has \"*\" out password!\n" + print "If this user no longer works here you should assign ownership of their" + print "files to somebody else then have this user's password entry removed.\n" + # If the password is "*", there should not be a .rhosts or hosts.equiv + # in the home directory or .forward + if [ -d "$home" ]; then + if [ -f "$home/.rhosts" ]; then + print "$me: Warning: User: $user has a .rhosts file in $home\n" + print "You should remove this user's ~/.rhosts file.\n" + fi + + if [ -f "$home/.forward" ]; then + print "$me: Warning: User: $user has a .forward file in $home\n" + print "You should remove this user's ~/.forward file.\n" + fi + fi # home directory exists + + # There should not be a crontab or atjob for the user + if [ -f $crondir/$user ]; then + print "$me: Warning: User: $user has a crontab file in $crondir/$user\n" + print "You should remove this user's crontab file.\n" + fi + + if [ -f $atdir/$user ]; then + print "$me: Warning: User: $user has a at file in $atdir/$user\n" + print "You should remove this user's at file.\n" + fi +} # starred_out_checks + +function check_users { + # This function checks users in the password file. + + # Parse all the lines in /etc/passwd + IFS=":" + while read user password uid gid comment home shell rest; do + # Check if the user has a local home directory + local_user $user $home + local=$? + + # Checks for users who shouldn't log-in, i.e. password is "*" + if [ $local -eq 1 ]; then # Only check local users + if [ "$password" = '*' ]; then + if [ "$user" = "adm" -o \ + "$user" = "anon" -o \ + "$user" = "bin" -o \ + "$user" = "daemon" -o \ + "$user" = "ftp" -o \ + "$user" = "lp" -o \ + "$user" = "nuucp" -o \ + "$user" = "rje" -o \ + "$user" = "root" -o \ + "$user" = "sync" -o \ + "$user" = "tftp" -o \ + "$user" = "uucp" -o \ + "$user" = "who" ]; then + : # Skip some users who should be starred out + else + starred_out_checks + fi + else + if [ "$password" = "" ]; then + print "$me: Warning: User: $user has a NULL password\n" + print "You must assign a proper password to this user.\n" + fi + + # No wildcards in ~/.rhosts or /etc/host.equiv + if [ -f ~/.rhosts -a $local -eq 1 ]; then + LINES="$(sed -e '/^#/d' ~/.rhosts | grep -e '+' 2> /dev/null | wc -l)" + if [ "$LINES" -ne 0 ]; then + print "$me: Warning: User: $user has \"+\" in $home/.rhosts\n" + print "This can be fixed by logging on as $user and running:" + print "/app/admin/bin/fixrhosts\n" + fi + fi + fi + fi + done < /etc/passwd +} # check_users + +function miscellaneous_checks { + # Check for execution by root + + if [ "$(whoami)" != "root" ]; then + print -u2 "$me: Error: This script must be run by root". + exit 1 + fi + + # Checks that are only done once + + # Check no wildcards in /etc/host.equiv + if [ -f /etc/hosts.equiv ]; then + lines="$(sed '/^#/d' /etc/hosts.equiv | grep -e '+' 2> /dev/null | wc -l)" + if [ "$lines" -ne 0 ]; then + print "$me: Warning: System has \"+\" in /etc/host.equiv\n" + print "You should remove this \"+\" from /etc/host.equiv\n" + fi + fi +} # miscellaneous_checks + +miscellaneous_checks +check_users +/usr/local/etc/admdaemon.dy -clear -secu -mailto root + +exit 0 diff --git a/clients/HP/bin/setup b/clients/HP/bin/setup new file mode 100644 index 0000000..56fb75c --- /dev/null +++ b/clients/HP/bin/setup @@ -0,0 +1,75 @@ +#!/bin/ksh +################################################################################ +# +# File: setup +# RCS: $Header: setup,v 1.2 99/02/15 20:35:58 root Exp $ +# Description: This script will setup the necessary links for the AppServer. +# Author: Andrew DeFaria, California Language Labs +# Created: Thu May 16 09:51:15 PDT 1996 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# First determine where/how the appserver is mounted on local machine +if [ -d "/net/bismol" ]; then + MOUNTPOINT=/net + export APPSERVER=bismol +elif [ -d "/net/hpclbis" ]; then + MOUNTPOINT=/net + export APPSERVER=hpclbis +elif [ -d "/nfs/bismol" ]; then + MOUNTPOINT=/nfs + export APPSERVER=bismol +elif [ -d "/nfs/hpclbis" ]; then + MOUNTPOINT=/nfs + export APPSERVER=hpclbis +fi + +# Export APPROOT properly +export APPROOT=$MOUNTPOINT/$APPSERVER + +function make_symlink { + if [ ! -h "$1" ]; then + ln -sf $APPROOT$1 $1 + fi +} # make_symlink + +make_symlink /etc/socks.conf +make_symlink /usr/lib/font +make_symlink /usr/local/lib/emacs +make_symlink /usr/local/etc/newsdomain +make_symlink /usr/local/hindsight_4.0 + +# Create ispell directory if not there already +mkdir -p /usr/local/lib/ispell + +make_symlink /usr/local/lib/ispell/english.hash + +# Create import directory if not there already. +mkdir -p /usr/vue/config/import + +# Special symlink +ln -sf $APPROOT/usr/vue/config/export/tools /usr/vue/config/import/tools +ln -s /app/mh /usr/local/bin/mh +ln -s /app/mh-lib /usr/local/lib/mh + +# Xsession stuff + +# Check that Xsession is indeed a link +if [ -f /usr/vue/config/Xsession ]; then + if [ ! -h /usr/vue/config/Xsession ]; then + mv /usr/vue/config/Xsession /usr/vue/config/Xsession.old + ln -sf $APPROOT/usr/vue/config/export/Xsession /usr/vue/config/Xsession + fi +fi + +# Turned off as per Mark Keil's request +#if [ ! -h /usr/softbench ]; then +# ln -sf $APPROOT/aspirin/softbench /usr/softbench +#fi + +# Fix ups for SURF +mkdir -p /opt/surf +make_symlink /opt/surf/newconfig diff --git a/clients/HP/bin/setup.new.system2 b/clients/HP/bin/setup.new.system2 new file mode 100644 index 0000000..7e08b81 --- /dev/null +++ b/clients/HP/bin/setup.new.system2 @@ -0,0 +1,195 @@ +#!/bin/ksh +################################################################################ +# +# File: setup.new.system2 +# RCS: $Header:$ +# Description: This script sets up a new system. +# Author: Andrew DeFaria, California Language Labs +# Created: Tue Apr 15 14:20:02 PDT 1997 +# Modified: +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Logfile +logfile=/tmp/setup.new.system2.log + +# Redirect all output to setup.new.system.log +exec | tee -a $logfile > /dev/tty 2>&1 + +## Set global env variables +# Set me +me=${0##*/} + +# Set OS +OS=$(uname -r | cut -c3-) + +# Set step_nbr +integer step_nbr=0 + +function error { + print -u2 "$me: Error: $1" +} # error + +function warning { + print -u2 "$me: Warning: $1" +} # warning + +function display { + print "$1" +} # display + +function info { + display "$me: Info: $1" +} # info + +function verbose { + if [ ! -z "$verbose" ]; then + display "$1" + fi +} # verbose + +function debug { + if [ ! -z "$debug" ]; then + print -u2 "$1" + fi +} # debug + +function usage { + display "$ME -c/learcase [-v|verbose] [-d|debug] [-usage]" + display " -c/learcase Perform ClearCase installation" + display " -v|verbose: Turns on verbose mode" + display " -d|debug: Turns on debug mode" + display " -usage: Print this usage message" + + error "$1" + exit 1 +} # usage + +function step { + let step_nbr=step_nbr+1 + display "Step #$step_nbr: $@" +} # step + +function install_clearcase { + license_host=wampus + registry_host=wampus + registry_region=cll + log_file=/tmp/ClearCase.install_log + os=$(print "$OS" | cut -c1-2) + + if [ "$os" = "09" ]; then + os="9" + fi + + case "$(uname -m)" in + 9000/712|9000/715) + model=link + ;; + 9000/829|9000/849) + model=full + ;; + + *) + model=standard + ;; + esac + + case "$clearcase" in + 2.1) + +clearcase_release_area=/net/bismol/aspirin/cc_v$clearcase/clearcase_v$clearcase/hp${os}_pa + cd $clearcase_release_area/install + ./install_release \ + -model $model \ + -to /usr/atria \ + -from $clearcase_release_area \ + -lh $license_host \ + -rh $registry_host \ + -rr $registry_region \ + -mvfs \ + -log $log_file \ + -local \ + -no_query >> $logfile + ;; + + 3.0) + + +clearcase_release_area=/net/wampus/opt/ccase_rls/clearcase_v$clearcase/hp${os}_pa + cd $clearcase_release_area/install + ./install_release \ + -model $model \ + -to /usr/atria \ + -from $clearcase_release_area \ + -lh $license_host \ + -rh $registry_host \ + -rr $registry_region \ + -mvfs \ + -log $log_file \ + -local \ + -comp +atria_install,atria_base,CC_base,atria_X11_base,atria_hlp_viewer,atria_server,CC_client,atria_cplus_base,atria_gui,CC_doc,CC_vob_svr,CC_bld_client,CC_view_svr,CC_int_client,CC_gui_client,CC_cnv_client,CC_MIN_STD,CC_ONLY_SERVER,CC_FULL +\ + -nlog \ + -level 5 \ + -no_query >> $logfile + ;; + + *) + usage "Unknown ClearCase version $clearcase" + ;; + esac +} # install_clearcase + +# Set initial parm values +clearcase= +verbose= +debug= + +# Get parameters +while [ $# -ge 1 ]; do + case "$1" in + -usage) + usage + ;; + + -v|-verbose) + verbose=yes + ;; + + -d|-debug) + debug=yes + ;; + + -c|-clearcase) + if [ $# -le 1 ]; then + usage "ClearCase version not specified!" + fi + shift + clearcase="$1" + ;; + + *) + usage "Unrecognized parameter $1" + ;; + esac + shift +done + +if [ $(id -u) -ne 0 ]; then + error "Must be root to execute this command" + exit 1 +fi + +if [ "_$clearcase" = "_" ]; then + usage "ClearCase version not specified!" +else + step "Installing ClearCase Version $clearcase" + display "This step will reboot the machine" + install_clearcase + # Preceeding step should reboot the system. If we get here then there + # is something definitely wrong! + error "Unable to install ClearCase Version $clearcase!" +fi diff --git a/clients/HP/bin/setup_cron b/clients/HP/bin/setup_cron new file mode 100644 index 0000000..924b59c --- /dev/null +++ b/clients/HP/bin/setup_cron @@ -0,0 +1,28 @@ +#!/bin/bash +################################################################################ +# +# File: setup_cron +# Description: This script sets up Cygwin's cron on the local machine +# Author: Andrew@DeFaria.com +# Created: +# Language: Bash Shell +# Modifications: +# +# (c) Copyright 2002, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) +# Make sure that certain directories and files do not exist! This is to let +# cron create them, which appears to be the only way to get these created +# correctly! +if [ -d /var/cron ]; then + rm -rf /var/cron + rm -rf /var/run/cron.pid + rm -rf /var/log/cron.log + + # Install cron service: + cygrunsrv -I cron -p /usr/sbin/cron -a -D -d "Cygwin cron" -e "MAILTO=$USER@broadcom.com" -e "CYGWIN=ntsec" +fi + +# Start cron service +cygrunsrv -S cron diff --git a/clients/HP/bin/setup_ssmtp b/clients/HP/bin/setup_ssmtp new file mode 100644 index 0000000..b1ea7d2 --- /dev/null +++ b/clients/HP/bin/setup_ssmtp @@ -0,0 +1,58 @@ +#!/bin/bash +################################################################################ +# +# File: setup_ssmtp +# Description: This script sets up ssmtp mail configuration +# Author: Andrew@DeFaria.com +# Created: Wed Jan 9 12:57:13 2002 +# Language: Bash Shell +# Modifications: +# +# (c) Copyright 2002, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +# Setup /etc/ssmtp config directory +ssmtp_dir=/etc/ssmtp +domain=${domain:-broadcom.com} +mail_server=smtphost + +mkdir -p $ssmtp_dir +chmod 700 $ssmtp_dir + +# Make some simple aliases. Alias $USER to the proper email address and then +# alias root, Administrator and postmaster to the user's address thus making +# the user "god" of smtp on this machine only. +cat > $ssmtp_dir/revaliases < $ssmtp_dir/ssmtp.conf <" + exit 1 +} # usage + +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: Must be root to execute this command!" + usage +fi + +# Get parameters +if [ $# -ne 1 ]; then + usage; +else + new_license_server="$1" +fi + +license_server_file=/usr/adm/atria/config/license_host + +if [ -f $license_server_file ]; then + old_license_server=$(cat $license_server_file) + if [ "$old_license_server" = "$new_license_server" ]; then + print -u2 "$me: The license server is already $new_license_server" + print -u2 "$me: Nothing changed!" + exit + fi + cp $license_server_file $license_server_file.old + print $new_license_server > $license_server_file + print "$me: Switched license server from $old_license_server \c" + print "to $new_license_server." + print "$me: Saved old license server setting in $license_server_file.old" +fi diff --git a/clients/HP/bin/switch_region b/clients/HP/bin/switch_region new file mode 100644 index 0000000..cdfc435 --- /dev/null +++ b/clients/HP/bin/switch_region @@ -0,0 +1,48 @@ +#!/bin/ksh +################################################################################ +# +# File: switch_region +# Description: A script to switch the registry region from one region to +# another. +# Author: Andrew DeFaria, California Language Labs +# Created: Wed Jan 15 16:52:22 PST 1997 +# Modified: Wed Jan 15 16:52:22 PST 1997 (Andrew DeFaria) defaria@cup.hp.com +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +function usage { + print "Usage: $me: " + exit 1 +} # usage + +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: Must be root to execute this command!" + usage +fi + +# Get parameters +if [ $# -ne 1 ]; then + usage; +else + new_registry_region="$1" +fi + +registry_region_file=/usr/adm/atria/rgy/rgy_region.conf + +if [ -f $registry_region_file ]; then + old_registry_region=$(cat $registry_region_file) + if [ "$old_registry_region" = "$new_registry_region" ]; then + print -u2 "$me: The registry region is already $new_registry_region" + print -u2 "$me: Nothing changed!" + exit + fi + cp $registry_region_file $registry_region_file.old + print $new_registry_region > $registry_region_file + print "$me: Switched registry region from $old_registry_region \c" + print "to $new_registry_region." + print "$me: Saved old registry setting in $registry_region_file.old" +fi diff --git a/clients/HP/bin/switch_rgy b/clients/HP/bin/switch_rgy new file mode 100644 index 0000000..ded8c03 --- /dev/null +++ b/clients/HP/bin/switch_rgy @@ -0,0 +1,48 @@ +#!/bin/ksh +################################################################################ +# +# File: switch_rgy +# Description: A script to switch the registry host from one machine to +# another. +# Author: Andrew DeFaria, California Language Labs +# Created: Wed Jan 15 16:52:22 PST 1997 +# Modified: Wed Jan 15 16:52:22 PST 1997 (Andrew DeFaria) defaria@cup.hp.com +# Language: Korn Shell +# +# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved +# +################################################################################ +me=$(basename $0) + +function usage { + print "Usage: $me: " + exit 1 +} # usage + +if [ $(id -u) -ne 0 ]; then + print -u2 "$me: Error: Must be root to execute this command!" + usage +fi + +# Get parameters +if [ $# -ne 1 ]; then + usage; +else + new_registry_server="$1" +fi + +registry_host_file=/usr/adm/atria/rgy/rgy_hosts.conf + +if [ -f $registry_host_file ]; then + old_registry_server=$(cat $registry_host_file) + if [ "$old_registry_server" = "$new_registry_server" ]; then + print -u2 "$me: The registry server is already $new_registry_server" + print -u2 "$me: Nothing changed!" + exit + fi + cp $registry_host_file $registry_host_file.old + print $new_registry_server > $registry_host_file + print "$me: Switched registry server from $old_registry_server \c" + print "to $new_registry_server." + print "$me: Saved old registry setting in $registry_host_file.old" +fi diff --git a/clients/HP/bin/sysinfo b/clients/HP/bin/sysinfo new file mode 100644 index 0000000..03bc8f3 --- /dev/null +++ b/clients/HP/bin/sysinfo @@ -0,0 +1,5851 @@ +#!/bin/ksh +# +# +# Title: sysinfo +# Author: Scott Truesdale +# Organization: Hewlett-Packard Account Support Organization +# America's Engineering Services Team +# +# NOTE: This script is a contributed utility. No official support for it +# will be provided by Hewlett-Packard. Any requests for bug fixes +# or enhancements will be handled by the author, time permitting. +# +# Version: 1.00 08/01/96 +# Changes: 1.01 08/05/96 added functions to handle each module +# 1.02 \ cleaned up various +# 1.03 / output screens +# 1.04 08/20/96 added filesystem check using lvol +# 1.05 08/25/96 added savecore flag and space check +# 1.06 09/03/96 changed filesystem check to use mnttab +# 1.07 09/03/96 fixed filesystem check when bdf is 2 lines +# 1.08 10/10/96 general cleanup, added more dump checking +# 1.09 10/10/96 added use of pager variable for output +# 1.10 10/23/96 fixed dump checking section (I hope) +# added 10.10 compression calculation (-s) +# 1.11 10/30/96 fixed display of number of stale extents (-l) +# added comments to help document functions. +# 1.12 10/31/96 added -N option to disable paging option. +# 1.13 11/06/96 added cpu speed display (in MHz). (-s) +# 1.14 11/08/96 removed tabs and added comments. +# 1.15 11/11/96 added check for non HP-UX systems. +# 1.16 11/20/96 expanded mapping to include number of +# extents and mirrors. (-m) +# 1.17 11/21/96 added kernel size display (-k) +# added check for non-LVM disks (-p) +# 1.18 11/26/96 added license, machine id (-s) +# added domain name (-k) +# fixed batch to include header information +# added check for vgcfg files > 1 year old. (-v) +# added kernel size to memory dump calculations +# 1.19 12/03/96 fixed error if no CD mounted in CD-ROM drive +# changed help (-h) to use man page +# 1.20 12/12/96 added physical disk mapping option (-M) +# for 10.x systems +# added dbc_max_pct kernel parm +# 1.21 12/17/96 added physical disk mapping for 9.x +# 1.22 01/07/97 fixed bug in path display for cdroms +# 1.23 02/04/97 added last patch date display +# 1.24 02/10/97 fixed bug in physical check for cdrom +# device busy error +# 1.25 02/12/97 fixed display of dump on default for 9.x +# 1.26 02/28/97 added display of default router +# 1.27 03/10/97 added display of MAC address +# 1.28 03/18/97 added display of alternate links +# added bootable check to Physical info +# 1.29 04/15/97 added check for dynamic buffer caching +# added nflocks kernel parm +# added check for async disk write +# added check for savecore compression in +# /etc/rc.config.d/savecore +# fixed exit code for warnings +# added auto boot string output +# 1.30 04/22/97 cleaned up swap and dump disk display +# added check for cdfs to % full warning +# fixed dbc and its warning for only 10.x +# added ability to specify savecore +# compression factor as variable +# 1.31 04/22/97 fixed bug in calculating savecore capacity +# 1.32 04/22/97 added display of boot disks +# 1.33 07/08/97 fixed pre 10.20 warning for not +# enough savecore space +# 1.34 07/19/97 added dns server display +# changed netmask to decimal.dot format +# 1.35 07/29/97 added use of model command to detect new +# system models +# added following from Mike Ryan: +# fixed display of multiple MAC addresses +# patch for pvdisplay difference in 10.20 +# fix VG display when PVG-strict policies used +# (thanks Mike!) +# 1.36 07/31/97 fixed bug in alternate PV link detection +# 1.37 08/01/97 added super page check +# removed dynamic buffer warning +# improved debug message handling +# changed debug messages to tee to file +# 1.38 08/17/97 added check for number of volume groups equal +# to maxvgs +# started adding HTML hooks (-H option) +# added HTML headers to each section +# added HTML links to each section +# added HTML info to man page +# 1.39 08/20/97 added check for existing logfiles +# ask user if we should delete batch logfile +# automatically delete HTML logfile +# changed temp file names to sysinfo.$$. +# 1.40 08/26/97 changed physical disk section to not query +# alternate links +# 1.41 08/28/97 added kernel parms section extracted using +# tools from SAM. +# 1.42 09/19/97 changed network to use lanscan due to +# problems with multiple I/F cards. +# 1.43 10/21/97 added hw path to network card info. +# added fstype display to filesystem info. +# fixed display of cdfs space usage. +# fixed man page that incorrectly stated free +# space threshold was 10% instead of 5%. +# 1.44 04/09/98 major enhancements +# added ioscan listing. +# added software listing (10.x only) +# added listing of striped discs. +# launched io, kernel and lvm scans +# as background jobs to speed things up. +# 1.45 04/17/98 fixed bug that caused dbc parms not to +# be displayed. +# 1.46 04/30/98 changed swap disk header to swap data +# added fs swaptype to total swap display +# 1.47 05/03/98 added warning about static buffer cache +# numbers reported from kernel. +# 1.48 05/20/98 added variable for logfile directory. +# removed user query if removing existing logfile. +# reworked logical volume section into two parts. +# 1.49 07/01/98 first set of changes to work on 11.x +# savecore now called savecrash +# changed BOOTABLE to check for >= 10 +# physmem now called phys_mem_pages +# 1.49a added host name to WARNING messages +# added TOP link to html output +# 1.49b 07/16/98 fixed problems for 9.x induced by background +# scans of sam, swap and ioscan +# samscan, ioscan, swapmem +# removed samscan (getkinfo) from 9.x +# changed to force getkinfo to rescan (-b) +# 1.49c 07/23/98 more ioscan changes for 9.x +# 1.49d 07/27/98 major kernel changes +# 1.49e 08/01/98 fixed problem with filesystem display +# if size greater than 65 GB. +# 1.49f 08/03/98 added separate 9.x kernel function +# including many more kernel metrics +# moved kernel size to system section +# rewrote header section for HTML +# added batch print for software section +# changed lanscan -i for 9.x +# 1.49g 08/05/98 lots +# 1.50 08/06/98 fixed kernel parms on 10.x & 11.x +# 1.51 08/27/98 fixed savecore free space calculation when +# using non-standard lvol name +# added cstm extract of cpu & memory info +# 1.52 10/14/98 fixed adb on 11.0 with 64 bit kernel +# added display of 32 or 64 bit kernel on 11.0 +# 1.53 10/16/98 added processor info from stm +# removed old SAM kernel code +# 1.54 10/20/98 increased field for PDC to 12 chars +# 1.55 10/20/98 fixed ifconfig problem with grep +# 1.56 10/20/98 added No such file or directory check to diskinfo +# changed rphysvol to use ioscan rather than +# calculating +# increased display of hwpath for EMC drives +# 1.57 10/22/98 fixed bug in getting rdsk name +# 1.58 10/27/98 added bad block relocation to logical display +# added warning for EMC disks with LVM bad +# block relocation enabled +# 1.59 11/3/98 added check for iodevice w/o phyvol +# +# 1.70 04/12/99 added check for unsupported cstm versions +# < 09 & > 13 +# 1.71 04/12/99 Numerous changes by Greg Sterling +# Code handles CRASHCONF utility +# Allows for dump devices in V11.x. +# Dump devices can be disk drives in addition +# to logical volumes. +# Allow for Fibrechannel devices to be +# accurately parsed in the Phys Device section. +# Updated the wait for ioscan to complete. +# The prior time was 15 seconds, this is not +# enough for a large system with many devices. +# I increased the wait to 125 seconds. +# Fixed the "Last Patch" section to work with +# a standard swinstall type system. +# Added security check. Checks file permissions +# on some critical files and dirs, and checks +# modem access. +# Check system log files (i.e. syslog.log, +# mail.log, btmp, and wtmp). These files are +# known to get large very quickly. +# Changes the Date stamp on output files +# to include a four digit year for Y2K reasons. +# Check the sendmail queue for old (older than +# 2 days) or large qty of entries. +# Added code to check/output information +# related to system diags (if its installed). +# This included diags and predictive. +# This option only applies to V10.x and up. +# Fixed a few bugs in the code which limited +# output to 10.10 or 10.20 systems. I had +# to change some of the IF statements. +# For V10.x systems and higher I added the +# /var/adm/sw/*.log files to the logfile +# check routine. +# 1.72 04/25/99 fixed bug in crashconf size calculation +# added ip name to ip addr in networking +# moved 32/64 bit to follow OS version +# added check for non-configured software +# i.e. transient, corrupt, available +# or installed +# added listing of boot paths under bootable disks +# 1.73 05/14/99 fixed cstm hang problem - finally! +# vers 12 reversed the meanings of the +# SaveAs and Print commands for Infolog +# 1.74 05/25/99 improved formatting of cstm output +# 1.75 06/02/99 fixed bug when cstm_tot_phys = N/A +# added path to crashconf executable (/sbin/) +# fixed bug when Online dir has .2 suffix +# 1.76 07/12/99 several performance changes thanks to J. Semroc +# changed filesystem section +# added vxfs fragmentation; removed inodes +# added check if Vxfs version < 3 on > 10.10 +# replaced cstm memory output +# added umask of 077 for security purposes +# 1.77 08/03/99 fixed Ignite version check for older versions +# removed cd-rom size from total p_size +# 1.78 09/07/99 added PA RISC chip and version +# removed cstm upper version check +# 1.78a 9/14/99 removed DVD size from total p_size +# increased sum lines for CAPACITY +# increased display size of product (model) +# 1.78b 9/18/99 Incorporated numerous changes by Jerry Schwartz: +# changed HTML output to use frames +# #fixed bug in physical disk enumeration +# fixed bug in check for /.profile +# made cosmetic changes to error messages +# ("Logfile" changed to "Important file", +# "doesn not" changed to "does not") +# 1.78c 10/2/99 Added cstm disk scan to retrieve firmware +# and serial number info. +# 1.78d 10/11/99 Updated models table +# 1.78e +# 1.78f Added XP256 information +# 1.79b +# | +# 1.79f 04/18/00 Added INSTALL script +# Added checks for diagmond to prevent hangs +# Added disk array checks for FC60, AutoRaid +# Cascade, and Nike. +# 1.79g 04/19/00 Added return to diagmond check +# 1.79h 05/15/00 Added additional system models +# Removed get_array_data due to cstm problem +# +# +# Acknowledgements: +# I would like to acknowledge the following for assistance in +# developing and testing this tool. +# +# Jerry Schwartz, Jeff Semroc, Greg Sterling, Mike Ryan & Bill Taylor +# from the HP Account Support Organization for their help in debugging +# and improving the code. +# +# LVMcollect.* scripts from Peter Van Giel in the Hewlett-Packard +# Country Response Center Belgium. +# capture script from Dave Olker of the Hewlett-Packard Worldwide +# Technology Expert Center. +# +# Most of all I would like to thank the PRODUNIX support team +# at Oracle Corp. for allowing me access and time to develop +# and test using their systems. +# +# +version="1.79h" # +umask 077 +ROOT=$PWD # +export RESOLV_CONF=/etc/resolv.conf # +#script=`basename $0` # +script="SysInfo" # +typeset PAGER=${PAGER:-more} # +typeset -x osmajor # +typeset -R4 lcount=0 # number of logical volumes +typeset -R4 pcount=0 # number of physical volumes +typeset -R4 vgcount=0 # number of volume groups +typeset -i total_stale=0 # number of stales extents +typeset stale=0 # flag set if stale extents found +typeset all_logvols # list of all logical volumes +typeset -L17 physvol # name of phyical volume +typeset -R21 rphysvold # name of raw phyical volume +typeset -R24 hwpathd # path information for disk +typeset -L8 vendor # vendor id string from disk +typeset EMC_found=0 # flag for EMC disks +typeset -R14 product # vendor model number from disk +typeset -R1 bootable_pv # is disk bootable? +typeset -R5 rev_level # firmware revision code from disk +#typeset -R12 kernel_size #\ +typeset -i shmem # \ +typeset -R8 shmmni # \ +typeset -R8 shmmax # \ +typeset -R8 shmseg # \ +typeset -R8 maxfiles # \ +typeset -R8 maxfiles_lim # \ +typeset -R8 maxuprc # \ +typeset -R8 nproc # \ +typeset -R8 fs_async # \ +typeset -R8 nfile # kernel parameters +typeset -R8 nflocks # +typeset -R8 super_page_support # / +typeset -R8 dbc_max_pct # / +typeset -R8 dbc_min_pct # / +typeset -R8 ninode # / +typeset -R8 npty # / +typeset -R8 nbuf # / +typeset -R8 bufpages # / +typeset -R8 maxvgs # / +typeset SAVECORE # flag set if savecore is enabled +typeset COMPRESS=0 # +typeset COMPRESSION="N/A" # set if on 10.10 or later +typeset Compress_Option="N/A" # enabled in /etc/rc.config.d/savecore +typeset -R8 lv_pbuf_cnt # \ +typeset -R8 lv_pbuf_inuse # \ +typeset -R8 lv_pbuf_maxuse # more kernel parameters +typeset -R8 lv_pbuf_pending_Q # for lvm +typeset -R8 lv_vgs_opn # / +typeset -R8 lv_lvs_opn # / +typeset -i psize # physical disk size (in KBytes) +typeset -R8 psize_mb # physical disk size (in Mbytes) +### Changed 6/15/99 J.Semroc - Changed to handle large systems with 1000+ LU's +### typeset -R3 lu # physical disk logical unit number +typeset -R4 lu # physical disk logical unit number +### end of Change +typeset -L20 volgroup # +typeset -R6 CURLV # +typeset -R10 CURPV # +typeset -R8 PeSize # +typeset -R9 AllocPe # +typeset -R8 FreePe # +typeset -R8 TotalPe # +typeset -R11 AllocMb # +typeset -R8 FreeMb # +typeset -R8 TotalMb # +typeset -R8 TotalAllocMb=0 # total allocated Megabytes +typeset -R8 TotalFreeMb=0 # total free Megabytes +typeset -R8 SystemTotalMb=0 # total of all Megabytes +typeset -R8 MirrorMb=0 # size of mirror +typeset -R8 TotalMirrorMb=0 # total size of mirrors +typeset -R8 OtherMb=0 # +typeset -R11 total_p_mb=0 # total physical Megabytes +typeset -R8 total_l_mb=0 # total logical Megabytes +typeset -R8 unused_cap=0 # +typeset -L4 fs_type # +typeset -R4 vxfs_frag # +typeset -i no_lost=0 # flag if lost+found/.fsadm not found +typeset logvol # +typeset -L40 logvold # +typeset pvol # +typeset -L16 statusout # status of extents (e.g. stale) +typeset -R6 LVSize # size of logical volume +typeset -R7 LogicalExtents # +typeset -R8 StaleExtents # +typeset -L35 MOUNT # +typeset -R8 MirrorCopies # number of mirrors +typeset -R8 Consistency # mirror consistency strategy +typeset -i REAL_MEM # memory size (in pages) +typeset -i memory # memory size (in MBytes) +typeset -i num_cpus # number of active CPUs +typeset -i StaleMB=0 # stale Megabytes +typeset -i TotalStaleMb=0 # total stale Megabytes +typeset -i cpu_speed=0 # clock speed in MHz +typeset exit_code=0 # exit code [ 0, 1, 2, 3 ] +typeset ERROR=1 # exit condition (program error) +typeset WARN=2 # exit condition (system warning) +typeset SYS_ERROR=3 # exit condition (system error) +typeset SYSTEM=0 # \ +typeset FULL_KERNEL=0 # \ +typeset LITE_KERNEL=0 # \ +typeset FILESYSTEM=0 # \ +typeset NETWORK=0 # \ +typeset DEBUG=0 # \ +typeset SWLIST=0 # \ +typeset PHYSICAL=0 # flags set at runtime via +typeset LOGICAL=0 # command line options +typeset IOSCAN=0 # / +typeset -x HTML=0 # / +typeset NOPAGER=0 # / +typeset VOLUMES=0 # / +typeset CAPACITY=0 # / +typeset BATCH=0 # / +typeset LMAP=0 # / +typeset PMAP=0 #/ +typeset KernelSafetyFactor=2 # adds two MBytes to kernel size +typeset lvm_installed=0 # flag set if lvm present +typeset -R6 DumpDiskCapacity=0 # space to hold memory dump +typeset -R6 CompressedMemoryDumpSize # +typeset -R6 compression_factor # +typeset -i MemoryDumpSize # amount of memory (in MBytes) +typeset -i TotalMemoryDumpSize # amount of memory + kernel size +typeset -R6 MemoryDumpSizeOut # display version of MemoryDumpSize +typeset -R6 TotalMemoryDumpSizeOut # display version of TotalMemoryDumpSize +typeset -R6 SaveCoreAvail_Out # space to hold savecore + # can be compressed on 10.10 and later +############## +# Variables for Chk_Logfiles section +############## +LOGFILELISTV10="/var/adm/syslog/syslog.log /var/adm/syslog/mail.log \ + /var/adm/btmp /var/adm/wtmp /var/adm/sw/swagent.log /var/adm/sw/swagentd.log \ + /var/adm/sw/swconfig.log /var/adm/sw/swcopy.log /var/adm/sw/swinstall.log \ + /var/adm/sw/swmodify.log /var/adm/sw/swreg.log /var/adm/sw/swremove.log" + +LOGFILELISTV9="/usr/adm/syslog /usr/spool/mqueue/log /etc/btmp /etc/wtmp" +############## +# Variables for Chk_SysAccess section +############## +WORLDREADFILES="/etc/passwd /etc/group /etc/hosts /etc/services \ + /etc/inetd.conf" + +NOREADFILES=~root/.profile +############## +# variables for io_scan section +############## +GREP_ARGS="" +GREP_V_ARGS="-eNO_HW" +typeset -x ioscan_args="-F" +typeset -x io_scan_out=/tmp/sysinfo.$$.io_scan.out +typeset -x io_scan_tmp=/tmp/sysinfo.$$.io_scan.tmp +typeset -x io_scan_done=/tmp/sysinfo.$$.io_scan_done +typeset -x io_scan_command_file=/tmp/sysinfo.$$.io_scan_command_file +############## +# variables for lvm_scan section +############## +typeset -x vg_list_file=/tmp/sysinfo.$$.vg.list +typeset -x vg_out_file=/tmp/sysinfo.$$.vg.out +typeset -x lvol_list_file=/tmp/sysinfo.$$.lvol.list +typeset -x lvol_out_file=/tmp/sysinfo.$$.lvol.out +typeset -x pvol_list_file=/tmp/sysinfo.$$.pvol.list +typeset -x pvol_out_file=/tmp/sysinfo.$$.pvol.out +typeset -x lvm_scan_command_file=/tmp/sysinfo.$$.lvm_scan_command_file +typeset -x lvm_scan_done=/tmp/sysinfo.$$.lvm_scan_done +############## +# variables for sam_scan section +############## +typeset -x sam_scan_command_file=/tmp/sysinfo.$$.sam_scan_command_file +typeset -x sam_scan_done=/tmp/sysinfo.$$.sam_scan_done +typeset -x sam_out_file=/tmp/sysinfo.$$.sam.out +#typeset -x sam_kinfo=/tmp/sysinfo.$$.kinfo +typeset -x sam_kinfo_new=/tmp/sysinfo.$$.kinfo_new +############## +# variables for kernel section +############## +typeset -x sam_kinfo=${sam_kinfo:-/tmp/sysinfo.$$.sam_kinfo} +typeset -x all_parms_file=/tmp/sysinfo.$$.all_parms +typeset -x all_classes_file=/tmp/sysinfo.$$.all_classes +############## +# variables for cstm section +############## +typeset -x cstm_command_file=/tmp/sysinfo.$$.cstm_command_file +typeset -x cstm_cpu_out=/tmp/sysinfo.$$.cstm_cpu_out +typeset -x cstm_cpu_out2=/tmp/sysinfo.$$.cstm_cpu_out2 +typeset -x cstm_mem_out=/tmp/sysinfo.$$.cstm_mem_out +typeset -x cstm_disk_out=/tmp/sysinfo.$$.cstm_disk_out +typeset -x cstm_array_out=/tmp/sysinfo.$$.cstm_array_out +############# +# variables for sap section +############# +# translate uppercase to lowercase +TRUL='tr "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"' +typeset -x r3_dir=/var/opt/perf/datafiles/r3dsi +typeset -x r3_prog=${r3_dir}/r3agent +typeset -i num_instances=0 + + +ALL="TRUE" +FORCE="FALSE" +TEMPFILE=/var/sam/sam.$$ +save_lang=$LANG +LANG=C + + +################################################################################ +# Function: DebugOn() +# Description: Turns debugging mode on. +# Arguments: none +# Returns: none + +DebugOn() { +# set -o xtrace + export _DEBUG=1 + export _DEBUG_FILE=/tmp/sysinfo_${sysname}_`date '+%Y%m%d'`_debug + #Debug Debug ON: info will be logged to screen and to $_DEBUG_FILE + print "\nDebug ON: info will be logged to $_DEBUG_FILE" + Debug Debug ON: info will be logged to $_DEBUG_FILE +} + +################################################################################ +# Function: DebugOff() +# Description: Turns debugging mode off. +# Arguments: none +# Returns: none + +DebugOff() { + + Debug Debug OFF + _DEBUG=0 + _DEBUG_FILE=$ROOT/debug.out +} + +############################################################################### +# Function: Debug() +# Description: Prints debug statements to stderr when debug mode is on. +# Arguments: Text to echo. +# Returns: none + +Debug() { + + if [ "$_DEBUG" -gt 0 ] + then + #echo "DEBUG (PID $$): $*" | tee -a $_DEBUG_FILE 1>&2 + echo "DEBUG (PID $$): $*" >> $_DEBUG_FILE 2>&1 + fi +} + + +#-----------------------------------------------------------# +# Exit function, called by trapped signals +#-----------------------------------------------------------# +function _sigexit +{ +# print "Cleaning up, please wait." + if (($DEBUG)) && ((!(($NOPAGER)) )) + then + read answer?"Delete temp files? [Y/n]" + if [[ ${answer} = n ]] + then + print "O.K. Don't forget to delete /tmp/sysinfo.$$.*" + print "exit value = ${exit_code}" + else + print "O.K. I'm deleting temp files /tmp/sysinfo.$$.*" + rm -f /tmp/sysinfo.$$.* > /dev/null 2>&1 + print "exit_code = ${exit_code}" + fi + else + rm -f /tmp/sysinfo.$$.* > /dev/null 2>&1 + fi + exit ${exit_code} +} +trap _sigexit EXIT KILL HUP QUIT INT + + +function usage +{ +cat << EOF | $PAGER + +${script} ${version} by Scott Truesdale + +Usage: ${script} [-aADfikKlLmMnpsSv] [-b|-H|-N] + ${script} [-h] + + -a displays all of the following options. + -A displays file access security. + -D checks system diagnostic information. + -f checks filesystems for free space. + -h displays detailed help message. + -i displays io configuration. + -k displays brief kernel parameters. + -K displays verbose kernel parameters. + -l displays logical volume data. + -L displays system logfile info. + -m displays logical to physical disk mapping. + -M displays physical to logical disk mapping. + -n displays network interface data. + -p displays physical disk data. + -P checks for R/3 instances. + -s displays the system and root disk data. + -S displays software listing (swlist). + -v displays volume group data. + + -b send output to a logfile. + -H send output to a logfile in HTML format. + -N turn off paging in screen mode. + +Note: disk capacity data is displayed only when using -a or -lpv. + +EOF +} # end of usage + +function print_help +{ +export MANPATH=/usr/contrib/man:${where}:$MANPATH +# to debug help -d must come before -h +Debug "print_help" +Debug " where=${where}" +Debug " MANPATH=${MANPATH}" +if [[ -f ${where}/man1m/sysinfo.1m ]] || \ + [[ -f /usr/contrib/man/man1m/sysinfo.1m ]] +then + man sysinfo + exit_code=0 +else + print "Cannot find man page for ${script}!" + print "Expected to find it in /usr/contrib/man/man1m/" + exit_code=${ERROR} +fi +} + + +#=================================================================== +# get_args +# gets command line arguments passed in at run time +#=================================================================== +function get_args +{ +if (($# == 0)) +then +#print "\n$Must specify one or more of the following:$\n" + usage + exit ${ERROR} +fi +while getopts :abdfhiklmnpsvADHKLMNPS arguments +do + case $arguments in + a) LITE_KERNEL=1 + LOGFILES=1 + FILEACCESS=1 + DIAGNOSTICS=1 + SYSTEM=1 + NETWORK=1 + IOSCAN=1 + LVMSCAN=1 + PHYSICAL=1 + VOLUMES=1 + LOGICAL=1 + FILESYSTEM=1 + SWLIST=1 + PMAP=1 + LMAP=1;; + A) FILEACCESS=1;; + b) BATCH=1 + + LOGDIR=${SYSINFO_LOGDIR:-"/tmp"} + LOGFILE="${LOGDIR}/sysinfo_${sysname}_`date '+%Y%m%d'`" + Debug "Removing $LOGFILE" + rm -f $LOGFILE > /dev/null 2>&1 + + ;; + d) DEBUG=1 + DebugOn;; + D) DIAGNOSTICS=1;; + f) FILESYSTEM=1;; + h) print_help + exit ${exit_code};; + H) HTML=1 + BATCH=1 + LOGFILES=1 + LITE_KERNEL=1 + FILEACCESS=1 + DIAGNOSTICS=1 + SYSTEM=1 + NETWORK=1 + PHYSICAL=1 + VOLUMES=1 + IOSCAN=1 + LVMSCAN=1 + LOGICAL=1 + FILESYSTEM=1 + SWLIST=1 + PMAP=1 + LMAP=1 + LOGDIR=${SYSINFO_LOGDIR:-"/tmp"} + LOGFILE="${LOGDIR}/sysinfo_${sysname}_`date '+%Y%m%d'`.html" + if [[ -f ${LOGFILE} ]] + then + rm -f $LOGFILE >> /dev/null 2>&1 + Debug "Removing $LOGFILE" + fi + LOGFILE_INDEX_REL="`basename ${LOGFILE} .html`.index.html" + LOGFILE_INDEX="`dirname ${LOGFILE}`/${LOGFILE_INDEX_REL}" + if [[ -f ${LOGFILE_INDEX} ]] + then + rm -f ${LOGFILE_INDEX} >> /dev/null 2>&1 + Debug "Removing ${LOGFILE_INDEX}" + fi + LOGFILE_MAIN_REL="`basename ${LOGFILE} .html`.main.html" + LOGFILE_MAIN="`dirname ${LOGFILE}`/${LOGFILE_MAIN_REL}" + if [[ -f ${LOGFILE_MAIN} ]] + then + rm -f ${LOGFILE_MAIN} >> /dev/null 2>&1 + Debug "Removing ${LOGFILE_MAIN}" + fi;; + i) IOSCAN=1;; + k) LITE_KERNEL=1;; + K) FULL_KERNEL=1;; + l) LOGICAL=1 + LVMSCAN=1;; + L) LOGFILES=1;; + m) LMAP=1;; + M) PHYSICAL=1 + SYSTEM=1 + PMAP=1;; + n) NETWORK=1;; + p) PHYSICAL=1 + SYSTEM=1;; + P) PASS=1;; + s) SYSTEM=1;; + S) SWLIST=1;; + v) VOLUMES=1 + LVMSCAN=1;; + N) NOPAGER=1;; + ?) print "\nI don't understand that option\n" + usage + exit ${ERROR};; + esac + if (($PHYSICAL)) && (($VOLUMES)) && (($LOGICAL)) + then + CAPACITY=1 + fi + if (($LITE_KERNEL)) && (($FULL_KERNEL)) + then + LITE_KERNEL=0 + fi + if (($BATCH)) && (($DEBUG)) + then + NOPAGER=1 + fi +done +Debug "FLAGS: System=$SYSTEM Batch=$BATCH FullKernel=$FULL_KERNEL" +Debug "FLAGS: LiteKernel=$LITE_KERNEL Network=$NETWORK" +Debug "FLAGS: Volumes=$VOLUMES Capacity=$CAPACITY Logical=$LOGICAL" +Debug "FLAGS: Physical=$PHYSICAL LMapping=$LMAP PMapping=$PMAP" +Debug "FLAGS: Filesystem=$FILESYSTEM NoPager=$NOPAGER Html=$HTML" +Debug "FLAGS: Ioscan=$IOSCAN lvm_scan=$LVMSCAN Sam_scan=$SAMSCAN" +Debug "FLAGS: Swlist=$SWLIST Diagnostics=$DIAGNOSTICS" +Debug "FLAGS: PASS=$PASS" +if (($BATCH)) +then + print "\nOutput going to ${LOGFILE}" +fi +} # end of get_args + + +#=================================================================== +# f_display_file +# this function displays a file to the screen. it takes one parm, +# the file to display. It uses the defined PAGER or more if that +# variable is not defined. +#=================================================================== +function f_display_file +{ + if [[ -s $1 ]] + then + if (($BATCH)) + then + cat $1 >> $LOGFILE + if (($HTML)) + then + grep -v "#Top" $1 | grep -v "TOP> $LOGFILE_MAIN + fi + elif (($NOPAGER)) + then + cat $1 + else # not batch so use PAGER + $PAGER $1 + fi + fi +} # end of f_display_file + + +############################################################################### +# Function: check_for_sap +# Description: Check for any instances of R/3 by running r3agent -all. +# The output is scanned for the required info. +# +# The r3agentSYSTEM output is as follows: +# 01 "31G" "QAS" "sapgui sapd370 nr=01 name=QAS" +# +# The r3agentCONFIGURATION output is as follows: +# 01 "DVEBMGS01" "QAS" "sapd370" "" + +function check_for_sap +{ + print "Checking for SAP R/3 instances." + DB_on_this_sys=0 + if (($HTML)) + then + print "" >> /tmp/sysinfo.$$.sap + print "" >> /tmp/sysinfo.$$.sap + print "

" >> /tmp/sysinfo.$$.sap + print "

" >> /tmp/sysinfo.$$.sap + print "TOP

" >> /tmp/sysinfo.$$.sap + print "" >> /tmp/sysinfo.$$.sap + print "SAP R/3 Info

" >> /tmp/sysinfo.$$.sap + print "
"  >> /tmp/sysinfo.$$.sap
+  else
+    print "" >> /tmp/sysinfo.$$.sap
+    print "SAP R/3 Information" >> /tmp/sysinfo.$$.sap
+    print "===================" >> /tmp/sysinfo.$$.sap
+    print "" >> /tmp/sysinfo.$$.sap
+  fi
+  if [ -f ${r3_prog} ]
+  then
+    ${r3_prog} -all
+    num_instances=$( cat ./r3agentSYSTEM | wc -l)
+    if ((num_instances == 0))
+    then
+      print "No R/3 instances found."
+      print "No R/3 instances found." >> /tmp/sysinfo.$$.sap
+      rm ./r3agent[A-Z]* > /dev/null 2>&1
+      break
+    else
+      print "Found ${num_instances} instances."
+      cat ./r3agentCONFIGURATION | 
+      while read inst_id INSTANCE_NAME SAPSYSTEMNAME SAPDBHOST p5 p6 p7
+      do
+        INSTANCE_NAME=$(echo ${INSTANCE_NAME} | sed -e 's/\"*//g')
+        SID=$(echo ${SAPSYSTEMNAME} | sed -e 's/\"*//g')
+        SAPDBHOST=$(echo ${SAPDBHOST} | sed -e 's/\"*//g')
+        SAP_ADM="`echo $SID | $TRUL`adm"
+        startsap=$(su - ${SAP_ADM}  -c  "alias startsap" 2>&1 | tail -1)
+        sapstart=$(ps -ef | grep sapstart | grep -v grep | awk '{print $9}')
+        #PROFILE_DIR=$(grep "^PROFILE_DIR" ${startsap} | awk -F\" '{print $2}')
+        PROFILE_DIR=/usr/sap/${SID}/SYS/profile
+        EXE_DIR=/usr/sap/${SID}/SYS/exe/run
+        startprofile=$(grep "^START_PROFILE" ${startsap} |awk -F\" '{print $2}')
+        #SAPDBHOST=$(awk -F= '/SAPDBHOST/ {print $2}' $PROFILE_DIR/DEFAULT.PFL)
+        ${EXE_DIR}/disp+work -V > /tmp/sysinfo.$$.dispwork 2>&1
+
+        Debug "Saving dispwork -V output file"
+        cp /tmp/sysinfo.$$.dispwork ${r3_dir}/dispwork > /dev/null 2>&1
+
+        r3kernel=$(grep "kernel release" /tmp/sysinfo.$$.dispwork | \
+                    awk '{print $3}')
+        r3patch=$(grep "patch level" /tmp/sysinfo.$$.dispwork | \
+                    head -1 | awk '{print $3}')
+        r3db=$(grep "database kernel" /tmp/sysinfo.$$.dispwork | \
+                    awk '{print $4}')
+        r3dbver=$(grep "database kernel" /tmp/sysinfo.$$.dispwork | \
+                    awk '{print $5}')
+        if [[ -f ${PROFILE_DIR}/${startprofile} ]]
+        then
+          Debug "Saving profile ${PROFILE_DIR}/${startprofile}"
+          cp ${PROFILE_DIR}/${startprofile} ${r3_dir} > /dev/null 2>&1
+        fi
+        if [[ $SAPDBHOST = $sysname ]]
+        then
+          DB_on_this_sys=1
+          startdb=${EXE_DIR}/startsb
+          ORASID="ora`echo $SID | $TRUL`"
+          ORACLE_HOME=/oracle/${SID}
+          db_profile=${ORACLE_HOME}/dbs/init${SID}.ora
+          INITORA=$ORACLE_HOME/dbs/init${SID}.ora
+          if [[ -f ${db_profile} ]]
+          then
+            Debug "Saving profile ${db_profile}"
+            cp ${db_profile} ${r3_dir} > /dev/null 2>&1
+          fi
+        fi
+        print "  Instance ID     = $inst_id"         >> /tmp/sysinfo.$$.sap
+        print "  Instance Name   = ${INSTANCE_NAME}" >> /tmp/sysinfo.$$.sap
+        print "  SAP System Name = ${SID}"           >> /tmp/sysinfo.$$.sap
+        print "  R/3 Kernel Vers = ${r3kernel}"      >> /tmp/sysinfo.$$.sap
+        print "  R/3 Patch Level = ${r3patch}"       >> /tmp/sysinfo.$$.sap
+        print "  R/3 DB Vendor   = ${r3db}"          >> /tmp/sysinfo.$$.sap
+        print "  R/3 DB Version  = ${r3dbver}"       >> /tmp/sysinfo.$$.sap
+        print "  SAP adm user    = ${SAP_ADM}"       >> /tmp/sysinfo.$$.sap
+        print "  startsap        = ${startsap}"      >> /tmp/sysinfo.$$.sap
+        print "  sapstart        = ${sapstart}"      >> /tmp/sysinfo.$$.sap
+        print "  Profile Dir     = ${PROFILE_DIR}"   >> /tmp/sysinfo.$$.sap
+        print "  startprofile    = ${startprofile}"  >> /tmp/sysinfo.$$.sap
+        print "  SAPDBHOST       = ${SAPDBHOST}"     >> /tmp/sysinfo.$$.sap
+        if (($DB_on_this_sys))
+        then
+          print "  DB_on_this_sys  = true"           >> /tmp/sysinfo.$$.sap
+          print "    ORASID        = ${ORASID}"      >> /tmp/sysinfo.$$.sap
+          print "    ORACLE_HOME   = ${ORACLE_HOME}" >> /tmp/sysinfo.$$.sap
+          print "    INITORA       = ${INITORA}"     >> /tmp/sysinfo.$$.sap
+        else
+          print "  DB_on_this_sys  = false"          >> /tmp/sysinfo.$$.sap
+        fi
+        print "" >> /tmp/sysinfo.$$.sap
+      done
+    fi
+  else
+    print "  r3agent not found!"
+    print "  Scanning for dw.sap processes."
+    allinst=$(ps -ef | grep dw.sap | grep -v grep | awk '{print $(NF -1)}' | sort | uniq)
+    if [[ -z $allinst ]]
+    then
+      num_instances=0
+    else
+      num_instances=$(echo $allinst | wc -w)
+    fi
+    if ((num_instances == 0))
+    then
+      print "No R/3 instances found."
+      print "No R/3 instances found." >> /tmp/sysinfo.$$.sap
+      break
+    else
+      print "Found ${num_instances} instances."
+      for inst in ${allinst}
+      do
+        numchar=$(echo $inst | wc -c)
+        (( numchar = numchar - 1 ))
+        (( numchar1 = numchar - 1 ))
+        SID=$(echo $inst | cut -b7-9)
+        inst_id=$(echo $inst | cut -b${numchar1}-${numchar})
+        INSTANCE_NAME=$(echo $inst | cut -b11-${numchar})
+        SAP_ADM="`echo $SID | $TRUL`adm"
+        PROFILE_DIR=/usr/sap/${SID}/SYS/profile
+        startsap=$(su - ${SAP_ADM}  -c  "alias startsap" 2>&1 | tail -1)
+        #sapstart=$(ps -ef | grep sapstart | grep $SID |grep -v grep | awk '{print $9}')
+        sapstart=$(ls -L ${PROFILE_DIR}/START_${INSTANCE_NAME})
+        #echo $sapstart
+        startprofile=$(grep "^START_PROFILE" ${sapstart} |awk -F\" '{print $2}')
+        EXE_DIR=/usr/sap/${SID}/SYS/exe/run
+        SAPDBHOST=$(awk -F= '/SAPDBHOST/ {print $2}' $PROFILE_DIR/DEFAULT.PFL)
+        SAPDBHOST=$(echo $SAPDBHOST | sed -e 's/\ *//g')
+        if [[ $SAPDBHOST = $sysname ]]
+        then
+          DB_on_this_sys=1
+          startdb=${EXE_DIR}/startsb
+          ORASID="ora`echo $SID | $TRUL`"
+          ORACLE_HOME=/oracle/${SID}
+          INITORA=$ORACLE_HOME/dbs/init${SID}.ora
+          if [[ -f ${db_profile} ]]
+          then
+            Debug "Saving profile ${db_profile}"
+            cp ${db_profile} ${r3_dir} > /dev/null 2>&1
+          fi
+        fi
+        ${EXE_DIR}/disp+work -V > /tmp/sysinfo.$$.dispwork 2>&1
+
+        Debug "Saving dispwork -V output file"
+        cp /tmp/sysinfo.$$.dispwork ${r3_dir}/dispwork > /dev/null 2>&1
+
+        r3kernel=$(grep "kernel release" /tmp/sysinfo.$$.dispwork | \
+                    awk '{print $3}')
+        r3patch=$(grep "patch level" /tmp/sysinfo.$$.dispwork | \
+                    head -1 | awk '{print $3}')
+        r3db=$(grep "database kernel" /tmp/sysinfo.$$.dispwork | \
+                    awk '{print $4}')
+        r3dbver=$(grep "database kernel" /tmp/sysinfo.$$.dispwork | \
+                    awk '{print $5}')
+
+        print "  Instance ID     = $inst_id"         >> /tmp/sysinfo.$$.sap
+        print "  Instance Name   = ${INSTANCE_NAME}" >> /tmp/sysinfo.$$.sap
+        print "  SAP System Name = ${SID}" >> /tmp/sysinfo.$$.sap
+        print "  R/3 Kernel Vers = ${r3kernel}"      >> /tmp/sysinfo.$$.sap
+        print "  R/3 Patch Level = ${r3patch}"       >> /tmp/sysinfo.$$.sap
+        print "  R/3 DB Vendor   = ${r3db}"          >> /tmp/sysinfo.$$.sap
+        print "  R/3 DB Version  = ${r3dbver}"       >> /tmp/sysinfo.$$.sap
+        print "  SAP adm user    = ${SAP_ADM}"       >> /tmp/sysinfo.$$.sap
+        print "  startsap        = ${startsap}"      >> /tmp/sysinfo.$$.sap
+        print "  sapstart        = ${sapstart}"      >> /tmp/sysinfo.$$.sap
+        print "  Profile Dir     = ${PROFILE_DIR}"   >> /tmp/sysinfo.$$.sap
+        print "  startprofile    = ${startprofile}"  >> /tmp/sysinfo.$$.sap
+        print "  SAPDBHOST       = ${SAPDBHOST}"     >> /tmp/sysinfo.$$.sap
+        if (($DB_on_this_sys))
+        then
+          print "  DB_on_this_sys  = true" >> /tmp/sysinfo.$$.sap
+          print "    ORASID        = ${ORASID}" >> /tmp/sysinfo.$$.sap
+          print "    ORACLE_HOME   = ${ORACLE_HOME}" >> /tmp/sysinfo.$$.sap
+          print "    INITORA       = ${INITORA}" >> /tmp/sysinfo.$$.sap
+        else
+          print "  DB_on_this_sys  = false" >> /tmp/sysinfo.$$.sap
+        fi
+        print "" >> /tmp/sysinfo.$$.sap
+      done
+    fi
+  fi
+
+}
+
+###############################################################################
+# Function:    chk_ignite()
+# Description: Check if IgniteUX is installed. If so, check for the last
+#              completed make_recovery. Check if make_recovery -C has been
+#              run. If so, run check_recovery and display results.
+#
+# Arguments:   none
+# Returns:     none
+
+function chk_ignite
+{
+  Debug "  Starting chk_ignite"
+  if [[ ${osmajor} <  10 ]]
+  then
+    print "IgniteUX is not supported on less that HP-UX 10.x"
+    Debug "  Unsupported HP-UX version $osmajor"
+    break
+  fi
+  print "Checking for IgniteUX."
+  if [ -d /opt/ignite ]
+  then
+    if [ -f /opt/ignite/Version ]
+    then
+      ignite_ver=$(cat /opt/ignite/Version)
+      print "IgniteUX is installed. Version = $ignite_ver" >> \
+                   /tmp/sysinfo.$$.ignite
+    else
+      print "IgniteUX is installed. Version = N/A." \
+                >> /tmp/sysinfo.$$.ignite
+    fi
+    if [ -f /var/opt/ignite/logs/makerec.log1 ]
+    then
+      last_make_recovery=$(grep Completed /var/opt/ignite/logs/makerec.log1)
+      if [ -z $last_make_recovery ]
+      then
+        print "WARNING (${sysname}): IGNITE make_recovery not run." >> \
+                 /tmp/sysinfo.$$.errwarn
+      else
+        print "Most recent make_recovery  = ${last_make_recovery}" >> \
+                 /tmp/sysinfo.$$.ignite
+      fi
+    else
+      print "WARNING (${sysname}): IGNITE make_recovery not run or logfile deleted." \
+              >> /tmp/sysinfo.$$.errwarn
+    fi
+    if [ -f /var/opt/ignite/recovery/makerec.last ]
+    then
+      check_recovery #> /dev/null 2>&1
+    else
+      print "WARNING (${sysname}): IGNITE check_recovery log not found"  \
+              >> /tmp/sysinfo.$$.errwarn
+    fi
+  else
+    print "WARNING (${sysname}): IgniteUX is NOT installed." \
+            >> /tmp/sysinfo.$$.errwarn
+  fi
+  f_display_file /tmp/sysinfo.$$.ignite
+}
+###############################################################################
+# Function:    chk_diags()
+# Description: Check the system's diagnostic software configuration.  Output
+#              the predictive setting if its installed. This is important info.
+#
+# Arguments:   none
+# Returns:     none
+
+chk_diags()
+{
+  Debug "  Starting Chk_Diags. OSMAJOR = $osmajor"
+
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.diagnostics.info + print "" >> \ + /tmp/sysinfo.$$.diagnostics.info + print "

" >> \ + /tmp/sysinfo.$$.diagnostics.info + print "

TOP

" >> \ + /tmp/sysinfo.$$.diagnostics.info + print "" >> \ + /tmp/sysinfo.$$.diagnostics.info + print "System Diagnostics Settings

" >> \ + /tmp/sysinfo.$$.diagnostics.info + print "
"   >> \
+               /tmp/sysinfo.$$.diagnostics.info
+  else
+    print "SYSTEM DIAGNOSTICS SETTINGS" >> \
+               /tmp/sysinfo.$$.diagnostics.info
+    print "==========================" >> \
+               /tmp/sysinfo.$$.diagnostics.info
+  fi
+
+  print -n "checking system diagnostics "
+
+  print "" >> /tmp/sysinfo.$$.diagnostics.info
+  case $osmajor in
+    10 | 11 )
+#
+# Look for the OnlineDiag product file. If it exists, then the product is
+# installed on the system. You can use the product's INDEX file to get the
+# product version (this can be important info).
+#
+      print ".\c"
+      prodfile=$(ls -d /var/adm/sw/products/OnlineDiag* 2>&1)
+      Debug "Found OnlineDiag dir - ${prodfile}"
+      if [ -d "$prodfile" ]
+      then
+        print -n "Online Diagnostics are Installed: " \
+                  >> /tmp/sysinfo.$$.diagnostics.info
+        print "Version: $(grep ^revision $prodfile/pfiles/INDEX \
+            | awk '{print $NF}')\t\c" >> /tmp/sysinfo.$$.diagnostics.info
+        print "Status: \c" >> /tmp/sysinfo.$$.diagnostics.info
+#
+# Now use the PS command to see if diagnostics are running.
+#
+       ps -ef | grep -q diagmon
+       if [ $? -eq 0 ]
+       then
+         print "Running" >> /tmp/sysinfo.$$.diagnostics.info
+       else
+         print "Down" >> /tmp/sysinfo.$$.diagnostics.info
+       fi
+       print "" >> /tmp/sysinfo.$$.diagnostics.info
+#
+# If the diagnostics software is properly installed then there should be
+# programs in the LIF area named ODE, MAPPER, and MAPFILE. If these values
+# are not present, then diags will not run from console mode.
+#
+# By checking all boot disks (obtained from lvlnboot -v), we also check
+# any mirrored volumes. This is good because mirrored root volumes are
+# often missed.
+#
+       typeset -i liferrors
+       bootdsks=$(lvlnboot -v 2>/dev/null | grep "Boot Disk" | awk '{print $1}')
+
+       print "Checking LIF Information (ODE, MAPPER and, MAPFILE)" >> \
+              /tmp/sysinfo.$$.diagnostics.info
+       print ".\c"
+#
+# Now loop for each boot disk found by lvlnboot -v. This will check mirrors
+# as well as primary disks. All boot disks should have diags installed.
+#
+       for bdisk in $bootdsks
+       do
+         liferrors=0
+         lifls -l $bdisk >> /tmp/sysinfo.$$.diagnostics.lifinfo
+         for lfdiag in ODE MAPPER MAPFILE
+         do
+           grep -q $lfdiag /tmp/sysinfo.$$.diagnostics.lifinfo
+           if [ $? -ne 0 ]
+           then
+             print "WARNING (${sysname}): Missing $lfdiag on ${bdisk}." \
+                  >> /tmp/sysinfo.$$.errwarn
+             liferrors=liferrors+1
+           fi
+         done
+#
+# If the liferrors variable is greater than zero then this disk was missing at
+# least one of the required LIF files. If its equal to zero, then this disk
+# has all the required info.
+#
+         if [ $liferrors -eq 0 ]
+         then
+           print "$bdisk\tOK" >> /tmp/sysinfo.$$.diagnostics.info
+         fi
+        done
+      else
+      print "WARNING (${sysname}): Online Diagnostics are NOT Installed." >> \
+            /tmp/sysinfo.$$.errwarn
+      print "Online Diagnostics are NOT Installed." >> \
+            /tmp/sysinfo.$$.diagnostics.info
+      fi
+#
+# Now check the system product database to see if Predictive is installed. 
+# If it is, then output its version info, and check to see if its running 
+# (again using the ps command).
+#
+      print ".\c"
+      print " " >> /tmp/sysinfo.$$.diagnostics.info
+      prodfile=$(ls -d /var/adm/sw/products/Predictive* 2>&1)
+      Debug "Found Predictive dir - ${prodfile}"
+      if [ -d "$prodfile" ]
+      then
+        print -n "Predictive is Installed: Version:" \
+             >> /tmp/sysinfo.$$.diagnostics.info
+        print " $(grep ^revision $prodfile/pfiles/INDEX | awk \
+            '{print $NF}')\t\c" >> /tmp/sysinfo.$$.diagnostics.info
+        print "Status: \c" >> /tmp/sysinfo.$$.diagnostics.info
+        ps -ef | grep -q psmond
+        if [ $? -eq 0 ]
+        then
+          print "Running" >> /tmp/sysinfo.$$.diagnostics.info
+        else
+          print "Down" >> /tmp/sysinfo.$$.diagnostics.info
+        fi
+#
+# Predictive is installed. Run PSCONFIG to output the configuration info and
+# the recent log history. This is good documentation of the system, and shows
+# whether the system has been reporting problems to the response center.
+#
+        print ".\c"
+        print "" >> /tmp/sysinfo.$$.diagnostics.info
+        print "Predictive Configuration Information" >> \
+                     /tmp/sysinfo.$$.diagnostics.info 
+        if [ -x /opt/pred/bin/PSCONFIG ]
+        then
+          print ".\c"
+          /opt/pred/bin/PSCONFIG print configuration >> \
+                     /tmp/sysinfo.$$.diagnostics.info 2>/dev/null
+          print ".\c"
+          /opt/pred/bin/PSCONFIG print action >> \
+                     /tmp/sysinfo.$$.diagnostics.info 2>/dev/null
+        else
+          print "ARNING (${sysname}): PSCONFIG is not executable" >> \
+                        /tmp/sysinfo.$$.errwarn
+        fi
+      else
+        print "Predictive is NOT Installed." >> \
+                    /tmp/sysinfo.$$.diagnostics.info
+        print "WARNING (${sysname}): Predictive is NOT Installed." >> \
+                    /tmp/sysinfo.$$.errwarn
+      fi
+    ;;
+#
+# I did not implement any code which would work with V9.x or earlier. At this
+# point, most customers should be at V10.x by now. V9.x is off support life.
+#
+    8 | 9 )
+      print "This module was created for V10.x and higher. Sorry."
+    ;;
+  esac
+
+  print ""
+  print "" >> /tmp/sysinfo.$$.diagnostics.info
+
+  f_display_file /tmp/sysinfo.$$.diagnostics.info
+
+  return $return_code
+}
+
+###############################################################################
+# Function:    chk_sysaccess()
+# Description: Routine used to check some of the security characteristics of
+#              the system. This includes checking the permissions of the
+#              /etc/passwd, and /etc/group files as well as checking for
+#              .rhosts and other files.
+# Arguments:   none
+# Returns:     none
+
+chk_sysaccess() {
+  Debug "  Starting Chk_SysAccess. OSMAJOR = $osmajor"
+
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.sysaccess.info + print "" >> /tmp/sysinfo.$$.sysaccess.info + print "

" >> /tmp/sysinfo.$$.sysaccess.info + print "

" >> /tmp/sysinfo.$$.sysaccess.info + print "TOP

" >> /tmp/sysinfo.$$.sysaccess.info + print "" >> /tmp/sysinfo.$$.sysaccess.info + print "System Security Audit

" >> /tmp/sysinfo.$$.sysaccess.info + print "
" >> /tmp/sysinfo.$$.sysaccess.info
+  else
+    print "SYSTEM SECURITY AUDIT" >> /tmp/sysinfo.$$.sysaccess.info
+    print "==========================" >> /tmp/sysinfo.$$.sysaccess.info
+  fi
+
+  last -R > /tmp/sysinfo.$$.last 
+  print -n "checking system security "
+  print "" >> /tmp/sysinfo.$$.sysaccess.info
+
+  print "File Permissions. Files which should be World and Group Read-Only." \
+           >>  /tmp/sysinfo.$$.sysaccess.info
+
+  for lfile in $WORLDREADFILES
+  do
+    Debug "   chk_SysAccess. Checking $lfile."
+    if [[ ! -a "$lfile" ]]
+    then
+      print "ERROR ($sysname): Important file $lfile does not exist." >> \
+              /tmp/sysinfo.$$.errwarn
+      return_code=$ERROR
+    else
+#
+# Get the important file's directory information.
+#
+      llinfo=$(ll -d $lfile)
+#
+# Now check the file's permissions
+#
+      echo "$llinfo" | cut -c5-10 | egrep -q "w"
+      if [ $? -eq 0 ]
+      then
+        print "WARNING ($sysname): Important file $lfile has Group or World WRITE access.  " >> /tmp/sysinfo.$$.errwarn
+        return_code=$WARN
+      fi
+    echo "$llinfo" >> /tmp/sysinfo.$$.sysaccess.info
+    fi
+  done
+#
+# Now check the system for files/directories which should be accessible to
+# root only. This code will flag files which have any access other than the
+# owner.
+#
+  print "" >> /tmp/sysinfo.$$.sysaccess.info
+  print "File Permissions. Files which should be Accessible to Root only." >> \
+             /tmp/sysinfo.$$.sysaccess.info
+
+  for lfile in $NOREADFILES
+  do
+    Debug "   chk_SysAccess. Checking $lfile."
+    if [[ ! -a "$lfile" ]]
+    then
+      print "WARNING ($sysname): Important file $lfile does not exist." >> \
+               /tmp/sysinfo.$$.errwarn
+      return_code=$WARN
+    else
+#
+# Get the Important file's directory information.
+#
+      llinfo=$(ll -d $lfile)
+#
+# Now check the file's permissions
+#
+      echo "$llinfo" | cut -c5-10 | egrep -q "r|w|x"
+      if [ $? -eq 0 ]
+      then
+        print "WARNING ($sysname): Important file $lfile has Group or World access." \
+                >> /tmp/sysinfo.$$.errwarn
+        return_code=$WARN
+      fi
+      echo "$llinfo" >> /tmp/sysinfo.$$.sysaccess.info
+    fi
+  done
+
+  print "" >> /tmp/sysinfo.$$.sysaccess.info
+  print "Check for Important Audit Files:" >> /tmp/sysinfo.$$.sysaccess.info
+#
+# Now check for the wtmp and btmp files. These are important to login history.
+# make sure they exist, if not, then give a warning. then check their security.
+# The wtmp file tracks login history. The btmp file tracks invalid logons.
+#
+# Also check the sulog file. This file tracks the history of SU'ing to root.
+#
+  case $osmajor in
+    8 | 9 )
+      WTMP="/etc/wtmp"
+      BTMP="/etc/btmp"
+      SULOG="/usr/adm/sulog"
+    ;;
+
+    * )
+      WTMP="/var/adm/wtmp"
+      BTMP="/var/adm/btmp"
+      SULOG="/var/adm/sulog"
+    ;;
+  esac
+#
+# Check the wtmp file
+#
+  if [[ ! -a "$WTMP" ]]
+  then
+    print "WARNING ($sysname): Audit File $WTMP does not exist." >> \
+                /tmp/sysinfo.$$.errwarn
+    print "If you create $WTMP you can track logon history." >> \
+                /tmp/sysinfo.$$.errwarn
+    print " " >> /tmp/sysinfo.$$.errwarn
+  else
+    llinfo=$(ll -d $WTMP)
+
+    echo "$llinfo" | cut -c8-10 | egrep -q "w"
+    if [ $? -eq 0 ]
+    then
+      print -n "WARNING ($sysname): Audit File $WTMP has Group or " >> \
+                  /tmp/sysinfo.$$.errwarn
+      print "World WRITE access." >> /tmp/sysinfo.$$.errwarn
+      print "   $WTMP should have at most World read access." >> \
+                  /tmp/sysinfo.$$.errwarn
+      print " " >> /tmp/sysinfo.$$.errwarn
+    fi
+    echo "$llinfo" >> /tmp/sysinfo.$$.sysaccess.info
+  fi
+#
+# Now check the btmp file.
+#
+  if [[ ! -a "$BTMP" ]]
+  then
+    print "WARNING ($sysname): Audit File $BTMP does not exist." >> \
+               /tmp/sysinfo.$$.errwarn
+    print "If you create $BTMP you can track invalid logon history." >> \
+               /tmp/sysinfo.$$.sysaccess.warn
+    print " " >> /tmp/sysinfo.$$.sysaccess.warn
+  else
+    llinfo=$(ll -d $BTMP)
+
+    echo "$llinfo" | cut -c5-10 | egrep -q "w"
+    if [ $? -eq 0 ]
+    then
+      print -n "WARNING ($sysname): Audit File $BTMP has Group or ">> \
+                  /tmp/sysinfo.$$.errwarn
+      print "World WRITE access." >> /tmp/sysinfo.$$.errwarn
+      print "$BTMP should have at most Group or World read access." >> \
+                  /tmp/sysinfo.$$.errwarn
+      print " " >> /tmp/sysinfo.$$.errwarn
+    fi
+
+    echo "$llinfo" >> /tmp/sysinfo.$$.sysaccess.info
+  fi
+#
+# Check the sulog file now.
+#
+  if [[ ! -a "$SULOG" ]]
+  then
+    print "WARNING ($sysname): Audit File $SULOG does not exist." >> \
+        /tmp/sysinfo.$$.errwarn
+    print "If you create $SULOG you can track su logon history." >> \
+         /tmp/sysinfo.$$.sysaccess.warn
+    print " " >> /tmp/sysinfo.$$.sysaccess.warn
+  else
+    llinfo=$(ll -d $SULOG)
+
+    echo "$llinfo" | cut -c5-10 | egrep -q "w"
+    if [ $? -eq 0 ]
+    then
+      print -n "WARNING ($sysname): Audit File $SULOG has Group or " >> \
+                   /tmp/sysinfo.$$.errwarn
+      print "World WRITE access." >> /tmp/sysinfo.$$.sysaccess.warn
+      print "$SULOG should have at most Group or World read access." >> \
+                  /tmp/sysinfo.$$.sysaccess.warn
+      print " " >> /tmp/sysinfo.$$.sysaccess.warn
+    fi
+
+    echo "$llinfo" >> /tmp/sysinfo.$$.sysaccess.info
+    print " " >> /tmp/sysinfo.$$.sysaccess.info
+    print "Five Most Recent SUlog entries:" >> /tmp/sysinfo.$$.sysaccess.info
+    tail -5 $SULOG >> /tmp/sysinfo.$$.sysaccess.info
+  fi
+#
+# Check the validity of the /etc/passwd and /etc/group files by running
+# the pwck and grpck commands. This will help identify illegal password and
+# group entries. Also, check the /etc/passwd file for entries missing
+# passwords.
+#
+  if [[ -x "/etc/pwck" ]]
+  then
+    print " " >> /tmp/sysinfo.$$.sysaccess.info
+    print "Running Passwd Check Script:" >> /tmp/sysinfo.$$.sysaccess.info
+    /etc/pwck >> /tmp/sysinfo.$$.sysaccess.info 2>&1
+  fi
+#
+# Check the password file for entries w/o a password.
+#
+  awk -F: -v sysname=$sysname ' $2 == "" { printf("\nERROR. (%s).  NULL Password found in /etc/passwd\nPassword Record = %s\n\n",sysname,$0)}' /etc/passwd >> \
+             /tmp/sysinfo.$$.errwarn 2>&1
+
+  if [[ -x "/etc/grpck" ]]
+  then
+    print " " >> /tmp/sysinfo.$$.sysaccess.info
+    print "Running Group Check Script:" >> /tmp/sysinfo.$$.sysaccess.info
+    /etc/grpck >> /tmp/sysinfo.$$.sysaccess.info 2>&1
+
+  fi
+#
+# Now check for an .rhost file definition for root.
+# If this file exists, then print a message since this is a potential security
+# issue.
+#
+  if [[ -a "/.rhosts" ]]
+  then
+    print "WARNING ($sysname): Root has a /.rhosts file." >> \
+               /tmp/sysinfo.$$.errwarn
+    print "This file allows users from other systems to logon as root w/o a password." >> /tmp/sysinfo.$$.errwarn
+    print " " >> /tmp/sysinfo.$$.errwarn
+
+    llinfo=$(ll -d /.rhosts)
+
+    echo "$llinfo" | cut -c5-10 | egrep -q "r|w|x"
+    if [ $? -eq 0 ]
+    then
+      print "WARNING ($sysname): The /.rhosts file has Group or World access." \
+             >> /tmp/sysinfo.$$.errwarn
+      print "If this existence if this file is required then ONLY root should have access." >> /tmp/sysinfo.$$.errwarn
+      print " " >> /tmp/sysinfo.$$.errwarn
+    fi
+
+    echo "$llinfo" >> /tmp/sysinfo.$$.sysaccess.warn
+    print "" >> /tmp/sysinfo.$$.sysaccess.warn
+    print "Contents of /.rhosts file:" >> /tmp/sysinfo.$$.sysaccess.warn
+    cat /.rhosts >> /tmp/sysinfo.$$.sysaccess.warn
+  fi
+#
+# Now check the system for modem definitions. This first pass will not include
+# uucp items. I'm checking for ttyd* files in the /dev directory, then I'll
+# campare any matches to the /etc/inittab file. This will allow me to
+# look for getty processes.
+#
+  print " " >> /tmp/sysinfo.$$.sysaccess.info
+  print "Dialin/Modem Definitions:" >> /tmp/sysinfo.$$.sysaccess.info
+  print " " >> /tmp/sysinfo.$$.sysaccess.info
+
+  MLIST=$(ls /dev/ttyd*  2>&1)
+
+  Debug "  chk_SysAccess. MLIST = $MLIST"
+  for modtty in $MLIST
+  do
+    modttyb=$(basename $modtty)
+    Debug "  chk_SysAccess. Checking = $modtty"
+#
+# Check the /etc/inittab file for the terminal entry. Exclude lines which
+# begin with a '#'. Include lines which contain 'getty'
+#
+    gettyinfo=$( grep -v '^#' /etc/inittab | grep 'getty' | grep -i $modttyb )
+    gettystate=$( echo $gettyinfo | awk -F: '{print $3}' )
+
+    Debug "  chk_SysAccess. Getty Info/State = $gettyinfo $gettystate"
+    case $gettystate in
+      respawn )
+        Debug " chkSysAccess. Respawn in getty"
+        ps -ef | grep getty | grep -q $modttyb
+        if [ $? -eq 0 ]
+        then
+          Debug "Found Getty for $modttyb"
+          print "Modem: $modttyb (waiting for a connection)" >> \
+             /tmp/sysinfo.$$.sysaccess.info
+        else
+          Debug "No Getty Found for $modttyb"
+          if ps -t $modttyb | tail +2 | wc -l
+          then
+            Debug "No Processes Found for $modttyb"
+            print "Modem: $modttyb (getty missing?)" >> \
+                    /tmp/sysinfo.$$.sysaccess.info
+            print "WARNING ($sysname): $modttyb does not have a getty or a login process" >> /tmp/sysinfo.$$.errwarn
+          else
+            Debug "Modem in Use"
+            print "Modem: $modttyb (currently in use)" >> \
+                     /tmp/sysinfo.$$.sysaccess.info
+          fi
+        fi
+
+        echo $gettyinfo | awk -F: '{printf("Inittab Info: %s\n",$4)}' >> \
+              /tmp/sysinfo.$$.sysaccess.info
+        print " " >> /tmp/sysinfo.$$.sysaccess.info
+        print "Five most recent Logons for $modttyb" >> \
+                 /tmp/sysinfo.$$.sysaccess.info
+        #last -R > /tmp/sysinfo.$$.last
+        grep -i $modttyb /tmp/sysinfo.$$.last | tail -5 >> /tmp/sysinfo.$$.sysaccess.info
+        print " " >> /tmp/sysinfo.$$.sysaccess.info
+      ;;
+
+      off )
+        print "Modem: $modttyb (disabled in /etc/inittab)" >> \
+                    /tmp/sysinfo.$$.sysaccess.info
+      ;;
+
+      * )
+      ;;
+    esac
+  done
+  print " "
+
+  print " " >> /tmp/sysinfo.$$.sysaccess.info
+
+  f_display_file /tmp/sysinfo.$$.sysaccess.info
+  f_display_file /tmp/sysinfo.$$.sysaccess.warn
+
+  return $return_code
+}
+
+
+###############################################################################
+# Function:    chk_logfiles()
+# Description: Routine used to check the system logfiles. We want to make sure
+#              that the logfiles exist, and are not greater than 2 Mbytes.
+# Arguments:   none
+# Returns:     none
+
+chk_logfiles() {
+  Debug "  Starting Chk_Logfiles. OSMAJOR = $osmajor"
+
+  case $osmajor in
+    8 | 9 )
+      FLIST="$LOGFILELISTV9"
+    ;;
+
+    * )
+      FLIST="$LOGFILELISTV10"
+    ;;
+  esac
+
+  Debug " chk_logfiles. FLIST=$FLIST"
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.logfile.info + print "" >> /tmp/sysinfo.$$.logfile.info + print "

" >> /tmp/sysinfo.$$.logfile.info + print "

" >> /tmp/sysinfo.$$.logfile.info + print "TOP

" >> /tmp/sysinfo.$$.logfile.info + print "" >> /tmp/sysinfo.$$.logfile.info + print "System Logfile Information

" >> /tmp/sysinfo.$$.logfile.info + print "
"  >> /tmp/sysinfo.$$.logfile.info
+  else
+    print "SYSTEM LOGFILE INFORMATION" >> /tmp/sysinfo.$$.logfile.info
+    print "==========================" >> /tmp/sysinfo.$$.logfile.info
+  fi
+  print -n "checking system logfiles"
+  print "" >> /tmp/sysinfo.$$.logfile.info
+  print "Checking System Logfiles. Validating file sizes and Permissions." >> \
+              /tmp/sysinfo.$$.logfile.info
+
+  for lfile in $FLIST
+  do
+    Debug "   chk_logfiles. Checking $lfile."
+    if [[ ! -a "$lfile" ]]
+    then
+      print "ERROR ($sysname): Logfile $lfile does not exist." >> \
+         /tmp/sysinfo.$$.errwarn
+      return_code=$ERROR
+    else
+#
+# Get the logfile's directory information. Then check its size.
+#
+      llinfo=$(ll -d $lfile)
+
+      psize=$( echo $llinfo | awk '{print $5}' )
+      if (( $psize >= 2097152 ))
+      then
+        print "WARNING ($sysname): Logfile $lfile is greater than 2 Mbytes." \
+          >> /tmp/sysinfo.$$.errwarn
+        return_code=$WARN
+      fi
+#
+# Now check the file's permissions
+#
+      echo "$llinfo" | cut -c5-10 | egrep -q "w"
+      if [ $? -eq 0 ]
+      then
+        print "WARNING ($sysname): Logfile $lfile has Group or World WRITE access.  " >> /tmp/sysinfo.$$.errwarn
+        return_code=$WARN
+      fi
+      echo "$llinfo" >> /tmp/sysinfo.$$.logfile.info
+    fi
+  done
+
+  print " " >> /tmp/sysinfo.$$.logfile.info
+#
+# Now check the system's crash directory for crash files. If these files exist
+# there could be space problems later.
+#
+  case $osmajor in
+    10 | 11 )
+      if [[ -a "/etc/rc.config.d/savecrash" ]]
+      then
+        . /etc/rc.config.d/savecrash
+        if [ ! -z "$CRASHDIR" ]
+        then
+          LOGCRASH=$CRASHDIR
+        else
+          LOGCRASH="/var/adm/crash"
+        fi
+      else
+        LOGCRASH="/var/adm/crash"
+      fi
+
+      CRASHFILES=$(ll $LOGCRASH | tail +2)
+      if [ -z "$CRASHFILES" ]
+      then
+        print "There are NO Crash Dumps in $LOGCRASH." >> \
+                   /tmp/sysinfo.$$.logfile.info
+      else
+        print " " >> /tmp/sysinfo.$$.logfile.warn
+        print "WARNING ($sysname): There are files in the Crash Dump directory $LOGCRASH." >> /tmp/sysinfo.$$.errwarn
+        echo "$CRASHFILES" >> /tmp/sysinfo.$$.errwarn
+      fi
+    ;;
+
+  * )
+    ;;
+  esac
+#
+# Now output the contents of the DMESG command. This can provide useful
+# info regarding recent events on the system.
+#
+  print " " >> /tmp/sysinfo.$$.logfile.info
+  print "Ouput of System DMESG Info:" >> /tmp/sysinfo.$$.logfile.info
+  print "___________________________" >> /tmp/sysinfo.$$.logfile.info
+
+  dmesg >> /tmp/sysinfo.$$.logfile.info 2>&1
+
+  print " " >> /tmp/sysinfo.$$.logfile.info
+  print "End of DMESG Output" >> /tmp/sysinfo.$$.logfile.info
+  print "___________________________" >> /tmp/sysinfo.$$.logfile.info
+  print " " >> /tmp/sysinfo.$$.logfile.info
+#
+# Now check the Sendmail Queue for a large number of entries, or entries
+# which are older than two days. Finding entries in the queue could represent
+# a problem.
+#
+  print " " >> /tmp/sysinfo.$$.logfile.info
+  print "Checking Sendmail Queue: \c" >> /tmp/sysinfo.$$.logfile.info
+#
+# Before changing to the Sendmail Queue directory, save our current directory
+# value so we can change back to it when we're finished.
+#
+  OLDPWD=$(pwd)
+  case $osmajor in
+    8 | 9 )
+      mailqdir=/usr/spool/mqueue
+      mailpodir=/usr/mail
+    ;;
+
+    * )
+      mailqdir=/var/spool/mqueue
+      mailpodir=/var/mail
+    ;;
+  esac
+#
+# Go to the Sendmail Queue directory and scan it for entries. Iff some are
+# found then check to see if any are older than 2 days.
+#
+  cd $mailqdir
+  llinfo=$(ll 2>&1 | tail +2)
+
+  if [[ -z "$llinfo" ]]
+  then
+    print "Sendmail Queue is Empty." >> /tmp/sysinfo.$$.logfile.info
+  else
+    print "Sendmail Queue has $(ls | wc -w | awk '{print $1}') entries." >> \
+            /tmp/sysinfo.$$.logfile.info
+    ll 2>&1 | tail +2 >> /tmp/sysinfo.$$.logfile.info
+#
+# Use the find command to list entries older than 2 days
+#
+    findinfo=$(find . -mtime +2 -exec ll -d {} \;)
+    if [[ ! -z "$findinfo" ]]
+    then
+      print " " >> /tmp/sysinfo.$$.logfile.warn
+      print "Sendmail Queue has Entries Older than 2 days." >> \
+                /tmp/sysinfo.$$.logfile.warn
+      find . -mtime +2 -exec ll -d {} \; >> /tmp/sysinfo.$$.logfile.warn
+      print " " >> /tmp/sysinfo.$$.logfile.warn
+    fi
+  fi
+#
+# Now change to the Sendmail Post Office directory. This is the directory
+# where mail is normally stored on the system. Check for entries which are
+# large and very old.
+#
+  cd $mailpodir
+  print " " >> /tmp/sysinfo.$$.logfile.info
+  print "Checking the Mail Post Office Directory: \c" >> \
+              /tmp/sysinfo.$$.logfile.info
+
+  llinfo=$(ls 2>&1)
+  if [[ -z "$llinfo" ]]
+  then
+    print "No Entries Found." >> /tmp/sysinfo.$$.logfile.info
+  else
+    print "Found $(echo $llinfo | wc -w) Entries." >> \
+               /tmp/sysinfo.$$.logfile.info
+    ll 2>&1 >> /tmp/sysinfo.$$.logfile.info
+#
+# Now that we have found entries in the directory, check to see if they are
+# larger than 2 Mbytes.
+#
+    find . -size +4096 -exec ll -d {} \; > /tmp/sysinfo.$$.logfile.tmp 2>&1
+    if [[ -s "/tmp/sysinfo.$$.logfile.tmp" ]]
+    then
+      print " " >> /tmp/sysinfo.$$.logfile.warn
+      print "WARNING ($sysname): Post Office Directory has Files Larger than 2 Mbytes." >> /tmp/sysinfo.$$.errwarn
+      cat /tmp/sysinfo.$$.logfile.tmp >> /tmp/sysinfo.$$.errwarn
+      print " " >> /tmp/sysinfo.$$.errwarn
+    fi
+#
+# Now check for entries which have not been access in 90 days. These files
+# may be considered obsolete.
+#
+    find . -mtime +90 -exec ll -d {} \; > /tmp/sysinfo.$$.logfile.tmp 2>&1
+    if [[ -s "/tmp/sysinfo.$$.logfile.tmp" ]]
+    then
+      print " " >> /tmp/sysinfo.$$.logfile.warn
+      print "WARNING ($sysname): Post Office Directory has Files Older than 90 days." >> /tmp/sysinfo.$$.errwarn
+      cat /tmp/sysinfo.$$.logfile.tmp >> /tmp/sysinfo.$$.errwarn
+      print " " >> /tmp/sysinfo.$$.errwarn
+    fi
+  fi
+#
+# Change back to our original directory
+#
+  cd $OLDPWD
+
+  print " " >> /tmp/sysinfo.$$.logfile.info
+  print " "
+
+  f_display_file /tmp/sysinfo.$$.logfile.info
+  f_display_file /tmp/sysinfo.$$.logfile.warn
+
+  return $return_code
+}
+
+
+
+################################################################################
+# Function:    LookupName()
+# Description: Lookup the full name for a specified hostname.  Uses nslookup.
+# Arguments:   
+# Output:      fully qualified hostname
+# Returns:     0: successfully determined name
+#              1: unable to find name (using /etc/hosts)
+#              2: unable to find name (using name server)
+
+LookupName() {
+
+#   if [ $# -ne 1 ]
+#   then
+#       Panic "${0}: expect  argument"
+#   fi
+
+    #nslookup "$1" > $_TMP 2>&1
+    # Return 0 if name found, 1 if not found and using /etc/hosts,
+    # 2 if not found and using some sort of name server.
+    #
+    nslookup "$1" 2>&1 | 
+    awk '
+         BEGIN              { ret_val=2 }
+         $0 ~ "/etc/hosts"  { ret_val=1 }
+         $1 == "Name:"      { print $2; ret_val=0 }
+         END                { exit (ret_val) }
+        ' $_TMP
+    return_value=$?
+    case $return_value in
+      0)  return_string="found using nslookup";;
+      1)  return_string="found in /etc/hosts/";;
+      2)  return_string="not found";;
+    esac
+    Debug "  return from LookupName = $return_value ($return_string)"
+    return $return_value
+
+}
+
+################################################################################
+# GetCurrentDNS()
+GetCurrentDNS() {
+
+### Changed 6/16/99 J.Semroc - allows for possibility of multiple nameservers,
+###                            domain search directive, and possibility that
+###                            no domain is specified
+###  07/12/99 - added -s option to cut in case nslookup does not return
+###          fully qualified name.  
+###          added ^ to nameserver to ignore commented entries
+
+    if [ -f $RESOLV_CONF ]
+    then
+      CURRENT_DOMAIN=$(nslookup ${sysname} | grep "^Name: " | \
+            awk -F: '{print $2}'| cut -s -d. -f2- )
+      if [[ -z ${CURRENT_DOMAIN} ]]
+      then
+        Debug "Could not find domain using nslookup - checking resolv.conf"
+# Extract the domain from resolv.conf
+        set -- $(awk '
+          $1 == "domain"     { DOMAIN=$2 }
+          $1 == "nameserver" { ADDRESS=$2 ; exit }
+          END { printf "%s %s\n", DOMAIN, ADDRESS }' $RESOLV_CONF)
+        CURRENT_DOMAIN="$1"
+      else
+        Debug "Found domain using nslookup"
+      fi
+
+### Extract the  address and name of nameserver from resolv.conf
+###     if [ $# -eq 2 ]
+###     then
+###         # See if we can get a name for the nameserver
+###         CURRENT_DOMAIN="$1"
+###         CURRENT_DNS_SERVER_IP="$2"
+###         CURRENT_DNS_SERVER=$(LookupName $CURRENT_DNS_SERVER_IP)
+###         if [ -z "$CURRENT_DNS_SERVER" ]
+###         then
+###             CURRENT_DNS_SERVER=unknown
+###         fi
+###     else
+###         unset CURRENT_DOMAIN CURRENT_DNS_SERVER_IP CURRENT_DNS_SERVER
+###    fi
+
+      CURRENT_DNS_SERVER_IP=$(for server in `grep ^nameserver \
+              ${RESOLV_CONF} | awk '{print $2}'`
+               do
+                  print -n $server"  "
+               done | awk '{ print $1}')
+      CURRENT_DNS_SERVER=$(LookupName `echo ${CURRENT_DNS_SERVER_IP} \
+              | awk '{ print $1}' `)
+    fi
+
+}
+
+#===================================================================
+# weed_targets
+#
+# Scan the output from ioscan and filter out all SCSI "target"
+# lines.  Also filter out entries with a low_level driver of "root"
+#===================================================================
+weed_targets()
+{
+    awk -F: '
+        {
+            class  = $9;
+            low_level_driver = $10
+            if (class != "target" && low_level_driver != "root")
+                print $0
+        }' -
+}
+
+
+#==================================================================
+# This routine invokes ioscan with any passed in arguments and
+# generates the above mentioned colon separated output. Note that
+# all lines begin and end with colons. This makes for easy parsing
+# of the output to match specific fields via grep.
+#===================================================================
+formatter()
+{
+    awk -F: '
+        {
+#=====================================================================
+# Not all of the fields of ioscan output are used by SAM.
+# They are all listed here for documentation purposes.
+#=====================================================================
+#       bus_type               = $1
+        cdio                   = $2
+#       is_block               = $3
+#       is_char                = $4
+#       is_pseduo              = $5
+#       block_major_number     = $6
+#       character_major_number = $7
+#       minor_number           = $8
+        class                  = $9
+#       low_level_driver       = $10
+        full_hw                = $11
+        identify_bytes         = $12
+#       device instance        = $13
+#       module_path            = $14
+        driver                 = $15
+        sw_status              = $16
+#       hardware_type          = $17
+        ident                  = $18
+        instance               = $19
+        num_hw   = split(full_hw, hw_path, ".");
+        address = "";
+        unit    = "";
+#============================================================
+#
+# Identifying bytes for PA Modules contain this information:
+#
+#  Byte
+#  Address   Name            Description
+#  --------- --------------- --------------------------------------
+#  0-1       IODC_HVERSION   Hardware version number
+#  2         IODC_SPA        Soft physical address capability
+#  3         IODC_TYPE       Type of module
+#  4-7       IODC_SVERSION   Software version number
+#  8         IODC_REV        IODC revision
+#  9         IODV_DEP        HVERSION dependent
+#  10-11     RESERVED
+#  12-13     IODC_CHECK      Checksum
+#  14-15     IODC_LENGTH     Length of entry point table
+#
+#============================================================
+
+        split(identify_bytes, id_flds, " ");
+        hversion= (((((id_flds[1]*256)+id_flds[2])*256)+id_flds[3])*256)+id_flds[4];
+        sversion= (((((id_flds[5]*256)+id_flds[6])*256)+id_flds[7])*256)+id_flds[8];
+        if ( id_flds[9] != "" ) {
+                device_id = id_flds[9] " " id_flds[10] " " id_flds[11] " " id_flds[12] " " id_flds[13] " " id_flds[14] " " id_flds[15] " " id_flds[16];
+        }
+        else {
+                device_id = "";
+        }
+        #
+        # Specifically for multi path environments (FiberChannel),
+        # save the driver and last 8 bytes of the identify_bytes
+        # of this device ("ext_bus" class; parent of actual devices)
+        # tacking on to actual devices later.
+        #
+        if ( class == "ext_bus") {
+           if ( ( identify_bytes != "") && (( driver == "fcpmux") || ( driver == "fcpdev"))) {
+                parent_driver = driver;
+                parent_id = device_id;
+           }
+           else {
+                parent_driver=""
+                parent_id=""
+           }
+        }
+
+        #
+        # Set driver to "?" if not known
+        #
+        if ((substr(driver, 1, 1) == "?") || (driver == "pdn0") ||
+            (driver == ""))
+        {
+            #
+            # SPECIAL CASES FOR NON-AUTOCONFIGURABLE DEVICES
+            # Check the hardware identifier field, if it matches
+            # a non-autoconfigurable device and there is no driver
+            # bound to the device, fill in the driver field with the
+            # appropriate driver name flag to true
+            #
+#
+# Change this to use the device description.
+#
+            if (ident == "0x2080") {
+                driver = "pdn0";
+            }
+#
+# Change this to use the device description.
+#
+            else if (ident == "0x2f80") {
+                driver = "pdn0";
+            }
+
+            else if ((substr(driver, 1, 1) == "?") || (driver == "")) {
+                driver = "?";
+            }
+
+            not_configured = 1;
+        } else
+            not_configured = 0;
+
+        if (sw_status != "CLAIMED")
+                not_configured = 1;
+
+        if ((driver == "tape1") || (driver == "tape2")      ||
+            (driver == "lpr0")  || (driver == "lpr1")       ||
+            (driver == "disc3") || (driver == "sflop")      ||
+            (driver == "schgr") || (driver == "autox0")     ||
+            (driver == "cs80")  || (driver == "sdisk")      ||
+            (driver == "stape") || (driver == "disc4")) {
+          address = hw_path[num_hw-1];
+          unit    = hw_path[num_hw];
+        }
+        else if ((driver == "disc1") || (driver == "disc2") ||
+                 (driver == "instr0")|| (driver == "pflop")) {
+          address = hw_path[num_hw];
+        }
+
+
+#       printf(":%s:%s:%s:%s:%s:%s:%d:%s:0x%x;0x%x:%s:%s:%s:%s:\n",
+#           cdio, driver, instance, full_hw, address, unit,
+#           not_configured, sw_status, sversion, hversion, ident,
+#           device_id, parent_driver, parent_id );
+        printf("%22s %12s  %s\n", full_hw, driver, ident );
+    }' -
+} # end of formatter
+
+#===========================================================
+# lvm_scan
+#===========================================================
+function lvm_scan
+{
+  # first get all volume groups, logical volumes & physical volumes
+  vgdisplay -v 2>&1 | \
+  awk '
+    BEGIN             { vgprinted = ""; onpvg = ""; numpvgs = 0
+                      }
+    /^VG Name/        {
+                          vg = substr($3, 6, length($3) - 5);
+                          vgprinted = ""; onpvg = ""; numpvgs = 0;
+                          freepe_count = 0; next;
+                      }
+    /VG Write Access/ {
+                           vgwrite = $4;
+                           next;
+                      }
+    /VG Status/       {
+                         vgstatus = "";
+                         for(i=3;i<=NF;i++)
+                            vgstatus = vgstatus $i;
+                         vgstatus = vgstatus "," vgwrite "@";
+                           next;
+                     }
+    $2 == "Server"   {
+                         vgstatus = vgstatus $1;
+                           next;
+                     }
+    $2 == "Client"   {
+                         vgstatus = vgstatus ",";
+                         vgstatus = vgstatus $1;
+                           next;
+                     }
+    /Max LV/         { maxlv = $3; next;  }
+    /Max PV/         { maxpv = $3; next;  }
+    /Cur LV/         { numlvs = $3; next; }
+    /Cur PV/         { numpvs = $3; next; }
+    /PE Size/        { pesize = $4; next; }
+    /Max PE per PV/  { maxpe = $5; next;  }
+    /Total PVG/      { numpvgs = $3; next; }
+    /LV Name/        {
+                       if (vgprinted == "")
+                       {
+                         printf("VG:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s::::::\n",
+                                 vg, vgstatus, maxlv, maxpv, numlvs,
+                                 numpvs, numpvgs, pesize, maxpe,
+                                 totalpe * pesize, freepe * pesize);
+                         vgprinted = "y";
+                       }
+                       printf("LV:%s:::::::%s::::%s:::::\n",
+                               vg, pesize, $3);
+                       next;
+                     }
+    /Alternate Link$/ {
+                       if (onpvg == "")
+                       {
+                         if (vgprinted == "")
+                         {
+                           printf("VG:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s::::::\n",
+                                   vg, vgstatus, maxlv, maxpv, numlvs,
+                                   numpvs, numpvgs, pesize, maxpe,
+                                   totalpe * pesize, freepe * pesize);
+                           vgprinted = "y";
+                          }
+                          printf("ALT:%s::::::::::::%s:%s:::\n", vg, pv, $3);
+                        }
+                        next;
+                      }
+    /PV Name/         {
+                        pv = $3;
+                        if (onpvg == "")
+                        {
+                          if (vgprinted == "")
+                          {
+                           printf("VG:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s::::::\n",
+                                   vg, vgstatus, maxlv, maxpv, numlvs,
+                                   numpvs, numpvgs, pesize, maxpe,
+                                   totalpe * pesize, freepe * pesize);
+                           vgprinted = "y";
+                          }
+                        }
+                        else
+                        {
+                          printf("PV:%s::::::::::::%s::::%s\n",vg, pv, pvg);
+                          pvg = "";
+                        }
+                        next;
+                      }
+    /Free PE/         {
+                        freepe = $3;
+                        if (freepe_count > 0)
+                        {
+                          printf("PV:%s::::::::::::%s::%s:%s:\n", 
+                                  vg, pv, totalpe, freepe);
+                        }
+                        freepe_count ++;
+                        next;
+                      }
+
+  ' >>   /tmp/sysinfo.vg.tmp
+  mv  /tmp/sysinfo.vg.tmp  $vg_list_file
+#
+# now get list of all logical volumes
+#
+  awk ' BEGIN           { FS = ":" }
+      { type = $1; vgstatus = $2;  pesize = $8;
+        if (type == "LV") 
+        {
+          printf ("%s\n",$13)
+        }
+      }
+  ' $vg_list_file  >> /tmp/sysinfo.lvol.list.tmp
+  sort  /tmp/sysinfo.lvol.list.tmp > $lvol_list_file
+  rm -f /tmp/sysinfo.lvol.list.tmp
+#
+# now get details on each logical volume
+#
+  lvol_list=$(cat $lvol_list_file)
+  for lvol in $lvol_list
+  do
+  
+    lvdisplay $lvol 2>&1 | \
+    awk '
+        BEGIN                  { mwc = 0;
+                                 nummir = 0;
+                                 mircon = 0;
+                                 bbr = 0;
+                                 conalloc = 0 ;
+                                 numstripes = 0;
+                                 stripesize = 0 }
+        /LV Name/              { lvname= $3; next }
+        /LV Permission/        { perm = $3; next }
+        /Mirror copies/        { nummir = $3; next }
+        /Consistency Recovery/ { mwc = $3; next }
+        /Schedule/             { sched = $2; next }
+        /LV Size/              { size = $4; next }
+        /Current LE/           { les = $3; next }
+        /Bad block/            { if ($3 == "on") bbr = 1; badblock = $3;
+                                 if (badblock == "NONE")
+                                   badblock = "NO";
+                                 next }
+        /Allocation/           { alloc=$2;
+                                if (alloc == "non-strict")
+                                   alloc = "ns";
+                                if (alloc == "non-strict/contiguous")
+                                   alloc = "ns-c";
+                                if (alloc == "strict")
+                                   alloc = "s";
+                                if (alloc == "strict/contiguous")
+                                   alloc = "s-c";
+                                if (alloc == "PVG-strict")
+                                   alloc = "PVG";
+                                if (alloc == "PVG-strict/contiguous")
+                                   alloc = "PVG-c";
+                                if (alloc == "PVG-strict/distributed")
+                                   alloc = "PVG-d";
+                                if (alloc == "PVG-strict/partially-distributed")
+                                    alloc = "PVG-p";
+                                  next;
+                               }
+        /LV Status/            { state = $3; 
+                                 if (state == "available/stale")
+                                     state = "stale";
+                                 if (state == "available/syncd")
+                                     state = "syncd";
+                                 if (state == "available")
+                                     state = "avail";
+                                 if (state == "unavailable")
+                                     state = "unavl";
+                                next }
+        /Stripes/              { numstripes = $2; next }
+        /Stripe Size/          { stripesize = $4; next }
+
+                               {next}
+        END                    {
+                                   if ( size == 0 )
+                                   {
+                                       pesize = size;
+                                   }
+                                   else
+                                   {
+                                       pesize = size / les;
+                                   }
+
+                            printf("%-32s %5s %3s %4s %4s %6s %6s  %-5s %-5s\n", 
+                                lvname, size, numstripes,
+                                stripesize, nummir, mwc, state, badblock,alloc)
+                               }
+    ' >> /tmp/sysinfo.lvol.data.tmp
+  done
+  mv /tmp/sysinfo.lvol.data.tmp  $lvol_out_file
+  rm -f /tmp/sysinfo.lvol.data.tmp
+#
+# now get list of all physical volumes
+#
+  awk ' BEGIN           { FS = ":" }
+      { type = $1; vgstatus = $2;  pesize = $8;
+        if (type == "PV") 
+        {
+          printf ("%s\n",$14)
+        }
+      }
+  ' $vg_list_file >> /tmp/sysinfo.pvol.list.tmp
+  sort  /tmp/sysinfo.pvol.list.tmp > $pvol_list_file
+  rm -f /tmp/sysinfo.pvol.list.tmp
+#
+# now get details on each physical volume
+#
+  pvol_list=$(cat $pvol_list_file)
+  for pvol in $pvol_list
+  do
+    pvdisplay -v $pvol 2>&1 | \
+    awk '
+        BEGIN               {found=0}
+
+        /PE Size/           {pesize = $4; next}
+        /LV Name/           {found=1; next}
+        /Physical extents/  {exit 0}
+
+        #
+        # Print "LV_Name Logical_MB_of_LV Physical_MB_of_LV"
+        #
+        {
+            if (found && NF == 3)
+                printf("%s:%d:%d\n", $1, $2 * pesize, $3 * pesize)
+        }
+    ' -  >> $pvol_out_file
+     
+  done
+}  # end of lvm_scan
+
+#===========================================================
+function launch_lvm_scan
+#===========================================================
+{
+  Debug "Building $lvm_scan_command_file"
+
+  rm -f $lvm_scan_done 
+
+  Debug "$vg_out_file, $vg_list_file, $lvol_out_file"
+  Debug "$lvol_list_file, $pvol_list_file $pvol_out_file"
+  Debug "$lvm_scan_done"
+
+  cat <<==end_of_command==   > $lvm_scan_command_file
+
+    # now call the lvm_scan function (exported from parent)
+    lvm_scan
+    date > \$lvm_scan_done
+
+==end_of_command==
+
+  chmod +x $lvm_scan_command_file
+  Debug "  launching $lvm_scan_command_file"
+  $lvm_scan_command_file &
+  Debug "  parent PID = $$, child PID = $!"
+
+}  # end of launch_lvm_scan
+
+#===========================================================
+# launch_kernel_scan
+#===========================================================
+function launch_kernel_scan
+{
+  Debug " Starting launch_kernel_scan.....building $kernel_scan_command_file"
+
+  # change filenames to send output to parent's PID
+  rm -f $kernel_scan_done 
+
+  Debug "$kernel_kinfo $kernel_out_file"
+  Debug "$kernel_scan_done"
+
+  cat <<==end_of_command==   > $kernel_scan_command_file
+
+    # now call the sam_scan function (exported from parent)
+    kernel_scan
+    date > \$kernel_scan_done
+
+==end_of_command==
+
+  chmod +x $kernel_scan_command_file
+  Debug "  launching $kernel_scan_command_file"
+  $kernel_scan_command_file &
+  Debug "  parent PID = $$, child PID = $!"
+
+
+}  # end of launch_kernel_scan
+
+#===========================================================
+# launch_io_scan
+#===========================================================
+function launch_io_scan
+{
+  Debug " Starting launch_io_scan.....building $io_scan_command_file"
+
+  # change filenames to send output to parent's PID
+  rm -f $io_scan_done
+
+  Debug "$io_scan_done"
+
+  if (( ${osmajor} >= 10 ))
+  then
+    cat <<==end_of_command==   > $io_scan_command_file
+
+    # now call the io_scan function (exported from parent)
+      io_scan
+      date > \$io_scan_done
+==end_of_command==
+
+    chmod +x $io_scan_command_file
+    Debug "  launching $io_scan_command_file"
+    $io_scan_command_file &
+    Debug "  parent PID = $$, child PID = $!"
+  else
+    Debug "  on 9.x - executing ioscan"
+    print    "H/W Path      LU       Driver" >> ${io_scan_out}
+    print -- "-----------------------------" >> ${io_scan_out}
+    ioscan -f | tail +3 | \
+      awk '{printf ("%-14s %-6s %-20s\n", $3, $2, $4)}' \
+      >> ${io_scan_out}
+    date > $io_scan_done
+  fi
+
+}  # end of launch_io_scan
+
+
+
+#===========================================================
+# check_if_scan_done
+#===========================================================
+function check_if_scan_done
+{
+  scan_type=$1
+  done_file=/tmp/sysinfo.$$.${scan_type}_done
+  Debug "  starting check_if_scan_done for ${scan_type}."
+  Debug "  looking for /tmp/sysinfo.$$.${scan_type}_done"
+  if (($BATCH))
+  then
+    print -n "retrieving ${scan_type} data "
+  fi
+  if [ ! -f ${done_file} ]     # enter time out loop
+  then
+    Debug "  ${scan_type}_done file not ready, entering loop."
+    FORCE="TRUE"
+    for fil in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+    do
+### Changed 6/15/99 J.Semroc - allow more time for large systems
+###   sleep 5
+      sleep 60
+### end of Change
+      Debug "    in loop $fil"
+      if (($BATCH))
+      then
+        print -n "."
+      fi
+      if [ -f ${done_file} ]
+      then
+        Debug "  ${scan_type} done."
+        FORCE="FALSE"
+        break
+      fi
+    done
+    if [ "$FORCE" = "TRUE" ]
+    then
+      Debug "  still no file, forcing an interactive ${scan_type}."
+      ${scan_type}
+    fi
+  else
+    Debug "  found ${scan_type}_done file"
+    if (($BATCH))
+    then
+      print ""
+    fi
+  fi
+}
+
+#===========================================================
+# io_scan
+#
+# this routine runs ioscan with the appropriate parameters and
+# places the output in /var/sam/.iout   It also
+# provides a semaphore for other asyncronous processes, by removing
+# and then creating /var/sam/.dion
+#
+#===========================================================
+function io_scan
+{
+
+#       bus_type               = $1
+#       cdio                   = $2
+#       is_block               = $3
+#       is_char                = $4
+#       is_pseduo              = $5
+#       block_major_number     = $6
+#       character_major_number = $7
+#       minor_number           = $8
+#       class                  = $9
+#       low_level_driver       = $10
+#       full_hw                = $11
+#       identify_bytes         = $12
+#       device instance        = $13
+#       module_path            = $14
+#       driver                 = $15
+#       sw_status              = $16
+#       hardware_type          = $17
+#       ident                  = $18
+#       instance               = $19
+
+#
+#  If an inadaquate description is given from ioscan.  Initiate a diskinfo
+#  request to force an open operation and then perform another ioscan for
+#  that device.  If the diskinfo operation results in an error containing
+#  "Permission Denied" the device may be a tape drive needing a slightly
+#  different device file.  At the time of this modification to this script
+#  (7/5/94) an HPFL Disc will only give a useful description when there is
+#  a mounted file system on the disk.
+#
+#  Change the Internal Field Separator to ":".  All output fields of
+#  ioscan -F are separated by a ":".
+#
+  LANG=$save_lang
+  LANG=C
+  rm -f $io_scan_done
+  ioscan $ioscan_args > $io_scan_tmp
+  mv $io_scan_out $io_scan_out.old > /dev/null 2>&1
+  ifs_save=$IFS
+  IFS=:
+  cat $io_scan_tmp | \
+  while read p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19
+  do
+      if [ "$p18" = "HP-IB Device" -o "$p18" = "HP-IB Tape" -o \
+           "$p18" = "SCSI Tape"    -o "$p18" = "HPFL Disc" ]
+      then
+          mksf -r -H $p11 /var/sam/sam_tmp >/dev/null 2>&1
+          diskinfo /var/sam/sam_tmp >/dev/null 2>/var/sam/sam_err
+          if ( grep Permission /var/sam/sam_err >/dev/null 2>&1 )
+          then
+              mksf -r -c -u 0 -H $p11 /var/sam/sam_tmp >/dev/null 2>&1
+              diskinfo /var/sam/sam_tmp >/dev/null 2>&1
+          fi
+          ioscan -H $p11 -F >>$io_scan_out 2>/dev/null
+          rm -f /var/sam/sam_tmp /var/sam/sam_err
+      else
+          echo "$p1:$p2:$p3:$p4:$p5:$p6:$p7:$p8:$p9:$p10:$p11:$p12:$p13:$p14:$p15:$p16:$p17:$p18:$p19" >>$io_scan_out
+      fi
+  done
+  IFS=$ifs_save
+  date > $io_scan_done
+  rm $io_scan_tmp
+
+} #end of io_scan
+
+#==================================================================
+# sw_scan
+#==================================================================
+function sw_scan
+{
+  Debug "Beginning SW_SCAN"
+  if [[ -f /usr/sbin/swlist ]]
+  then
+    Debug "  found swlist"
+    if (($HTML))
+    then
+      print "
" >> /tmp/sysinfo.$$.swout + print "" >> /tmp/sysinfo.$$.swout + print "

" >> /tmp/sysinfo.$$.swout + print "

TOP

" >> /tmp/sysinfo.$$.swout + print "" >> /tmp/sysinfo.$$.swout + print "Software Data

" >> /tmp/sysinfo.$$.swout + print "
"  >> /tmp/sysinfo.$$.swout
+    else
+      print "" >> /tmp/sysinfo.$$.swout
+      print "SOFTWARE DATA" >> /tmp/sysinfo.$$.swout
+      print "=============" >> /tmp/sysinfo.$$.swout
+    fi
+  if (($BATCH))
+  then
+    print  "collecting software data "
+  fi
+    print    "Product                Version         Description" >> /tmp/sysinfo.$$.swout
+    print -- "--------------------------------------------------" >> /tmp/sysinfo.$$.swout
+    swlist -l product | grep -v "^#" | expand >> /tmp/sysinfo.$$.swout
+    f_display_file /tmp/sysinfo.$$.swout
+    #check for non-configured software
+    print  "checking for incompletely installed software "
+    swlist -l fileset -a state | grep -e transient -e corrupt \
+            -e available -e installed | expand >> /tmp/sysinfo.$$.sw_not_conf
+    if [[ -s /tmp/sysinfo.$$.sw_not_conf ]]
+    then
+      print "" >> /tmp/sysinfo.$$.sw_not_header
+      print "Found incompletely installed filesets" >> \
+                /tmp/sysinfo.$$.sw_not_header
+      print "=====================================" >> \
+                /tmp/sysinfo.$$.sw_not_header
+      print "WARNING (${sysname}): Found incompletely installed software." >> \
+             /tmp/sysinfo.$$.errwarn
+      f_display_file /tmp/sysinfo.$$.sw_not_header
+      f_display_file /tmp/sysinfo.$$.sw_not_conf
+    fi
+  else
+  Debug " could not find swlist."
+  fi
+}
+
+#==================================================================
+#f_build_sched_file
+#        This function retrieves the os version information and
+#        series type. It then sets the kernel pointers.
+#===================================================================
+function f_build_sched_file
+{
+  Debug "Beginning build_sched_file"
+cat <<==end_of_file==   >  ${where}/sched.models
+600     1.0     PA7000
+635     1.0     PA7000
+645     1.0     PA7000
+700     1.1     PA7000
+705     1.1a    PA7000
+715     1.1c    PA7100LC
+710     1.1a    PA7000
+712     1.1c    PA7100LC
+720     1.1a    PA7000
+722     1.1c    PA7100LC
+725     1.1c    PA7100LC
+728     1.1d    PA7200
+730     1.1a    PA7000
+735     1.1b    PA7100
+742     1.1b    PA7100
+743     1.1c    PA7100LC
+744     1.1e    PA7300
+745     1.1b    PA7100
+747     1.1b    PA7100
+750     1.1a    PA7000
+755     1.1b    PA7100
+770     1.1d    PA7200
+777     1.1d    PA7200
+778     1.1e    PA7300
+779     1.1e    PA7300
+780     2.0     PA8000
+781     2.0     PA8000
+782     2.0     PA8200
+785     2.0     PA8500
+800     1.0     PA7000
+801     1.1c    PA7100LC
+802     2.0     PA8000
+803     1.1e    PA7300
+804     2.0     PA8000
+806     1.1c    PA7100LC
+807     1.1a    PA7000
+808     1.0     PA7000
+809     1.1d    PA7200
+810     2.0     PA8000
+811     1.1c    PA7100LC
+813     1.1e    PA7300
+815     1.0     PA7000
+816     1.1c    PA7100LC
+817     1.1a    PA7000
+819     1.1d    PA7200
+820     2.0     PA8000
+821     1.1d    PA7200
+822     1.0     PA7000
+825     1.0     PA7000
+826     1.1c    PA7100LC
+827     1.1a    PA7000
+829     1.1d    PA7200
+831     1.1d    PA7200
+832     1.0     PA7000
+834     1.0     PA7000
+835     1.0     PA7000
+837     1.1a    PA7000
+839     1.1d    PA7200
+840     1.0     PA7000
+841     1.1d    PA7200
+842     1.0     PA7000
+845     1.0     PA7000
+847     1.1a    PA7000
+849     1.1d    PA7200
+850     1.0     PA7000
+851     1.1d    PA7200
+852     1.0     PA7000
+855     1.0     PA7000
+856     1.1c    PA7100LC
+857     1.1a    PA7000
+859     1.1d    PA7200
+860     1.0     PA7000
+861     2.0     PA8000
+865     1.0     PA7000
+867     1.1a    PA7000
+869     1.1d    PA7200
+870     1.0     PA7000
+871     2.0     PA8000
+877     1.1a    PA7000
+879     2.0     PA8000
+887     1.1b    PA7100
+889     2.0     PA8000
+890     1.0     PA7000
+891     1.1b    PA7100
+892     1.1b    PA7100
+893     2.0     PA8000
+897     1.1b    PA7100
+898     2.0     PA8200
+899     2.0     PA8200
+F10     1.1a    PA7000
+F20     1.1a    PA7000
+H20     1.1a    PA7000
+F30     1.1a    PA7000
+G30     1.1a    PA7000
+H30     1.1a    PA7000
+I30     1.1a    PA7000
+G40     1.1a    PA7000
+H40     1.1a    PA7000
+I40     1.1a    PA7000
+G50     1.1b    PA7100
+H50     1.1b    PA7100
+I50     1.1b    PA7100
+G60     1.1b    PA7100
+H60     1.1b    PA7100
+I60     1.1b    PA7100
+G70     1.1b    PA7100
+H70     1.1b    PA7100
+I70     1.1b    PA7100
+E25     1.1c    PA7100LC
+E35     1.1c    PA7100LC
+E45     1.1c    PA7100LC
+E55     1.1c    PA7100LC
+T500    1.1b    PA7100
+T520    1.1b    PA7100
+T540    2.0     PA8000
+T600    2.0     PA8000
+K100    1.1d    PA7200
+K200    1.1d    PA7200
+K210    1.1d    PA7200
+K220    1.1d    PA7200
+K230    1.1d    PA7200
+K400    1.1d    PA7200
+K410    1.1d    PA7200
+K420    1.1d    PA7200
+DXO     1.1c    PA7100LC
+DX0     1.1c    PA7100LC
+DX5     1.1c    PA7100LC
+D200    1.1c    PA7100LC
+D210    1.1c    PA7100LC
+D310    1.1c    PA7100LC
+D410    1.1d    PA7200
+D250    1.1d    PA7200
+D350    1.1d    PA7200
+J200    1.1d    PA7200
+J210    1.1d    PA7200
+C100    1.1d    PA7200
+J220    2.0     PA8000
+J280    2.0     PA8000
+J282    2.0     PA8000
+S715    1.1e    PA7300
+S760    1.1e    PA7300
+D650    2.0     PA8000
+J410    2.0     PA8000
+J400    2.0     PA8000
+J210XC  1.1d    PA7200
+J2240   2.0     PA8200
+J5000   2.0     PA8500
+J5600   2.0     PA8600
+J6000   2.0     PA8600
+J7000   2.0     PA8500
+C200+   2.0     PA8200
+C240+   2.0     PA8200
+C360    2.0     PA8500
+C180    2.0     PA8000
+C180-XP 2.0     PA8000
+C160    2.0     PA8000
+C160L   1.1e    PA7300
+C140    2.0     PA8000
+C130    2.0     PA8000
+C120    1.1e    PA7300
+C115    1.1e    PA7300
+C110    1.1d    PA7200
+B160L   1.1e    PA7300
+B132L   1.1e    PA7300
+B120    1.1e    PA7300
+B115    1.1e    PA7300
+B1000   2.0     PA8500
+B2000   2.0     PA8500
+C3000   2.0     PA8500
+C3600   2.0     PA8600
+S700i   1.1e    PA7300
+S744    1.1e    PA7300
+D330    1.1e    PA7300
+D230    1.1e    PA7300
+D320    1.1e    PA7300
+D220    1.1e    PA7300
+D360    1.1d    PA7200
+K360    2.0     PA8000
+K370    2.0     PA8200
+K460    2.0     PA8000
+K460-EG 2.0     PA8000
+K460-XP 2.0     PA8000
+K260    2.0     PA8000
+K260-EG 2.0     PA8000
+D260    1.1d    PA7200
+D270    2.0     PA8000
+D280    2.0     PA8000
+D370    2.0     PA8000
+D380    2.0     PA8000
+D390    2.0     PA8000
+R380    2.0     PA8000
+R390    2.0     PA8000
+K250    2.0     PA8000
+K450    2.0     PA8000
+K270    2.0     PA8200
+K470    2.0     PA8200
+K380    2.0     PA8200
+K580    2.0     PA8200
+V2200   2.0     PA8200
+V2250   2.0     PA8200
+V2500   2.0     PA8500
+V2600   2.0     PA8600
+L1000-36  2.0   PA8500
+L1000-44  2.0   PA8500
+L2000-36  2.0   PA8500
+L2000-44  2.0   PA8500
+N4000-36  2.0   PA8500
+N4000-44  2.0   PA8500
+A180    1.1     PA7300LC
+A180C   1.1     PA7300LC
+
+==end_of_file==
+
+chmod 444 ${where}/sched.models
+}
+
+#==================================================================
+#f_get_sys_type
+#        This function retrieves the os version information and
+#        series type. It then sets the kernel pointers.
+#===================================================================
+function f_get_sys_type
+{
+  Debug "Beginning GET SYSTEM TYPE"
+  osletter=$(uname -r | awk -F. '{print $1}')
+  osmajor=$(uname -r | awk -F. '{print $2}')
+  osminor=$(uname -r | awk -F. '{print $3}')
+  system=$(uname -m | awk -F/ '{print $1}')
+  series=$(uname -m | awk -F/ '{print $2}')
+  machine_id=$(uname -i)
+  license=$(uname -l)
+  Debug "  `uname -a`"
+  Debug "  system = $system"
+  Debug "  series = $series"
+  Debug "  OS = $osletter.$osmajor.$osminor"
+  Debug "  machine = $machine_id"
+  Debug "  license = $license"
+  if (( `echo $series | cut -b1` == 7 )) && (( $osmajor <= 9 ))
+  then
+    print "\nSorry. Not supported on Series 700 running HP-UX 9.x\n"
+    exit ${ERROR}
+  fi
+  if [[ ! -z $(whence model) ]]
+  then
+    series=`model`
+    Debug "  model returned $series"
+    sched_file=${where}/sched.models
+    f_build_sched_file
+    pa_ver="N/A"
+    pa_chip="N/A"
+    if [[ -f ${sched_file} ]]
+    then
+      check_pa=$(model | awk -F/ '{print $NF}')
+      pa_ver=$(grep "${check_pa} " $sched_file | awk '{print $2}')
+      pa_chip=$(grep "${check_pa} " $sched_file | awk '{print $3}')
+    else
+      pa_ver=""
+      pa_chip=""
+    fi
+  else
+    Debug "  model not found, using inline series check"
+    case $series in
+      780) series="780/C160";;
+      801) series="801/DX0";;
+      811) series="811/DX5";;
+      806) series="806/E25";;
+      807) series="807/F10";;
+      809) series="809/K100";;
+      816) series="816/E35";;
+      817) series="817/F20";;
+      819) series="819/K200";;
+      821) series="821/D200/D400";;
+      826) series="826/E45";;
+      827) series="827/H20";;
+      829) series="829/K400";;
+      831) series="831/D200/D400";;
+      837) series="837/F30";;
+      839) series="839/K210";;
+      841) series="841/D210/D410";;
+      847) series="847/G30/H30";;
+      851) series="851/D210/D410";;
+      849) series="849/K410";;
+      856) series="856/E55";;
+      857) series="857/I30";;
+      859) series="859/K220";;
+      867) series="867/G40/H40";;
+      869) series="869/K420";;
+      877) series="877/I40";;
+      887) series="887/G50/H50/G60/H60/G70/H70";;
+      890) series="890";;
+      891) series="891/T500";;
+      892) series="892/T520";;
+      897) series="897/I50/I60/I70";;
+        *) series=$series
+             Debug "Series type not found for $series" ;;
+    esac
+  fi
+  if [ $osmajor -lt 10 ]
+  then
+    kernel=/hp-ux
+  else
+    kernel=/stand/vmunix
+  fi
+  Debug "  kernel=${kernel}"
+  if [[ -f /etc/lvmtab ]]
+  then
+    lvm_installed=1
+    Debug "  LVM Detected."
+  else
+    lvm_installed=0
+    Debug "  LVM NOT Detected."
+  fi
+# set PATH variable to ensure access to required commands
+  for i in \
+    /etc \
+    /usr/sbin \
+    /bin \
+  ; 
+  do
+    if [ -d $i ]
+    then
+      PATH=$PATH:$i
+    fi
+  done
+  export PATH
+  Debug "  PATH = $PATH"
+  if [ -f ${where}/system_db ]
+  then
+    conf_file=${where}/system_db
+  elif [ -f /usr/local/bin/system_db ]
+  then
+    conf_file=/usr/local/bin/system_db
+  fi
+  if [[ -n ${conf_file} ]]
+  then
+    Debug "  Found config file = $conf_file"
+    serial_number=$(grep $sysname $conf_file | awk -F: '{print $4}')
+    Debug "    serial number = ${serial_number}"
+  fi
+  swap_devs=$(swapinfo -d | grep -v "Kb" |grep -v "TYPE" \
+         | awk '{printf "%s ", $NF}')
+# if (($FULL_KERNEL)) || (( ${LITE_KERNEL} ))
+# then
+#   if (( ${osmajor} >= 10 ))
+#     rm -f $kernel_scan_done
+#     launch_kernel_scan
+#     Debug "Calling kernel_scan"
+#     if (($BATCH))
+#     then
+#       print "launching background kernel scan"
+#     fi
+#   fi
+# fi
+  if (($IOSCAN)) || (($PHYSICAL))
+  then
+    rm -f $io_scan_done
+    launch_io_scan $ioscan_args
+    Debug "Calling io_scan"
+    if (($BATCH))
+    then
+      print "launching background ioscan"
+    fi
+  fi
+  if (($LVMSCAN))
+  then
+    rm -f $lvm_scan_done
+    launch_lvm_scan
+    Debug "Calling launch_lvm_scan"
+    if (($BATCH))
+    then
+      print "launching background lvm scan"
+    fi
+  fi
+}                # end of f_get_sys_type
+
+#===================================================================
+#
+#===================================================================
+function f_run_cstm
+{
+cstm_ok=0
+print -n "Checking digmond...."
+
+diagmond_result=$(ps -ef | grep -v grep | grep  diagmond > /dev/null 2>&1)
+diagmond_result=$?
+if (($diagmond_result != 0))
+then
+  cstm_ok=1
+  Debug "Error: diagmond is not running."
+  Debug "diagmond_result = $diagmond_result"
+  print "diagmond is NOT running!"
+  print "No cstm info is available."
+  return
+else
+  print "diagmond is running."
+fi
+
+print -n "Checking cstm......."
+cstm_version=$(echo "Version" | /usr/sbin/cstm | grep Version \
+          | tail -1 |  awk '{print $2}' )
+cstm_major=$(echo ${cstm_version} | awk -F. '{print $2}')
+
+echo "Version" | /usr/sbin/cstm >/dev/null 2>&1
+cstm_result=$?
+if (($cstm_result != 0)) 
+then
+  cstm_ok=1
+  Debug "Error returned from cstm"
+  print "Error returned from cstm"
+  print "cstm_result = $cstm_result"
+fi
+
+if (($cstm_ok == 0))
+then
+  cstm_version=$(echo "Version" | /usr/sbin/cstm | grep Version \
+            | tail -1 |  awk '{print $2}' )
+  cstm_major=$(echo ${cstm_version} | awk -F. '{print $2}')
+  print "found version ${cstm_version}"
+  ### Changed 6/30/99 J.Semroc also works with V14 
+  ### if (($cstm_major >= 08))  && (($cstm_major <= 13))
+  ###  and V16 
+  ### if (($cstm_major >= 08))  && (($cstm_major <= 16))
+  ### Removed upper end version check on cstm 
+  if (($cstm_major >= 08))
+  ### end Change
+  then
+    print "Running cstm....please wait."
+  
+    if (($cstm_major == 12))
+    then
+      cat <<==end_of_command==   > ${cstm_command_file}
+      # testtt
+      #
+      # The following connects the UI to the system the UI is being run on,
+      #  and selects this system.
+      # SelCurrentSys system add localhost  system 1
+      # Use current user name
+      # No password required on local system.
+      # don't prompt for overwrite
+      gop confirmation no
+      #Select all
+      #Select class cpu
+      SelClass type processor qualifier cpu
+      #collect the information and wait for it to finish
+      Information ; wait
+      #now display the info log
+      #version 12 has SaveAs & Print Commands reversed.
+      InfoLog
+        Print
+        $cstm_cpu_out
+        Done
+      #map
+      unselall
+      SelClass type memory
+      Information ; wait
+      InfoLog
+        Print
+        $cstm_mem_out
+        Done
+      unselall
+      SelClass type disk
+      Information ; wait
+      InfoLog
+        Print
+        $cstm_disk_out
+        Done
+      Exit
+      Ok
+  
+==end_of_command==
+  
+    else
+
+      cat <<==end_of_command==   > ${cstm_command_file}
+      # testtt
+      #
+      # The following connects the UI to the system the UI is being run on,
+      #  and selects this system.
+      #SelCurrentSys system add localhost  system 1
+      # Use current user name
+      # No password required on local system.
+      #don't prompt for overwrite
+      gop confirmation no
+      #Select all
+      #Select class cpu
+      SelClass type processor qualifier cpu
+      #collect the information and wait for it to finish
+      Information ; wait
+      #now display the info log
+      InfoLog
+        SaveAs
+        $cstm_cpu_out
+        Done
+      #map
+      unselall
+      SelClass type memory
+      Information ; wait
+      InfoLog
+        SaveAs
+        $cstm_mem_out
+        Done
+      unselall
+      SelClass type disk
+      Information ; wait
+      InfoLog
+        SaveAs
+        $cstm_disk_out
+        Done
+      Exit
+      Ok
+  
+==end_of_command==
+    fi
+    /usr/sbin/cstm -f ${cstm_command_file} > /dev/null 2>&1
+
+  awk '
+      /Hardware path/         {path = $3; next;}
+      /Slot Number/           {slot = $3; next; }
+      /PDC Firmware Revision/ {pdc = $4; next;}
+      /Instruction Cache/     {icache = $4; next;}
+      /Data Cache/            {dcache = $4; next;}
+      /Instruction TLB/       {itlb = $4; next;}
+      /Data TLB/              {dtlb = $5;
+                               printf("%6s%6s  %12s%8s %6s%6s %6s\n",
+                               path, slot, pdc, icache, dcache, itlb, dtlb);
+                              }
+      ' $cstm_cpu_out > $cstm_cpu_out2
+
+  rm -f ${cstm_command_file}
+  #rm -f ${cstm_cpu_out}
+  Debug "cstm_cpu_out2 = ${cstm_cpu_out2}"
+  #Debug "Data Cache            = ${data_cache}"
+  #Debug "Instruction Cache     = ${inst_cache}"
+  #Debug "Data TLB              = ${data_cache}"
+  #Debug "Instruction TLB       = ${inst_cache}"
+  #Debug "PDC Firmware Revision = ${pdc_rev}"
+  #Debug "${memory_interleave}"
+
+    check_na=$(awk ' /Total Physical Memory/   {print $NF}
+            ' $cstm_mem_out  | tail -1)
+    if [[ ${check_na} != "N/A" ]]
+    then
+      cstm_tot_phys=$(awk ' /Total Physical Memory/   {print $(NF -1)}
+        ' $cstm_mem_out  | tail -1)
+    else
+      cstm_tot_phys="N/A"
+    fi
+    cstm_tot_conf=$(awk ' /Total Configured Memory/  {print $(NF -1)}
+        ' $cstm_mem_out  | tail -1)
+    cstm_page_size=$(awk ' /Page Size/ {print $(NF -1)}
+        ' $cstm_mem_out  | tail -1)
+    cstm_interleave=$(awk ' /Memory interleaving/ { print $0}
+        ' $cstm_mem_out | tail -1)
+    if [[ -z ${cstm_tot_conf} ]] || [[ -z ${cstm_page_size} ]]
+    then
+      cstm_tot_conf="N/A"
+      cstm_page_size="N/A"
+    fi
+  else
+    print "Sorry, this version is not supported by SysInfo."
+    print "Hardware level information will not be available."
+    Debug "unsupported cstm version ${cstm_version}"
+    cstm_ok=1
+  fi
+fi
+} # end of function f_run_cstm
+
+
+#===================================================================
+# f_get_array_data
+#===================================================================
+function f_get_array_data
+{
+  if (( ${cstm_ok} == 0 ))
+  then
+    Debug "Getting array data"
+    if (($cstm_major == 12))
+    then
+      cat <<==end_of_command==   > ${cstm_command_file}
+      # testtt
+      #
+      # The following connects the UI to the system the UI is being run on,
+      #  and selects this system.
+      # SelCurrentSys system add localhost  system 1
+      # Use current user name
+      # No password required on local system.
+      # don't prompt for overwrite
+      gop confirmation no
+      #unselall
+      Sel path $hwpath
+      Information ; wait
+      InfoLog
+        Print
+        $cstm_array_out
+        Done
+      Exit
+      Ok
+
+==end_of_command==
+
+    else   # cstm not equal to 12
+
+      cat <<==end_of_command==   > ${cstm_command_file}
+      # testtt
+      #
+      # The following connects the UI to the system the UI is being run on,
+      #  and selects this system.
+      #SelCurrentSys system add localhost  system 1
+      # Use current user name
+      # No password required on local system.
+      #don't prompt for overwrite
+      gop confirmation no
+      #unselall
+      Sel path $hwpath
+      Information ; wait
+      InfoLog
+        SaveAs
+        $cstm_array_out
+        Done
+      Exit
+      Ok
+
+==end_of_command==
+
+    fi
+    /usr/sbin/cstm -f ${cstm_command_file} > /dev/null 2>&1
+    cat $cstm_array_out | tail +6 >> /tmp/sysinfo.$$.array
+    rm $cstm_array_out
+  else
+    print "Array info not available  -  Problem with cstm."
+  fi
+
+} # end of f_get_array_data
+
+#===================================================================
+# f_get_system_data
+#        This function retrieves various system  and boot data.
+#        e.g. amount of memory, number of cpus, etc.
+#        It also checks to see if memory dumping is properly
+#        configured.
+#===================================================================
+function f_get_system_data
+{
+  if [[ (-f /usr/sbin/cstm) && (-x /usr/sbin/cstm) ]]
+  then
+    f_run_cstm 
+  else
+    cstm_ok=1
+    Debug " cstm not found....skipping"
+    print "WARNING (${sysname}): CSTM not installed." >> \
+           /tmp/sysinfo.$$.errwarn
+  fi
+  Debug "Beginning SYSTEM/ROOT check."
+  if (($BATCH))
+  then
+    print -n "collecting system data "
+  fi
+  # Determine cpu speed in MHz
+  # Determine the memory size.
+  # Real memory expressed in units of pages (4 kbytes per page).
+  if [ ${osmajor} -eq 11 ]
+  then
+  cpu_speed=$(echo itick_per_tick/D | adb -k $kernel /dev/kmem | tail -1 \
+          | awk '{print $2 / 10000}')
+  REAL_MEM=$(echo 'phys_mem_pages/D'| adb -k $kernel /dev/kmem | tail -1 \
+             | awk '{print $2}')
+  MemoryDumpSize=$(expr ${REAL_MEM} / 256)
+  k32_64=$(getconf KERNEL_BITS)
+  processor_count=$(echo 'processor_count/D' | adb -k $kernel /dev/kmem \
+                    | tail -1 | awk '{print $2}')
+  else
+  cpu_speed=$(echo itick_per_tick/D | adb $kernel /dev/kmem | tail -1 \
+          | awk '{print $2 / 10000}')
+  dumppages=$(echo 'dumpsize/D'| adb  $kernel /dev/kmem | tail -1 \
+              | awk '{print $2}')
+  MemoryDumpSize=$(expr ${dumppages} / 256)
+  REAL_MEM=$(echo 'physmem/D'| adb  $kernel /dev/kmem | tail -1 \
+             | awk '{print $2}')
+  # determine number of active processors (cpus)
+  processor_count=$(echo 'processor_count/D' | adb $kernel /dev/kmem \
+                    | tail -1 | awk '{print $2}')
+  fi
+  memory=$(expr ${REAL_MEM} / 256)
+  if (($BATCH))
+  then
+    print -n "."
+  fi
+  boot_time=$(who -b | awk '{printf "%s %s %s ", $4, $5, $6}')
+   
+  #now get date of last patch
+  #
+  #Modified: Greg Sterling
+  #updated lastpatch for 10.x & 11.x
+  #
+  last_patch="unknown"
+  if (( $osmajor >= 10 ))
+  then
+    if [ -d /var/adm/sw/products ]
+    then
+      last_patch=$(ls -lt /var/adm/sw/products | egrep 'PHNE|PHCO|PHKL|PHSS' \
+           | head -1 | awk '{ print $6,$7,$8}')
+    else
+      Debug "ERROR: Product IPD database does not exist."
+    fi
+  else
+    if [ -d /system ]
+    then
+      last_patch=$(ls -lt /system/ | egrep 'PHNE|PHCO|PHKL|PHSS' \
+           | head -1 | awk '{ print $6,$7,$8}')
+    fi
+  fi
+  if (($BATCH))
+  then
+    print -n "."
+  fi
+  if (($BATCH))
+  then
+    print -n "."
+  fi
+  lvlnboot -v /dev/vg00 > /tmp/sysinfo.$$.root 2>&1
+  rootboot=$(grep "Boot Disk" /tmp/sysinfo.$$.root \
+             | awk '{printf "%s  ", $1}')
+  rootroot=$(grep "^Root:" /tmp/sysinfo.$$.root \
+             | awk '{print $2,$4}')
+  rootswap=$(grep "^Swap:" /tmp/sysinfo.$$.root \
+             | awk '{print $2,$4}')
+  rootdump=$(grep "^Dump:" /tmp/sysinfo.$$.root \
+             | awk '{printf  "%s ",$2}')
+  if (($BATCH))
+  then
+    print -n "."
+  fi
+
+  kernel_size=$(ll ${kernel} | awk '{print $5}' 2>&1)
+# gather memory dump parms
+  (( KernelSizeMb=`ll ${kernel} | awk '{print $5}'` / 1024 / 1024 + 1 ))
+  if (( $osmajor < 10 ))
+  then                                        
+    # it is a 9.x system
+    if [[ $(grep "dumps" /etc/conf/gen/S800*) = *default* ]]
+    then
+      DumpDiskCapacity=$(swapinfo -mat | grep dev | head -1 | awk '{print $2}')
+      rootdump="default"
+      Debug "  9.x system. default found in S800."
+      Debug "  rootdump=${rootdump}"
+    else
+      Debug "  9.x system. default not found in S800. using rootdump"
+    fi
+    SAVECORE=0
+    grep "/etc/savecore" /etc/rc > /dev/null 2>&1
+    if ((! ($?) ))
+    then
+      SAVECORE=1
+    fi
+    SAVECORE_DIR=$(grep "/etc/savecore" /etc/rc | tail -1 | awk '{print $NF}')
+
+  elif  (( $osmajor >= 11 ))
+  then
+    # 11.x system
+    Debug "  11.x system."
+    if [ -f /etc/rc.config.d/savecrash ] 
+    then
+      . /etc/rc.config.d/savecrash
+      # check if SAVECRASH is set
+      if [[ ! -z $SAVECRASH ]]
+      then
+      case ${COMPRESS} in
+        0) Compress_Option="Turned off. ";;
+        1) Compress_Option="Turned on. ";;
+        2) Compress_Option="Don't care (default). ";;
+        *) Compress_Option="N/A";;
+      esac
+      SAVECORE=$SAVECRASH
+      SAVECORE_DIR=$SAVECRASH_DIR
+      Debug "  found /etc/rc.config.d/savecrash with following parms:"
+      Debug "    SAVECORE=$SAVECRASH"
+      Debug "    SAVECORE_DIR=$SAVECRASH_DIR"
+      Debug "    CHUNK_SIZE=$CHUNK_SIZE"
+      Debug "    COMPRESS=$COMPRESS"
+      Debug "    MIN_FREE=$MIN_FREE"
+      Debug "    SWAP_LEVEL=$SWAP_LEVEL"
+      Debug "    FOREGRD=$FOREGRD"
+      Debug "    SAVE_PART=$SAVE_PART"
+      Debug "    LOG_ONLY=$LOG_ONLY"
+      else
+      Debug "  SAVECRASH is DISABLED"
+      SAVECORE=0
+      fi
+#
+# Now check for the crashconf file. This file can be used to set additional
+# dump parameters in V11.x
+#
+      if [ -f /etc/rc.config.d/crashconf ]
+      then
+        . /etc/rc.config.d/crashconf
+        # check if CRASHCONF_ENABLED is set
+        if [[ -z $CRASHCONF_ENABLED ]]
+        then
+          Debug "  CrashConf is disabled."
+      else
+
+# Changed: 12/15/98 by Greg Sterling
+# If we're using V11.x, and CRASHCONF is enabled, the we've costomized the
+# DUMP output. The equation below does not apply to this scenario.
+# TotalMemoryDumpSize = MemoryDumpSize + KernelSizeMb + KernelSafetyFactor
+#
+# The actual dumpsize can not be computed from the crashconf utility. The
+# kernel size and safety values can be set to zero since the crashconf utility
+# already calculates these values.
+#
+        crashconf_dumpsize=$(/sbin/crashconf -v | grep 'Total pages included' \
+               | awk '{ print $6}')
+        crashconf_dumpsize=$(expr ${crashconf_dumpsize} \* 4096 / 1024 / 1024)
+#       KernelSizeMB=0
+#       KernelSafetyFactor=0
+
+        Debug "  found /etc/rc.config.d/crashconf with following parms:"
+        Debug "    CRASHCONF_ENABLED=$CRASHCONF_ENABLED"
+        Debug "    CRASH_INCLUDED_PAGES=$CRASH_INCLUDED_PAGES"
+        Debug "    CRASH_EXCLUDED_PAGES=$CRASH_EXCLUDED_PAGES"
+        Debug "    CRASHCONF_READ_FSTAB=$CRASHCONF_READ_FSTAB"
+        Debug "    CRASHCONF_REPLACE=$CRASHCONF_REPLACE"
+#
+# Check to see if the CRASHCONF_READ_FSTAB variable is set. If yes, then
+# the system will check the /etc/fstab file to see if there are any additional
+# dump spaces defined. If the CRASHCONF_REPLACE variable is set then all
+# the definitions/parameters defined in this section will replace any
+# previously defined DUMP parameters in the kernel.
+#
+        if [[ ! -z $CRASHCONF_READ_FSTAB ]]
+        then
+          Debug "  crashconf_read_fstab is enabled."
+          crashconf_fstabs=$(awk ' $3=="dump" {printf("%s ",$1)}' /etc/fstab )
+
+          Debug "  list of crashconf_fstabs = $crashconf_fstabs"
+          if [[ -z $crashconf_fstabs ]]
+          then
+            Debug "  crashconf_fstabs list is empty. Will continue to "
+            Debug "    use the lvlnboot info."
+          else
+            if [[ -z $CRASHCONF_REPLACE ]]
+            then
+              Debug "  crashconf_fstabs will be added to existing \
+                         configuration."
+              rootdump="$rootdump $crashconf_fstabs"
+            else
+              Debug "  crashconf_fstabs will replace default dump config."
+              rootdump=$crashconf_fstabs
+            fi
+          fi
+        fi
+      fi
+    else
+      Debug "  could not find /etc/rc.config.d/crashconf"
+      print "ERROR ${sysname}:/etc/rc.config.d/crashconf defaults file MISSING" >> /tmp/sysinfo.$$.errwarn
+    fi
+  fi
+  else  
+    # must be a 10.x system
+    Debug "  10.x system."
+    if [ -f /etc/rc.config.d/savecore ] 
+    then
+      . /etc/rc.config.d/savecore
+      case ${COMPRESS} in
+        0) Compress_Option="Turned off. ";;
+        1) Compress_Option="Turned on. ";;
+        2) Compress_Option="Don't care (default). ";;
+        *) Compress_Option="N/A";;
+      esac
+      Debug "  found /etc/rc.config.d/savecore with following parms:"
+      Debug "    SAVECORE=$SAVECORE"
+      Debug "    SAVECORE_DIR=$SAVECORE_DIR"
+      Debug "    CHUNK_SIZE=$CHUNK_SIZE"
+      Debug "    COMPRESS=$COMPRESS"
+      Debug "    MIN_FREE=$MIN_FREE"
+      Debug "    SWAP_LEVEL=$SWAP_LEVEL"
+      Debug "    FOREGRD=$FOREGRD"
+    else
+      Debug "  could not find /etc/rc.config.d/savecore"
+      print "ERROR: ${sysname}:/etc/rc.config.d/savecore defaults file MISSING" >> /tmp/sysinfo.$$.errwarn
+    fi
+
+  fi
+
+# Updated: Greg Sterling
+# I moved this section of code outside the savesore/crashconf checks above.
+# This dump calculation is pertinent to any version of HPUX and should not be
+# restricted to V10.x
+#
+  if (($lvm_installed))
+  then
+    Debug "Checking for dump space"
+    Debug "  rootdump = ${rootdump}"
+    for logvol in ${rootdump}
+    do
+#
+# Added by Greg Sterling
+# This code checks for a preceeding /dev. if it exists then
+# continue, otherwise append the /dev/vg00 to the lvol definition.
+#
+      echo $logvol | grep -q "^/dev/"
+      if [[ $? -ne 0 ]]
+      then
+        Debug "  adding /dev/vg00 to lvol name"
+        logvol="/dev/vg00/${logvol}"
+      fi
+#
+# Added by Greg Sterling
+# Validate the logvol is a logical volume. Its possible for dump
+# devices in later versions of HPUX to be disks w/out LVM
+#
+        lvdisplay $logvol > /dev/null 2>&1
+        if [[ $? -ne 0 ]]
+        then
+          Debug "    dump device is not a logical volume."
+          rlogvol=$( echo $logvol | sed -e "s:^/dev/dsk/:/dev/rdsk/:" )
+          DumpSize=$( diskinfo $rlogvol | grep "size" | awk '{print $2}')
+          DumpSize=$( expr $DumpSize / 1024 )
+        else
+          DumpSize=$(lvdisplay $logvol | grep "LV Size" | awk '{print $4}')
+          Debug "    $logvol DumpSize = ${DumpSize}"
+        fi
+        Debug "  Adding $DumpSize to DumpDiskCapacity = ${DumpDiskCapacity}"
+        ((DumpDiskCapacity = DumpDiskCapacity + DumpSize))
+      done
+      Debug "  DumpDiskCapacity =${DumpDiskCapacity}"
+    fi
+    Debug "Checking how much to dump"
+    # add kernel size to memory plus 2Mb safety factor
+    ((TotalMemoryDumpSize = MemoryDumpSize + KernelSizeMb + KernelSafetyFactor))
+    Debug "  REAL_MEM = $REAL_MEM"
+    Debug "  memory =               $memory"
+    Debug "  KernelSizeMb =           $KernelSizeMb"
+    Debug "  KernelSafetyFactor =     $KernelSafetyFactor"
+    Debug "                     ---------"
+    Debug "  TotalMemoryDumpSize =  $TotalMemoryDumpSize"
+
+    if (($BATCH))
+    then
+      print -n "."
+    fi
+# now check to see if everything is okay.
+#
+# Updated: 12/15/98 by Greg Sterling
+# I updated this code to consider the CRASHCONF utility on V11.x. The
+# TotalMemoryDumpSize parameter is only relevent for a FULL crash dump.
+# Normal system crashes (if there is such a thing), can be captured within
+# smaller dump spaces due to the CRASHUTIL utility.
+#
+    case $osmajor in
+      11 )
+         if (( DumpDiskCapacity < TotalMemoryDumpSize ))
+         then
+           if (( DumpDiskCapacity < crashconf_dumpsize ))
+           then
+             print "WARNING (${sysname}): Dump space is underconfigured!" \
+                     >> /tmp/sysinfo.$$.errwarn
+           else
+             print "WARNING (${sysname}): Dump space is underconfigured \
+for a FULL crashdump." >> /tmp/sysinfo.$$.errwarn
+             print "WARNING (${sysname}): Dump space is adequate for the \
+CRASHCONF configuration." >> /tmp/sysinfo.$$.errwarn
+           fi
+         fi
+       ;;
+
+ 8 | 9 | 10 )
+         if (( DumpDiskCapacity < TotalMemoryDumpSize ))
+         then
+           print "WARNING (${sysname}): Dump space is under configured!" \
+                   >> /tmp/sysinfo.$$.errwarn
+         fi
+       ;;
+  esac
+  if ((! (($exit_code)) ))
+  then
+    exit_code=${WARN}
+  fi
+
+  if (( ! $SAVECORE ))
+  then
+    SAVECORE=Disabled
+    if ((! (($exit_code)) ))
+    then
+      exit_code=${WARN}
+    fi
+
+    case $osmajor in
+      8 | 9 | 10 )
+       print "WARNING (${sysname}): Savecore is not enabled!" \
+                 >> /tmp/sysinfo.$$.errwarn
+      ;;
+
+      11 )
+       if [[ -z $CRASHCONF_ENABLED ]]
+       then
+        Debug "Savecore is Disabled and CrashConf is Disabled."
+        print "WARNING (${sysname}):Both Savecore and crashconf are disabled!" \
+                 >> /tmp/sysinfo.$$.errwarn
+       fi
+      ;;
+    esac
+
+  else
+
+
+  # Now check if enough disk space exists to hold savecore
+  Debug "Checking for sufficient savecore space"
+  COMPRESSION="Not Applicable"
+  if [[ -d $SAVECORE_DIR ]] 
+  then
+    #SaveCoreAvail=$(bdf $SAVECORE_DIR | grep /dev/ | awk '{print $4}')
+    # fix for non-standard lvol names
+    SaveCoreAvail=$(df -b $SAVECORE_DIR | awk '{print $5}')
+    ((SaveCoreAvail = SaveCoreAvail / 1024))
+    Debug "  SAVECORE=$SAVECORE"
+    Debug "  SAVECORE_DIR=$SAVECORE_DIR" 
+    Debug "  SaveCoreAvail=$SaveCoreAvail" 
+  else
+    SaveCoreAvail=0
+    if ((! (($exit_code)) ))
+    then
+      exit_code=${WARN}
+    fi
+    print "WARNING (${sysname}): Directory $SAVECORE_DIR does not exist!" >> /tmp/sysinfo.$$.errwarn
+  fi
+    if ((($osmajor == 10))  && (($osminor >= 10))) || (( $osmajor > 10 ))
+    then
+      COMPRESSION="Available"
+      compression_factor=${compression_factor:-50}
+      ((MemoryCompression = (TotalMemoryDumpSize * $compression_factor) / 100 ))
+      ((CompressedMemoryDumpSize = TotalMemoryDumpSize - MemoryCompression))
+
+      Debug "  Checking for savecore compression"
+      Debug "    Compress_option=$Compress_Option"
+      Debug "    Compression=$COMPRESSION"
+      Debug "    compression_factor=$compression_factor"
+      Debug "    CompressedMemoryDumpSize after = $CompressedMemoryDumpSize"
+      if (( $CompressedMemoryDumpSize  > $SaveCoreAvail ))
+      then
+        if ((! (($exit_code)) ))
+        then
+          exit_code=${WARN}
+        fi
+        print "WARNING (${sysname}): Insufficient file space to hold savecore!" >> /tmp/sysinfo.$$.errwarn
+      fi
+    else
+      if (( $TotalMemoryDumpSize  > $SaveCoreAvail ))
+      then
+        if ((! (($exit_code)) ))
+        then
+          exit_code=${WARN}
+        fi
+        print "WARNING (${sysname}): Insufficient file space to hold savecore!" >> /tmp/sysinfo.$$.errwarn
+      fi
+    fi
+    SaveCoreAvail_Out=$SaveCoreAvail
+    SAVECORE=Enabled
+  fi
+
+  TotalMemoryDumpSizeOut=$TotalMemoryDumpSize
+
+# now let's print it.
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.sysout + print "" >> /tmp/sysinfo.$$.sysout + print "

" >> /tmp/sysinfo.$$.sysout + print "" >> /tmp/sysinfo.$$.sysout + print "System Data" >> /tmp/sysinfo.$$.sysout + print "

" >> /tmp/sysinfo.$$.sysout + print "
" >> /tmp/sysinfo.$$.sysout
+  else
+    print "" >> /tmp/sysinfo.$$.sysout
+    print "SYSTEM DATA" >> /tmp/sysinfo.$$.sysout
+    print "===========" >> /tmp/sysinfo.$$.sysout
+  fi
+  print "HOSTNAME:      ${sysname}" >> /tmp/sysinfo.$$.sysout
+  print "SYSTEM:        ${system}" >> /tmp/sysinfo.$$.sysout
+  print "MODEL:         ${series}" >> /tmp/sysinfo.$$.sysout
+  if [[ -n ${pa_chip} ]]
+  then
+    print "RISC CHIP:     ${pa_chip}" >> /tmp/sysinfo.$$.sysout
+    print "PA VERSION:    ${pa_ver}" >> /tmp/sysinfo.$$.sysout
+  fi
+  if [[ -n ${serial_number} ]]
+  then
+    print "SERIAL #:      ${serial_number}" >> /tmp/sysinfo.$$.sysout
+  fi
+  print "SYSTEM ID:     ${machine_id}" >> /tmp/sysinfo.$$.sysout
+  print "CPU SPEED:     ${cpu_speed} MHz" >> /tmp/sysinfo.$$.sysout
+  print "CPUS:          ${processor_count} active processor(s) " >> /tmp/sysinfo.$$.sysout
+  print "MEMORY:        ${memory} Mbytes of memory." >> /tmp/sysinfo.$$.sysout
+  print -n "HP-UX VERSION: ${osletter}.${osmajor}.${osminor}" >> /tmp/sysinfo.$$.sysout
+  if (( $osmajor == 11 ))
+  then
+    print "   ${k32_64} Bit" >> /tmp/sysinfo.$$.sysout
+  else
+    print "" >> /tmp/sysinfo.$$.sysout
+  fi
+  print "USER LICENSE:  ${license}" >> /tmp/sysinfo.$$.sysout
+  print "LAST BOOT:     ${boot_time}" >> /tmp/sysinfo.$$.sysout
+  print "LAST PATCH:    ${last_patch}\n" >> /tmp/sysinfo.$$.sysout
+  print "" >> /tmp/sysinfo.$$.sysout
+
+  if (( ${cstm_ok} == 0 ))
+  then
+    print "System H/W data" >> /tmp/sysinfo.$$.sysout
+    print "===============" >> /tmp/sysinfo.$$.sysout
+    print "  Processor data" >> /tmp/sysinfo.$$.sysout
+    print -- "  --------------" >> /tmp/sysinfo.$$.sysout
+    print "       H/W          PDC        Cache Size    TLB Size" >>/tmp/sysinfo.$$.sysout
+    print "   path  slot    rev level    Inst   Data  Inst   Data" >>/tmp/sysinfo.$$.sysout
+    print -- "  -----------------------------------------------------" >>/tmp/sysinfo.$$.sysout
+    cat $cstm_cpu_out2 | awk -F: '
+        {printf("%8s%6s%14s%7s%7s%6s%6s\n",$1,$2,$3,$4,$5,$6,$7)}
+        ' >> /tmp/sysinfo.$$.sysout
+
+    print "" >> /tmp/sysinfo.$$.sysout
+    print    "  Memory Information" >> /tmp/sysinfo.$$.sysout
+    print -- "  ------------------" >> /tmp/sysinfo.$$.sysout
+    #print "    Total Physical Memory    = $cstm_tot_phys MB" \
+    #         >> /tmp/sysinfo.$$.sysout
+    #print "    Total Configured Memory  = $cstm_tot_conf MB" \
+    #         >> /tmp/sysinfo.$$.sysout
+    #print "    Memory Page Size         = $cstm_page_size Bytes" \
+    #         >> /tmp/sysinfo.$$.sysout
+    #print "$cstm_interleave" >> /tmp/sysinfo.$$.sysout
+    #print "" >> /tmp/sysinfo.$$.sysout
+
+    cat ${cstm_mem_out} | tail -n +10 | sed -e '/^$/d' >> /tmp/sysinfo.$$.sysout
+    print "" >> /tmp/sysinfo.$$.sysout
+  fi
+
+  print "SWAP DATA" >> /tmp/sysinfo.$$.sysout
+  print "=========" >> /tmp/sysinfo.$$.sysout
+  if (( $osmajor >= 10 ))
+  then
+    Debug "`swapinfo -dtfnrMa`"
+  else
+    Debug "`swapinfo -dtfa`"
+  fi
+
+  swapinfo -m | grep dev | \
+      awk '{printf "%6s MB on %s\n",$2,$9}' >> /tmp/sysinfo.$$.sysout
+  swapinfo -m | grep fs | \
+      awk '{printf "%6s MB on %s\n",$2,$9}' >> /tmp/sysinfo.$$.sysout
+  swapinfo -m | grep memory | \
+      awk '{printf "%6s MB on memory\n",$2}' >> /tmp/sysinfo.$$.sysout
+  print -- "  ----" >> /tmp/sysinfo.$$.sysout
+
+  if (( $osmajor >= 10 ))
+  then
+    swapinfo -mdfMt | grep total | \
+        awk '{printf "%6s MB Total \n",$2}' >> /tmp/sysinfo.$$.sysout
+  else
+    swapinfo -mdft | grep tot | \
+        awk '{printf "%6s MB Total \n",$2}' >> /tmp/sysinfo.$$.sysout
+  fi
+  print "" >> /tmp/sysinfo.$$.sysout
+  print "DUMP DISKS"            >> /tmp/sysinfo.$$.sysout
+  print "=========="            >> /tmp/sysinfo.$$.sysout
+  lvlnboot -v /dev/vg00 2>&1 | grep Dump | awk '{print "  "$0}' >> \
+               /tmp/sysinfo.$$.sysout 
+  print "" >> /tmp/sysinfo.$$.sysout
+  print "DUMP DATA" >> /tmp/sysinfo.$$.sysout
+  print "=========" >> /tmp/sysinfo.$$.sysout
+  print "SAVECORE:                  ${SAVECORE}" >> /tmp/sysinfo.$$.sysout
+  case ${SAVECORE} in
+    D* )
+      ;;
+    E* )
+      print "SAVECORE DIR:              ${SAVECORE_DIR}" >> \
+                   /tmp/sysinfo.$$.sysout
+      if ((($osmajor == 10)) && (($osminor >= 10))) || (( $osmajor > 10 ))
+      then
+        print "SAVECORE COMPRESSION:      ${COMPRESSION}" >> \
+                   /tmp/sysinfo.$$.sysout
+        print "COMPRESSION OPTION:        ${Compress_Option}" >> \
+                   /tmp/sysinfo.$$.sysout
+        print "COMPRESSION FACTOR:          ${compression_factor} %" >> \
+                   /tmp/sysinfo.$$.sysout
+        print "COMPRESSED MEMORY TO DUMP:   ${CompressedMemoryDumpSize} MB" >> \
+                   /tmp/sysinfo.$$.sysout
+        print "SAVECORE CAPACITY:           ${SaveCoreAvail_Out} MB\n" >> \
+                   /tmp/sysinfo.$$.sysout
+      fi
+      ;;
+  esac
+  
+#
+# Added: Greg Sterling
+# Added code to output the status of the CrashConf configuration.
+#
+  if (($osmajor > 10))
+  then
+    if [[ ! -z $CRASHCONF_ENABLED ]]
+    then
+      print "" >> /tmp/sysinfo.$$.sysout
+      if [[ -z $CRASHCONF_READ_FSTAB ]]
+      then
+        print "CRASHCONF             : Enabled" >> /tmp/sysinfo.$$.sysout
+      else
+        print "CRASHCONF             : Enabled (referencing /etc/fstab)" >> \
+                /tmp/sysinfo.$$.sysout
+      fi
+      if [[ -z $CRASHCONF_REPLACE ]]
+      then
+        print "   Replace Option     : CrashConf values have been Added to existing Kernel Definitions." >> /tmp/sysinfo.$$.sysout
+      else
+        print "   Replace Option     : CrashConf values REPLACE existing Kernel Definitions." >> /tmp/sysinfo.$$.sysout
+      fi
+
+      print "   Included Pages     : $CRASH_INCLUDED_PAGES" >> \
+                /tmp/sysinfo.$$.sysout
+      print "   Excluded Pages     : $CRASH_EXCLUDED_PAGES" >> \
+                /tmp/sysinfo.$$.sysout
+      print "   FSTAB File Entries : $crashconf_fstabs" >> \
+                /tmp/sysinfo.$$.sysout
+      print "   CRASHCONF Configured MEMORY TO DUMP: ${crashconf_dumpsize} MB" \
+                 >> /tmp/sysinfo.$$.sysout
+    else
+      print "CRASHCONF             : Disabled" >> /tmp/sysinfo.$$.sysout
+    fi
+    print "" >> /tmp/sysinfo.$$.sysout
+  fi
+
+  print "KERNEL SIZE:                ${kernel_size} Bytes." >> \
+                     /tmp/sysinfo.$$.sysout
+  print "TOTAL MEMORY TO DUMP:        ${TotalMemoryDumpSizeOut} MB" >> \
+                     /tmp/sysinfo.$$.sysout
+
+  print "DUMP DISK CAPACITY:          ${DumpDiskCapacity} MB" >> \
+                   /tmp/sysinfo.$$.sysout
+
+  f_display_file /tmp/sysinfo.$$.sysout 
+  f_display_file /tmp/sysinfo.$$.stmout 
+  #f_display_file /tmp/sysinfo.$$.dumpwarn 
+  print "" >> /tmp/sysinfo.$$.sysout
+
+#  if (($BATCH))
+#  then
+    print 
+#  fi
+}                # end of f_get_system_data
+
+function f_call_getkinfo
+{
+/usr/sam/lbin/getkinfo -b -o ${sam_kinfo}
+}
+
+function get_all_parms
+{
+Debug "starting get_all_parms"
+awk '
+     BEGIN { FS = "\n"; RS = "}" }
+     {print $0}
+    ' $sam_kinfo | \
+    awk '
+         /KC_PARAM_NAME/      {name = $3;  printf("%s,", name)}
+         /KC_PARAM_CLASS/     {class = $3 " " $4; printf("%s\n", class)}
+        ' #| sed -e 's/\"*//g'
+}
+
+function get_all_classes
+{
+Debug "starting get_all_classes"
+awk ' BEGIN { FS = "\n"; RS = "}" }
+      $0 ~ /'\"$parm\"'/ {print $0}' $sam_kinfo \
+        | awk '
+          /^KC_PARAM_CLASS/     {printf("%s %s\n",$3,$4)}
+          ' #| sed -e 's/\"*//g'
+}
+
+function f_query_sam
+{
+  sam_parm=$1
+  type=$2
+    awk ' BEGIN { FS = "\n"; RS = "}" }
+      $0 ~ /'$sam_parm'/ {print $0}' $sam_kinfo \
+          | awk '
+          /^KC_PARAM_NAME/      {name = $3}
+          /^KC_PARAM_STATUS/    {status = $3}
+          /^KC_PARAM_DEFAULT/   {default = $3}
+          /^KC_PARAM_MAX/       {max = $3}
+          /^KC_PARAM_MIN/       {min = $3}
+          /^KC_PARAM_CLASS/     {class = $3" " $4}
+          /^KC_PARAM_DESC/      {desc = ""
+                                 for(i=3;i<=NF;i++)
+                                 desc = desc $i " ";
+                                 }
+
+          END { printf("%s@%s@%s@%s@%s@%s@%s\n",
+                        name,status,default,max,min,desc,class)}
+    ' | sed -e 's/\"*//g'
+
+}
+
+#===================================================================
+# f_get_kernel_data
+#        This function queries the kernel for various parameters.
+#===================================================================
+function f_get_kernel_data 
+{
+
+  Debug "Beginning KERNEL check."
+  if (($BATCH))
+  then
+    print -n "collecting kernel data "
+    print "" >> /tmp/sysinfo.$$.kernout
+  else
+    print    "Collecting kernel metrics....please wait."
+  fi
+ 
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.kernout + print "" >> /tmp/sysinfo.$$.kernout + print "

" >> /tmp/sysinfo.$$.kernout + print "

TOP

" >> /tmp/sysinfo.$$.kernout + print "" >> /tmp/sysinfo.$$.kernout + if (( ${FULL_KERNEL} )) + then + print "Kernel Parms (Verbose Listing)" >> /tmp/sysinfo.$$.kernout + else + print "Kernel Parms (Brief Listing)" >> /tmp/sysinfo.$$.kernout + fi + print "

" >> /tmp/sysinfo.$$.kernout + print "
" >> /tmp/sysinfo.$$.kernout
+  else
+    print "KERNEL PARAMETERS" >> /tmp/sysinfo.$$.kernout
+    print "=================" >> /tmp/sysinfo.$$.kernout
+  fi
+
+Debug "calling f_call_getkinfo -> ${sam_kinfo}"
+f_call_getkinfo
+
+Debug "calling get_all_parms -> ${all_parms_file}"
+get_all_parms > ${all_parms_file}
+Debug " parm names = `cat ${all_parms_file}`"
+
+Debug "calling get_all_classes -> ${all_classes_file}"
+get_all_classes | sort -t , -k 7 | uniq  > ${all_classes_file}
+    #sed -e 's/ /_/g' -e 's/_$//g'  > ${all_classes_file}
+Debug " class names = `cat ${all_classes_file}`"
+
+exec 3< ${all_classes_file}
+exec 4< ${all_parms_file}
+while read -u3 class
+do
+  if (($BATCH))
+  then
+    print -n "."
+  fi
+  print_class=$(echo $class | sed -e 's/\"*//g')
+  if (($HTML))
+  then
+    print "

${print_class} Metrics

" >> /tmp/sysinfo.$$.kernout + else + print "${print_class} Metrics" >> /tmp/sysinfo.$$.kernout + print "============================" >> /tmp/sysinfo.$$.kernout + fi + Debug "Class = ${class}" + for parm1 in $(grep "${class}" ${all_parms_file} | awk -F, '{print $1}') + do + Debug "Parm1 = $parm1" + if (($FULL_KERNEL)) + then + f_query_sam ${parm1} | \ + awk 'BEGIN {FS = "@"} + {printf("%s\n",$1) + printf(" Title: %s\n",$6) + printf(" Current: %s\n",$2) + printf(" Default: %s\n",$3) + printf(" Min: %s\n",$5) + printf(" Max: %s\n",$4) + #printf(" Class: %s\n",$7) + } '>> /tmp/sysinfo.$$.kernout + else + f_query_sam ${parm1} | \ + awk 'BEGIN {FS = "@"} + {printf(" %-20s %s\n",$1,$2) + } ' >> /tmp/sysinfo.$$.kernout + fi + done +print "" >> /tmp/sysinfo.$$.kernout +done + print "" >> /tmp/sysinfo.$$.kernout + f_display_file /tmp/sysinfo.$$.kernout + +if (($PASS)) +then + if (($DB_on_this_sys)) + then + dbc_max=$(grep dbc_max /tmp/sysinfo.$$.kernout | awk '{print $2}') + if (( dbc_max > 10 )) + then + print "WARNING ($sysname): dbc_max is set to ${dbc_max} on DB server" >> \ + /tmp/sysinfo.$$.sapwarn + fi + fi +fi + f_display_file /tmp/sysinfo.$$.kernwarn + if (($BATCH)) + then + print "" + fi +} # end of f_get_kernel_data + +#=================================================================== +# f_get_9x_kernel_data +# This function queries the kernel for various parameters. +#=================================================================== +function f_get_9x_kernel_data +{ + + Debug "Beginning 9x KERNEL check." + if (($BATCH)) + then + print -n "collecting kernel data " + fi + shmmni=$(echo 'shmmni/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + maxfiles=$(echo 'maxfiles/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + shmmax=$(echo 'shmmax/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + shmseg=$(echo 'shmseg/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + shmem=$(echo 'shmem/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + maxfiles_lim=$(echo 'maxfiles_lim/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + maxuprc=$(echo 'maxuprc/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + nproc=$(echo 'nproc/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + nfile=$(echo 'nfile/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + nflocks=$(echo 'nflocks/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + ninode=$(echo 'ninode/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi +# PA8000 chips support variable page sizes + super_page_supp=$(echo cpu_has_var_size_pages/D | adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + case $super_page_supp in + 0) super_page_support=no;; + 1) super_page_support=yes;; + *) super_page_support=n/a;; # not found in kernel + esac + if (($BATCH)) + then + print -n "." + fi + npty=$(echo 'npty/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') +# check for asynch disc writes enabled + fs_async=$(echo 'fs_async/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if ((${fs_async} == 0)) + then + fs_async=no + else + fs_async=yes + fi + if (($BATCH)) + then + print -n "." + fi + nbuf=$(echo 'nbuf/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + bufpages=$(echo 'bufpages/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + + if (($BATCH)) + then + print -n "." + fi + msgmap=$(echo 'msgmap/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + maxdsiz=$(echo 'maxdsiz/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + maxssiz=$(echo 'maxssiz/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + maxtsiz=$(echo 'maxtsiz/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + maxuprc=$(echo 'maxuprc/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + ncdnode=$(echo 'ncdnode/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + sema=$(echo 'sema/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + semmap=$(echo 'semmap/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi +# get LVM related kernel parameters + maxvgs=$(echo 'maxvgs/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + lv_vgs_opn=$(echo 'lv_vgs_opn/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + lv_lvs_opn=$(echo 'lv_lvs_opn/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + lv_pbuf_cnt=$(echo 'lv_pbuf_cnt/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + lv_pbuf_inuse=$(echo 'lv_pbuf_inuse/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + lv_pbuf_maxuse=$(echo 'lv_pbuf_maxuse/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + if (($BATCH)) + then + print -n "." + fi + lv_pbuf_pending_Q=$(echo 'lv_pbuf_pending_Q/D'|adb $kernel /dev/kmem \ + | tail -1 | awk '{print $2}') + + if (($HTML)) + then + print "
" >> /tmp/sysinfo.$$.kernout + print "" >> /tmp/sysinfo.$$.kernout + print "" >> /tmp/sysinfo.$$.kernout + print "

Kernel Data

" >> /tmp/sysinfo.$$.kernout + print "
" >> /tmp/sysinfo.$$.kernout
+  else
+    print "KERNEL DATA" >> /tmp/sysinfo.$$.kernout
+    print "===========" >> /tmp/sysinfo.$$.kernout
+  fi
+  print "Super page support (cpu_has_var_size_pages) $super_page_support" >> /tmp/sysinfo.$$.kernout
+  print "" >> /tmp/sysinfo.$$.kernout
+  print "Max shared memory segments in system (shmmni)$shmmni" >> /tmp/sysinfo.$$.kernout
+  print "Enable Sys V Shared Memory(shmem)            ${shmem}" >> /tmp/sysinfo.$$.kernout
+
+  print "" >> /tmp/sysinfo.$$.kernout
+  print "Soft file limit per process (maxfiles)       $maxfiles" >> /tmp/sysinfo.$$.kernout
+  print "Hard file limit per process (maxfiles_lim)   $maxfiles_lim" >> /tmp/sysinfo.$$.kernout
+  print "Max number of processes (nproc)              $nproc" >> /tmp/sysinfo.$$.kernout
+  print "Max number of user processes (maxuprc)       $maxuprc" >> /tmp/sysinfo.$$.kernout
+  print "Number of open files in system (nfile)       $nfile" >> /tmp/sysinfo.$$.kernout
+  print "Maximum number of file locks (nflocks)       $nflocks" >> /tmp/sysinfo.$$.kernout
+  print "Max number of in-core inodes (ninode)        $ninode" >> /tmp/sysinfo.$$.kernout
+  print "Asynchronous disk writes allowed (fs_async)  $fs_async" >> /tmp/sysinfo.$$.kernout
+  print "Number of pseudo-teletypes (npty)            $npty" >> /tmp/sysinfo.$$.kernout
+  print "Number of filesystem buffer headers (nbuf)   $nbuf" >> /tmp/sysinfo.$$.kernout
+  print "Number of buffer pages in cache (bufpages)   $bufpages" >> /tmp/sysinfo.$$.kernout
+  print "Max Number of Message Map Entries (msgmap)   $msgmap" >> /tmp/sysinfo.$$.kernout
+  print "Max Data Segment Size (Bytes) (maxdsiz)      $maxdsiz" >> /tmp/sysinfo.$$.kernout
+  print "Max Stack Segment Size (Bytes) (maxssiz)     $maxssiz" >> /tmp/sysinfo.$$.kernout
+  print "Max Text Segment Size (Bytes) (maxtsiz)      $maxtsiz" >> /tmp/sysinfo.$$.kernout
+  print "Enable Sys V Semaphores (sema)               $sema" >> /tmp/sysinfo.$$.kernout
+
+  if (($lvm_installed))
+  then
+    print "" >> /tmp/sysinfo.$$.kernout
+    print "LVM Parms" >> /tmp/sysinfo.$$.kernout
+    print "  Max number of volume groups (maxvgs)       $maxvgs" >> /tmp/sysinfo.$$.kernout
+    print "  Number of open volume groups (lv_vgs_opn)  $lv_vgs_opn" >> /tmp/sysinfo.$$.kernout
+    print "  Number of open logical volumes (lv_lvs_opn)$lv_lvs_opn" >> /tmp/sysinfo.$$.kernout
+    print "  Lvol pbuf count (lv_pbuf_cnt)              $lv_pbuf_cnt" >> /tmp/sysinfo.$$.kernout
+    print "  Lvol pbuf current usage (lv_pbuf_inuse)    $lv_pbuf_inuse" >> /tmp/sysinfo.$$.kernout
+    print "  Lvol pbuf high water mark (lv_pbuf_maxuse) $lv_pbuf_maxuse" >> /tmp/sysinfo.$$.kernout
+    print "  lv_pbuf_pending_Q:                         $lv_pbuf_pending_Q \n" >> /tmp/sysinfo.$$.kernout
+  fi
+  f_display_file /tmp/sysinfo.$$.kernout
+  f_display_file /tmp/sysinfo.$$.kernwarn
+  if (($BATCH))
+  then
+    print ""
+  fi
+}                # end of f_get_9x_kernel_data
+
+
+#===================================================================
+# f_get_network_data
+#        This function queries each lan card and retrieves information
+#        for each one.
+#===================================================================
+function f_get_network_data
+{
+  Debug "Beginning NETWORK check."
+  if (($BATCH))
+  then
+    print -n "scanning network cards "
+  fi
+  GetCurrentDNS
+  #DOMAIN=$(nslookup ${sysname} | grep Name | grep -v Server | cut -d. -f2-6)
+  default_router=$( netstat -r | grep default | awk '{print $2}')
+  default_router_ip=$( netstat -rn | grep default | awk '{print $2}')
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.netout + print "" >> /tmp/sysinfo.$$.netout + print "

" >> /tmp/sysinfo.$$.netout + print "

TOP

" >> /tmp/sysinfo.$$.netout + print "" >> /tmp/sysinfo.$$.netout + print "Network Data

" >> /tmp/sysinfo.$$.netout + print "
" >> /tmp/sysinfo.$$.netout
+  else
+    print "NETWORK DATA" >> /tmp/sysinfo.$$.netout
+    print "============" >> /tmp/sysinfo.$$.netout
+  fi
+  print "DOMAIN NAME:    ${CURRENT_DOMAIN}" >> /tmp/sysinfo.$$.netout
+  print -n "DNS SERVER:     ${CURRENT_DNS_SERVER}  " >> /tmp/sysinfo.$$.netout
+  print "(${CURRENT_DNS_SERVER_IP})" >> /tmp/sysinfo.$$.netout
+  print -n "DEFAULT ROUTER: ${default_router}  "  >> /tmp/sysinfo.$$.netout
+  print "(${default_router_ip})"  >> /tmp/sysinfo.$$.netout
+  print "" >> /tmp/sysinfo.$$.netout
+
+  #for CARD in $(netstat -in | grep lan | awk '{print $1}' | sed 's/\*//')
+  # 1.42 change to handle multiple I/F cards
+  if (( ${osmajor} >= 10 ))
+  then
+    card_list=$(/etc/lanscan -i | awk '{print $1}')
+    Debug " 10.x using lanscan -i"
+  else
+    card_list=$(/etc/lanscan | tail +3 | awk '{printf("%s\n",$5)}')
+    Debug " 9.x using lanscan "
+  fi
+  for CARD in ${card_list}
+  do
+    ifconfig "${CARD}" > /tmp/sysinfo.$$.ipdata 2>&1
+    if [ $? -eq 0 ]
+    then
+      Debug " checking lan card -> $CARD"
+      #lanconfig "$CARD" >> /tmp/sysinfo.$$.ipdata 2>&1
+      #card_type=$(lanconfig "$CARD" | grep ${CARD} | awk '{print $2}')
+      if (( ${osmajor} >= 11 ))
+      then
+        card_type=$(lanscan -im  | grep "${CARD} " | awk '{print $NF}')
+      else
+        card_type=$(lanscan | grep "${CARD} " | awk '{print $8}')
+      fi
+      Debug "  card_type=$card_type"
+      #MWR fix for incorrect handling of multiple lan cards
+      #macaddr=$(/etc/lanscan | grep x | awk '{print $2}')
+      macaddr=$(/etc/lanscan | grep "${CARD} " | awk '{print $2}')
+      lan_hw_addr=$(/etc/lanscan | grep "${CARD} " | awk '{print $1}')
+      nmid=$(/etc/lanscan | grep "${CARD} " | awk '{print $7}')
+      ip_addr=$(grep inet /tmp/sysinfo.$$.ipdata | awk '{print $2}')
+      ip_addr_name=$(LookupName ${ip_addr})
+      lanspeed=$(lanadmin -s ${nmid} | awk '{print $3}')
+      netmask=$(grep inet /tmp/sysinfo.$$.ipdata | awk '{print $4}')
+
+      #convert hex netmask to decimal-dot.
+      typeset -Z8  hex=0${netmask#0x}; typeset +Z hex
+      typeset -L2  ott=
+      typeset -i10 dec=
+      netmask=""
+      while [ "$hex" ]; do
+        ott=$hex
+        dec=16#$ott
+        netmask=$netmask.$dec
+        hex=${hex#??}
+      done
+      netmask=${netmask#.}
+
+      broadcast=$(grep inet /tmp/sysinfo.$$.ipdata | awk '{print $6}')
+      if (($HTML))
+      then
+        print "
" >> /tmp/sysinfo.$$.netout + print "

INTERFACE DATA for ${CARD}

" >> /tmp/sysinfo.$$.netout + print "
" >> /tmp/sysinfo.$$.netout
+      else
+        print "INTERFACE DATA for ${CARD}" >> /tmp/sysinfo.$$.netout
+        print "===========================" >> /tmp/sysinfo.$$.netout
+      fi
+      #print "NMID:        ${nmid}" >> /tmp/sysinfo.$$.netout
+      print "H/W ADDR:    ${lan_hw_addr}" >> /tmp/sysinfo.$$.netout
+      print "CARD TYPE:   ${card_type}" >> /tmp/sysinfo.$$.netout
+      print "SPEED:       ${lanspeed}" >> /tmp/sysinfo.$$.netout
+      print "MAC ADDRESS: ${macaddr}" >> /tmp/sysinfo.$$.netout
+      print -n "IP ADDRESS:  ${ip_addr}" >> /tmp/sysinfo.$$.netout
+      print "   (${ip_addr_name})" >> /tmp/sysinfo.$$.netout
+      print "BROADCAST:   ${broadcast}" >> /tmp/sysinfo.$$.netout
+      print "NETMASK:     ${netmask}\n" >> /tmp/sysinfo.$$.netout
+    fi
+    if (($BATCH))
+    then
+      print -n "."
+    fi
+  done
+  f_display_file /tmp/sysinfo.$$.netout 
+  if (($BATCH))
+  then
+    print
+  fi
+}                # end of f_get_network_data
+
+function query_EMC_disks
+{
+Debug "Beginning query_EMC_disks"
+if [ -f ${where}/inq.hp ]
+then
+  Debug "  found inq.hp"
+  #inq.hp  
+else
+  Debug "  Could not find inq.hp....no query done."
+fi
+
+}
+rawDiskFilter () {
+    # Filters out the first raw disk file after an HP Claimed disk
+        awk '
+        ( $0 ~ "CLAIMED" )              { hit=0 }
+        ( $0 ~ "CLAIMED" && $0 ~ "HP")  { hit=1; next }
+        ( $0 !~ "CLAIMED" && hit==1)    { hit=0; print $2 }
+        '
+} # rawDiskFilter()
+
+
+#===================================================================
+# f_get_physical_disk_data
+#        This function scans each physical disk.
+#        It uses ioscan to collect disk info and the queries each
+#        device using diskinfo. 
+#        The output is displayed in sorted order.
+#===================================================================
+function f_get_physical_disk_data
+{
+  Debug "Beginning PHYSICAL DISK check."
+# first let's print header information
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.physinfoh + print "" >> /tmp/sysinfo.$$.physinfoh + print "

" >> /tmp/sysinfo.$$.physinfoh + print "

TOP

" >> /tmp/sysinfo.$$.physinfoh + print "" >> /tmp/sysinfo.$$.physinfoh + print "Physical Disk Data

" >> /tmp/sysinfo.$$.physinfoh + print "
"                       >> /tmp/sysinfo.$$.physinfoh
+    print "
" >> /tmp/sysinfo.$$.boot + print "

Bootable Disks

" >> /tmp/sysinfo.$$.boot + print "
"                >> /tmp/sysinfo.$$.boot
+    print    "Volume Name                 H/W Path    Auto Boot String" >> \
+              /tmp/sysinfo.$$.boot
+    print -- "--------------            ------------  ----------------" >> \
+              /tmp/sysinfo.$$.boot
+    print ""                     >> /tmp/sysinfo.$$.boot
+  else
+    print    "PHYSICAL DISK DATA" >> /tmp/sysinfo.$$.physinfoh
+    print    "==================" >> /tmp/sysinfo.$$.physinfoh
+    print    "BOOTABLE DISKS" >> /tmp/sysinfo.$$.boot
+    print    "==============" >> /tmp/sysinfo.$$.boot
+    print    "Volume Name                    H/W Path    Auto Boot String" >> \
+              /tmp/sysinfo.$$.boot
+    print -- "--------------               ------------  ----------------" >> \
+              /tmp/sysinfo.$$.boot
+  fi
+
+ # Header for XP256 Information
+  print > /tmp/sysinfo.$$.256header
+  print "XP256 Disc Array Information" >> /tmp/sysinfo.$$.256header
+  print "============================" >> /tmp/sysinfo.$$.256header
+  print -n "                                      " >> /tmp/sysinfo.$$.256header
+  print "                                    Size" >> /tmp/sysinfo.$$.256header
+  print -n "Device File            Port  Scsi  Lun CU:Ldev Serial#" \
+                                   >> /tmp/sysinfo.$$.256header
+  print "           Type     (MB)" >> /tmp/sysinfo.$$.256header
+
+ # Header for NIKE Array Information
+  print > /tmp/sysinfo.$$.arrayheader
+  print "Disk Array Information" >> /tmp/sysinfo.$$.arrayheader
+  print "======================" >> /tmp/sysinfo.$$.arrayheader
+  
+  if (($PMAP))
+  then
+    if (($HTML))
+    then
+      print "
" >> /tmp/sysinfo.$$.pmap + print "" >> /tmp/sysinfo.$$.pmap + print "

" >> /tmp/sysinfo.$$.pmap + print "

TOP

" >> /tmp/sysinfo.$$.pmap + print "" >> /tmp/sysinfo.$$.pmap + print "Physical Disk To Logical Volume Mapping

" >> /tmp/sysinfo.$$.pmap + print "
"        >> /tmp/sysinfo.$$.pmap
+    else
+      print    "PHYSICAL DISK TO LOGICAL VOLUME MAPPING" >> /tmp/sysinfo.$$.pmap
+      print    "=======================================" >> /tmp/sysinfo.$$.pmap
+    fi
+    print -n "Physical Disk                           " >> /tmp/sysinfo.$$.pmap
+    print    "     Alternate Link" >> /tmp/sysinfo.$$.pmap
+    print    "       Logical Volume     LE        PE" >> /tmp/sysinfo.$$.pmap
+    print -n -- "----------------------------------------" >> /tmp/sysinfo.$$.pmap
+    print --    "-----------------------" >> /tmp/sysinfo.$$.pmap
+  fi
+  Debug "  calling check_if_scan_done"
+  check_if_scan_done io_scan
+  print -n "scanning physical disks "
+
+#get physical disk names
+  if (( $osmajor >= 10 ))
+  then
+    Debug "Found 10.x system"
+#   hw_path=$(ioscan -kfC disk | sed '1,/^=/d' | awk '{print $3}')
+    hw_path=$(grep disk $io_scan_out | awk -F: '{print $11}' | sort)
+    Debug "hw_path=$hw_path"
+    for hwpath in ${hw_path}
+    do
+      Debug "hwpath=${hwpath}"
+      lu=""
+      vendor=""
+      tmpin=$(echo $hwpath | cut -d. -f1)
+### Changed 6/15/99 J.Semroc - to improve Performance reuse existing data
+###   inst=$(ioscan -kf | grep "^ext_bus" | grep " ${tmpin} " \
+###               | grep -v fcpdev | awk '{print $2}')
+      inst=$(grep $hwpath $io_scan_out | grep disk | awk '{print $NF}' \
+                 | cut -d: -f2)
+### end of Change
+      #scsi_addr=$(echo $hwpath | cut -d. -f2)
+      #unit_addr=$(echo $hwpath | cut -d. -f3)
+      #physvol="/dev/dsk/c${inst}t${scsi_addr}d${unit_addr}"
+      #rphysvol="/dev/rdsk/c${inst}t${scsi_addr}d${unit_addr}"
+      #physvol=$(ioscan -kfnH ${hwpath} | awk ' BEGIN {FS=" "; RS=" "} /dev\/dsk/ {printf("%s", $1)}')
+      #rphysvol=$(ioscan -kfnH ${hwpath} | awk ' BEGIN {FS=" "; RS=" "} /dev\/rdsk/ {printf("%s", $1)}')
+      #block_major=$(grep "$hwpath" $io_scan_out | grep disk | awk -F: '{print $6}')
+      #char_major=$(grep "$hwpath" $io_scan_out | grep disk | awk -F: '{print $7}')
+      #block_minor=$(grep "$hwpath" $io_scan_out | grep disk | awk -F: '{print $8}')
+      #Debug "  block_major = ${block_major}"
+      #Debug "  char_major  = ${char_major}"
+      #Debug "  block_minor = ${block_minor}"
+
+      scsi_addr=$(echo $hwpath | awk -F. '{print $(NF-1)}')
+      unit_addr=$(echo $hwpath | awk -F. '{print $NF}')
+      physvol="/dev/dsk/c${inst}t${scsi_addr}d${unit_addr}"
+      rphysvol="/dev/rdsk/c${inst}t${scsi_addr}d${unit_addr}"
+
+      Debug "Physical volume ${physvol}"
+      Debug "  tmpin=${tmpin}"
+      Debug "  inst=${inst} scsi_addr=${scsi_addr} unit_addr=${unit_addr}"
+
+      XP256=$(grep ${hwpath} ${io_scan_out} | weed_targets | awk -F: '{print $18}')
+      if [[ ${XP256} = *OPEN* ]] 
+      then
+        print -n "X"
+        if [[ -f /usr/contrib/bin/inquiry256 ]]
+        then 
+          inqcmd="/usr/contrib/bin/inquiry256"
+        else
+          inqcmd="${where}/inquiry256"
+        fi
+        Debug "XP256 disc array found! ${XP256} ${hwpath}"
+        Debug "inqcmd=${inqcmd}"
+        info=$(diskinfo -v ${rphysvol}  2>&1)
+        case "$info" in
+          *"No such file or directory"* )
+            Debug "  diskinfo reports No such file or directory on $physvol"
+            #echo "$Inq" | \
+            #   awk -F"+" '{printf("%55s\n"),$1}' \
+            #      >> /tmp/sysinfo.$$.inq256
+            rphysvold=$rphysvol
+            print "$rphysvold   No such file or directory" \
+                  >> /tmp/sysinfo.$$.inq256
+          ;;
+          *"No such device or address"* )
+            Debug "  diskinfo reports No such device or address on $physvol"
+           #echo "$Inq" | \
+           #   awk -F"+" '{printf("%55s\n"),$1}' \
+           #      >> /tmp/sysinfo.$$.inq256
+            rphysvold=$rphysvol
+            print "$rphysvold   No such device or address" \
+                  >> /tmp/sysinfo.$$.inq256
+          ;;
+          * )
+          Debug "  found a device (no diskinfo error)...so follow it"
+          Inq=$(${inqcmd} ${rphysvol} 2>&1 )
+          psize=$(echo $info | sed -e 's/^.*size: //' -e 's/ .*$//')
+          psize_mb=$(expr ${psize} / 1024)
+          product1=$(echo $info | sed -e 's/^.*product id: //' -e 's/ .*$//')
+          echo "$Inq+$product1+$psize_mb" | \
+             awk -F"+" '{printf("%55s%16s%8s\n"),$1,$2,$3}' \
+                >> /tmp/sysinfo.$$.inq256
+        esac
+      fi  # end of XP256
+
+      case ${XP256} in
+
+        *C1300* | *C2300* | *C3400* )
+          Debug " found an Nike disk array at $hwpath"
+          print -n "N" 
+          #f_get_array_data
+        ;;
+        *C2430* )
+          Debug " found a Cascade disk array at $hwpath"
+          print -n "C" 
+          #f_get_array_data
+        ;;
+        *C5447A* | *C3586A* )
+          # C5447A is 12H   C3586A is 12
+          Debug " found a AutoRaid disk array at $hwpath"
+          print -n "A" 
+          #f_get_array_data
+        ;;
+        *A5277A* )
+          Debug " found a FC60 disk array at $hwpath"
+          print -n "F" 
+          #f_get_array_data
+        ;;
+        * )
+          Debug " found a jbod disk at $hwpath"
+          print -n "." 
+          #f_get_array_data
+        ;;
+      esac
+
+
+# Run pvdisplay to get the disk information
+      pvdisplay -v ${physvol} > /tmp/sysinfo.$$.pvdisp 2>&1
+# Check for alternate link so that we don't try to access it
+      Debug "  Checking if this is an alternate link"
+      grep "Using Primary Link" /tmp/sysinfo.$$.pvdisp > /dev/null 2>&1
+      detect_alt_link=$?
+      if ((detect_alt_link == 0))
+      then
+        Debug "  this IS an alternate link, so skip"
+        alt_link=true
+      elif [[ "${rphysvol}" = "" ]] then
+        Debug "  no physvol found for $hwpath"
+        if ((! (($exit_code)) ))
+        then
+          exit_code=${WARN}
+        fi
+        print "WARNING (${sysname}):No device file found for $hwpath" >> \
+                     /tmp/sysinfo.$$.errwarn
+      else
+        Debug "  this is NOT an alternate link, so query disk"
+        hwpathd=${hwpath} # for display purposes
+        #info=$(diskinfo -v /dev/rdsk/c${inst}t${scsi_addr}d${unit_addr} 2>&1)
+        info=$(diskinfo -v ${rphysvol}  2>&1)
+        Debug "info= ${info}"
+        case "$info" in
+          *"Device busy"* )
+            Debug "  diskinfo reports Device Busy Error on $rphysvol"
+            lu=$(grep ${hwpath} $io_scan_out | grep -v target \
+                  | awk '{print $2}')
+            vendor1=$(ioscan -H $hwpath | tail -1 | awk '{print $3}')
+            vendor=${vendor1}
+            product1=$(ioscan -H $hwpath | tail -1 | awk '{print $NF}')
+            product=${product1}
+            print "${physvol}${lu}${hwpathd} ${vendor}${product}" \
+                   >> /tmp/sysinfo.$$.physinfo
+            Debug "  ${physvol}${lu}${hwpathd}${vendor}${product}" 
+          ;;
+          *"No such file or directory"* )
+            Debug "  diskinfo reports No such file or directory on $physvol"
+            lu="n/f"
+            vendor1=$(ioscan -H $hwpath | tail -1 | awk '{print $3}')
+            vendor=${vendor1}
+            product1=$(ioscan -H $hwpath | tail -1 | awk '{print $NF}')
+            product=${product1}
+            print "${physvol}${lu}${hwpathd} ${vendor}${product}" \
+                     >> /tmp/sysinfo.$$.physinfo
+          ;;
+          *"No such device or address"* )
+            Debug "  diskinfo reports No such device or address on $physvol"
+            lu="n/f"
+            vendor1=$(ioscan -H $hwpath | tail -1 | awk '{print $3}')
+            vendor=${vendor1}
+            product1=$(ioscan -H $hwpath | tail -1 | awk '{print $NF}')
+            product=${product1}
+            print "${physvol}${lu}${hwpathd} ${vendor}${product}" \
+                     >> /tmp/sysinfo.$$.physinfo
+          ;;
+          * )
+            Debug "  found a device (no diskinfo error)...so follow it"
+        
+          #lu=$(grep ${hwpath} $io_scan_out | grep -v target | awk '{print $2}')
+### Changed 6/15/99 J.Semroc - to improve Performance reuse existing data
+###       lu=$(ioscan -kfCdisk | grep "${hwpath}" | awk '{print $2}')
+          lu=$(grep ${hwpath} $io_scan_out | grep -v target | grep disk | \
+               awk -F: '{print $13}')
+### end of Change
+          Debug "LU = ${lu}"
+          ludebug=$(grep ${hwpath} $io_scan_out | grep -v target )
+          Debug "ludebug= ${ludebug}"
+          psize=$(echo $info | sed -e 's/^.*size: //' -e 's/ .*$//')
+          psize_mb=$(expr ${psize} / 1024)
+          product1=$(echo $info | sed -e 's/^.*product id: //' -e 's/ .*$//')
+  
+          vendor1=$(echo $info | sed -e 's/^.*vendor: //' -e 's/ .*$//')
+          vendor=${vendor1}
+          rev_level=$(echo $info | sed -e 's/^.*rev level: //' -e 's/ .*$//')
+          #rev_level=$(echo $info | grep "rev level" \
+          #       | awk '{print $3}')
+          product=${product1}
+          if [[ "${product1}" != "CD-ROM" ]] && [[ "${product1}" != "DVD-ROM" ]]
+          then
+            ((total_p_mb=total_p_mb + psize_mb))
+            ((pcount=pcount + 1))
+          fi
+          Debug "    vendor1=$vendor1"
+          Debug "    product=$product"
+          Debug "    rev_level=$rev_level"
+          Debug "    psize=$psize"
+          Debug "    psize_mb=$psize_mb"
+#
+# check for bootable disk
+#
+          Debug "  Checking for Bootable PV"
+          lifls ${physvol} 2> /dev/null | grep -i isl > /dev/null 2>&1
+          if [ $? -eq 0 ]
+          then   
+            Debug "    Found Bootable PV at ${physvol}"
+            bootable_pv="Y"
+            lifls ${rphysvol} | grep AUTO > /dev/null 2>&1
+            if [ $? -eq 0 ]
+            then   
+              Debug "    Found auto_string=$auto_string"
+              auto_string=$(lifcp ${rphysvol}:AUTO -)
+              print "${physvol}${hwpathd}   ${auto_string}" >> \
+                       /tmp/sysinfo.$$.boot
+            else
+              Debug "    Did not find auto_string."
+            fi
+          else 
+            Debug "    Did not find Bootable PV on ${physvol}"
+            bootable_pv="N"
+          fi
+          if grep "find the volume group" /tmp/sysinfo.$$.pvdisp > /dev/null
+          then
+            Debug "  NON-LVM   /dev/dsk/c${inst}t${scsi_addr}d${unit_addr}" 
+            Debug "    id as::${vendor}${product}${psize_mb} Mbytes." 
+            #lu="nlv"
+          elif grep "path does not correspond" /tmp/sysinfo.$$.pvdisp > /dev/null
+          then
+            Debug "Specified path not found! ${rphysvol}"
+          else            
+            Debug "  LVM disk"
+### Changed 6/15/99 J.Semroc - to improve Performance reuse existing data
+###         lu=$(ioscan -kfCdisk | grep " ${hwpath}" | awk '{print $2}')
+            lu=$(grep ${hwpath} $io_scan_out | grep -v target | grep disk | \
+                 awk -F: '{print $13}')
+### end of Change
+            if [[ "${vendor1}" = "EMC" ]]  # && ((detect_alt_link == 0))
+            then
+              EMC_found=1
+### Correction 6/15/99  J.Semroc - physvol was misspelled
+              Debug " Found EMC  at ${physvol}."
+              Debug "   detect_alt_link = ${detect_alt_link}"
+              bblvols=$(pvdisplay -v ${physvol} |  \
+                      awk ' /current/ {print $3}' | sort | uniq | \
+                      grep -v "/dsk/")
+              for bblvol in $bblvols
+              do
+                bblock=$(lvdisplay $bblvol | awk ' /Bad block/ {print $3}')
+                Debug "    bblvol=  $bblvol"
+                Debug "    bblock=  $bblock"
+                if [[ "${bblock}" != "NONE" ]]
+                then
+                  if ((! (($exit_code)) ))
+                  then
+                    exit_code=${WARN}
+                  fi
+                  print "WARNING (${sysname}):EMC w/ LVM bad block enabled on ${bblvol}" >> /tmp/sysinfo.$$.errwarn
+                fi
+              done
+            fi
+            if (($PMAP)) 
+            then
+              Debug "  Begin PHYSICAL TO LOGICAL Mapping"
+              alt_link=""
+              if  (($osmajor == 11))
+              then
+                # PVdisplay looks different on 10.20 (MWR)
+                alt_link=$(grep "^PV Name" /tmp/sysinfo.$$.pvdisp | \
+                   grep "Alternate Link" | awk '{printf "%s ", $3}' )
+                Debug "  =11     alt_link=$alt_link"
+              elif (($osmajor == 10)) && (($osminor >= 20))
+              then
+                # PVdisplay looks different on 10.20 (MWR)
+                alt_link=$(grep "^PV Name" /tmp/sysinfo.$$.pvdisp | \
+                   grep "Alternate Link" | awk '{printf "%s ", $3}' )
+                Debug "  >=10.20     alt_link=$alt_link"
+              else 
+                #less than 10.20
+                alt_link=$(grep "^   PV Name" /tmp/sysinfo.$$.pvdisp | \
+                   grep "Alternate Link" | awk '{printf "%s ", $3}' )
+                Debug "  <10.20   alt_link=$alt_link"
+              fi
+              if  [ "$alt_link" = "" ]
+              then
+                alt_link="None"
+              fi
+              Debug "    alt_link=$alt_link"
+              print "${physvol}                           ${alt_link}" \
+                 >> /tmp/sysinfo.$$.pmap
+              sed '1,15d;/current/d;/Status/d;/free/d;' \
+                /tmp/sysinfo.$$.pvdisp | \
+                sed '/^$/d;/---/d;/LV/d; s/\/dev/    \/dev/' \
+                >> /tmp/sysinfo.$$.pmap
+            fi   # end of PMAP
+          fi
+          print -n "${physvol}${lu}${hwpathd} ${vendor}${product}" >> \
+                      /tmp/sysinfo.$$.physinfo
+          print " ${psize_mb} ${bootable_pv}" >> \
+                      /tmp/sysinfo.$$.physinfo
+          ;;
+        esac
+        #print -n "."
+      fi
+    done # end of hwpath loop
+    # end of 10.x system
+  else      
+    Debug "must be a 9.x system"
+    pvol=$(vgdisplay -v 2>&1 | grep "^   PV Name" | grep -v "Alternate Link" \
+           | sort | awk '{printf "%s ", $3}' )
+    ioscan -kfCdisk | sort > /tmp/sysinfo.$$.io_disk
+    #now force access to disks.
+    for physvol in ${pvol}                        # loop through all phys vols
+    do
+      hwpath=$(lssf ${physvol} | awk '{printf "%s ", $(NF -1)}')
+      hwpathd=${hwpath} # for display purposes
+      disktype=$(echo ${physvol} | sed s/dsk/rdsk/)
+      diskinfo -v ${disktype} > /tmp/sysinfo.$$.diskinfo 2>&1
+      if (($?))
+      then
+        print "ERROR:${sysname}: diskinfo reports an error on ${physvol}."
+        >> /tmp/sysinfo.$$.errwarn
+        exit_code=${SYS_ERROR}
+      else
+        vendor=$(grep "vendor" /tmp/sysinfo.$$.diskinfo \
+                 | awk '{printf "%s ", $2}')
+        product1=$(grep "product id" /tmp/sysinfo.$$.diskinfo \
+                 | awk '{printf "%s ", $3}')
+        type=$(grep "type" /tmp/sysinfo.$$.diskinfo \
+                 | cut -b22- )
+        psize=$(grep "size" /tmp/sysinfo.$$.diskinfo \
+                 | awk '{printf "%s ", $2}')
+        psize_mb=$(expr ${psize} / 1024)
+        lu=$(grep " ${hwpath}" /tmp/sysinfo.$$.io_disk | awk '{print $2}')
+        rev_level=$(grep "rev level" /tmp/sysinfo.$$.diskinfo \
+                 | awk '{print $3}')
+        product=${product1}
+        if [[ "${product1}" != "CD-ROM" ]] && [[ "${product1}" != "DVD-ROM" ]]
+        then
+          ((total_p_mb=total_p_mb + psize_mb))
+          ((pcount=pcount + 1))
+        fi
+        if (($PMAP))
+        then
+          pvdisplay -v ${physvol} > /tmp/sysinfo.$$.pvdisp 2>&1
+          alt_link=""
+          alt_link=$(grep "^   PV Name" /tmp/sysinfo.$$.pvdisp | \
+               grep "Alternate Link" | awk '{printf "%s ", $3}' )
+          #alt_link="/dev/dsk/cxtxdx"
+          if  [ "$alt_link" = "" ]
+          then
+            alt_link="None"
+          fi
+          print "${physvol}                           ${alt_link}" \
+             >> /tmp/sysinfo.$$.pmap
+          sed '1,15d;/current/d;/Status/d;/free/d;' /tmp/sysinfo.$$.pvdisp | \
+            sed '/^$/d;/---/d;/LV/d; s/\/dev/    \/dev/' \
+            >> /tmp/sysinfo.$$.pmap
+        fi
+        Debug "\ndisktype=$disktype"
+        Debug "hwpath=$hwpath"
+        Debug "vendor=$vendor"
+        Debug "product=$product"
+        Debug "psize=$psize"
+        Debug "psize_mb=$psize_mb"
+        Debug "lu=$lu"
+        Debug "type=$type"
+        Debug "total_p_mb=$total_p_mb"
+        Debug "pcount=$pcount"
+        Debug "rev_level=$rev_level"
+        Debug "alt_link=$alt_link"
+        print -n "."
+        print "${physvol}${lu}${hwpathd}${vendor}${product}${psize_mb}" >> /tmp/sysinfo.$$.physinfo
+      fi
+    done
+  fi # end of 9.x
+
+  print "                             Rev" > /tmp/sysinfo.$$.disk_rev
+  print "             HW Path        Level         Serial Number      LUN" \
+          >> /tmp/sysinfo.$$.disk_rev
+  print "   ---------------------    -----    ---------------------   ----" \
+          >> /tmp/sysinfo.$$.disk_rev
+  
+  if (( ${cstm_ok} == 0 ))
+  then
+  awk '
+    /Hardware path/ {path = $3; next;}
+    /Product Id/   {prod = $3; vend = $NF; next;}
+    /Firmware Rev/ {fw = $NF; next;}
+    /Logical Unit/ {lu = $NF; next;}
+    /Serial Number/ {sn = $3; next;}
+    /Capacity/ {cap = $NF; printf("%24s %8s %24s %6s\n",
+       path,fw,sn,lu);}' $cstm_disk_out >> /tmp/sysinfo.$$.disk_rev
+  print "" >> /tmp/sysinfo.$$.disk_rev
+  fi
+
+  if (($EMC_found))
+  then
+    Debug "calling EMC query routine"
+    #query_EMC_disks
+
+  fi
+#
+# check for boot path settings
+#
+  if [[ -f /usr/sbin/setboot ]]
+  then
+    pri_boot_path=$(/usr/sbin/setboot | grep Primary | awk '{print $4}')
+    alt_boot_path=$(/usr/sbin/setboot | grep Alternate | awk '{print $4}')
+    auto_boot=$(/usr/sbin/setboot | grep Autoboot | awk '{print $3}')
+    auto_search=$(/usr/sbin/setboot | grep Autosearch | awk '{print $3}' )
+    print "" >> /tmp/sysinfo.$$.boot
+    print "Primary Boot Path   = ${pri_boot_path}" >> /tmp/sysinfo.$$.boot
+    print "Alternate Boot Path = ${alt_boot_path}" >> /tmp/sysinfo.$$.boot
+    print "Autoboot            = ${auto_boot}"     >> /tmp/sysinfo.$$.boot
+    print "Autosearch          = ${auto_search}"   >> /tmp/sysinfo.$$.boot
+  fi
+  print  "\n" >> /tmp/sysinfo.$$.boot
+
+# now print out totals
+### Changed 6/16/99 J.Semroc sort LU numerically
+###  sort -k2. -o /tmp/sysinfo.$$.physinfos /tmp/sysinfo.$$.physinfo
+  sort -k2n -o /tmp/sysinfo.$$.physinfos /tmp/sysinfo.$$.physinfo
+### end of Change
+  rm -f /tmp/sysinfo.$$.physinfo 2>&1
+  print
+# print     "" >> /tmp/sysinfo.$$.physinfoh
+  print  -n "                         " >> /tmp/sysinfo.$$.physinfoh
+  print     "                                               Size" >> /tmp/sysinfo.$$.physinfoh
+  print  -n " Volume Name      LU#         " >> /tmp/sysinfo.$$.physinfoh
+  print     "     H/W Path     Vendor  /  Model        (MB)  B" >> /tmp/sysinfo.$$.physinfoh
+  print  -n " --------------   ---       " >> /tmp/sysinfo.$$.physinfoh
+  print     " ----------------  --------------------    ------ -" >> /tmp/sysinfo.$$.physinfoh
+  print     "                                                                       ======" >> /tmp/sysinfo.$$.physinfot
+  print  -n "                                                   Total (MB)" >> /tmp/sysinfo.$$.physinfot
+  print     "     ${total_p_mb}" >> /tmp/sysinfo.$$.physinfot
+### Changed 6/15/99 J.Semroc - generated the following error
+###  "cat: Cannot use /tmp/sysinfo.14950.physinfod as both input and output."
+###  cat /tmp/sysinfo.$$.physinfo? > /tmp/sysinfo.$$.physinfod
+  cat /tmp/sysinfo.$$.physinfo? > /tmp/sysinfo.$$.PHYSINFOD
+  mv /tmp/sysinfo.$$.PHYSINFOD /tmp/sysinfo.$$.physinfod
+### end of Change
+  print "B = Bootable Disk" >> \
+             /tmp/sysinfo.$$.physinfod
+  print "n/v = Not Valid, n/f = Not Found\n" >> \
+             /tmp/sysinfo.$$.physinfod
+  f_display_file /tmp/sysinfo.$$.physinfod
+  print "" >> /tmp/sysinfo.$$.physwarn
+  f_display_file /tmp/sysinfo.$$.physwarn
+  f_display_file /tmp/sysinfo.$$.disk_rev
+  if [[ -f  /tmp/sysinfo.$$.inq256 ]]
+  then
+    f_display_file /tmp/sysinfo.$$.256header
+    print "" >> /tmp/sysinfo.$$.inq256
+    f_display_file /tmp/sysinfo.$$.inq256
+  fi
+
+  if [[ -f  /tmp/sysinfo.$$.array ]]
+  then
+    f_display_file /tmp/sysinfo.$$.arrayheader
+    print "\n\n" >> /tmp/sysinfo.$$.array
+    f_display_file  /tmp/sysinfo.$$.array
+  fi
+
+  f_display_file /tmp/sysinfo.$$.boot
+  if (($PMAP))
+  then
+    f_display_file /tmp/sysinfo.$$.pmap
+  fi
+  
+}                # end of f_get_physical_disk_data
+
+#===================================================================
+# f_get_ioscan_data
+#===================================================================
+function f_get_ioscan_data
+{
+  Debug "  calling check_if_scan_done"
+  check_if_scan_done io_scan
+  GREP_V_ARGS="-eboot_console $GREP_V_ARGS"
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.ioout + print "" >> /tmp/sysinfo.$$.ioout + print "

" >> /tmp/sysinfo.$$.ioout + print "

TOP

" >> /tmp/sysinfo.$$.ioout + print "" >> /tmp/sysinfo.$$.ioout + print "I/O Configuration Data

" >> /tmp/sysinfo.$$.ioout + print "
"   >> /tmp/sysinfo.$$.ioout
+  else
+    print "I/O CONFIGURATION DATA" >> /tmp/sysinfo.$$.ioout
+    print "======================" >> /tmp/sysinfo.$$.ioout
+  fi
+  print "" >> /tmp/sysinfo.$$.ioout
+  print "              H/W Path       Driver  Identifier String" >>/tmp/sysinfo.$$.ioout
+  print "              --------       ------  -----------------" >>/tmp/sysinfo.$$.ioout
+ 
+  Debug "  `cat ${io_scan_out}`"
+  if (( ${osmajor} >= 10 ))
+  then
+    Debug "found 10.x or later"
+    Debug "sending $io_scan_out to formatter"
+    Debug "  GREP_V_ARGS = $GREP_V_ARGS"
+
+    cat $io_scan_out | weed_targets | formatter | \
+        grep -F -v $GREP_V_ARGS >> /tmp/sysinfo.$$.ioout
+  else
+    Debug "found 9.x"
+    cp ${io_scan_out} /tmp/sysinfo.$$.ioout
+  fi
+  Debug "  `cat /tmp/sysinfo.$$.ioout`"
+  
+  #rm -f $io_scan_tmp
+  print "" >>/tmp/sysinfo.$$.ioout
+  f_display_file /tmp/sysinfo.$$.ioout
+
+}                # end of f_get_ioscan_data
+
+#===================================================================
+# f_get_volume_group_data
+#        This function retrieves volume group data using vgdisplay
+#        and by scannig /etc/lvmconf for config files.
+#===================================================================
+function f_get_volume_group_data
+{
+  Debug "Beginning VOLUME GROUP check."
+  # first print header information
+
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.vginfoh + print "" >> /tmp/sysinfo.$$.vginfoh + print "

" >> /tmp/sysinfo.$$.vginfoh + print "

TOP

" >> /tmp/sysinfo.$$.vginfoh + print "" >> /tmp/sysinfo.$$.vginfoh + print "Volume Group Data

" >> /tmp/sysinfo.$$.vginfoh + print "
"     >> /tmp/sysinfo.$$.vginfoh
+  else
+    print                     >> /tmp/sysinfo.$$.vginfoh
+    print "VOLUME GROUP DATA" >> /tmp/sysinfo.$$.vginfoh
+    print "=================" >> /tmp/sysinfo.$$.vginfoh
+  fi
+  Debug "  calling check_if_scan_done"
+  check_if_scan_done lvm_scan
+
+  vgdisplay -v > /tmp/sysinfo.$$.vgout 2>&1
+  #MWR fix when PVG-strict policies used
+  #all_volgroups=$(grep "VG Name" /tmp/sysinfo.$$.vgout | awk '{print $3}' | sort)
+  all_volgroups=$(grep -v "PVG Name" /tmp/sysinfo.$$.vgout | \
+     grep "VG Name" | awk '{print $3}' | sort)
+  all_logvols=$(grep "LV Name" /tmp/sysinfo.$$.vgout | awk '{print $3}' | sort)
+  #Debug "all_volgroups=\n$all_volgroups"
+  #Debug "all_logvols=\n$all_logvols"
+  
+  print -n "scanning volume groups "
+  for volgroup in ${all_volgroups}
+  do
+    Debug "Volumegroup = $volgroup"
+    vgdisplay $volgroup > /tmp/sysinfo.$$.volgroup 2>&1
+    #Debug "vgdisplay=\n`cat /tmp/sysinfo.$$.volgroup`"
+    ((vgcount=vgcount + 1))
+    CURLV=$(grep "Cur LV" /tmp/sysinfo.$$.volgroup | awk '{print $3}')
+    CURPV=$(grep "Cur PV" /tmp/sysinfo.$$.volgroup | awk '{print $3}')
+    AllocPe=$(grep "Alloc PE" /tmp/sysinfo.$$.volgroup | awk '{print $3}')
+    FreePe=$(grep "Free PE" /tmp/sysinfo.$$.volgroup | awk '{print $3}')
+    TotalPe=$(grep "Total PE" /tmp/sysinfo.$$.volgroup | awk '{print $3}')
+    PeSize=$(grep "PE Size" /tmp/sysinfo.$$.volgroup | awk '{print $4}')
+    ((AllocMb = AllocPe * PeSize))
+    ((FreeMb = FreePe * PeSize))
+    ((TotalMb = TotalPe * PeSize))
+    ((TotalAllocMb = TotalAllocMb + AllocMb))
+    ((TotalFreeMb = TotalFreeMb + FreeMb))
+    ((SystemTotalMb = SystemTotalMb + TotalMb))
+    Debug "  Physical Extent Size = ${PeSize}"
+    Debug "  Number of Allocated Physical Extents = ${AllocPe}"
+    Debug "  Free Physical Extents = ${FreePe}"
+    Debug "  Total Physical Extents = ${TotalPe}"
+    Debug "  Allocated Mb = ${AllocMb}"
+    Debug "  Free Mb = ${FreeMb}"
+    Debug "  Total Mb = ${TotalMb}"
+    Debug "  Total Allocated Mb = ${TotalAllocMb}"
+    Debug "  Total Free Mb = ${TotalFreeMb}"
+    Debug "  System Total Mb = ${SystemTotalMb}"
+    print -n "."
+    print -n "${volgroup}${CURLV}${CURPV}${PeSize}" >> /tmp/sysinfo.$$.vginfos
+    print    "${AllocMb}${FreeMb}${TotalMb}" >> /tmp/sysinfo.$$.vginfos
+  done
+  print  
+  Debug "Checking for vgcount = maxvgs"
+  if [[ -z $maxvgs ]]
+  then
+    maxvgs=$(echo 'maxvgs/D'|adb -k $kernel /dev/kmem \
+             | tail -1 | awk '{print $2}')
+  fi
+  Debug " vgcount = $vgcount"
+  Debug " maxvgs = $maxvgs"
+  if ((vgcount == maxvgs))
+  then
+    if ((! (($exit_code)) ))
+    then
+      exit_code=${WARN}
+    fi
+    print "WARNING (${sysname}): number of volume groups is at maximum."\
+           >> /tmp/sysinfo.$$.errwarn
+  fi
+  
+# now check for a cfg backup file for each volume group.
+
+  print -n "scanning config files "
+  Debug "Checking vg config files"
+  for volgroup in ${all_volgroups}
+  do
+    Debug "  volgroup ${volgroup}"
+    vg=$(echo ${volgroup} | awk -F/ '{print $3}')
+    print -n "."
+    if [ -f /etc/lvmconf/${vg}.conf ]
+    then
+      # this is a kludge. if file is less than 6 months old then 
+      # ls -l prints the time, so scan for a colon.
+      ls -l /etc/lvmconf/${vg}.conf | awk '{print $8}' | grep ":" > /dev/null
+      if (($?))
+      then
+        if ((! (($exit_code)) ))
+        then
+          exit_code=${WARN}
+        fi
+        print "WARNING (${sysname}): vgconfig file > 6 months old for /etc/lvmconf/${vg}.conf"\
+               >> /tmp/sysinfo.$$.errwarn
+      fi
+    else
+      if ((! (($exit_code)) ))
+      then
+        exit_code=${WARN}
+      fi
+      print -n "WARNING (${sysname}): no config " >> /tmp/sysinfo.$$.errwarn
+      print    "file found for volume group ${vg}." >> /tmp/sysinfo.$$.errwarn
+      if ((! (($exit_code)) ))
+      then
+        exit_code=${WARN}
+      fi
+    fi
+  done
+  print  ""
+  f_display_file /tmp/sysinfo.$$.novgcfg 
+  print    "" >> /tmp/sysinfo.$$.vginfoh
+  print    " Volume               Logical  Physical  Extent   MBs of Physical Space" >> /tmp/sysinfo.$$.vginfoh
+  print    " Group                Volumes  Volumes  Size(MB)  Alloc    Free   Total"  >> /tmp/sysinfo.$$.vginfoh
+  print    " ---------            -------  --------  ------   -----    ----   -----"  >> /tmp/sysinfo.$$.vginfoh
+  print    "                                                  =====    ====   =====" >> /tmp/sysinfo.$$.vginfot
+  print -n "                                        Totals " >> /tmp/sysinfo.$$.vginfot
+  print     "${TotalAllocMb}${TotalFreeMb}${SystemTotalMb}" >> /tmp/sysinfo.$$.vginfot
+  cat /tmp/sysinfo.$$.vginfo? > /tmp/sysinfo.$$.vginfod
+  f_display_file /tmp/sysinfo.$$.vginfod
+
+} # end of f_get_volume_group_data
+
+#===================================================================
+# f_get_logical_volume_data
+#        This function uses lvdisplay to scan logical volumes.
+#        It retrieves information about the logvol and also checks
+#        for stale mirrors (if used).
+#===================================================================
+function f_get_logical_volume_data
+{
+  Debug "Beginning LOGICAL DISK check."
+  # first print out header information
+  
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.lvinfoh + print "" >> /tmp/sysinfo.$$.lvinfoh + print "

" >> /tmp/sysinfo.$$.lvinfoh + print "

TOP

" >> /tmp/sysinfo.$$.lvinfoh + print "" >> /tmp/sysinfo.$$.lvinfoh + print "Logical Volume And Extent Data

" >> /tmp/sysinfo.$$.lvinfoh + print "
"           >> /tmp/sysinfo.$$.lvinfoh
+  else
+    print                                     >> /tmp/sysinfo.$$.lvinfoh
+    print  "LOGICAL VOLUME AND EXTENT DATA"   >> /tmp/sysinfo.$$.lvinfoh  
+    print  "=============================="   >> /tmp/sysinfo.$$.lvinfoh
+  fi
+  Debug "  calling check_if_scan_done"
+  check_if_scan_done lvm_scan
+  
+  print -n "scanning logical volumes "
+  if [[ ! -f /tmp/sysinfo.$$.vgout ]]
+  then
+    vgdisplay -v > /tmp/sysinfo.$$.vgout 2>&1
+    all_volgroups=$(grep "VG Name" /tmp/sysinfo.$$.vgout | awk '{print $3}' | sort)
+    all_logvols=$(grep "LV Name" /tmp/sysinfo.$$.vgout | awk '{print $3}' | sort)
+  fi
+  for logvol in ${all_logvols}
+  do
+    Debug "lvdisplay of ${logvol}"
+    lvol_major=$(ls -l $logvol | awk '{print $5}')
+    lvol_minor=$(ls -l $logvol | awk '{print $6}')
+    Debug "  major= $lvol_major minor=$lvol_minor"
+    lvdisplay -v ${logvol} > /tmp/sysinfo.$$.logical 2>&1
+    STATUS=$(grep "LV Status" /tmp/sysinfo.$$.logical | awk '{print $3}')
+    LVSize=$(grep "LV Size" /tmp/sysinfo.$$.logical | awk '{print $4}')
+    LogicalExtents=$(grep "Current LE" /tmp/sysinfo.$$.logical \
+                  | awk '{print $3}')
+    StaleExtents=$(grep stale /tmp/sysinfo.$$.logical | wc -l)
+    MirrorCopies=$(grep "Mirror copies" /tmp/sysinfo.$$.logical \
+                  | awk '{print $3}')
+    Consistency=$(grep "Consistency Recovery" /tmp/sysinfo.$$.logical \
+                  | awk '{print $3}')
+  
+  
+    ((total_l_mb = total_l_mb + LVSize))
+    ((MirrorMb = LVSize * MirrorCopies))
+    ((TotalMirrorMb = TotalMirrorMb + MirrorMb))
+    
+  # check to make sure lvol has extents allocated to it
+    if (( $LogicalExtents > 0 ))                 
+    then
+### Changed 6/15/99 J.Semroc - grep for lvol1 would also match lvol10, lvol11...
+###   MOUNT=$(cat /etc/mnttab | grep ${logvol}  | cut -f 2 -d" ")
+      MOUNT=$(cat /etc/mnttab | grep "${logvol} " | cut -f 2 -d" ")
+### end of Change
+      if [[ ${swap_devs} = *${logvol}* ]]
+      then
+        MOUNT="(swapdisk)"
+      fi
+      ((lcount=lcount + 1))
+      if (( ${StaleExtents} > 0 ))        # we found stale extents
+      then
+        Debug " Found ${StaleExtents} STALE extents on ${logvol}!"
+        stale=1
+        ((StaleMB = (LVSize / LogicalExtents) * StaleExtents ))
+        ((TotalStaleMb = TotalStaleMb + StaleMB))
+        ((total_stale = $total_stale + $StaleExtents))
+      fi                                # end of stale extents
+    else                                # no extents allocated
+      if ((! (($exit_code)) ))
+      then
+        exit_code=$WARN
+      fi
+      zero_length=1
+      print -n "\nWARNING (${sysname}): Detected logical " >> /tmp/sysinfo.$$.errwarn
+      print "volume (${logvol}) with no extents!\n" >> /tmp/sysinfo.$$.errwarn
+    fi                                # end of check for allocated extents
+    Debug "  STATUS= ${STATUS}"
+    Debug "  LVSize= ${LVSize}"
+    Debug "  LogicalExtents = ${LogicalExtents}"
+    Debug "  StaleExtents = ${StaleExtents}"
+    Debug "  StaleMb= $StaleMB"
+    Debug "  TotalStaleMb= $TotalStaleMb "
+    Debug "  TotalMb checked= $total_l_mb"
+
+# now let's print out the results.
+    print -n "."
+    logvold=${logvol}                        # for display purposes only.
+    print "${logvold}${MOUNT}"               >> /tmp/sysinfo.$$.lvinfos
+    #print "${LogicalExtents}${StaleExtents}" >> /tmp/sysinfo.$$.lvinfos
+    #print "${MirrorCopies}${Consistency}"    >> /tmp/sysinfo.$$.lvinfos
+  done                                
+# end of loop for all log vols
+# now print out any errors or warnings.
+  f_display_file /tmp/sysinfo.$$.nolvext 
+# print    "" >> /tmp/sysinfo.$$.lvinfoh
+  print    "                                     "  >> /tmp/sysinfo.$$.lvinfoh
+  print -n " Volume Name                            " >> /tmp/sysinfo.$$.lvinfoh
+  print    "Mounted File System"  >> /tmp/sysinfo.$$.lvinfoh
+  print -n " --------------                         " >> /tmp/sysinfo.$$.lvinfoh
+  print -- "--------------------"  >> /tmp/sysinfo.$$.lvinfoh
+  print    "" >> /tmp/sysinfo.$$.lvinfos
+  cat /tmp/sysinfo.$$.lvinfo? > /tmp/sysinfo.$$.lvinfod
+  f_display_file /tmp/sysinfo.$$.lvinfod 
+
+  print "\nAllocation" > /tmp/sysinfo.$$.lvol_legend
+  print -n "  ns    non-strict                " >> /tmp/sysinfo.$$.lvol_legend
+  print    "PVG-s  PVG-strict                " >> /tmp/sysinfo.$$.lvol_legend
+  print -n "  ns-c  non-strict/contiguous     " >> /tmp/sysinfo.$$.lvol_legend
+  print    "PVG-c  PVG-strict/contiguous" >> /tmp/sysinfo.$$.lvol_legend
+  print -n "  s     strict                    " >> /tmp/sysinfo.$$.lvol_legend
+  print    "PVG-d  PVG-strict/distributed    " >> /tmp/sysinfo.$$.lvol_legend
+  print -n "  s-c   strict/contiguous         " >> /tmp/sysinfo.$$.lvol_legend
+  print    "PVG-p  PVG-strict/partially-distributed" >> /tmp/sysinfo.$$.lvol_legend
+  print "" >> /tmp/sysinfo.$$.lvol_legend
+
+
+# display using data from batch lvm_scan
+  print    "" > /tmp/sysinfo.$$.lvinfoh
+  print -n "                                 "  >> /tmp/sysinfo.$$.lvinfoh
+  print    "                                  Bad" >> /tmp/sysinfo.$$.lvinfoh
+  print -n "                                 "  >> /tmp/sysinfo.$$.lvinfoh
+  print    "  Size Stripes    Mirrors    LV   Block" >> /tmp/sysinfo.$$.lvinfoh
+  print -n " Volume Name                     "  >> /tmp/sysinfo.$$.lvinfoh
+  print    "  (MB)  # Size    #  Const  State Reloc  Alloc" >> /tmp/sysinfo.$$.lvinfoh
+  print -n " --------------                  "  >> /tmp/sysinfo.$$.lvinfoh
+  print    " ----- -------   ---------  ----- -----  -----"  >> /tmp/sysinfo.$$.lvinfoh
+  f_display_file /tmp/sysinfo.$$.lvinfoh
+  f_display_file $lvol_out_file
+  f_display_file /tmp/sysinfo.$$.lvol_legend
+  if (($BATCH))
+  then
+    print
+  fi
+
+}         # end of f_get_logical_volume_data
+
+
+#===================================================================
+# f_logical_to_physical
+#        This function produces a cross reference of physical disks
+#        for each logical volume.
+#===================================================================
+function f_logical_to_physical
+{
+  Debug "Beginning LOGICAL TO PHYSICAL Mapping."
+  
+  if [[ ! -f /tmp/sysinfo.$$.vgout ]]
+  then
+    Debug "/tmp/sysinfo.$$.vgout not found....building."
+    vgdisplay -v > /tmp/sysinfo.$$.vgout 2>&1
+    all_logvols=$(grep "LV Name" /tmp/sysinfo.$$.vgout | awk '{print $3}' |sort)
+  fi
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.l2p + print "" >> /tmp/sysinfo.$$.l2p + print "

" >> /tmp/sysinfo.$$.l2p + print "

TOP

" >> /tmp/sysinfo.$$.l2p + print "" >> /tmp/sysinfo.$$.l2p + print "Logical Volume To Physical Disk Mapping

" >> /tmp/sysinfo.$$.l2p + print "
"             >> /tmp/sysinfo.$$.l2p
+  else
+    print    "" >> /tmp/sysinfo.$$.l2p
+    print    "LOGICAL VOLUME TO PHYSICAL DISK MAPPING                 " >> /tmp/sysinfo.$$.l2p
+    print    "=========================================================" >> /tmp/sysinfo.$$.l2p
+  fi
+  print "Logical Volume" >> /tmp/sysinfo.$$.l2p
+  print " extents  Primary disk     Mirror Disk 1    Mirror Disk 2" >> /tmp/sysinfo.$$.l2p
+  print -- "---------------------------------------------------------" >> /tmp/sysinfo.$$.l2p
+  print -n "generating disk mappings "
+
+  for logvol in ${all_logvols}
+  do
+    Debug "  scanning ${logvol}"
+    lvdisplay -v ${logvol} > /tmp/sysinfo.$$.logical 2>&1
+    PhysicalDisks=$(awk '$1 ~ /\/dev\/dsk\/.*/ {printf "%s\n",$1}' \
+                     /tmp/sysinfo.$$.logical \
+                     | sed -e 's/\/dev\/dsk\///' | sort)
+    # output physical disk data for each logical volume
+    print    "${logvol}    " >> /tmp/sysinfo.$$.l2p
+#   print -n "     Disks = " >> /tmp/sysinfo.$$.l2p
+
+# count the number of physical disks found.
+    diskcount=0
+    for disk in ${PhysicalDisks}
+    do
+      ((diskcount = diskcount + 1))
+      Debug "    disk = $disk"
+    done
+    Debug "    found $diskcount physical disks"
+    lvdisplay -v $logvol | sed '1,/   LE/d' | awk '{print $2, $5, $8}' \
+                     | sort | grep "dev" | uniq -c | awk \
+                     '{printf "%6s %18s %16s %16s\n",$1,$2,$3,$4}' \
+                     >> /tmp/sysinfo.$$.l2p
+#   print "" >> /tmp/sysinfo.$$.l2p
+    print -n "."
+  done
+  print "" >> /tmp/sysinfo.$$.l2p
+  f_display_file /tmp/sysinfo.$$.l2p 
+  print  ""
+
+}        # end of f_logical_to_physical
+
+
+#===================================================================
+# f_filesystem_check
+#        This function checks mounted filesystems and reports 
+#        capcity information. It prints warnings if greater than
+#        95% full.
+#===================================================================
+
+function f_filesystem_check
+{
+  Debug "Beginning FILE SYSTEM check."
+
+  # first print out headers
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.bdf_outh + print "" >> /tmp/sysinfo.$$.bdf_outh + print "

" >> /tmp/sysinfo.$$.bdf_outh + print "

TOP

" >>/tmp/sysinfo.$$.bdf_outh + print "" >> /tmp/sysinfo.$$.bdf_outh + print "File System Data

" >> /tmp/sysinfo.$$.bdf_outh + print "
" >> /tmp/sysinfo.$$.bdf_outh
+  else
+    print    "" >> /tmp/sysinfo.$$.bdf_outh
+    print    "FILE SYSTEM DATA" >> /tmp/sysinfo.$$.bdf_outh
+    print    "================" >> /tmp/sysinfo.$$.bdf_outh
+  fi
+  print -n "scanning filesystems "
+
+  typeset -R10 kbytes used avail iused ifree
+  typeset -R5 percent_used
+  mnttab=$(cat /etc/mnttab | grep /dev  | awk '{printf "%s\n", $2}')
+  num_fs=$(bdf -il 2>&1 | grep "/dev/" | wc -l)
+  ((num_fs = num_fs -1))
+  Debug "Found $num_fs mounted file systems"
+# bdf -i | tail -${num_fs} > /tmp/sysinfo.$$.bdf_data 2>&1
+  for mounted in ${mnttab}
+  do
+    bdf -i ${mounted} 2>&1 | tail -1 > /tmp/sysinfo.$$.bdf_data 2>&1
+    if ( grep "No such file" /tmp/sysinfo.$$.bdf_data >/dev/null 2>&1 )
+    then 
+      Debug " bdf reports No such file or directory on ${mounted}"
+      print "WARNING (${sysname}): No such file or directory for ${mounted}" >>  /tmp/sysinfo.$$.errwarn
+    else
+    fs_type=$(cat /etc/mnttab | grep " ${mounted} " | awk '{printf "%s\n", $3}')
+    Debug "filesys = ${mounted}  fs_type = ${fs_type}"
+    if [[ $fs_type = vxfs ]]
+    then
+      mnt_lvol=$(cat /etc/mnttab | grep " ${mounted} " | awk '{printf "%s\n", $1}')
+      fs_ver=$(fstyp -v ${mnt_lvol} 2>&1 | grep version | awk '{printf "%s\n", $2}')
+      if [[ -f ${mounted}/lost+found/.fsadm ]]
+      then
+      vxfs_defrag=$(fsadm -F vxfs -E ${mounted} | grep \
+                  "extents 64 blks or larger" | awk '{print $NF}')
+      ((vxfs_frag = 100 - vxfs_defrag))
+      vxfs_pct="%"
+      else
+        Debug " ${mounted}/lost+found/.fsadm not found - no frag check"
+        no_lost=1
+        vxfs_frag="**"
+        vxfs_pct="*"
+      fi
+      Debug "fs_ver = ${fs_ver} vxfs_frag = ${vxfs_frag}"
+      if ( [[ $osmajor = 10 ]] && [[ $osminor > 10 ]] ) || [[ $osmajor = 11 ]]
+      then
+        if [[ $fs_ver < 3 ]]
+        then
+          Debug "Found vxfs version $fs_ver"
+          print "WARNING (${sysname}): Version ${fs_ver} of vxfs found on ${mounted}" >> /tmp/sysinfo.$$.errwarn
+        fi
+      fi
+    fi
+    Debug "  `cat /tmp/sysinfo.$$.bdf_data`"
+    kbytes=$(awk '{if (NF == 9) print $2; else print $1}' /tmp/sysinfo.$$.bdf_data) 
+    used=$(awk '{if (NF == 9) print $3; else print $2}' /tmp/sysinfo.$$.bdf_data)
+    if [[ $fs_type  != "cdfs" ]]
+    then
+      avail=$(awk '{if (NF == 9) print $4; else print $3}' /tmp/sysinfo.$$.bdf_data)
+      iused=$(awk '{if (NF == 9) print $6; else print $5}' /tmp/sysinfo.$$.bdf_data)
+      ifree=$(awk '{if (NF == 9) print $7; else print $6}' /tmp/sysinfo.$$.bdf_data)
+      #((percent_used = (used * 100) / (used + avail) ))
+      percent_used=$(echo $used $avail | \
+        awk '{ used = $1
+               avail = $2
+               pct_used =  ($1 * 100) / ($1 + $2)
+               printf("%d", pct_used)
+              } ' )
+
+      if (($percent_used > 95)) && [[ $fs_type  != "cdfs" ]]
+      then
+        if ((! (($exit_code)) ))
+        then
+          exit_code=${WARN}
+        fi
+        print "WARNING (${sysname}): ${mounted} has less than 5% free space left!" >> /tmp/sysinfo.$$.errwarn
+      fi
+    else #must be a cdrom, so don't calculate free space
+      avail=0
+      iused="-"
+      ifree="-"
+      percent_used="-"
+    fi
+    if [[ $fs_type != vxfs ]]
+    then
+      vxfs_frag="n/"
+      vxfs_pct="a"
+    fi
+    print "${mounted}" >> /tmp/sysinfo.$$.bdf_outs
+#   print "              ${fs_type} ${kbytes}${used}${avail}${percent_used}${iused}${ifree}" >> /tmp/sysinfo.$$.bdf_outs
+    print "              ${fs_type} ${kbytes}${used}${avail}${percent_used}     ${vxfs_frag}${vxfs_pct}" >> /tmp/sysinfo.$$.bdf_outs
+    print -n "."
+    fi
+  done
+  print "" >> /tmp/sysinfo.$$.bdf_outs
+  print -n "Mounted                               " >> /tmp/sysinfo.$$.bdf_outh
+  print -- "                    Extents" >> /tmp/sysinfo.$$.bdf_outh
+  print -n "Filesystems   Type     Kbytes      Used     Avail" >> /tmp/sysinfo.$$.bdf_outh
+# print    "   %      Iused     Ifree" >> /tmp/sysinfo.$$.bdf_outh
+  print    "   %    Fragmented" >> /tmp/sysinfo.$$.bdf_outh
+  print -n " ----------   ----     ------    ------    ------" >> /tmp/sysinfo.$$.bdf_outh
+  print -- "  ---   ----------" >> /tmp/sysinfo.$$.bdf_outh
+  cat /tmp/sysinfo.$$.bdf_out? > /tmp/sysinfo.$$.bdf_outd
+  if (( ${no_lost} == 1 ))
+  then
+    print -n "***  could not get fsadm lock - " >> /tmp/sysinfo.$$.bdf_outd
+    print "lost+found/.fsadm not found" >> /tmp/sysinfo.$$.bdf_outd
+    print "" >> /tmp/sysinfo.$$.bdf_outd
+  fi
+  f_display_file /tmp/sysinfo.$$.bdf_outd 
+  f_display_file /tmp/sysinfo.$$.bdf_warn 
+  print ""
+
+}        # end of f_filesystem_check
+
+#===================================================================
+# f_disk_capacity
+#        This function displays total disk, group, and lvol capacities.
+#        The data comes from the logical, physical, & volume functions.
+#        Therefore, this function does not stand alone. It must be run
+#        with the l, p, & v options.
+#===================================================================
+function f_disk_capacity
+{
+  Debug "Beginning DISK CAPACITY calculations."
+  if (($HTML))
+  then
+    print "
" >> /tmp/sysinfo.$$.capacity + print "" >> /tmp/sysinfo.$$.capacity + print "

" >> /tmp/sysinfo.$$.capacity + print "

TOP

" >>/tmp/sysinfo.$$.capacity + print "" >> /tmp/sysinfo.$$.capacity + print "Disk Capacity Data

" >> /tmp/sysinfo.$$.capacity + print "
" >> /tmp/sysinfo.$$.capacity
+  else
+    print "DISK CAPACITY DATA" >> /tmp/sysinfo.$$.capacity
+    print "==================" >> /tmp/sysinfo.$$.capacity
+  fi
+  ((unused_cap = total_p_mb - TotalAllocMb))
+  ((OtherMb = TotalAllocMb - total_l_mb - TotalMirrorMb))
+  print "Logical Volume Space  =    $total_l_mb MB" >> /tmp/sysinfo.$$.capacity
+  print "Mirror Space          =    $TotalMirrorMb MB" >> /tmp/sysinfo.$$.capacity
+  print "Other Space Allocated =    $OtherMb MB" >> /tmp/sysinfo.$$.capacity
+  print "                        -----------" >> /tmp/sysinfo.$$.capacity
+  print "Total Disk Allocated  =    $TotalAllocMb MB" >> /tmp/sysinfo.$$.capacity
+  print "Unallocated Disk      =    $unused_cap MB" >> /tmp/sysinfo.$$.capacity
+  print "                        ===========" >> /tmp/sysinfo.$$.capacity
+  print "Total Physical Disk   = $total_p_mb MB\n" >> /tmp/sysinfo.$$.capacity
+
+  print "Checked:" >> /tmp/sysinfo.$$.capacity
+  print "${pcount} physical volumes" >> /tmp/sysinfo.$$.capacity
+  print "${vgcount} volume groups" >> /tmp/sysinfo.$$.capacity
+  print "${lcount} logical volumes" >> /tmp/sysinfo.$$.capacity
+
+  Debug "  found ${pcount} physical volumes"
+  Debug "  found ${vgcount} volume groups"
+  Debug "  found ${lcount} logical volumes"
+  
+  if  ((${stale}))
+  then
+    Debug "found ${total_stale} STALE extents"
+    Debug "  calculating re-syncing time"
+    exit_code=${SYS_ERROR}
+    print "STALE extents detected!" >> /tmp/sysinfo.$$.capacity
+    print "  check error listing for more details." >> /tmp/sysinfo.$$.capacity
+    print -n "\n\nERROR:${sysname}: ${total_stale}" >> /tmp/sysinfo.$$.errwarn
+    print    " stale extents detected.\n" >> /tmp/sysinfo.$$.errwarn
+    print -n "Estimated time to re-sync ${total_stale}" >> /tmp/sysinfo.$$.errwarn
+    print    " stale extents is" >> /tmp/sysinfo.$$.errwarn
+    if ((${TotalStaleMb} < 100))
+    then
+      print " less than 1 minute." >> /tmp/sysinfo.$$.errwarn
+      Debug " less than 1 minute" 
+    else
+      ((TIME = TotalStaleMb / 100))
+      ((HOURS = TIME /60))
+      ((MINUTES = TIME % 60))
+      print " ${HOURS} hours and ${MINUTES} minutes." >> /tmp/sysinfo.$$.errwarn
+      Debug " ${TIME} total minutes or" 
+      Debug "     ${HOURS} hours and ${MINUTES} minutes" 
+    fi
+    print >> /tmp/sysinfo.$$.errwarn
+  else
+    print "with no stale extents detected.\n"   >> /tmp/sysinfo.$$.capacity
+    Debug "No stale extents detected"
+  fi
+  f_display_file /tmp/sysinfo.$$.capacity
+
+}                 # end of f_disk_capacity
+
+
+#===================================================================
+# f_check_root
+#        This function checks to see if the user is root.
+#===================================================================
+function f_check_root
+{
+  id | grep '(root)' > /dev/null
+  if (($?))
+  then
+    print "\nYou must be super-user to run ${script}.\n"
+    exit ${ERROR}
+  fi
+}                # end of check_root
+
+#===================================================================
+# f_check_hpux
+#        This function checks to see if running on HP-UX
+#===================================================================
+function f_check_hpux
+{
+  uname -s | grep HP-UX > /dev/null
+  if (($?))
+  then
+    print "\nThis utility is only supported on HP-UX systems!\n"
+    exit ${ERROR}
+  fi
+}                # end of check_hpux
+
+#===================================================================
+# f_extract_errors
+#        This function extract WARNINGS & ERRORS from the logfile
+#===================================================================
+function f_extract_errors
+{
+  if [[ -f /tmp/sysinfo.$$.errwarn ]]
+  then
+    if (($HTML))
+    then
+      print "
" >> /tmp/sysinfo.$$.errwarn.header + print "" >> /tmp/sysinfo.$$.errwarn.header + print "

" >> /tmp/sysinfo.$$.errwarn.header + print "

" >> /tmp/sysinfo.$$.errwarn.header + print "TOP

" >> /tmp/sysinfo.$$.errwarn.header + print "" >> /tmp/sysinfo.$$.errwarn.header + print "Summary of Errors/Warnings

" >> /tmp/sysinfo.$$.errwarn.header + print "
"   >> /tmp/sysinfo.$$.errwarn.header
+    else
+      print ""                                >> /tmp/sysinfo.$$.errwarn.header
+      print "ERROR/WARNING SUMMARY"           >> /tmp/sysinfo.$$.errwarn.header
+      print "====================="           >> /tmp/sysinfo.$$.errwarn.header
+    fi
+
+    grep  -e WARNING -e ERROR /tmp/sysinfo.$$.errwarn > /dev/null 2>&1
+    if [ $? -eq 1 ]
+    then
+      Debug "No errors/warnings found."
+      if (($BATCH))
+      then
+        print "No ERRORS or WARNINGS found."
+      fi
+      print "($sysname): No errors/warnings found." >> /tmp/sysinfo.$$.errwarn
+    else
+      Debug "Found errors/warnings, displaying /tmp/sysinfo.$$.errwarn"
+      if (($BATCH))
+      then
+        print "Errors and/or Warnings were found." 
+        print "Please check output file ${LOGFILE}."
+      fi
+    fi
+    print "" >> /tmp/sysinfo.$$.errwarn
+    f_display_file /tmp/sysinfo.$$.errwarn.header
+    f_display_file /tmp/sysinfo.$$.errwarn
+  else
+    print "Could not find /tmp/sysinfo.$$.errwarn"
+  fi
+}
+
+function print_header
+{
+#print
+#print " ****             *****"
+#print "*                   *                       "
+#print "*     *   *  ***    *   **   * ****  **** "
+#print " ****  * *  *       *   * *  * *    *    *"
+#print "     *  *    ***    *   *  * * ***  *    *"
+#print "     *  *       *   *   *   ** *    *    *"
+#print " ****   *    ***  ***** *    * *     ****"
+#print
+print
+print " @@@@             @@@@@"
+print "@                   @                       "
+print "@     @   @  @@@    @   @@   @ @@@@  @@@@ "
+print " @@@@  @ @  @       @   @ @  @ @    @    @"
+print "     @  @    @@@    @   @  @ @ @@@  @    @"
+print "     @  @       @   @   @   @@ @    @    @"
+print " @@@@   @    @@@  @@@@@ @    @ @     @@@@"
+print
+}
+#===================================================================
+# BEGIN MAIN CODE
+#===================================================================
+typeset -fx lvm_scan
+typeset -fx sam_scan
+typeset -fx io_scan
+typeset -fx f_query_sam
+sysname=$(hostname)
+where=`dirname ${0}`
+f_check_hpux
+f_check_root
+get_args $*
+if (($BATCH))
+then
+  #print "\n${script}  ${version} by Scott Truesdale\n"
+  print_header
+  print "Author:  Scott Truesdale"
+  print "Version: ${version}\n"
+  if (($HTML))
+  then
+    print ""                                 >> $LOGFILE
+    print ""                                 >> $LOGFILE_INDEX
+    print ""                                 >> $LOGFILE_MAIN
+    print "Sysinfo for ${sysname}"        >> $LOGFILE
+    print "Sysinfo (Index) for ${sysname}" >> $LOGFILE_INDEX
+    print "Sysinfo (Main) for ${sysname}" >> $LOGFILE_MAIN
+    print ""                                      >> $LOGFILE
+    print "> $LOGFILE
+    print "BORDERCOLOR='darkblue' FRAMESPACING='2'"      >> $LOGFILE
+    print "BORDER='2'>"                                  >> $LOGFILE
+    print "> $LOGFILE
+    print "NAME='IndexFrame' SCROLLING='NO'>"            >> $LOGFILE
+    print "> $LOGFILE
+    print "NAME='MainFrame'"                             >> $LOGFILE
+    print "SCROLLING='AUTO'>"                  >> $LOGFILE
+    print "<BODY BGCOLOR=lightblue>"                     >> $LOGFILE
+    print "</HEAD><BODY BGCOLOR=lightblue>"              >> $LOGFILE_INDEX
+    print "</HEAD><BODY BGCOLOR=lightblue>"              >> $LOGFILE_MAIN
+    print "<CENTER>"                                     >> $LOGFILE
+    print "<A name='TOP'></A>"                           >> $LOGFILE
+    print "<FONT SIZE=6 COLOR=darkblue>"                 >> $LOGFILE
+    print "${script} ${version} "                        >> $LOGFILE
+    print "by Scott Truesdale</FONT><BR>"                >> $LOGFILE
+    print "<FONT SIZE=6>Configuration Data for"          >> $LOGFILE
+    print "<FONT COLOR=red>${sysname}</FONT></FONT><BR>" >> $LOGFILE
+    print "<FONT SIZE=3>Collected on `date`.</FONT><BR>" >> $LOGFILE
+    print "<A HREF='#System'>System</A>"                 >> $LOGFILE
+    print "<A HREF='#Kernel'>Kernel</A>"                 >> $LOGFILE
+    print "<A HREF='#Network'>Network</A>"               >> $LOGFILE
+    print "<A HREF='#File'>File System</A>"              >> $LOGFILE
+    print "<BR>"                                         >> $LOGFILE
+    print "<A HREF='#IO'>IO Configuration</A>"           >> $LOGFILE
+    print "<A HREF='#Physical'>Physical Disks</A>"       >> $LOGFILE
+    print "<A HREF='#Pmap'>Physical Mapping</A>"         >> $LOGFILE
+    print "<A HREF='#Volume'>Volume Groups</A>"          >> $LOGFILE
+    print "<BR>"                                         >> $LOGFILE
+    print "<A HREF='#Logical'>Logical Disks</A>"         >> $LOGFILE
+    print "<A HREF='#Lmap'>Logical Mapping</A>"          >> $LOGFILE
+    print "<A HREF='#Capacity'>Disk Capacity</A>"        >> $LOGFILE
+    print "<A HREF='#Software'>Software List</A>"        >> $LOGFILE
+    print "<BR>"                                         >> $LOGFILE
+    print "<A HREF='#SYSACCESS'>Security Check</A>"      >> $LOGFILE
+    print "<A HREF='#DIAGNOSTICS'>Diagnostic Settings</A>" >> $LOGFILE
+    print "<A HREF='#LOGFILES'>System Logfiles</A>"      >> $LOGFILE
+    print "<A HREF='#ErrWarn'>Errors/Warnings</A>"       >> $LOGFILE
+    if (($PASS))
+    then
+      print "<BR>"                                       >> $LOGFILE
+      print "<A HREF='#SAP'>SAP R/3 Info</A>"            >> $LOGFILE
+    fi
+    print "</CENTER>"                                    >> $LOGFILE
+    print "<CENTER>"                                     >> $LOGFILE_INDEX
+    print "<A name='TOP'></A>"                           >> $LOGFILE_INDEX
+    print "<FONT SIZE=6 COLOR=darkblue>"                 >> $LOGFILE_INDEX
+    print "${script} ${version} "                        >> $LOGFILE_INDEX
+    print "by Scott Truesdale</FONT><BR>"                >> $LOGFILE_INDEX
+    print "<FONT SIZE=6>Configuration Data for"          >> $LOGFILE_INDEX
+    print "<FONT COLOR=red>${sysname}</FONT></FONT><BR>" >> $LOGFILE_INDEX
+    print "<FONT SIZE=3>Collected on `date`.</FONT><BR>" >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#System' TARGET='MainFrame'>System</A>"                 >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#Kernel' TARGET='MainFrame'>Kernel</A>"                 >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#Network' TARGET='MainFrame'>Network</A>"               >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#File' TARGET='MainFrame'>File System</A>"              >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#IO' TARGET='MainFrame'>IO Configuration</A>"           >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#Physical' TARGET='MainFrame'>Physical Disks</A>"       >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#Pmap' TARGET='MainFrame'>Physical Mapping</A>"         >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#Volume' TARGET='MainFrame'>Volume Groups</A>"          >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#Logical' TARGET='MainFrame'>Logical Disks</A>"         >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#Lmap' TARGET='MainFrame'>Logical Mapping</A>"          >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#Capacity' TARGET='MainFrame'>Disk Capacity</A>"        >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#Software' TARGET='MainFrame'>Software List</A>"        >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#SYSACCESS' TARGET='MainFrame'>Security Check</A>"      >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#DIAGNOSTICS' TARGET='MainFrame'>Diagnostic Settings</A>" >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#LOGFILES' TARGET='MainFrame'>System Logfiles</A>"      >> $LOGFILE_INDEX
+    print "<A HREF='${LOGFILE_MAIN_REL}#ErrWarn' TARGET='MainFrame'>Errors/Warnings</A>"       >> $LOGFILE_INDEX
+    if (($PASS))
+    then
+      print "<A HREF='${LOGFILE_MAIN_REL}#SAP' TARGET='MainFrame'>SAP R/3 Info</A>"            >> $LOGFILE_INDEX
+    fi
+    print "</CENTER>"                                    >> $LOGFILE_INDEX
+
+  else
+    print "\n${script} ${version} by Scott Truesdale\n" >> $LOGFILE
+    print "Configuration data for ${sysname}\ncollected on `date`\n" >> $LOGFILE
+  fi
+else
+  print_header
+  print "Author:  Scott Truesdale"
+  print "Version: ${version}\n"
+  print "Configuration data for ${sysname}\ncollected on `date`.\n" 
+fi
+touch /tmp/sysinfo.$$.errwarn
+#===================================================================
+# Begin PASS section
+#===================================================================
+if (($PASS))
+then
+  touch /tmp/sysinfo.$$.sapwarn
+  check_for_sap
+fi
+
+#===================================================================
+#  SYSTEM CHECK AND ROOT DATA 
+#===================================================================
+f_get_sys_type
+
+if (($SYSTEM))
+then
+  f_get_system_data
+fi
+#===================================================================
+# KERNEL DATA 
+#===================================================================
+if (($FULL_KERNEL)) || (($LITE_KERNEL))
+then
+  if (( ${osmajor} >= 10 ))
+  then
+    f_get_kernel_data
+  else
+    f_get_9x_kernel_data
+  fi
+fi
+
+#if (($SAMSCAN)) && (( ${osmajor} >= 10 ))
+#then
+#  f_display_sam_kernel_data
+#fi
+
+#===================================================================
+# NETWORK CARD DATA
+#===================================================================
+if (($NETWORK))
+then
+  f_get_network_data
+fi
+
+#===================================================================
+# FILE SYSTEM CHECK
+#===================================================================
+if (($FILESYSTEM))
+then
+  f_filesystem_check
+fi
+
+#===================================================================
+# IOSCAN CHECK
+#===================================================================
+if (($IOSCAN))
+then
+  f_get_ioscan_data
+fi
+
+#===================================================================
+# PHYSICAL DISK CHECK
+#===================================================================
+if (($PHYSICAL))
+then
+  f_get_physical_disk_data
+fi
+
+#===================================================================
+# VOLUME GROUP CHECK
+#===================================================================
+if (($VOLUMES)) 
+then
+  if (($lvm_installed))
+  then
+    f_get_volume_group_data
+  else
+    print "LVM must be installed to use this option."
+  fi
+fi
+
+#===================================================================
+# LOGICAL DISK CHECK
+#===================================================================
+if (($LOGICAL)) 
+then
+  if (($lvm_installed))
+  then
+    f_get_logical_volume_data
+  else
+    print "LVM must be installed to use this option."
+  fi
+fi
+
+#===================================================================
+# LOGICAL VOLUME TO PHYSICAL DISK MAPPING 
+#===================================================================
+# check which physical disks have this logvol on them
+if (($LMAP))
+then
+  if (($lvm_installed))
+  then
+    f_logical_to_physical
+  else
+    print "LVM must be installed to use this option."
+  fi
+fi
+
+#===================================================================
+# DISK CAPACITY TABLE
+#===================================================================
+# note that the CAPACITY flag cannot be set directly.
+# it is automatically enabled when either the -a or -lpv flags
+if (($CAPACITY))
+then
+  if (($lvm_installed))
+  then
+    f_disk_capacity
+  else
+    print "LVM must be installed to use this option."
+  fi
+fi
+
+#===================================================================
+# SOFTWARE LIST
+#===================================================================
+if (($SWLIST))
+then
+  sw_scan
+fi
+
+#===================================================================
+# Check system file/directory access and some security parms.
+#===================================================================
+if (($FILEACCESS))
+then
+  chk_sysaccess
+fi
+
+#===================================================================
+# Check to see if the system has diagnostics
+#===================================================================
+if (($DIAGNOSTICS))
+then
+  chk_diags
+  chk_ignite
+fi
+
+#===================================================================
+# Check System Logfiles
+#===================================================================
+
+if (($LOGFILES))
+then
+  chk_logfiles
+fi
+
+#===================================================================
+# Extract ERROR/WARNING messages
+#===================================================================
+f_extract_errors
+
+if (($PASS))
+then
+  f_display_file /tmp/sysinfo.$$.sap
+  print "\n\n" >> /tmp/sysinfo.$$.sapwarn
+  f_display_file /tmp/sysinfo.$$.sapwarn
+
+fi
+
+#===================================================================
+# Clean up end of HTML files if necessary
+#===================================================================
+
+if (($HTML))
+then
+  print "</BODY></HTML>" >> $LOGFILE_INDEX
+  print "</BODY></HTML>" >> $LOGFILE_MAIN
+  print "</BODY>" >> $LOGFILE
+  chmod 444 $LOGFILE_INDEX $LOGFILE_MAIN $LOGFILE
+fi
+
+#===================================================================
+# END OF SCRIPT - SO LET'S GET OUT OF HERE!
+#===================================================================
+Debug "exit_code = ${exit_code}" 
+exit ${exit_code}
+
diff --git a/clients/HP/bin/sysmodel b/clients/HP/bin/sysmodel
new file mode 100644
index 0000000..6def4b7
--- /dev/null
+++ b/clients/HP/bin/sysmodel
@@ -0,0 +1,230 @@
+#!/bin/ksh
+# Oslo Feb. 2 1995
+# sys_info 1.3, a hack by Ole Kristian Foss, HPNAS,
+# to display HP9000 model and the clock frequency of the CPU(s)
+# Version 1.0                                                 Oslo Jan. 25
+1995
+# Version 1.1 added call to the $SCHED_FILE.                  Oslo Jan. 25
+1995
+# Version 1.2 added the get_physmem function.                 Oslo Feb. 2
+1995
+# Version 1.3 added limited functionality for HP-UX 10.X.     Oslo Feb. 28
+1995
+# Version 1.4 more robust 10.X handling.                      Oslo Mar. 13
+1996
+#             This version should handle all cominations of
+#             HP-UX 9.X and 10.X as well as S700 and S800
+#
+#
+# Initialize variables:
+ADB="adb -k"
+ADB_CMD=""
+MODEL=""
+PA_INFO=""
+PA_RISC=""
+CPU_REV=""
+OS_REV=""
+VER="1.4"
+CORES=""
+PROG=`basename $0`
+SCHED_FILE="/usr/lib/sched.models"
+export PATH=/etc:/bin:/usr/bin
+typeset -R4 ID=""
+typeset -i FADB_OUT
+typeset -i MHZ
+typeset -i HZ
+typeset -i SPEED
+#
+function usage
+{
+        print -u2 "Usage: $PROG <-h|-m> [-v]"
+        exit 1
+}
+#
+function get_os_rev
+{
+        OS_REV=`uname -r| cut -f2 -d"."`
+        case $OS_REV in
+                09) CORES="/hp-ux /dev/kmem"
+                   if /bin/hp9000s700
+                   then
+                        ADB_CMD="mpproc_info+34/X"
+                   elif /bin/hp9000s800
+                   then
+                         ADB_CMD="mpproc_info+1E8/X"
+                   else
+                        echo "This machine is not supported by $PROG"
+                   exit 1
+                   fi ;;
+
+                10) CORES="/stand/vmunix /dev/kmem"
+                    ADB_CMD="_mpproc_info+270/X" ;;
+
+                 *) echo "$PROG does not support this version of HP-UX"
+                    exit 1 ;;
+        esac
+
+}
+function get_id
+{
+        ID=`echo $ADB_CMD | $ADB $CORES |  tail -1 | cut -d: -f 2`
+}
+#
+#
+function get_model
+{
+        case $ID in
+                "  40"|0040) MODEL="840" ;;
+                "  80"|0080) MODEL="825" ;;
+                "  A0"|00A0) MODEL="835/635" ;;
+                "  B0"|00B0) MODEL="845/645" ;;
+                "  C0"|00C0) MODEL="850" ;;
+                " 810"|0810) MODEL="855" ;;
+                " 820"|0820) MODEL="860" ;;
+                " 830"|0830) MODEL="865/870" ;;
+                1010) MODEL="822" ;;
+                1020) MODEL="832" ;;
+                1040) MODEL="842" ;;
+                1050) MODEL="852" ;;
+                1810) MODEL="890" ;;
+                1820) MODEL="891/T500" ;;
+                1830) MODEL="892/T520" ;;
+                2000) MODEL="720" ;;
+                2010) MODEL="750" ;;
+                2020) MODEL="730" ;;
+                2030) MODEL="735" ;;
+                2040) MODEL="755" ;;
+                2060) MODEL="735/125" ;;
+                2800) MODEL="817/F20" ;;
+                2800) MODEL="827/H20" ;;
+                2810) MODEL="837/F30" ;;
+                2810) MODEL="847/G30/H30" ;;
+                2810) MODEL="857/I30" ;;
+                2820) MODEL="807/F10" ;;
+                2830) MODEL="867/G40/H40" ;;
+                2830) MODEL="877/I40" ;;
+                2840) MODEL="887/G50/H50" ;;
+                2840) MODEL="897/I50" ;;
+                2870) MODEL="887/G70/H70" ;;
+                2870) MODEL="897/I70" ;;
+                2880) MODEL="887/G60/H60" ;;
+                2880) MODEL="897/I60" ;;
+                3000) MODEL="710" ;;
+                3020) MODEL="705" ;;
+                3100) MODEL="715/50" ;;
+                3110) MODEL="715/33" ;;
+                3120) MODEL="715s/50" ;;
+                3130) MODEL="715s/33" ;;
+                3140) MODEL="715t/50" ;;
+                3150) MODEL="715t/33" ;;
+                3160) MODEL="715/75" ;;
+                3180) MODEL="725/50" ;;
+                3190) MODEL="725/75" ;;
+                4010) MODEL="745i/50" ;;
+                4020) MODEL="742i" ;;
+                4030) MODEL="745i/100" ;;
+                4800) MODEL="806/E25" ;;
+                4810) MODEL="816/E35" ;;
+                4820) MODEL="826/E45" ;;
+                4830|4831) MODEL="856/E55" ;;
+                5800) MODEL="809/K100" ;;
+                5810) MODEL="839/K210" ;;
+                5820) MODEL="829/K400" ;;
+                5830) MODEL="849/K410" ;;
+                5870) MODEL="841/D210/D410" ;;
+                5880) MODEL="851/D210/D4102-way" ;;
+                5890) MODEL="821/D200/D400" ;;
+                58A0) MODEL="831/D200/D4002-way" ;;
+                58B0) MODEL="819/K200" ;;
+                58C0) MODEL="859/K230" ;;
+                58D0) MODEL="869/K430" ;;
+                6000) MODEL="712/60" ;;
+                6010) MODEL="712/80" ;;
+                6020) MODEL="712/100" ;;
+                6030) MODEL="743i/60" ;;
+                6040) MODEL="743i/100" ;;
+                60A0) MODEL="715/64" ;;
+                60B0) MODEL="715/100" ;;
+                60D0) MODEL="725/100" ;;
+                6170) MODEL="V743i" ;;
+                6180) MODEL="V743i/100" ;;
+                6190) MODEL="715/80" ;;
+                61A0) MODEL="811/DX5" ;;
+                61B0) MODEL="801/DXO" ;;
+                *)     MODEL="UNKNOWN" ;;
+        esac
+}
+#
+function get_tics
+{
+        ADB_CMD="itick_per_tick/D"
+        FADB_OUT=`echo $ADB_CMD | $ADB $CORES | tail -1 | cut -f 2`
+#
+        if [ $1 = "HZ" ]
+        then
+                ((HZ=$FADB_OUT * 100))
+                SPEED=$HZ
+        else
+                ((MHZ=$FADB_OUT / 10000))
+                SPEED=$MHZ
+        fi
+}
+#
+function get_physmem
+{
+        ADB_CMD="physmem/D"
+        PHYS_MEM=`echo $ADB_CMD | $ADB $CORES | tail -1 | \
+        awk '$2 > 0 { print $2 / 256 }' `
+        echo "Your system has $PHYS_MEM Mbyte ram installed"
+}
+#
+function get_painfo
+{
+        MODEL="`echo $MODEL|cut -f1 -d'/'`"
+        PA_INFO=`grep ^$MODEL $SCHED_FILE`
+        if [  -n "$PA_INFO" ]
+        then
+                PA_RISC="`echo $PA_INFO | cut -d' ' -f 3 `"
+                CPU_REV="`echo $PA_INFO | cut -d' ' -f 2 `"
+                echo "The PA-RISC processor(s) is of type $PA_RISC rev.
+$CPU_REV"
+        fi
+}
+
+## Main program ##
+if [ $# -eq 0 ]
+then
+        usage
+        exit 1
+fi
+#
+if [ `whoami` != "root" ]
+then
+        echo "You must be root to run $PROG ! "
+        exit 1
+fi
+
+while getopts :mMhHv OPT
+do case $OPT in
+   h|H) get_os_rev
+        get_id
+        get_model
+        get_tics HZ
+        print "Your HP9000 Model $MODEL has CPU(s) running at $SPEED Hz"
+        get_painfo
+        get_physmem
+        ;;
+   m|M) get_os_rev
+        get_id
+        get_model
+        get_tics MHZ
+        print "Your HP9000 Model $MODEL has CPU(s) running at $SPEED MHz"
+        get_painfo
+        get_physmem
+        ;;
+     v) echo "You are running version $VER of $PROG"
+        ;;
+   \?)  print -u2 "$PROG: unknown option $OPTARG"
+        usage
+   esac
+done
diff --git a/clients/HP/bin/tbdf b/clients/HP/bin/tbdf
new file mode 100644
index 0000000..ad7d5a6
--- /dev/null
+++ b/clients/HP/bin/tbdf
@@ -0,0 +1,76 @@
+#! /bin/sh
+
+# tbdf (total bdf 'cause it shows the total K bytes used)
+#
+# written by Tom Bukowski 1990,1991
+#  tbdf version 2.2   Jan 4, 1993
+# @(#)  tbdf version 3.0   Aug 19, 1996
+
+egrepCmd=''
+
+if [ $# -eq 0 ];then
+        command=`mount|cut -d' ' -f1-4|grep -v ':'| cut -d' ' -f1`
+
+elif [ $1 = 'help' -o $1 = 'HELP' ];then
+
+        echo "Usage: $0 [-r][-rv] [pattern]"
+        echo '\n  options:'
+        echo '    -r   total all filesystems beginning with
+pattern'
+        echo '    -rv  total all filesystems excluding pattern\n'
+
+        exit
+
+elif [ $1 != "-r" -a $1 != "-rv" ];then
+        command=$*
+
+elif [ $1 = "-r" -o $1 = "-rv" ];then
+
+        test $1 = '-rv' && opt='-v'
+        shift
+        egrepCmd=$1
+        if [ $# -gt 1 ];then
+                while [ $# -gt 0 ]
+                do
+                        egrepCmd="$egrepCmd|^$1"
+                        shift
+                done
+        fi
+
+        command=`mount |\
+        awk '{printf"%s %s %s\n",$1,$2,$3 }' |\
+        grep -v : |\
+        cut -d' ' -f1 |\
+        egrep $opt $egrepCmd |\
+        awk '{ print $NF }'`
+        test -z "$command" && exit
+
+fi
+
+if [ -x /usr/bin/nawk ];then
+ AWK=/usr/bin/nawk
+else
+ AWK=awk
+fi
+
+bdf $command |\
+$AWK '
+{
+        print
+        if ( NR > 1 )
+           if ( NF == 6) {
+                Kbytes_total += $2
+                Used_total += $3
+                Avail_total += $4
+           } else
+            if ( NF == 5 ) {
+                Kbytes_total += $1
+                Used_total += $2
+                Avail_total += $3
+            }
+
+}
+        END { printf"%43s\n","------  ------  ------"
+              printf"%27d %7d %7d\n",Kbytes_total,Used_total,Avail_total
+            }'
+
diff --git a/clients/HP/bin/testmach b/clients/HP/bin/testmach
new file mode 100644
index 0000000..88d86d4
--- /dev/null
+++ b/clients/HP/bin/testmach
@@ -0,0 +1,59 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         testmach
+# Description:  A script to execute a command on all test class machines
+# Author:       Andrew@DeFaria.com
+# Created:      Thu May 11 11:08:24 PDT 2000
+# Modified:
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+# Set me to command name
+me=$(basename $0)
+
+# Set adm_base
+adm_base=${adm_base:-$HOME/adm}
+
+# Set adm_fpath
+adm_fpath=${adm_fpath:-$adm_base/functions}
+
+# Source functions
+. $adm_fpath/common
+
+# Set machines
+machines=${machines:-$adm_base/data/machines}
+
+if [ "$1" = "-f" ]; then
+  shift
+  machines="$1"
+  shift
+fi
+
+PATH=/adm/bin:$PATH
+
+if [ "$1" = "-r" ]; then
+  root=yes
+  shift
+fi
+
+for test_machine in $(grep -ve ^# $machines | grep :Test: | cut -d: -f1); do
+  # Execute command. Note if no command is given then the effect is to
+  # rlogin to each machine.
+  print "$test_machine:$@"
+  if [ $# -gt 0 ]; then
+    if [ -z "$root" ]; then
+      remsh $test_machine -n "$@"
+    else
+      root remsh $test_machine -n "$@"
+    fi
+  else
+    if [ -z "$root" ]; then
+      remsh $test_machine
+    else
+      root remsh $test_machine
+    fi
+  fi
+done
diff --git a/clients/HP/bin/trim_sd_logs b/clients/HP/bin/trim_sd_logs
new file mode 100644
index 0000000..f965a7a
--- /dev/null
+++ b/clients/HP/bin/trim_sd_logs
@@ -0,0 +1,124 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         trim_sw_logs
+# Description:  Script to trim logfiles produced by SD-UX
+# Author:       Andrew@DeFaria.com (Derived from /usr/sbin/cleanup on HP-UX
+#               10.20)
+# Created:      Thu Feb 17 16:12:17 PST 2000
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+# Set me to command name
+me=$(basename $0)
+
+# Set adm_base
+adm_base=${adm_base:-$HOME/adm}
+
+# Set adm_fpath
+adm_fpath=${adm_fpath:-$adm_base/functions}
+
+# Source functions
+. $adm_fpath/common
+tmpprefix=/tmp/$me
+. $adm_fpath/tmpfiles
+trap cleanup INT EXIT ERR
+
+function usage {
+  if [ "_$1" != "_" ]; then
+    display "$1"
+    display
+  fi
+  display "Usage: $me"
+  exit 1
+} # usage
+
+# Check for execution by root
+if is_not_root; then
+  error "This script must be run as root" 1
+fi
+
+while [ $# -ge 1 ]; do
+  case "$1" in
+    -usage)
+      usage
+    ;;
+
+    -v|-verbose)
+      verbose=yes
+    ;;
+
+    -d|-debug)
+      debug=yes
+    ;;
+
+    *)
+      usage "Unrecognized parameter $1"
+    ;;
+  esac
+  shift
+done
+
+logdir=/var/adm/sw
+
+# This routine will trim the given SD logfile by deleting old session
+# log information.  By specifying a date in the mm/dd/yy format, the
+# user can trim all log information for sessions prior to the date.
+function trim_sd_logfile {
+  date=$1
+  logfile=$2
+
+  # Process logfile.
+  # Toss all lines until a line of the form:    =======  date
+  # is discovered.  Retain all lines after recognizing this one.
+  awk '
+    print_all == 1 \
+      {
+      print;
+      next;
+      }
+
+      /^=======  / \
+      {
+      key = sprintf("%s%s", "=======  ", searchdate);
+      if ( index($0, key) == 1 )
+        {
+        print;
+        print_all = 1;
+        }
+      next;
+      }
+' searchdate="$date" $logfile > $tmpprefix
+
+  # Check the size of the tmp file to see if any trimming occurred
+  # If the tmp file is zero-length, then do NOT overwrite the logfile.
+
+  length=$(wc -l $tmpprefix | awk '{print $1}')
+
+  if [ "$length" != "0" ]; then
+    cat $tmpprefix 2>/dev/null > $logfile
+    if [ $? != 0 ]; then
+       warning "Cannot overwrite $logfile" 1
+    fi
+  fi
+} # trim_sd_logfile
+
+function trim_sd_logfiles {
+  cd $logdir
+  for file in $(ls sw*.log); do
+    if [ -s $file ]; then
+      verbose "Trimming $file"
+
+      # Get a suitable date from the file to pass to "trim" The date will be
+      # the 2nd to last date mentioned in  the logfile.
+      target_date=$(awk '/^=======/ {print $2, $3}' $file | \
+                                   uniq | tail -5 | head -1)
+
+      trim_sd_logfile "$target_date" $file
+    fi
+  done
+} # trim_sd_logfiless
+
+trim_sd_logfiles
diff --git a/clients/HP/bin/unmount_nfs b/clients/HP/bin/unmount_nfs
new file mode 100644
index 0000000..333a2f7
--- /dev/null
+++ b/clients/HP/bin/unmount_nfs
@@ -0,0 +1,93 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         mount_nfs
+# RCS:          $Header:$
+# Description:  A script to mount all nfs mounts. Note if the automounter is
+#		running then this script will first shutdown the automounter.
+#		This script returns 0 for success or non zero if it was unable
+#		to umount all nfs mounts. This script must run as root.
+# Author:       Andrew DeFaria, California Language Labs
+# Created:      Fri Jun  6 10:31:51 PDT 1997
+# Modified:     
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+# Set me to command name
+me=$(basename $0)
+
+# Set adm_base
+adm_base=${adm_base:-$HOME/adm}
+
+# Set adm_fpath
+adm_fpath=${adm_fpath:-$adm_base/functions}
+
+# Source functions
+. $adm_fpath/common
+
+if is_not_root; then
+  error "This script must be run as root" 1
+fi
+
+integer automount_pid=$(process_is_running automount)
+kill_automounter=yes
+
+if [ $automount_pid -ne 0 ]; then
+  print "Attempting to shutdown the automounter..."
+  kill -15 $automount_pid
+
+  print "Waiting for the automounter to shutdown..."
+  integer max_tries=5
+  integer wait_time=10
+
+  while [ $max_tries -ne 0 ]; do
+    sleep 10
+    automount_pid=$(process_is_running automount)
+    process_is_running automount
+    if [ $automount_pid -ne 0 ]; then
+      print "The automounter ($automount_pid) is still running!"
+      print "I will wait $max_tries more time\c"
+      if [ $max_tries -gt 1 ]; then
+	print -u2 "s\c"
+      fi
+      print ". Waiting $wait_time seconds..."
+      sleep $wait_time
+    else
+      break
+    fi
+    let max_tries=max_tries-1
+  done
+fi
+
+automount_pid=$(process_is_running automount)
+if [ $automount_pid -ne 0 ]; then
+  print "The automounter has not shutdown! Continuing..."
+else
+  print "The automounter has been shut down successfully"
+  touch /etc/automounter_was_here
+fi
+
+print "\nAttempting to unmount all nfs mounts"
+if [ "$OS" = "09" ]; then
+  /etc/umount -at nfs
+else
+  /usr/sbin/umount -a -F nfs
+fi
+
+integer nfs_mounts_left=$(grep -c "nfs" /etc/mnttab)
+
+if [ $nfs_mounts_left -eq 0 ]; then
+  print "All nfs filesystems have been successfully unmounted!"
+  exit 0
+else
+  print "There \c"
+  if [ $nfs_mounts_left -eq 1 ]; then
+    print "is one filesystem left mounted:\n"
+  else
+    print "are $nfs_mounts_left filesystems left mounted:\n"
+  fi
+  grep nfs /etc/mnttab
+  exit 1
+fi
diff --git a/clients/HP/bin/update_machine_info b/clients/HP/bin/update_machine_info
new file mode 100644
index 0000000..e11b40d
--- /dev/null
+++ b/clients/HP/bin/update_machine_info
@@ -0,0 +1,110 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         update_machine_info
+# Description:  Updates machine infor file (/vob/admin/machines)
+# Author:       Andrew@DeFaria.com
+# Created:      Fri Apr 30 14:13:56 PDT 1999
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+# Set me to command name
+me=$(basename $0)
+
+# Set adm_base
+adm_base=${adm_base:-$HOME/adm}
+
+# Set adm_fpath
+adm_fpath=${adm_fpath:-$adm_base/functions}
+
+# Source functions
+. $adm_fpath/common
+
+# Set machines
+machines=${machines:-$adm_base/data/machines}
+
+tmp_file=/tmp/machines.$$
+machine=$(uname -n)
+ip=$(getip $machine)
+mod=$(uname -m)
+osversion=$(uname -r)
+
+verbose=false
+
+while getopts v OPT; do
+  case $OPT in
+    v) verbose=true
+    ;;
+  esac
+done
+
+if [ -x /usr/atria/bin/cleartool ]; then
+  ccversion=$(/usr/atria/bin/cleartool -version | grep "ClearCase version" |
+\
+    cut -f3 -d' ')
+  eclipseid=`ls -ld /usr/eclipse/etc 2> /dev/null | awk -F'> ' '{print $2}'
+\
+    | awk -F/ '{print $3}'`
+  [ $? -ne 0 ] && eclipseid="No Eclipse" || eclipseid=${eclipseid#eclipse}
+else
+  ccversion="Non ClearCase Machine"
+  eclipseid="No Eclipse"
+fi
+
+owner=Unknown
+usage=Unknown
+location=Unknown
+phone=Unknown
+class=Unknown
+
+# Unix doesn't really have a way to store such information such as owner,
+# usage and location. Attempt to ascertain this info from /etc/motd.
+if [ -f /etc/motd ]; then
+  usage=$(grep "^Usage:" /etc/motd | tr -s " " | cut -f2- -d" ")
+  owner=$(grep "^Owner:" /etc/motd | tr -s " " | cut -f2- -d" ")
+  phone=$(grep "^Phone:  " /etc/motd | tr -s " " | cut -f2- -d" ")
+  class=$(grep "^Class:" /etc/motd | tr -s " " | cut -f2- -d" ")
+  location=$(grep "^Location:" /etc/motd | tr -s " " | cut -f2- -d" ")
+fi
+
+rm -f $tmp_file
+
+if [ $verbose = "true" ]; then
+  print "Machine: $machine"
+  print "IP Address: $ip"
+  print "Model: $mod"
+  print "OS Version: $osversion"
+  print "ClearCase Version: $ccversion"
+  print "Owner: $owner"
+  print "Phone: $phone"
+  print "Usage: $usage"
+  print "Class: $class"
+  print "Location: $location\n"
+  print "Eclipse ID: $eclispeid\n"
+  print "Updating machine list...\c"
+fi
+
+# Add machine if not already present
+grep "^$machine" $machines > /dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+  print "$machine" >> $machines
+fi
+
+while read line; do
+  if [ "$(print $line | cut -f1 -d:)" = $machine ]; then
+    print
+"$machine:$ip:$mod:$osversion:$ccversion:$owner:$phone:$usage:$class:$location:$eclipseid"
+>> $tmp_file
+  else
+    print $line >> $tmp_file
+  fi
+done < $machines
+
+mv $tmp_file $machines
+
+if [ $verbose = "true" ]; then
+  print "done"
+fi
diff --git a/clients/HP/bin/veritas b/clients/HP/bin/veritas
new file mode 100644
index 0000000..78c34d3
--- /dev/null
+++ b/clients/HP/bin/veritas
@@ -0,0 +1,32 @@
+#!/bin/ksh
+###############################################################################
+#
+# File:         veritos
+# Description:  Run the veritos GUI
+# Author:       Andrew DeFaria 
+# Created:      Thu Jun  6 08:31:57 PDT 1996
+# Modified:     
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+###############################################################################
+me=$(basename $0)
+VRTS_veritos=/opt/VRTSvxva/bin/vxva
+SUNW_veritos=/opt/SUNWvxva/bin/vxva
+
+if [ $(/usr/xpg4/bin/id -u) -ne 0 ]; then
+  print -u2 "$me: Error: Must be root to run this command"
+  exit 1
+fi
+
+if [ -x $VRTS_veritos ]; then
+  veritos=$VRTS_veritos
+elif [ -x $SUNW_veritos ]; then
+  veritos=$SUNW_veritos
+else
+  print "$me: Error: Unable to find veritos"
+  exit 1
+fi
+
+$veritos "$@"
diff --git a/clients/HP/bin/vicron b/clients/HP/bin/vicron
new file mode 100644
index 0000000..c520074
--- /dev/null
+++ b/clients/HP/bin/vicron
@@ -0,0 +1,50 @@
+#! /bin/sh
+# upate the cron entries for the user name who is running this script
+#
+# Get info
+#
+echo Updating the cron entries for `whoami`
+TMP="/tmp/$$.`whoami`"
+TMP2="/tmp/2.$$.`whoami`"
+
+crontab -l > $TMP
+cp $TMP $TMP2
+
+vi $TMP
+
+echo "Changes made:"
+if diff $TMP2 $TMP
+then
+	exit 0
+fi
+
+echo "Install this new crontab file for `whoami` (y or n)?  \c"
+
+while true
+do
+	read response
+	case $response in
+		Y | y)	
+			crontab $TMP
+			echo "Done."
+			break
+			;;
+
+		N | n)
+			/bin/rm -f $TMP $TMP2
+			exit 0
+			;;
+		Q | q)
+			/bin/rm -f $TMP $TMP2
+			exit 0
+			;;
+
+		*)
+			echo  "	Please specify either Y or N. (Type Q to quit.)   \c"
+			;;
+	esac
+done
+
+/bin/rm -f $TMP $TMP2
+
+exit 0
diff --git a/clients/HP/bin/viewservers b/clients/HP/bin/viewservers
new file mode 100644
index 0000000..9ee196d
--- /dev/null
+++ b/clients/HP/bin/viewservers
@@ -0,0 +1,39 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         viewservers
+# RCS:          $Header: viewservers,v 1.1 98/01/27 22:31:42 defaria Exp $
+# Description:  A script to execute a command on all view servers.
+# Author:       Andrew DeFaria, California Language Labs
+# Created:      Wed Mar  5 16:31:13 PST 1997
+# Modified:     Fri Jan 16 13:56:05 PST 1998
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+PATH=/adm/bin:$PATH
+
+if [ "$1" = "-r" ]; then
+  root=yes
+  shift
+fi
+
+for viewserver in $(get_info server_names viewserver); do
+  # Execute command. Note if no command is given then the effect is to
+  # rlogin to each machine.
+  print "$viewserver:$@"
+  if [ $# -gt 0 ]; then
+    if [ -z "$root" ]; then
+      remsh $viewserver -n "$@"
+    else
+      root remsh $viewserver -n "$@"
+    fi
+  else
+    if [ -z "$root" ]; then
+      remsh $viewserver
+    else
+      root remsh $viewserver
+    fi
+  fi
+done
diff --git a/clients/HP/bin/vobadm b/clients/HP/bin/vobadm
new file mode 100644
index 0000000..27c9921
--- /dev/null
+++ b/clients/HP/bin/vobadm
@@ -0,0 +1,37 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         vobadm
+# Description:  A script run something as vobadm
+# Author:       Andrew@DeFaria.com
+# Created:      Mon May 17 07:35:59 PDT 1999
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+me=$(basename $0)
+
+sudo=${sudo:-/app/sudo}
+
+if [ ! -x $sudo ]; then
+  print -u2 "$me: Error: Unable to find sudo!"
+  exit 1;
+fi
+
+if [ $# -gt 0 ]; then
+  # Execute the commands
+  $sudo -u vobadm "$@"
+else
+  # Become vobadm
+  $sudo -u vobadm -s
+
+  if [ -x ~/.rc/functions ]; then
+    # Source in ksh functions (needed for set_title and set_prompt)
+    . ~/.rc/functions
+    # Reset title and prompt (if you can)
+    alias ct=/usr/atria/bin/cleartool
+    set_title
+    set_prompt
+  fi
+fi
diff --git a/clients/HP/bin/vobservers b/clients/HP/bin/vobservers
new file mode 100644
index 0000000..4372552
--- /dev/null
+++ b/clients/HP/bin/vobservers
@@ -0,0 +1,39 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         vobservers
+# RCS:          $Header: vobservers,v 1.2 98/01/28 12:22:27 defaria Exp $
+# Description:  A script to execute a command on all vob servers.
+# Author:       Andrew DeFaria, California Language Labs
+# Created:      Wed Mar  5 16:31:13 PST 1997
+# Modified:
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+PATH=/adm/bin:$PATH
+
+if [ "$1" = "-r" ]; then
+  root=yes
+  shift
+fi
+
+for vobserver in $(get_info server_names vobserver); do
+  # Execute command. Note if no command is given then the effect is to
+  # rlogin to each machine.
+  print "$vobserver:$@"
+  if [ $# -gt 0 ]; then
+    if [ -z "$root" ]; then
+      remsh $vobserver -l vobadm -n "$@"
+    else
+      root remsh $vobserver -n "$@"
+    fi
+  else
+    if [ -z "$root" ]; then
+      remsh $vobserver -l vobadm
+    else
+      root remsh $vobserver
+    fi
+  fi
+done
diff --git a/clients/HP/bin/whoison b/clients/HP/bin/whoison
new file mode 100644
index 0000000..dcf2fce
--- /dev/null
+++ b/clients/HP/bin/whoison
@@ -0,0 +1,72 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         whoison
+# RCS:          $Header: whoison,v 1.1 97/05/20 19:56:29 defaria Exp $
+# Description:  A script to show you who is on the system
+# Author:       Andrew DeFaria, California Language Labs
+# Created:      Wed May 14 00:40:02 PDT 1997
+# Modified:
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+tmpprefix=/tmp/whoison
+command="who | cut -f1 -d' ' | sort -u"
+
+function cleanup {
+  if [ ! -z $"tmpprefix" ]; then
+    rm -f ${tmpprefix}*
+  fi
+
+  exit
+} # cleanup
+
+trap cleanup INT EXIT ERR
+
+if [ -z "$PAGER" ]; then
+  pager=more
+else
+  pager="$PAGER"
+fi
+
+function report_whoison {
+  machine="$1"
+
+  if [ "$machine" = "$(uname -n)" ]; then
+    eval $command > $tmpprefix.$$
+  else
+    remsh $machine -n "$command" > $tmpprefix.$$
+  fi
+
+  integer nbr_of_users=$(wc -l $tmpprefix.$$ | tr -s " " | cut -f1 -d' ')
+
+  if [ $nbr_of_users -eq 1 ]; then
+    print "$nbr_of_users user on $machine:\n"
+  else
+    print "$nbr_of_users users on $machine:\n"
+  fi
+
+  integer i=1
+
+  cat $tmpprefix.$$ | while read user; do
+    print "$i: $user"
+    let i=i+1
+  done
+
+  print
+
+  rm -f $tmpprefix.$$
+} # report_whoison
+
+if [ $# -eq 0 ]; then
+  report_whoison "$(uname -n)" | $pager
+else
+  for machine in "$@"; do
+    report_whoison "$machine"
+  done | $pager
+fi
+
+who | cut -f1 -d' ' | sort -u > $tmpprefix.$$
+
diff --git a/clients/HP/bin/whosdown b/clients/HP/bin/whosdown
new file mode 100644
index 0000000..8871a4a
--- /dev/null
+++ b/clients/HP/bin/whosdown
@@ -0,0 +1,199 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         whosedown
+# Description:  Pings machines listed in machines database and produces a report
+#               about which machines are down
+# Author:       Andrew@DeFaria.com
+# Created:      Thu Oct  5 09:32:21 PDT 2000
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+# Set me to command name
+me=$(basename $0)
+
+# Set adm_base
+adm_base=${adm_base:-$HOME/adm}
+
+# Set adm_fpath
+adm_fpath=${adm_fpath:-$adm_base/functions}
+
+# Source functions
+. $adm_fpath/common
+
+# Set machines
+machines=${machines:-$adm_base/data/machines}
+
+function usage {
+  if [ "_$1" != "_" ]; then
+    display "$1"
+    display
+  fi
+  display "Usage: $me [-[c|ount] n | -[u|p] [-nocolor]"
+  display
+  display "Where:"
+  display "\t-c|ount:\tNumber of pings to attempt"
+  display "\t-u|p:\t\tReport machines that are up too"
+  display "\t-nocolor\tDo not produce color output"
+  exit 1
+} # usage
+
+function print_totals {
+  # Print totals
+  display_stderr
+  display_stderr - ------------------------
+
+  if [ "$up" = "true" ]; then
+    display_stderr "Total machines:\t$total_machines"
+    display_stderr "Total up:\t$total_up"
+  fi
+  if [ $total_down -ne 0 ]; then
+    display_stderr "Total down:\t$total_down"
+  fi
+  if [ $total_weak -ne 0 ]; then
+    display_stderr "Total weak:\t$total_week"
+  fi
+
+  exit
+} # print_totals
+
+# Totals
+integer total_machines=0
+integer total_up=0
+integer total_down=0
+integer total_weak=0
+
+# Get parameters
+integer count=2
+up=false
+if [ "$interactive" = "true" ]; then
+  color_output=true
+else
+  color_output=false
+fi
+
+while [ $# -ge 1 ]; do
+  case "$1" in
+    -usage)
+      usage
+    ;;
+
+    -v|-verbose)
+      verbose=yes
+    ;;
+
+    -d|-debug)
+      debug=yes
+    ;;
+
+    -c|-count)
+      if [[ $# -lt 2 ]]; then
+        error "Count not specified" 1
+      else
+        shift
+        count=$1
+      fi
+    ;;
+
+    -u|-up)
+      up=true
+    ;;
+
+    -nocolor)
+      color_output=false
+    ;;
+
+    *)
+      usage "Unrecognized parameter $1"
+    ;;
+  esac
+  shift
+done
+
+if [ "$color_output" = "true" ]; then
+  # Define some colors
+  esc=$(print "\033")
+
+  if [ "$TERM" = "vt100" -o "$TERM" = "vt220" ]; then
+    normal="$esc[0m"
+    up_color="$esc[1m"
+    limping_color="$esc[4m"
+    down_color="$esc[5m"
+  elif [ "$TERM" = "dtterm" -o -z DTTERM ]; then
+    normal="$esc[39m"
+    up_color="$esc[32m"
+    limping_color="$esc[35m"
+    down_color="$esc[31m"
+  elif [ "$TERM" = "hp" -o "$TERM" = "hpterm" ]; then
+    normal="$esc&d@$esc&v0S"
+    down_color="$esc&v1S"
+    limping_color="$esc&v5S"
+    up_color="$esc&v2S"
+  fi
+fi
+
+# Print heading
+display_stderr "Machine\t\tState"
+display_stderr - --------\\t--------
+
+trap print_totals INT
+
+# Check each known machine
+for machine in $(grep -v ^# $machines | cut -f1 -d:); do
+  let total_machines=total_machines+1
+
+  if [ "$up" = "true" ]; then
+    # If we are displaying up machine then print the machine name first
+    display "$machine\t\c"
+    if [ ${#machine} -lt 8 ]; then
+      display "\t\c"
+    fi
+  fi
+
+  # ping the machine
+  ping_result=$(ping $machine -n $count | tail -1 | cut -c44-)
+  integer state=0
+
+  # Translate the return string to states
+  case "$ping_result" in
+    "100% packet loss") # Total packet loss - machine is downes
+      state=1
+      ;;
+
+    "") # No packet loss - machine is fine
+      state=0
+      ;;
+
+    *) # Some other percentage of packet loss - machine is limping
+      state=2
+      ;;
+  esac
+
+  debug "Pinged $machine; result = $ping_result; state = $state"
+
+  # Output based on state
+  if [ $state -eq 0 ]; then
+    if [ "$up" = "true" ]; then
+      let total_up=total_up+1
+      display "${up_color}Up${normal}"
+    fi
+  else
+    if [ "$up" = "false" ]; then
+      display "$machine\t\c"
+      if [ ${#machine} -lt 8 ]; then
+        display "\t\c"
+      fi
+    fi
+    if [ $state -eq 1 ]; then
+      let total_down=total_down+1
+      display "${down_color}Down${normal}"
+    else
+      let total_weak=total_weak+1
+      display "${limping_color}Weak response${normal}"
+    fi
+  fi
+done
+
+print_totals
diff --git a/clients/HP/bin/wrkservers b/clients/HP/bin/wrkservers
new file mode 100644
index 0000000..003833e
--- /dev/null
+++ b/clients/HP/bin/wrkservers
@@ -0,0 +1,40 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         wrkservers
+# RCS:          $Header: wrkservers,v 1.1 98/01/27 22:31:43 defaria Exp $
+# Description:  A script to execute a command on all virtual workstation
+#               servers.
+# Author:       Andrew DeFaria, California Language Labs
+# Created:      Wed Mar  5 16:31:13 PST 1997
+# Modified:     Fri Jan 16 13:54:53 PST 1998
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+PATH=/adm/bin:$PATH
+
+if [ "$1" = "-r" ]; then
+  root=yes
+  shift
+fi
+
+for wrkserver in $(get_info server_names virtualws); do
+  # Execute command. Note if no command is given then the effect is to
+  # rlogin to each machine.
+  print "$wrkserver:$@"
+  if [ $# -gt 0 ]; then
+    if [ -z "$root" ]; then
+      remsh $wrkserver -n "$@"
+    else
+      root remsh $wrkserver -n "$@"
+    fi
+  else
+    if [ -z "$root" ]; then
+      remsh $wrkserver
+    else
+      root remsh $wrkserver
+    fi
+  fi
+done
diff --git a/clients/HP/cygwin_setup b/clients/HP/cygwin_setup
new file mode 100755
index 0000000..d013848
--- /dev/null
+++ b/clients/HP/cygwin_setup
@@ -0,0 +1,241 @@
+#!/bin/bash
+################################################################################
+#
+# File:         cygwin_setup
+# Description:  This script will perform additional setup to configure the
+#		local machine into the cygwin enviornment for Salira
+# Author:       Andrew@DeFaria.com
+# Created:      Fri Oct  5 15:30:16  2001
+# Modified:
+# Language:     Bash Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+# Set me to command name
+me=$(basename $0)
+
+# Global variables
+commonserver=sonscentral
+commonarea=common
+adm=//$commonserver/$commonarea/adm
+homeserver=sonscentral
+homeshare=users
+ccserver=sons-clearcase
+anonymous_ftp_server=sons-clearcase
+viewshare=views
+printerserver=sons-mrp
+printers="\
+  LJ4050PCL6\
+  LJ45500-Color\
+  LJ8150\
+"
+defaultprinter=LJ8150
+
+# Current machine's OS.
+OS=$(uname -s | cut -f2 -d-)
+
+# Current machine's hostname
+hostname=$(echo $(hostname) | tr [:upper:] [:lower:])
+
+# Setup standard mounts
+#
+# Home directory
+echo "Step 1 of 10: Setting up /home mount point"
+mount -tsf //$homeserver/$homeshare /home
+
+# Clearcase views
+echo "Step 2 of 10: Setting up /view mount point"
+if [ $hostname = $ccserver ]; then
+  mount -tsf C:/ClearCaseStorage/Views /view
+else
+  mount -tsf //$ccserver/$viewshare /view
+fi
+
+# Set cygdrive prefix to /dev
+echo "Step 3 of 10: Setting cygdrive-prefix to /dev"
+mount -s --change-cygdrive-prefix /dev
+
+# Remove user level cygdrive-prefix (Need to do this with regedit
+regedit /s \\\\$commonserver\\$commonarea\\FixCygwin.reg 
+
+# Link passwd file
+echo "Step 4 of 10: Create common password file"
+if [ ! -f /etc/passwd.local ]; then
+  if [ ! -L /etc/passwd ]; then
+    cp /etc/passwd /etc/passwd.local
+  fi
+fi
+
+if [ ! -L /etc/passwd ]; then
+  if [ "$OS" != "4.0" ]; then
+    rm /etc/passwd
+    ln -s //$commonserver/$commonarea/passwd /etc/passwd
+  else
+    cp //$commonserver/$commonarea/passwd /etc/passwd
+  fi
+else
+  if [ "$OS" = "4.0" ]; then
+    # Fix up NT 4.0 machines (they don't like symlinked /etc/passwd files!)
+    rm /etc/passwd
+    cp //$commonserver/$commonarea/passwd /etc/passwd
+  fi
+fi
+
+# Link group file
+echo "Step 5 of 10: Create common group file"
+if [ ! -f /etc/group.local ]; then
+  if [ ! -L /etc/group ]; then
+    cp /etc/group /etc/group.local
+  fi
+fi
+
+if [ ! -L /etc/group ]; then
+  rm /etc/group
+  ln -s //$commonserver/$commonarea/group /etc/group
+fi
+
+# Link /etc/profile
+echo "Step 6 of 10: Linking /etc/profile to common profile file"
+if [ ! -f /etc/profile.orig ]; then
+  if [ ! -L /etc/profile ]; then
+    cp /etc/profile /etc/profile.orig
+  fi
+fi
+
+if [ ! -L /etc/profile ]; then
+  rm /etc/profile
+  ln -s //$commonserver/$commonarea/profile /etc/profile
+fi
+
+# Setup printer mount
+echo "Step 7 of 10: Setting up printers"
+for printer in $printers; do
+  mount -bsf //$printerserver/$printer /dev/$printer
+done
+
+# Mount default printer
+mount -bsf //$printerserver/$defaultprinter /dev/lp
+
+# Install internet services
+echo "Step 8 of 10: Installing internet services"
+
+# First save any pre-existing /etc/motd
+if [ -f /etc/motd ]; then
+  cp /etc/motd /etc/motd.$$
+fi
+
+rm -f /etc/ftpusers /etc/ftpwelcome /etc/inetd.conf /etc/motd /etc/shells
+iu-config > /dev/null
+
+# In order to allow anonymous ftp access we need to clear /etc/ftpusers.
+# Do this only for the $anonymous_ftp_server for now
+if [ $hostname = $anonymous_ftp_server ]; then
+  cat /dev/null > /etc/ftpusers
+fi
+
+# Now replace that saved /etc/motd if it existed, otherwise remove the boring
+# /etc/motd that iu-config creates. First check to see if the user has a 
+# personalized /etc/motd in /etc/motd.save
+if [ -f /etc/motd.save ]; then
+  # User had a personalized motd so move it into place and remove any prior
+  # copies
+  mv /etc/motd.save /etc/motd
+  rm -f /etc/motd.$$
+elif [ -f /etc/motd.$$ ]; then
+  # Reinstall previous motd
+  # First update uname -a line
+  uname -a > /etc/motd
+
+  # Remove old uname -a line if present
+  grep -ve "^cygwin" /etc/motd.$$ >> /etc/motd.$$
+
+  # Cleanup
+  rm -f /etc/motd.$$
+else
+  # No saved motd or previous motd. Remove /etc/motd which will cause us
+  # to prompt for the information later.
+  rm /etc/motd
+fi
+
+# Need to hardlink /usr/bin/cygwin1.dll & /usr/sbin/cygwin1.dll
+# 12/17/2001: Stopped hardlinking cygwin1.dll. Enforcing having Windows system
+# environment variables instead. For this we need Cygwin's bin in the path. 
+# User should also set CYGWIN=ntsec in a Windows system environment variable.
+if [ -f /usr/sbin/cygwin1.dll ]; then
+  rm -f /usr/sbin/cygwin1.dll
+  #ln /usr/bin/cygwin1.dll /usr/sbin/cygwin1.dll
+  echo "Warning: Please make sure that you have a Windows *SYSTEM* environment"
+  echo "         variable named CYGWIN set to the value of \"ntsec\" and that"
+  echo "         you have \bin inserted into the Windows *SYSTEM*"
+  echo "         environment variable named PATH"
+fi
+
+# Set up anonymous ftp iff we are on the $anonymous_ftp_server
+if [ $hostname = $anonymous_ftp_server ]; then
+  # Toggle on write access to ~ftp/bin
+  chmod +w ~ftp/bin
+
+  # Remove old copies of ls and cygwin1.dll
+  rm -f ~ftp/bin/ls.exe 
+  rm -f ~ftp/bin/cygwin1.dll
+
+  # Install new copies (Note hardlinks will not work here since ~ftp/bin is
+  # on another file system. Doing an ln simply does a copy anyway)
+  # 12/17/2001: Skipping copying of cygwin1.dll as noted above
+  cp /bin/cygwin1.dll ~ftp/bin/cygwin1.dll
+  cp /bin/ls.exe ~ftp/bin/ls.exe
+
+  # Set security
+  chmod 555 ~ftp/bin/cygwin1.dll
+  chmod 111 ~ftp/bin/ls.exe
+  chown Administrator ~ftp/bin/cygwin1.dll 
+  chown Administrator ~ftp/bin/ls.exe
+  chmod -w ~ftp/bin
+fi
+
+# Install inetd as a service
+/usr/sbin/inetd --install-as-service
+
+# Start inetd service
+inetd_started=$(net start | grep -i inetd)
+
+if [ -z "$inetd_started" ]; then
+  net start inetd
+fi
+
+# Setup SMTP
+$adm/bin/setup_ssmtp
+
+# Setup cron
+$adm/bin/setup_cron
+
+# Create /etc/motd
+echo "Step 9 of 10: Gathering machine specific information"
+if [ ! -f /etc/motd ]; then
+  $adm/bin/make_motd
+  made_motd=true
+else
+  echo "Skipped: Machine info already gathered"
+fi
+
+# Fixup /etc/ftpwelcome
+host=$(hostname | tr [:upper:] [:lower:])
+echo "Welcome to $host's ftp service" > /etc/ftpwelcome
+
+# Update machines file
+echo "Step 10 of 10: Registering this machine (This takes a few seconds)"
+if [ ! -z "$made_motd" ]; then
+  $adm/bin/update_machine_info
+else
+  echo "Skipped: Machine already registered"
+fi
+
+# Sneaky other fixes...
+# Link /bin/more.exe -> /bin/less.exe
+if [ ! -L /bin/more.exe ]; then
+  ln -s /bin/less.exe /bin/more.exe
+fi
+
+# Finished
+echo "Done"
diff --git a/clients/HP/daily b/clients/HP/daily
new file mode 100755
index 0000000..ae93e19
--- /dev/null
+++ b/clients/HP/daily
@@ -0,0 +1,151 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         daily
+# Description:  This is the daily cronjob for root
+# Author:       Andrew@DeFaria.com
+# Created:      Wed Jul 21 12:12:28 PDT 1999
+# Modified:
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+me=$(basename $0)
+
+# Set adm_base
+adm_base=${adm_base:-$HOME/adm}
+
+# Set adm_fpath
+adm_fpath=${adm_fpath:-$adm_base/functions}
+
+# Source functions
+. $adm_fpath/common
+
+# Add $adm_base/bin and $adm_base/clearcase PATH
+export PATH=$adm_base/bin:$adm_base/clearcase:$PATH
+
+# Source in tmpfiles function
+tmpprefix=${TMPDIR:-/tmp}/$me.$$
+tmpfile=$tmpprefix
+. $adm_fpath/tmpfiles
+arm_trap
+
+# Where logs are kept
+logs=$adm_host/logs
+
+# Define admin_host. Admin_host is the machine where checks for the network
+# as a whole are run (such as check_view_storage)
+admin_host=dreamcicle # For now...
+
+verbose=
+debug=
+
+function usage {
+  display "$me [-v|verbose] [-d|debug] [-u|usage] [-n|notify ]"
+  display "        -v|verbose:     Turns on verbose mode"
+  display "        -d|debug:       Turns on debug mode"
+  display "        -u|usage:       Print this usage message\n"
+  display "        -n|notify:      Who to notify of problems (default root)"
+
+  error "$1" 1
+} # usage
+
+lab_admin=cdsadmin # For now
+local_admin=cdsadmin
+
+function notify {
+  debug "ENTER notify"
+  who=$1
+  logfile=$2
+
+  cat > $tmpfile <> $tmpfile
+
+  mailx -s "Notice: $me cronjob discovered the following problems" $who <
+$tmpfile
+  debug "EXIT notify"
+} # notify
+
+# Get parameters
+while [ $# -ge 1 ]; do
+  case "$1" in
+    -usage)
+      usage
+    ;;
+
+    -v|-verbose)
+      verbose=yes
+    ;;
+
+    -d|-debug)
+      debug=yes
+    ;;
+
+    -n|-notify)
+      shift
+      if [ $# -lt 1 ]; then
+        error "Notify email address was unspecified!" 1
+      fi
+      local_admin="$1"
+    ;;
+
+    *)
+      usage "Unrecognized parameter $1"
+    ;;
+  esac
+  shift
+done
+
+## Main
+# Some common portions of log filenames:
+host=$(uname -n) # System's name
+date=$(date +%d) # Note we keep one month of rolling logs
+
+if [ "$host" = "$admin_host" ]; then
+  network_diskspace_log=$logs/network.diskspace.$date.log
+  verbose "Diskspace Report -> $network_diskspace_log"
+  diskspace -network > $network_diskspace_log 2>&1
+
+  if [ -s $network_diskspace_log ]; then
+    notify $lab_admin $network_diskspace_log
+  fi
+
+  view_storage_log=$logs/viewstorage.$date.log
+  verbose "View Storage Report -> $view_storage_log"
+  check_view_storage > $view_storage_log 2>&1
+
+  if [ -s $view_storage_log ]; then
+    notify $lab_admin $view_storage_log
+  fi
+
+  # Produce a viewspace report for all production view servers
+  viewservers="cds-sundev-rem canon"
+
+  for viewserver in $viewservers; do
+    viewspace_log=$logs/$viewserver.viewspace.$date.log
+    verbose "Viewspace Report for $viewserver -> $viewspace_log"
+    viewspace -host $viewserver > $viewspace_log
+  done
+fi
+
+# Checks run on all machines
+local_diskspace_log=$logs/$host.diskspace.$date.log
+verbose "Diskspace Report -> $local_diskspace_log"
+diskspace -local > $local_diskspace_log 2>&1
+
+if [ -s $local_diskspace_log ]; then
+  notify local_admin $local_diskspace_log
+fi
+
+machine_configuration_log=$logs/$host.machine_configuration.$date.log
+verbose "Machine Configuration Report -> $machine_configuration_log" 2>&1 &
+configure_machine -f > $machine_configuraton_log 2>&1
+
+if [ -s $machine_configuration_log ]; then
+  notify local_admin $machine_configuration_log
+fi
diff --git a/clients/HP/packet2vob b/clients/HP/packet2vob
new file mode 100755
index 0000000..fee265e
--- /dev/null
+++ b/clients/HP/packet2vob
@@ -0,0 +1,37 @@
+#!/usr/bin/bash
+################################################################################
+#
+# File:         packet2vob
+# RCS:          $Header: packet2vob,v 1.1 97/04/23 13:11:08 defaria Exp $
+# Description:  A script to display what vob the packet is for
+# Author:       Andrew DeFaria, California Language Labs
+# Created:      Fri Feb 28 07:53:14 PST 1997
+# Modified:     
+# Language:     Korn Shell
+# Package:      N/A
+# Status:       Experimental (Do Not Distribute)
+#
+# (c) Copyright 1995, Hewlett-Packard Company, all rights reserved.
+#
+################################################################################
+alias ct=/usr/atria/bin/cleartool
+alias mt=/usr/atria/bin/multitool
+
+if [ $# -eq 1 ]; then
+  packets="*"
+else
+  packets="$@"
+fi
+
+if [ ! -f $RGY/vob_object ]; then
+  print -u2 "Unable to to interogate the registry ($RGY/vob_object)"
+  exit 1
+fi
+
+for packet in $packets; do
+  familyid=$(mt lspacket $packet 2> /dev/null | grep "family" | awk '{print $5}')
+  uuid=$(grep $familyid $RGY/vob_object | cut -f4 -d';' | cut -c14-)
+  vob=$(ct lsvob -long -uuid $uuid | grep "Tag:" | awk '{print $2}')
+  host=$(ct lsvob -long -uuid $uuid | grep "Server host:" | awk '{print $3}')
+  print "$packet $host:$vob"
+done
diff --git a/clients/HP/pingnet b/clients/HP/pingnet
new file mode 100755
index 0000000..9d0383f
--- /dev/null
+++ b/clients/HP/pingnet
@@ -0,0 +1,115 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         pingnet
+# RCS:          $Header: pingnet,v 1.3 98/03/04 00:42:49 defaria Exp $
+# Description:  A script to ping all machines and report status. This script
+#               uses /etc/hosts and selects only machines in the IP range of
+#               15.0.96.x to 15.0.99.x.
+# Author:       Andrew DeFaria 
+# Created:      Sat Oct 26 10:04:28 PDT 1996
+# Modified:     Sat Oct 26 12:05:26 PDT 1996 Andrew DeFaria 
+# Parameters:   count (default 2): number of times to ping a machine before
+#               considering it not responding.
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+me=$(basename $0)
+
+function usage {
+  print "$me: Usage: $me { count }"
+  print "\twhere count = number of times to ping a machine before
+considering"
+  print "\tthe machine to be not responding (default count = 2)."
+  exit 1
+} # usage
+
+os=
+
+function get_os {
+  machine=$1
+  # Attempt to determine the OS. First attempt to remsh to the machine and
+  # do a uname(1). This assumes Unix. We are unable to remsh then we'll
+  # assume that it's a PC (it could also be a line printer or any other of
+  # a number of network pingable devices!)
+  os=$(remsh $machine -n uname 2>&1)
+
+  # We're gonna make some guesses here...
+  if [[ "$os" = "HP-UX" ||
+        "$os" = "Linux" ]]; then
+    : Do nothing!
+  elif [[ "$os" = *Lost\ connection ]]; then
+    os="Linux? (Lost connection)"
+  elif [[ "$os" = *Permission\ denied. ]]; then
+    os="Linux? (Permission denied)"
+  elif [[ "$os" = *Login\ incorrect ]]; then
+    os="HP-UX? (Login incorrect)"
+  elif [[ "$os" = *Connection\ refused ]]; then
+    os="NT? (Connection refused)"
+  else
+    os="Unknown: $os"
+  fi
+} # get_os
+
+integer count=2
+
+if [ $# -eq 1 ]; then
+  count=$1
+elif [ $# -gt 1 ]; then
+  usage
+fi
+
+esc=$(print "\033")
+
+if [ "$TERM" = "dtterm" -o -z DTTERM ]; then
+  export normal="$esc[39m"
+  export red="$esc[31m"
+  export green="$esc[32m"
+elif [ "$TERM" = "hp" -o "$TERM" = "hpterm" ]; then
+  export normal="$esc&d@$esc&v0S"
+  export red="$esc&v1S"
+  export green="$esc&v2S"
+fi
+
+# Print heading
+print "       Machine\t\t      IP\tState\t  OS"
+print - "-----------------------\t-------------\t-----\t-------"
+
+subnet=${subnet:-15.28}
+integer starting_subnet_octect=${starting_subnet_octect:-96}
+integer ending_subnet_octect=${ending_subnet_octect:-103}
+integer subnet_octect=starting_subnet_octect
+integer starting_octect=${starting_octect:-0}
+integer ending_octect=${ending_octect:-255}
+integer octect=$starting_octect
+
+while [ $subnet_octect -le $ending_subnet_octect ]; do
+  while [ $octect -le $ending_octect ]; do
+    ip=$subnet.$subnet_octect.$octect
+    machine=$ip
+    nslookup $ip 2>&1 | grep Non-exist > /dev/null 2>&1
+    if [ $? -ne 0 ]; then
+      machine=$(nslookup $ip | grep Name: | awk '{print $2}' | cut -f1 -d.)
+    fi
+    print "$machine\t\c"
+    if [ ${#machine} -lt 8 ]; then
+      print "\t\t\c"
+    elif [ ${#machine} -lt 16 ]; then
+      print "\t\c"
+    fi
+    print "$ip\t\c"
+    ping_result=$(ping $ip -n $count | tail -1 | grep "100% packet loss")
+    if [ -z "$ping_result" -eq 0 ]; then
+      print "${green}UP${normal}\t\c"
+      get_os $machine
+      print "$os"
+    else
+      print "${red}DOWN${normal}\tUnknown"
+    fi
+    let octect=octect+1
+  done
+  let subnet_octect=subnet_octect+1
+  let octect=starting_octect
+done
diff --git a/clients/HP/roll_logs b/clients/HP/roll_logs
new file mode 100755
index 0000000..b38dc79
--- /dev/null
+++ b/clients/HP/roll_logs
@@ -0,0 +1,115 @@
+#!/bin/ksh
+################################################################################
+#
+# File:         roll_logs
+# Description:  Rolls log files
+# Author:       Andrew@DeFaria.com
+# Created:      Thu Dec  9 10:05:09 PST 1999
+# Modified:
+# Language:     Korn Shell
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+# Set me to command name
+me=$(basename $0)
+
+# Set adm_base
+adm_base=${adm_base:-$HOME/adm}
+
+# Set adm_fpath
+adm_fpath=${adm_fpath:-$adm_base/functions}
+
+# Source functions
+. $adm_fpath/common
+. $adm_fpath/logs
+
+function usage {
+  if [ "_$1" != "_" ]; then
+    display "$1"
+    display
+  fi
+  display "Usage: $me -[da|aily] | -[w|eekly]"
+  exit 1
+} # usage
+
+# Check for execution by root
+if is_not_root; then
+  error "This script must be run as root" 1
+fi
+
+type=
+while [ $# -ge 1 ]; do
+  case "$1" in
+    -usage)
+      usage
+    ;;
+
+    -v|-verbose)
+      verbose=yes
+    ;;
+
+    -d|-debug)
+      debug=yes
+    ;;
+
+    -da|-daily)
+      type=daily
+      ;;
+
+    -w|-weekly)
+      type=weekly
+      ;;
+
+    *)
+      usage "Unrecognized parameter $1"
+    ;;
+  esac
+  shift
+done
+
+if [ "_$type" = "_" ]; then
+  usage "Must specify -daily or -weekly"
+fi
+
+#Directory      logfile         backuplog               what
+dailylogs="\
+/var/adm        automount.log   autolog.week            automount\n\
+/var/adm        nettl.LOG00     nettl.week              nettracelog\n\
+/var/adm        ninstall.log    nlog.week               ninstall\n\
+/var/adm        ptydaemonlog    ptylog.week             ptydaemon\n\
+/var/adm        rpc.lockd.log   rpc.lockd.week          rpc.lockd\n\
+/var/adm        rpc.statd.log   rpc.statd.week          rpc.statd\n\
+/var/adm        vtdaemonlog     vtlog.week              vtdaemon\n\
+/var/adm/cron   log             log.week                cron\n\
+/var/adm/lp     log             log.week                lp\n\
+/var/adm/syslog syslog.log      syslog.week             syslogd"
+
+weeklylogs="\
+/var/adm        autolog.week    autolog.oldweek         automount\n\
+/var/adm        nettl.week      nettl.oldweek           nettracelog\n\
+/var/adm        nlog.week       nlog.oldweek            ninstall\n\
+/var/adm        ptylog.week     ptylog.oldweek          ptydaemon\n\
+/var/adm        rpc.lockd.week  rpc.lockd.oldweek       rpc.lockd\n\
+/var/adm        rpc.statd.week  rpc.statd.oldweek       rpc.statd\n\
+/var/adm        vtlog.week      vtlog.oldweek           vtdaemon\n\
+/var/adm/cron   log.week        log.oldweek             cron\n\
+/var/adm/lp     log.week        log.oldweek             lp\n\
+/var/adm/syslog syslog.week     syslog.oldweek          syslogd"
+
+if [ "$type" = "daily" ]; then
+  verbose "Daily roll_logs"
+  logfiles="$dailylogs"
+else
+  verbose "Weekly roll_logs"
+  logfiles="$weeklylogs"
+fi
+
+print "$logfiles" | while read dir logfile backup_logfile what; do
+  verbose "Rolling ($what) logfile $logfile -> $backup_logfile..."
+  if [ "$type" = "weekly" ]; then
+    # Clear out oldweek file first
+    rm -f $backup_logfile
+  fi
+  roll_log $dir $logfile $backup_logfile $what
+done
diff --git a/clients/HP/setup_cron b/clients/HP/setup_cron
new file mode 100755
index 0000000..fe1878e
--- /dev/null
+++ b/clients/HP/setup_cron
@@ -0,0 +1,28 @@
+#!/bin/bash
+################################################################################
+#
+# File:         setup_cron
+# Description:  This script sets up Cygwin's cron on the local machine
+# Author:       Andrew@DeFaria.com
+# Created:      
+# Language:     Bash Shell
+# Modifications:
+#
+# (c) Copyright 2002, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+me=$(basename $0)
+# Make sure that certain directories and files do not exist! This is to let
+# cron create them, which appears to be the only way to get these created
+# correctly! 
+if [ ! -d /var/cron ]; then
+  rm -rf /var/cron
+  rm -rf /var/run/cron.pid
+  rm -rf /var/log/cron.log
+
+  # Install cron service:
+  cygrunsrv -I cron -p /usr/sbin/cron -a -D -d "Cygwin cron" -e "MAILTO=$USER@Salira.com" -e "CYGWIN=ntsec"
+fi
+
+# Start cron service
+cygrunsrv -S cron
diff --git a/clients/HP/setup_ssmtp b/clients/HP/setup_ssmtp
new file mode 100755
index 0000000..726eeed
--- /dev/null
+++ b/clients/HP/setup_ssmtp
@@ -0,0 +1,58 @@
+#!/bin/bash
+################################################################################
+#
+# File:         setup_ssmtp
+# Description:  This script sets up ssmtp mail configuration
+# Author:       Andrew@DeFaria.com
+# Created:      Wed Jan  9 12:57:13  2002
+# Language:     Bash Shell
+# Modifications:
+#
+# (c) Copyright 2002, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+# Setup /etc/ssmtp config directory
+ssmtp_dir=/etc/ssmtp
+domain=${domain:-defaria.com}
+mail_server=10.1.1.101
+
+mkdir -p $ssmtp_dir
+chmod 700 $ssmtp_dir
+
+# Make some simple aliases. Alias $USER to the proper email address and then
+# alias root, Administrator and postmaster to the user's address thus making
+# the user "god" of smtp on this machine only.
+cat > $ssmtp_dir/revaliases < $ssmtp_dir/ssmtp.conf <rel2abs ($1);
+  $me           = (!defined $2) ? $0  : $2;
+  $me		=~ s/\.pl$//;
+
+  # Setup paths
+  $bin_path             = "$abs_path";
+  $lib_path             = "$abs_path/../lib";
+  $log_path             = "$abs_path/../log";
+
+  # Add the appropriate path to our modules to @INC array.
+  unshift (@INC, "$lib_path");
+} # BEGIN
+
+use ecrc;
+
+# Global variables
+my $servername		= (!defined $ENV {ECRDSERVER}) ? "lynx12" : $ENV {ECRDSERVER};
+my $port		= (!defined $ENV {ECRDPORT})   ? 1500     : $ENV {ECRDPORT};
+my $ecr			= "";
+my @query_fields	= ();
+my $verbose;
+my $debug;
+my $key;
+my $value;
+my %fields;
+my @ecrs;
+
+sub Usage {
+  my $msg = shift;
+
+  print "ERROR: $msg\n\n" if defined $msg;
+
+  print "Usage: ecrc [-u] [-v] [-d] [ -s  ] [ -p  ] ";
+  print "ECR [ fieldname... ]\n";
+  print "\nWhere:\n\n";
+  print "\t-u:\t\tDisplay usage\n";
+  print "\t-v:\t\tTurn on verbose mode (Default off)\n";
+  print "\t-d:\t\tTurn on debug mode (Default off)\n";
+  print "\t-s:\t\tUse server named servername (Default lynx12)\n";
+  print "\t-s:\t\tUse port (Default 1500)\n";
+  print "\tECR:\t\tECR number to obtain info about\n";
+  print "\tfieldname:\tECR field names to retrieve info about (Default all)\n";
+
+  exit 1;
+} # Usage
+
+sub GetParms {
+  while ($ARGV [0]) {
+    if ($ARGV [0] eq "-v") {
+      $verbose		= 1;
+      ecrc::set_verbose;
+    } elsif ($ARGV [0] eq "-d") {
+      $debug 		= 1;
+      ecrc::set_debug;
+    } elsif ($ARGV [0] eq "-u") {
+      Usage;
+    } elsif ($ARGV [0] eq "-p") {
+      shift @ARGV;
+      Usage "Port not specified" if !$ARGV [0];
+      $port = shift @ARGV;
+    } elsif ($ARGV [0] eq "-s") {
+      shift @ARGV;
+      Usage "Server name not specified" if !$ARGV [0];
+      $servername = shift @ARGV;
+    } else {
+      $ecr = shift (@ARGV);
+      last;
+    } # if
+    shift @ARGV;
+  } # while
+
+  @query_fields = @ARGV;
+
+  # Downshift any query_fields
+  my $i = 0;
+
+  foreach (@query_fields) {
+    $query_fields [$i++] = lc $_;
+  } # foreach
+} # GetParms
+
+# Main code
+GetParms;
+
+die "Unable to connect to $servername:$port\n" if !ecrc::Connect ($servername, $port);
+
+if ($ecr) {
+  if ($ecr eq "\*") {
+    @ecrs = ecrc::GetECRRecord $ecr;
+
+    foreach (@ecrs) {
+      print "$_\n";
+    } # foreach
+
+    exit;
+  } # if
+
+  %fields = ecrc::GetECRRecord ($ecr);
+
+  if (!%fields) {
+    print "ECR $ecr was not found\n";
+  } else {
+    if (@query_fields) {
+      foreach (@query_fields) {
+	if (@query_fields > 1) {
+	  if (defined $fields{$_}) {
+	    print "$_: $fields{$_}\n";
+	  } else {
+	    print "$_: \n";
+	  } # if
+	} else {
+	  if (defined $fields{$_}) {
+	    print "$fields{$_}\n";
+	  } else {
+	    print "$_: \n";
+	  } # if
+	} # if
+      } # foreach
+    } else {
+      while (($key, $value) = each (%fields)) {
+	print "$key: $value\n";
+      } # while
+    } # if
+  } # if
+} else {
+  print "Enter ECR:";
+
+  while (my $command = ) {
+    chomp $command;
+    last if $command =~ m/exit|quit/i;
+
+    $ecr = $command;
+
+    if ($ecr eq "\*") {
+      my @ecrs = ecrc::GetECRRecord $ecr;
+
+      foreach (@ecrs) {
+	print "$_\n";
+      } # foreach
+    } else {
+      %fields	= ecrc::GetECRRecord $ecr;
+
+      if (!%fields) {
+	print "ECR $ecr was not found\n";
+      } else {
+	while (($key, $value) = each (%fields)) {
+	  print "$key: $value\n";
+	} # while
+      } # if
+    } # if
+
+      print "Enter ECR:";
+  } # while
+} # if
diff --git a/clients/LynuxWorks/bin/ecrd b/clients/LynuxWorks/bin/ecrd
new file mode 100644
index 0000000..40e4057
--- /dev/null
+++ b/clients/LynuxWorks/bin/ecrd
@@ -0,0 +1,564 @@
+#!/usr/bin/perl
+################################################################################
+#
+# File:		ecrd: ECR Daemon
+# Description:  This script implements a daemon that handles requests for
+#		queries about information on ECRs contained in the Quintus
+#		database. In addition to lessoning the amount of time it takes
+#		for database opens, access to Quintus data is only available
+#		on certain machines. Additionally, for Perl to access this
+#		Informix database the Informix version of DBD would need to be
+#		locally installed. By calling this daemon instead clients need
+#		not have to install Informix and then code all the necessary
+#		code to access Quintus data as well as have to understand the
+#		structure of the database. Instead clients need only say "Give
+#		me what you got on ECR #".
+# Author:       Andrew@DeFaria.com
+# Created:      Tue Feb 15 09:54:59 PST 2005
+# Modified:
+# Language:     Perl
+#
+# (c) Copyright 2005, LynuxWorks, all rights reserved.
+#
+################################################################################
+use strict;
+use warnings;
+
+use IO::Socket;
+use Net::hostent;
+use POSIX qw(setsid);
+use DBI;
+
+my $ecrdb    = "lynxmigr1";
+my $port     = (!defined $ENV {ECRDPORT}) ? 1500 : $ENV {ECRDPORT};
+
+# Global variables
+my $DB;
+my $ecrserver;
+my $ecrclient;
+my $sth;
+my $statement;
+
+# Options
+my $verbose;
+my $debug;
+my $daemon_mode;
+my $quiet_mode;
+my $multithreaded;
+my $timeout	= 10;
+
+# ECR translations. Note the Quintus database stores certain choice lists as 
+# enumerations. They I guess they are configurable. The right thing to do 
+# would be to figure out how to look up the definition given the number. But
+# we are gonna cheat here and hard code a few important enumerations.
+my @defstatus = (
+  "Open",
+  "Closed",
+  "Fixed",
+  "Not a bug",
+  "Obsolete",
+  "Defered",
+  "Duplicate"
+);
+my @state = (
+  "Reported",
+  "Assigned",
+  "Selected",
+  "Resolved",
+  "Integrated",
+  "Retired",
+  "Reviewed",
+  "Pending Review"
+);
+my @priority = (
+  "Low",
+  "Medium",
+  "High",
+  "Critical"
+);
+my @severity = (
+  "Low",
+  "Medium",
+  "High",
+  "Critical"
+);
+
+# Pid
+my $pid = $$;
+
+my $me = `basename $0`;
+chomp $me;
+my $ecrdversion = "1.3";
+
+my @all_fields = (
+  "productdefect",	# integer
+  "componentdefect",	# integer
+  "defectdefectdup",	# integer
+  "workgroupdefect",	# integer
+  "reporterdefect",	# integer
+  "resolverdefect",	# integer
+  "confirmerdefect",	# integer
+  "buildversdefect",	# integer
+  "rpt_versdefect",	# integer
+  "res_versdefect",	# integer
+  "conf_versdefect",	# integer
+  "state",		# integer
+  "resolverstatus",	# integer
+  "confirmerstatus",	# integer
+  "escstatus",		# integer
+  "owner",		# integer
+  "severity",		# integer
+  "priority",		# integer
+  "summary",		# varchar(80,0)
+  "datereported",	# datetime year to second
+  "dateresolved",	# datetime year to second
+#  "description",	# text
+# Note: Some descriptions fields are huge containing things like
+# uuencoded tar files!  They are so huge that they cause this server
+# to fail (not sure why - it shouldn't but it does. So this hack
+# returns only the first 50K of description to avoid that problem.
+  "description [1,50000]",	# text
+  "cclist",		# varchar(80,0)
+  "dateconfirmed",	# datetime year to second
+  "datemodified",	# datetime year to second
+  "fix_by_date",	# date
+  "fix_by_version",	# integer
+  "history",		# text
+  "likelihood",		# integer
+  "estfixtime",		# datetime year to second
+  "actfixtime",		# datetime year to second
+  "resolution",		# text
+  "businessimpact",	# integer
+  "origin",		# integer
+  "docimpact",		# integer
+  "report_platform",	# integer
+  "resolve_platform",	# integer
+  "confirm_platform",	# integer
+  "test_file",		# varchar(64,0)
+  "visibility",		# integer
+  "misc",		# varchar(80,0)
+  "defecttype",		# integer
+  "defstatus",		# integer
+  "customertext",	# text
+  "modifiedby",		# varchar(20,0)
+  "classification",	# integer
+  "datefixed"		# datetime year to second
+);
+
+# Forwards
+sub CloseDB;
+sub GetRequest;
+
+sub timestamp {
+  my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
+
+  $mday  = "0$mday" if $mday < 10;
+  $mon   = "0$mon"  if $mon  < 10;
+  $hour  = "0$hour" if $hour < 10;
+  $min   = "0$min"  if $min  < 10;
+  $year += 1900;
+
+  return "$mon/$mday/$year $hour:$min";
+} # timestamp
+
+sub log_message {
+  print "[$pid] " . timestamp . " @_\n" if defined $verbose;
+} # log_message
+
+sub log_error {
+  print STDERR "[$pid] " . timestamp . " ERROR: @_\n"
+} # log_error
+
+sub log_warning {
+  print STDERR "[$pid] " . timestamp . " WARNING: @_\n"
+} # log_error
+
+sub debug {
+  print "[$pid] " . timestamp . " @_\n" if defined $debug;
+} # debug
+
+sub verbose {
+  print "[$pid] " . timestamp . " @_\n" if !defined $quiet_mode;
+} # verbose
+
+sub DBError {
+  my $msg       = shift;
+  my $statement = shift;
+
+  if (!defined $DB) {
+    print "Catostrophic error: DB undefined!\n";
+    exit 1;
+  } # if
+
+  print $msg . "\nError #" . $DB->err . " " . $DB->errstr . "\n";
+  print "SQL Statement: $statement\n" if defined $statement;
+
+  exit $DB->err;
+} # DBError
+
+sub timeout {
+  debug "After $timeout seconds of inactivity client timed out";
+
+  my $hostinfo = gethostbyaddr ($ecrclient->peeraddr);
+  my $host = $hostinfo->name || $ecrclient->peerhost;
+  debug "Closing connection to $host";
+
+  # Close client's connection
+  close $ecrclient;
+
+  # Set up signal handlers again
+  $SIG{ALRM} = \&timeout;
+  $SIG{INT}  = $SIG{QUIT} = 23234
+\&interrupt;
+  GetRequest;
+} # timeout
+
+sub interrupt {
+  log_warning "Interrupted - closing down...";
+  close $ecrserver;
+  verbose "Connection closed";
+  CloseDB;
+
+  exit;
+} # interrupt
+
+sub GetClientAck {
+  my $client = shift;
+  my $clientresp;
+
+  debug "ENTER: GetClientAck";
+  alarm $timeout;
+  while (defined $client and defined ($clientresp = <$client>)) {
+    chomp $clientresp;
+    chop $clientresp if $clientresp =~ /\r/;
+    if ($clientresp eq "ACK") {
+      return
+    } # if
+    log_warning "Received $clientresp from client - expected ACK";
+  } # while
+  debug "EXIT: GetClientAck";
+} # GetClientAck
+
+sub GetClientCmd {
+  my $client = shift;
+  my $clientresp;
+
+  alarm $timeout;
+  while (defined $client and defined ($clientresp = <$client>)) {
+    chomp $clientresp;
+    return $clientresp;
+  } # while
+} # GetClientResponse
+
+sub SendClientAck {
+  my $client = shift;
+
+  debug "ENTER: SendClientAck";
+  print $client "ACK\n";
+  debug "EXIT: SendClientAck";
+} # SendClientAck
+
+sub SendClientResponse {
+  my $client   = shift;
+  my $response = shift;
+
+  print $client "$response\n";
+} # SendClientResponse
+
+sub EnterDaemonMode {
+  my $logfile  = shift;
+  my $errorlog = shift;
+
+  $logfile  = "/dev/null" if $logfile  eq "";
+  $errorlog = "/dev/null" if $errorlog eq "";
+
+  # Change the current directory to /
+  chdir '/' 
+    or die "$me: Error: Can't chdir to / ($!)";
+
+  # Turn off umask
+  umask 0;
+
+  # Redirect STDIN to /dev/null
+  open STDIN, '/dev/null'
+    or die "$me: Error: Can't redirect /dev/null ($!)";
+
+  # Redirect STDOUT to logfile
+  open STDOUT, ">>$logfile"
+    or die "$me: Error: Can't redirect stdout to $logfile ($!)";
+
+  # Redirect STDERR to errorlog
+  open STDERR, ">>$errorlog"
+    or die "$me: Error: Can't redirect stderr to $errorlog ($!)";
+
+  # Now fork the daemon
+  defined (my $pid = fork)
+    or die "$me: Error: Can't create daemon ($!)";
+
+  # Now the parent exits
+  exit if $pid;
+
+  # Set process to be session leader
+  setsid
+    or die "$me: Error: Can't start a new session ($!)";
+} # EnterDaemonMode
+
+sub OpenDB {
+  # Connect to database. Note this is using anonymous access (read only)
+  $DB = DBI->connect("DBI:Informix:$ecrdb")
+    or DBError "Unable to open database";
+  log_message "Opened $ecrdb database";
+
+  # Setup our select statement with placeholders
+  $statement = "select ";
+
+  # Build up the field list
+  my $first_time = 1;
+  foreach (@all_fields) {
+    if ($first_time) {
+      $first_time = 0;
+      $statement .= $_;
+    } else {
+      $statement .= ",$_";
+    } # if
+  } # foreach
+
+  # Now add the table and condition
+  $statement .= " from defect where pkey=?";
+
+  $sth = $DB->prepare ($statement)
+    or DBError "Unable to prepare statement", $statement;
+} # OpenDB
+
+sub CloseDB {
+  $DB->disconnect ()
+    or DBError "Unable to disconnect from database!";
+  verbose "Closed $ecrdb database";
+} # CloseDB
+
+sub Usage {
+  my $msg = shift;
+
+  print "$msg\n\n" if defined $msg;
+
+  print "Usage: $me [ -D ] [ -v ] [ -d ] [-p ] [ -m ] [ -q ]\n\n";
+  print "Where:\t-D\tEnter Daemon mode\n";
+  print "\t-v\tVerbose mode (Default off)\n";
+  print "\t-d\tDebug mode (Default off)\n";
+  print "\t-p\tPort number to use (Default 1500)\n";
+  print "\t-m\tMultithreaded (Default off)\n";
+  print "\t-q\tQuiet mode (Default on)\n";
+  exit 1;
+} # Usage
+
+sub GetECRRecord {
+  my $ecr = shift;
+
+  if ($ecr =~ /\D/) {
+    log_error "ECR $ecr is not numeric!";
+    return ();
+  } # if
+
+  my %fields;
+  my $record;
+  my $value;
+
+  $sth->execute ($ecr)
+    or DBError "Unable to execute statement", $statement;
+
+  my $row = $sth->fetchrow_arrayref;
+
+  if (!defined $row) {
+    # @row is empty if there was no ECR by that number
+    log_error "ECR $ecr not found!";
+    return ();
+  } # if
+
+  my @rows = @{$row};
+  foreach (@all_fields) {
+    my $value = shift @rows;
+
+    # Transform newlines to "\n" so the field is treated as one large field
+    $value =~ s/\n/\\n/g if defined $value;
+
+    # Perform some choice list field translations. Again this would be
+    # better done by doing database lookups to translate the enums...
+    $value = $defstatus [$value]	if /defstatus/ and defined $value;
+    $value = $state     [$value]	if /state/     and defined $value;
+    $value = $priority  [$value]	if /priority/  and defined $value;
+    $value = $severity  [$value]	if /severity/  and defined $value;
+    # Fix description field back
+    if (/^description/) {
+      $_ = "description";
+    } # if
+    $fields {$_} = $value
+  } # foreach
+
+  return %fields;
+} # GetECRRecord
+
+sub ServiceClient {
+  my $ecrclient = shift;
+
+  # Service this client
+  my $hostinfo = gethostbyaddr ($ecrclient->peeraddr);
+  my $host = $hostinfo->name || $ecrclient->peerhost;
+
+  verbose "Connect from $host";
+  log_message "Waiting for command from $host";
+  while () {
+    GetClientAck ($ecrclient);
+    $_ = GetClientCmd ($ecrclient);
+    next unless /\S/; # Skip blank requests
+    last if /quit|exit/i;
+
+    if (/\*/) {
+      log_message "$host requests a list of all ECR #'s";
+      SendClientAck ($ecrclient);
+      ReturnAllECRNbrs ($ecrclient);
+      SendClientAck ($ecrclient);
+      next;
+    } # if
+
+    log_message "$host requests information about ECR $_";
+    SendClientAck ($ecrclient);
+    my %fields = GetECRRecord $_;
+
+    if (%fields) {
+      SendClientResponse ($ecrclient, "ecr: $_");
+      while (my ($key, $value) = each (%fields)) {
+	$value = !defined $value ? "" : $value;
+	SendClientResponse ($ecrclient, "$key: $value");
+      } # while
+    } else {
+      SendClientResponse ($ecrclient, "ECR $_ was not found");
+    } # if
+    SendClientAck ($ecrclient);
+  } # while
+
+  verbose "Closing connection from $host at client's request";
+  close $ecrclient;
+} # ServiceClient
+
+sub Funeral {
+  my $childpid = wait;
+  $SIG{CHLD} = \&Funeral;
+  log_message "Child has died" . ($? ? " with status $?" : "");
+} # Funeral
+
+sub GetRequest {
+  # Now wait for an incoming request
+  while ($ecrclient = $ecrserver->accept ()) {
+    my $hostinfo = gethostbyaddr ($ecrclient->peeraddr);
+    my $host = $hostinfo->name || $ecrclient->peerhost;
+    log_message "$host is requesting service";
+    if (defined ($multithreaded)) {
+      my $childpid;
+
+      log_message "Spawning child to handle request";
+
+      die "$me: ERROR: Can't fork: %!" unless defined ($childpid = fork ());
+
+      if ($childpid) {
+	# In parent - set up for clean up of child process
+	log_message "Parent produced child ($childpid)";
+	$SIG{CHLD} = \&Funeral;
+	log_message "Parent looking for another request to service";
+      } else {
+	# In child process - ServiceClient
+	$pid = $$;
+	debug "Child [$pid] has been born";
+	ServiceClient ($ecrclient);
+	log_message "Child finished servicing requests";
+	kill ("TERM", $$);
+	exit;
+      } # if
+    } else {
+      ServiceClient ($ecrclient);
+    } # if
+  } # while
+
+  close ($ecrserver);
+} # GetRequest
+
+sub ProcessRequests {
+  # The subroutine handles processing of requests by using a socket to
+  # communicate with clients.
+  $ecrserver = IO::Socket::INET->new (
+    Proto     => 'tcp',
+    LocalPort => $port,
+    Listen    => SOMAXCONN,
+    Reuse     => 1
+  );
+
+  die "$me: Error: Could not create socket ($!)\n" unless $ecrserver;
+
+  verbose "ECR DB Server (ecrd V$ecrdversion) accepting clients on port $port";
+
+  GetRequest;
+} # ProcessRequests
+
+sub ReturnAllECRNbrs {
+  my $ecrclient = shift;
+
+  my $statement = "select pkey from defect";
+
+  my $sth = $DB->prepare ($statement)
+    or DBError "Unable to prepare statement", $statement;
+
+  $sth->execute ()
+    or DBError "Unable to execute statement", $statement;
+
+  log_message "Returning all ECR numbers...";
+  while (my @row = $sth->fetchrow_array) {
+    SendClientResponse ($ecrclient, $row [0]);
+  } # while
+
+  log_message "All ECR numbers returned";
+} # ReturnAllECRNbrs
+		
+# Start main code
+# Reopen STDOUT.
+open STDOUT, ">-" or die "Unable to reopen STDOUT\n";
+
+# Set unbuffered output
+$| = 1;
+
+while ($ARGV [0]) {
+  if ($ARGV [0] eq "-D") {
+    $daemon_mode = 1;
+  } elsif ($ARGV [0] eq "-v") {
+    $verbose = 1;
+    undef ($quiet_mode);
+  } elsif ($ARGV [0] eq "-d") {
+    $debug = 1;
+    undef ($quiet_mode);
+  } elsif ($ARGV [0] eq "-m") {
+    $multithreaded = 1;
+  } elsif ($ARGV [0] eq "-q") {
+    $quiet_mode = 1;
+    undef ($verbose);
+  } elsif ($ARGV [0] eq "-p") {
+    shift @ARGV;
+    Usage "Must specify a port # after -p" if (!defined $ARGV [0]);
+    $port = $ARGV[0];
+  } else {
+    Usage "Unknown parameter found: " . $ARGV[0];
+  } # if
+
+  shift @ARGV;
+} # while
+
+my $tmp = (!defined $ENV {TMP}) ? "/tmp" : $ENV {TMP};
+my $ecrd_logfile = "$tmp/$me.log";
+my $ecrd_errfile = "$tmp/$me.err";
+
+EnterDaemonMode ($ecrd_logfile, $ecrd_logfile) if defined ($daemon_mode);
+
+OpenDB;
+
+# Set up signal handlers
+$SIG{ALRM} = \&timeout;
+$SIG{INT}  = $SIG{QUIT} = \&interrupt;
+
+ProcessRequests;
diff --git a/clients/LynuxWorks/bin/ecrdesc b/clients/LynuxWorks/bin/ecrdesc
new file mode 100644
index 0000000..9c70fb1
--- /dev/null
+++ b/clients/LynuxWorks/bin/ecrdesc
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+################################################################################
+#
+# File:         ecrdesc
+# Description:  This script will dump out the description for the ECR #(s) 
+#		passed in.
+# Author:       Andrew@DeFaria.com
+# Created:      Fri Jan  7 15:35:13 PST 2005
+# Language:     Perl
+#
+# (c) Copyright 2005, LynxWorks Inc., all rights reserved
+#
+################################################################################
+use strict;
+use warnings;
+use DBI;
+
+my $DB;
+
+# Called when a database error has occurred
+sub DBError {
+  my $msg       = shift;
+  my $statement = shift;
+
+  print $msg . "\nError #" . $DB->err . " " . $DB->errstr . "\n";
+
+  if (defined $statement) {
+    print "SQL Statement: $statement\n";
+  } # if
+
+  exit $DB->err;
+} # DBError
+
+# Connect to database. Note this is using anonymous access (read only)
+$DB = DBI->connect("DBI:Informix:lynxmigr1")
+  or DBError "Unable to open database";
+
+# Loop through ECR #s from the command line
+foreach my $ecr (@ARGV) {
+  print "ECR #: $ecr\n";
+
+  my $statement	= "select description from defect where pkey=\"$ecr\"";
+  my $sth	= $DB->prepare ($statement)
+    or DBError "Unable to prepare statement", $statement;
+
+  $sth->execute ()
+    or DBError "Unable to execute statement", $statement;
+
+  # Defect records are unique per pkey (AKA ECR) there for there will
+  # only be one entry in @row. Also the description is returned as one
+  # large string.
+  my @row = $sth->fetchrow_array;
+
+  if (!@row) {
+    # @row is empty if there was no ECR by that number
+    print "Nothing found!\n";
+  } else {
+    my $desc = pop @row;
+    print "Description:\n" . "-" x 80 . "\n" . $desc . "\n" . "-" x 80 . "\n";
+  } # if
+} # foreach
+
+$DB->disconnect;
+
+exit;
diff --git a/clients/LynuxWorks/bin/files4cr b/clients/LynuxWorks/bin/files4cr
new file mode 100644
index 0000000..5085dce
--- /dev/null
+++ b/clients/LynuxWorks/bin/files4cr
@@ -0,0 +1,202 @@
+#!/usr/bin/perl
+################################################################################
+#
+# File:         files4cr
+# Description:  This script will go through CVS looking for files that have
+#		the passed in CR #.
+# Author:       Andrew@DeFaria.com
+# Created:      Fri Dec 17 12:18:21 PST 2004
+# Language:     Perl
+#
+# (c) Copyright 2004, LynxWorks Inc., all rights reserved
+#
+################################################################################
+use warnings;
+use strict;
+
+# Options
+my $verbose	= 0;
+my $debug	= 0;
+my $execute	= 0;
+my $local	= "";
+
+my $cr;
+
+sub verbose {
+  my $msg = shift;
+
+  print "$msg\n" if $verbose;
+} # verbose
+
+sub debug {
+  my $msg = shift;
+
+  print "DEBUG: $msg\n" if $debug;
+} # debug
+
+sub Usage {
+  my $msg = shift;
+
+  print "ERROR: $msg\n\n" if defined $msg;
+
+  print "Usage: files4cr [-v] [-d] [-l] [-x] [-u] \n";
+  print "\nWhere:\n\n";
+  print "\t-v:\t\tTurn on verbose mode (Default: off)\n";
+  print "\t-d:\t\tTurn on debug mode (Default: off)\n";
+  print "\t-l:\t\tLocal directory only, no recursion\n";
+  print "\t-x:\t\tTurn on execute mode (Default: off)\n";
+  print "\t-u:\t\tDisplay usage\n";
+  print "\tcr\t\tCR number to search for\n";
+  exit 1;
+} # Usage
+
+sub GetFiles4 {
+  my $cr	= shift;
+  my $local	= shift;
+
+  # Perform a cvs log command and grep through the output
+  print "Gathering CVS info..." if $verbose;
+  my @output = grep {
+    /^Working file: /	or
+    /^revision /	or
+    /^date: /		or
+    /^\s*CR#/		or
+    /^\s*CR /
+  } `cvs -q log $local 2>/dev/null`;
+  verbose " done";
+
+  # Now process this array. Entries may look like:
+  #
+  # Working file: 
+  # revision 
+  # date:...
+  # revision 
+  # date:...
+  # CR Number: 
+  #
+  # It's quite possible that there are no CR numbers for a file. It's also
+  # possible that there is the same CR number for multiple revisions! For
+  # example:
+  #
+  # Working file: 
+  # revision 10.2
+  # date:...
+  # CR Number: 1000
+  # revision 10.1
+  # date:...
+  # CR Number: 1000
+  #
+  # In this case we want to return the  and 10.2.
+
+  my %files;
+  my $filename;
+  my $revision;
+
+  while ($_ = shift @output) {
+    chomp;
+    chop if /\r/;
+
+    if (/^Working file: (.*)/) {
+      $filename = $1;
+      debug "file: $filename";
+    } elsif (/^revision (.*)/) {
+      $revision = $1;
+      debug "revision: $revision";
+    } elsif (/^date:.*state: (.*);.*/) {
+      # Check to see if dead!
+      if ($1 eq "dead") {
+	# Indicate we're dead by setting $revision to blank.
+	debug "Dead file encountered $filename";
+	$revision= "";
+      } # if
+    } elsif (/^CR Number: (\d*)$/	or
+	     /^CR# (\d*)$/		or
+             /^CR # (\d*)$/	 	or
+             /^\s*CR (\d*)/) {
+      debug "CR: $1";
+      if ($cr eq $1) {
+	$files{$filename} = $revision;
+	debug "Set $filename: $revision";
+
+        # Now skip to next file
+	do {
+	  $_ = shift @output;
+	} while @output and !/^Working file: /;
+	unshift @output, $_;
+      } # if
+    } else {
+      verbose "Unknown line encountered: $_\n";
+    } # if
+  } # foreach
+
+  return %files;
+} # GetFiles4
+
+sub GetWorkingRev {
+  my $filename = shift;
+
+  my @output = grep { /Working revision:/ } `cvs status $filename`;
+
+  if (defined $output [0] and $output [0] =~ /Working revision:\s*(\S*)/) {
+    return $1;
+  } # if
+
+  return undef;
+} # GetWorkingRev
+
+# Get args
+while ($ARGV [0]) {
+  if ($ARGV [0] eq "-d") {
+    $debug = 1;
+  } elsif ($ARGV [0] eq "-v") {
+    $verbose = 1;
+  } elsif ($ARGV [0] eq "-l") {
+    $local = $ARGV [0];
+  } elsif ($ARGV [0] eq "-x") {
+    $execute = 1;
+  } elsif ($ARGV [0] eq "-u") {
+    Usage;
+  } # if
+
+  $cr = $ARGV [0];
+
+  shift (@ARGV);
+} # while
+
+Usage "No CR specified to process" if !defined $cr;
+
+my %files = GetFiles4 $cr, $local;
+
+foreach (keys %files) {
+  if ($files{$_} eq "") {
+    print "$_: Is dead\n";
+    next;
+  } # if
+
+  my $working_revision	= GetWorkingRev $_;
+  my $up_to_date	= 0;
+
+  if (defined $working_revision and $working_revision eq $files{$_}) {
+    $up_to_date = 1;
+  } # if
+
+  if ($execute) {
+    print "cvs update -r$files{$_}  $_";
+
+    if (!$up_to_date) {
+      `cvs update -r$files{$_} $_`;
+      print " - Updated\n";
+    } else {
+      print " - Already up to date\n";
+    } # if
+  } else {
+    print "$_: $files{$_}";
+
+    if ($up_to_date) {
+      print " - Already up to date\n";
+    } else {
+      print " - Out of date\n";
+    } # if
+  } # if
+} # foreach
+
diff --git a/clients/LynuxWorks/bin/files4ecr b/clients/LynuxWorks/bin/files4ecr
new file mode 100644
index 0000000..31c381a
--- /dev/null
+++ b/clients/LynuxWorks/bin/files4ecr
@@ -0,0 +1,185 @@
+#!/usr/bin/perl
+################################################################################
+#
+# File:         files4ecr
+# Description:  This script will go through CVS looking for files that have
+#		the passed in ECR #.
+# Author:       Andrew@DeFaria.com
+# Created:      Fri Dec 17 12:18:21 PST 2004
+# Language:     Perl
+#
+# (c) Copyright 2004, LynxWorks Inc., all rights reserved
+#
+################################################################################
+use warnings;
+use strict;
+
+# Options
+my $verbose	= 0;
+my $debug	= 0;
+my $execute	= 0;
+my $local	= "";
+
+my $ecr;
+
+sub verbose {
+  my $msg = shift;
+
+  print "$msg\n" if $verbose;
+} # verbose
+
+sub debug {
+  my $msg = shift;
+
+  print "DEBUG: $msg\n" if $debug;
+} # debug
+
+sub Usage {
+  my $msg = shift;
+
+  print "ERROR: $msg\n\n" if defined $msg;
+
+  print "Usage: files4ecr [-v] [-d] [-l] [-x] [-u] \n";
+  print "\nWhere:\n\n";
+  print "\t-v:\t\tTurn on verbose mode (Default: off)\n";
+  print "\t-d:\t\tTurn on debug mode (Default: off)\n";
+  print "\t-l:\t\tLocal directory only, no recursion\n";
+  print "\t-x:\t\tTurn on execute mode (Default: off)\n";
+  print "\t-u:\t\tDisplay usage\n";
+  print "\tecr\t\tECR number to search for\n";
+  exit 1;
+} # Usage
+
+sub GetFiles4 {
+  my $ecr	= shift;
+  my $local	= shift;
+
+  # Perform a cvs log command and grep through the output
+  print "Gathering CVS info..." if $verbose;
+  my @output = grep {
+    /^Working file: /	or
+    /^revision /	or
+    /^\s*ECR#/		or
+    /^\s*ECR /
+  } `cvs -q log $local 2>/dev/null`;
+  verbose " done";
+
+  # Now process this array. Entries may look like:
+  #
+  # Working file: 
+  # revision 
+  # revision 
+  # ECR Number: 
+  #
+  # It's quite possible that there are no ECR numbers for a file. It's also
+  # possible that there is the same ECR number for multiple revisions! For
+  # example:
+  #
+  # Working file: 
+  # revision 10.2
+  # ECR Number: 1000
+  # revision 10.1
+  # ECR Number: 1000
+  #
+  # In this case we want to return the  and 10.2.
+
+  my %files;
+  my $filename;
+  my $revision;
+
+  while ($_ = shift @output) {
+    chomp;
+    chop if /\r/;
+
+    if (/^Working file: (.*)/) {
+      $filename = $1;
+      debug "file: $filename";
+    } elsif (/^revision (.*)/) {
+      $revision = $1;
+      debug "revision: $revision";
+    } elsif (/^ECR Number: (\d*)$/	or
+	     /^ECR# (\d*)$/		or
+             /^ECR # (\d*)$/	 	or
+             /^\s*ECR (\d*)/) {
+      debug "ECR: $1";
+      if ($ecr eq $1) {
+	$files{$filename} = $revision;
+	debug "Set $filename: $revision";
+
+        # Now skip to next file
+	do {
+	  $_ = shift @output;
+	} while @output and !/Working file: /;
+	unshift @output, $_;
+      } # if
+    } else {
+      verbose "Unknown line encountered: $_\n";
+    } # if
+  } # foreach
+
+  return %files;
+} # GetFiles4
+
+sub GetWorkingRev {
+  my $filename = shift;
+
+  my @output = grep { /Working revision:/ } `cvs status $filename`;
+
+  if (defined $output [0] and $output [0] =~ /Working revision:\s*(\S*)/) {
+    return $1;
+  } # if
+
+  return undef;
+} # GetWorkingRev
+
+# Get args
+while ($ARGV [0]) {
+  if ($ARGV [0] eq "-d") {
+    $debug = 1;
+  } elsif ($ARGV [0] eq "-v") {
+    $verbose = 1;
+  } elsif ($ARGV [0] eq "-l") {
+    $local = $ARGV [0];
+  } elsif ($ARGV [0] eq "-x") {
+    $execute = 1;
+  } elsif ($ARGV [0] eq "-u") {
+    Usage;
+  } # if
+
+  $ecr = $ARGV [0];
+
+  shift (@ARGV);
+} # while
+
+Usage "No ECR specified to process" if !defined $ecr;
+
+my %files = GetFiles4 $ecr, $local;
+
+foreach (keys %files) {
+  my $working_revision	= GetWorkingRev $_;
+  my $up_to_date	= 0;
+
+  if (defined $working_revision and $working_revision eq $files{$_}) {
+    $up_to_date = 1;
+  } # if
+
+  if ($execute) {
+    print "cvs update -r$files{$_}  $_";
+
+    if (!$up_to_date) {
+      `cvs update -r$files{$_} $_`;
+      print " - Updated\n";
+    } else {
+      print " - Already up to date\n";
+    } # if
+  } else {
+    print "$_: $files{$_}";
+
+    if ($up_to_date) {
+      print " - Already up to date\n";
+    } else {
+      print " - Out of date\n";
+    } # if
+  } # if
+} # foreach
+
diff --git a/clients/LynuxWorks/bin/files4tag b/clients/LynuxWorks/bin/files4tag
new file mode 100644
index 0000000..7a420ec
--- /dev/null
+++ b/clients/LynuxWorks/bin/files4tag
@@ -0,0 +1,17 @@
+#!/bin/bash
+tag=$1
+file=""
+revision=""
+cvs -q log 2>/dev/null | grep -E "(Working file: |$tag)" | grep -B1 $tag |
+  while read line; do
+    if [[ $line == Working\ file:\ * ]]; then
+      file=$(echo $line | sed "s/Working file: //")
+    elif [[ $line == $tag* ]]; then
+      revision=$(echo $line | sed "s/$tag: //")
+    fi
+    if [ "$file" != "" -a "$revision" != "" ]; then
+      echo cvs update -r$revision $file
+      file=""
+      revision=""
+    fi
+  done
diff --git a/clients/LynuxWorks/lib/Diff.pm b/clients/LynuxWorks/lib/Diff.pm
new file mode 100644
index 0000000..98b7611
--- /dev/null
+++ b/clients/LynuxWorks/lib/Diff.pm
@@ -0,0 +1,584 @@
+package Diff;
+use strict;
+use vars qw($VERSION @EXPORT_OK @ISA @EXPORT);
+use integer;		# see below in _replaceNextLargerWith() for mod to make
+					# if you don't use this
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw(LCS diff traverse_sequences);
+$VERSION = sprintf('%d.%02d', (q$Revision: 1.10 $ =~ /\d+/g));
+
+# McIlroy-Hunt diff algorithm
+# Adapted from the Smalltalk code of Mario I. Wolczko, 
+# by Ned Konz, perl@bike-nomad.com
+
+=head1 NAME
+
+Algorithm::Diff - Compute `intelligent' differences between two files / lists
+
+=head1 SYNOPSIS
+
+  use Algorithm::Diff qw(diff LCS traverse_sequences);
+
+  @lcs    = LCS( \@seq1, \@seq2 );
+
+  @lcs    = LCS( \@seq1, \@seq2, $key_generation_function );
+
+  $lcsref = LCS( \@seq1, \@seq2 );
+
+  $lcsref = LCS( \@seq1, \@seq2, $key_generation_function );
+
+  @diffs = diff( \@seq1, \@seq2 );
+
+  @diffs = diff( \@seq1, \@seq2, $key_generation_function );
+  
+  traverse_sequences( \@seq1, \@seq2,
+                     { MATCH => $callback,
+                       DISCARD_A => $callback,
+                       DISCARD_B => $callback,
+                     } );
+
+  traverse_sequences( \@seq1, \@seq2,
+                     { MATCH => $callback,
+                       DISCARD_A => $callback,
+                       DISCARD_B => $callback,
+                     },
+                     $key_generation_function );
+
+=head1 INTRODUCTION
+
+(by Mark-Jason Dominus)
+
+I once read an article written by the authors of C; they said
+that they hard worked very hard on the algorithm until they found the
+right one.
+
+I think what they ended up using (and I hope someone will correct me,
+because I am not very confident about this) was the `longest common
+subsequence' method.  in the LCS problem, you have two sequences of
+items:
+
+        a b c d f g h j q z
+
+        a b c d e f g i j k r x y z
+
+and you want to find the longest sequence of items that is present in
+both original sequences in the same order.  That is, you want to find
+a new sequence I which can be obtained from the first sequence by
+deleting some items, and from the secend sequence by deleting other
+items.  You also want I to be as long as possible.  In this case
+I is
+
+        a b c d f g j z
+
+From there it's only a small step to get diff-like output:
+
+        e   h i   k   q r x y 
+        +   - +   +   - + + +
+
+This module solves the LCS problem.  It also includes a canned
+function to generate C-like output.
+
+It might seem from the example above that the LCS of two sequences is
+always pretty obvious, but that's not always the case, especially when
+the two sequences have many repeated elements.  For example, consider
+
+	a x b y c z p d q
+	a b c a x b y c z
+
+A naive approach might start by matching up the C and C that
+appear at the beginning of each sequence, like this:
+
+	a x b y c         z p d q
+	a   b   c a b y c z
+
+This finds the common subsequence C.  But actually, the LCS
+is C:
+
+	      a x b y c z p d q
+	a b c a x b y c z
+
+=head1 USAGE
+
+This module provides three exportable functions, which we'll deal with in
+ascending order of difficulty: C, C, and
+C.
+
+=head2 C
+
+Given references to two lists of items, LCS returns an array containing their
+longest common subsequence.  In scalar context, it returns a reference to
+such a list.
+
+  @lcs    = LCS( \@seq1, \@seq2 );
+  $lcsref = LCS( \@seq1, \@seq2 );
+
+C may be passed an optional third parameter; this is a CODE
+reference to a key generation function.  See L.
+
+  @lcs    = LCS( \@seq1, \@seq2, $keyGen );
+  $lcsref = LCS( \@seq1, \@seq2, $keyGen );
+
+Additional parameters, if any, will be passed to the key generation
+routine.
+
+=head2 C
+
+  @diffs     = diff( \@seq1, \@seq2 );
+  $diffs_ref = diff( \@seq1, \@seq2 );
+
+C computes the smallest set of additions and deletions necessary
+to turn the first sequence into the second, and returns a description
+of these changes.  The description is a list of I; each hunk
+represents a contiguous section of items which should be added,
+deleted, or replaced.  The return value of C is a list of
+hunks, or, in scalar context, a reference to such a list.
+
+Here is an example:  The diff of the following two sequences:
+
+  a b c e h j l m n p
+  b c d e f j k l m r s t
+
+Result:
+
+ [ 
+   [ [ '-', 0, 'a' ] ],       
+
+   [ [ '+', 2, 'd' ] ],
+
+   [ [ '-', 4, 'h' ] , 
+     [ '+', 4, 'f' ] ],
+
+   [ [ '+', 6, 'k' ] ],
+
+   [ [ '-', 8, 'n' ], 
+     [ '-', 9, 'p' ], 
+     [ '+', 9, 'r' ], 
+     [ '+', 10, 's' ], 
+     [ '+', 11, 't' ],
+   ]
+ ]
+
+There are five hunks here.  The first hunk says that the C at
+position 0 of the first sequence should be deleted (C<->).  The second
+hunk says that the C at position 2 of the second sequence should
+be inserted (C<+>).  The third hunk says that the C at position 4
+of the first sequence should be removed and replaced with the C
+from position 4 of the second sequence.  The other two hunks similarly. 
+
+C may be passed an optional third parameter; this is a CODE
+reference to a key generation function.  See L.
+
+Additional parameters, if any, will be passed to the key generation
+routine.
+
+=head2 C
+
+C is the most general facility provided by this
+module; C and C are implemented as calls to it.
+
+Imagine that there are two arrows.  Arrow A points to an element of
+sequence A, and arrow B points to an element of the sequence B.
+Initially, the arrows point to the first elements of the respective
+sequences.  C will advance the arrows through the
+sequences one element at a time, calling an appropriate user-specified
+callback function before each advance.  It willadvance the arrows in
+such a way that if there are equal elements C<$A[$i]> and C<$B[$j]>
+which are equal and which are part of the LCS, there will be some
+moment during the execution of C when arrow A is
+pointing to C<$A[$i]> and arrow B is pointing to C<$B[$j]>.  When this
+happens, C will call the C callback
+function and then it will advance both arrows. 
+
+Otherwise, one of the arrows is pointing to an element of its sequence
+that is not part of the LCS.  C will advance that
+arrow and will call the C or the C callback,
+depending on which arrow it advanced.  If both arrows point to
+elements that are not part of the LCS, then C will
+advance one of them and call the appropriate callback, but it is not
+specified which it will call.
+
+The arguments to C are the two sequences to
+traverse, and a callback which specifies the callback functions, like
+this:
+
+  traverse_sequences( \@seq1, \@seq2,
+                     { MATCH => $callback_1,
+                       DISCARD_A => $callback_2,
+                       DISCARD_B => $callback_3,
+                     } );
+
+Callbacks are invoked with at least the indices of the two arrows as
+their arguments.  They are not expected to return any values.  If a
+callback is omitted from the table, it is not called.
+
+If arrow A reaches the end of its sequence, before arrow B does,
+C will call the C callback when it
+advances arrow B, if there is such a function; if not it will call
+C instead.  Similarly if arrow B finishes first.
+C returns when both arrows are at the ends of
+their respective sequences.  It returns true on success and false on
+failure.  At present there is no way to fail.
+
+C may be passed an optional fourth parameter; this
+is a CODE reference to a key generation function.  See L.
+
+Additional parameters, if any, will be passed to the key generation
+function.
+
+=head1 KEY GENERATION FUNCTIONS
+
+C, C, and C accept an optional last parameter.
+This is a CODE reference to a key generating (hashing) function that should
+return a string that uniquely identifies a given element.
+It should be the case that if two elements are to be considered equal,
+their keys should be the same (and the other way around).
+If no key generation function is provided, the key will be the
+element as a string.
+
+By default, comparisons will use "eq" and elements will be turned into keys
+using the default stringizing operator '""'.
+
+Where this is important is when you're comparing something other than
+strings. If it is the case that you have multiple different objects 
+that should be considered to be equal, you should supply a key
+generation function. Otherwise, you have to make sure that your arrays
+contain unique references.
+
+For instance, consider this example:
+
+  package Person;
+
+  sub new
+  {
+    my $package = shift;
+    return bless { name => '', ssn => '', @_ }, $package;
+  }
+
+  sub clone
+  {
+    my $old = shift;
+    my $new = bless { %$old }, ref($old);
+  }
+
+  sub hash
+  {
+    return shift()->{'ssn'};
+  }
+
+  my $person1 = Person->new( name => 'Joe', ssn => '123-45-6789' );
+  my $person2 = Person->new( name => 'Mary', ssn => '123-47-0000' );
+  my $person3 = Person->new( name => 'Pete', ssn => '999-45-2222' );
+  my $person4 = Person->new( name => 'Peggy', ssn => '123-45-9999' );
+  my $person5 = Person->new( name => 'Frank', ssn => '000-45-9999' );
+
+If you did this:
+
+  my $array1 = [ $person1, $person2, $person4 ];
+  my $array2 = [ $person1, $person3, $person4, $person5 ];
+  Algorithm::Diff::diff( $array1, $array2 );
+
+everything would work out OK (each of the objects would be converted
+into a string like "Person=HASH(0x82425b0)" for comparison).
+
+But if you did this:
+
+  my $array1 = [ $person1, $person2, $person4 ];
+  my $array2 = [ $person1, $person3, $person4->clone(), $person5 ];
+  Algorithm::Diff::diff( $array1, $array2 );
+
+$person4 and $person4->clone() (which have the same name and SSN)
+would be seen as different objects. If you wanted them to be considered
+equivalent, you would have to pass in a key generation function:
+
+  my $array1 = [ $person1, $person2, $person4 ];
+  my $array2 = [ $person1, $person3, $person4->clone(), $person5 ];
+  Algorithm::Diff::diff( $array1, $array2, \&Person::hash );
+
+This would use the 'ssn' field in each Person as a comparison key, and
+so would consider $person4 and $person4->clone() as equal.
+
+You may also pass additional parameters to the key generation function
+if you wish.
+
+=head1 AUTHOR
+
+This version by Ned Konz, perl@bike-nomad.com
+
+=head1 CREDITS
+
+Versions through 0.59 (and much of this documentation) were written by:
+
+Mark-Jason Dominus, mjd-perl-diff@plover.com
+
+This version borrows the documentation and names of the routines
+from Mark-Jason's, but has all new code in Diff.pm.
+
+This code was adapted from the Smalltalk code of
+Mario Wolczko , which is available at
+ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
+
+The algorithm is that described in 
+I,
+CACM, vol.20, no.5, pp.350-353, May 1977, with a few
+minor improvements to improve the speed.
+
+=cut
+
+# Create a hash that maps each element of $aCollection to the set of positions
+# it occupies in $aCollection, restricted to the elements within the range of
+# indexes specified by $start and $end.
+# The fourth parameter is a subroutine reference that will be called to
+# generate a string to use as a key.
+# Additional parameters, if any, will be passed to this subroutine.
+#
+# my $hashRef = _withPositionsOfInInterval( \@array, $start, $end, $keyGen );
+
+sub _withPositionsOfInInterval
+{
+	my $aCollection = shift;	# array ref
+	my $start = shift;
+	my $end = shift;
+	my $keyGen = shift;
+	my %d;
+	my $index;
+	for ( $index = $start; $index <= $end; $index++ )
+	{
+		my $element = $aCollection->[ $index ];
+		my $key = &$keyGen( $element, @_ );
+		if ( exists( $d{ $key } ) )
+		{
+			push( @{ $d{ $key } }, $index );
+		}
+		else
+		{
+			$d{ $key } = [ $index ];
+		}
+	}
+	return wantarray ? %d: \%d;
+}
+
+# Find the place at which aValue would normally be inserted into the array. If
+# that place is already occupied by aValue, do nothing, and return undef. If
+# the place does not exist (i.e., it is off the end of the array), add it to
+# the end, otherwise replace the element at that point with aValue.
+# It is assumed that the array's values are numeric.
+# This is where the bulk (75%) of the time is spent in this module, so try to
+# make it fast!
+
+sub _replaceNextLargerWith
+{
+	my ( $array, $aValue, $high ) = @_;
+	$high ||= $#$array;
+
+	# off the end?
+	if ( $high == -1 || $aValue > $array->[ -1 ] )
+	{
+		push( @$array, $aValue );
+		return $high + 1;
+	}
+
+	# binary search for insertion point...
+	my $low = 0;
+	my $index;
+	my $found;
+	while ( $low <= $high )
+	{
+		$index = ( $high + $low ) / 2;
+#		$index = int(( $high + $low ) / 2);		# without 'use integer'
+		$found = $array->[ $index ];
+
+		if ( $aValue == $found )
+		{
+			return undef;
+		}
+		elsif ( $aValue > $found )
+		{
+			$low = $index + 1;
+		}
+		else
+		{
+			$high = $index - 1;
+		}
+	}
+
+	# now insertion point is in $low.
+	$array->[ $low ] = $aValue;		# overwrite next larger
+	return $low;
+}
+
+# This method computes the longest common subsequence in $a and $b.
+
+# Result is array or ref, whose contents is such that
+# 	$a->[ $i ] = $b->[ $result[ $i ] ]
+# foreach $i in ( 0..scalar( @result ) if $result[ $i ] is defined.
+
+# An additional argument may be passed; this is a hash or key generating
+# function that should return a string that uniquely identifies the given
+# element.  It should be the case that if the key is the same, the elements
+# will compare the same. If this parameter is undef or missing, the key
+# will be the element as a string.
+
+# By default, comparisons will use "eq" and elements will be turned into keys
+# using the default stringizing operator '""'.
+
+# Additional parameters, if any, will be passed to the key generation routine.
+
+sub _longestCommonSubsequence
+{
+	my $a = shift;	# array ref
+	my $b = shift;	# array ref
+	my $keyGen = shift;	# code ref
+	my $compare;	# code ref
+
+	# set up code refs
+	# Note that these are optimized.
+	if ( !defined( $keyGen ) )	# optimize for strings
+	{
+		$keyGen = sub { $_[0] };
+		$compare = sub { my ($a, $b) = @_; $a eq $b };
+	}
+	else
+	{
+		$compare = sub {
+			my $a = shift; my $b = shift;
+			&$keyGen( $a, @_ ) eq &$keyGen( $b, @_ )
+		};
+	}
+
+	my ($aStart, $aFinish, $bStart, $bFinish, $matchVector) = (0, $#$a, 0, $#$b, []);
+
+	# First we prune off any common elements at the beginning
+	while ( $aStart <= $aFinish
+		and $bStart <= $bFinish
+		and &$compare( $a->[ $aStart ], $b->[ $bStart ], @_ ) )
+	{
+		$matchVector->[ $aStart++ ] = $bStart++;
+	}
+
+	# now the end
+	while ( $aStart <= $aFinish
+		and $bStart <= $bFinish
+		and &$compare( $a->[ $aFinish ], $b->[ $bFinish ], @_ ) )
+	{
+		$matchVector->[ $aFinish-- ] = $bFinish--;
+	}
+
+	# Now compute the equivalence classes of positions of elements
+	my $bMatches = _withPositionsOfInInterval( $b, $bStart, $bFinish, $keyGen, @_ );
+	my $thresh = [];
+	my $links = [];
+
+	my ( $i, $ai, $j, $k );
+	for ( $i = $aStart; $i <= $aFinish; $i++ )
+	{
+		$ai = &$keyGen( $a->[ $i ] );
+		if ( exists( $bMatches->{ $ai } ) )
+		{
+			$k = 0;
+			for $j ( reverse( @{ $bMatches->{ $ai } } ) )
+			{
+				# optimization: most of the time this will be true
+				if ( $k
+					and $thresh->[ $k ] > $j
+					and $thresh->[ $k - 1 ] < $j )
+				{
+					$thresh->[ $k ] = $j;
+				}
+				else
+				{
+					$k = _replaceNextLargerWith( $thresh, $j, $k );
+				}
+
+				# oddly, it's faster to always test this (CPU cache?).
+				if ( defined( $k ) )
+				{
+					$links->[ $k ] = 
+						[ ( $k ? $links->[ $k - 1 ] : undef ), $i, $j ];
+				}
+			}
+		}
+	}
+
+	if ( @$thresh )
+	{
+		for ( my $link = $links->[ $#$thresh ]; $link; $link = $link->[ 0 ] )
+		{
+			$matchVector->[ $link->[ 1 ] ] = $link->[ 2 ];
+		}
+	}
+
+	return wantarray ? @$matchVector : $matchVector;
+}
+
+sub traverse_sequences
+{
+	my $a = shift;	# array ref
+	my $b = shift;	# array ref
+	my $callbacks = shift || { };
+	my $keyGen = shift;
+	my $matchCallback = $callbacks->{'MATCH'} || sub { };
+	my $discardACallback = $callbacks->{'DISCARD_A'} || sub { };
+	my $discardBCallback = $callbacks->{'DISCARD_B'} || sub { };
+	my $matchVector = _longestCommonSubsequence( $a, $b, $keyGen, @_ );
+	# Process all the lines in match vector
+	my $lastA = $#$a;
+	my $lastB = $#$b;
+	my $bi = 0;
+	my $ai;
+	for ( $ai = 0; $ai <= $#$matchVector; $ai++ )
+	{
+		my $bLine = $matchVector->[ $ai ];
+		if ( defined( $bLine ) )
+		{
+			&$discardBCallback( $ai, $bi++, @_ ) while $bi < $bLine;
+			&$matchCallback( $ai, $bi++, @_ );
+		}
+		else
+		{
+			&$discardACallback( $ai, $bi, @_ );
+		}
+	}
+
+	&$discardACallback( $ai++, $bi, @_ ) while ( $ai <= $lastA );
+	&$discardBCallback( $ai, $bi++, @_ ) while ( $bi <= $lastB );
+	return 1;
+}
+
+sub LCS
+{
+	my $a = shift;	# array ref
+	my $matchVector = _longestCommonSubsequence( $a, @_ );
+	my @retval;
+	my $i;
+	for ( $i = 0; $i <= $#$matchVector; $i++ )
+	{
+		if ( defined( $matchVector->[ $i ] ) )
+		{
+			push( @retval, $a->[ $i ] );
+		}
+	}
+	return wantarray ? @retval : \@retval;
+}
+
+sub diff
+{
+	my $a = shift;	# array ref
+	my $b = shift;	# array ref
+	my $retval = [];
+	my $hunk = [];
+	my $discard = sub { push( @$hunk, [ '-', $_[ 0 ], $a->[ $_[ 0 ] ] ] ) };
+	my $add = sub { push( @$hunk, [ '+', $_[ 1 ], $b->[ $_[ 1 ] ] ] ) };
+	my $match = sub { push( @$retval, $hunk ) if scalar(@$hunk); $hunk = [] };
+	traverse_sequences( $a, $b,
+		{ MATCH => $match, DISCARD_A => $discard, DISCARD_B => $add },
+		@_ );
+	&$match();
+	return wantarray ? @$retval : $retval;
+}
+
+1;
diff --git a/clients/LynuxWorks/lib/ecrc.pm b/clients/LynuxWorks/lib/ecrc.pm
new file mode 100644
index 0000000..456edc3
--- /dev/null
+++ b/clients/LynuxWorks/lib/ecrc.pm
@@ -0,0 +1,220 @@
+#!/usr/bin/perl
+################################################################################
+#
+# File:		ecrd.pm: ECR Daemon Client Library
+# Description:  Perl Module interface to ecrd (ECR Daemon). This is used
+#		by ecrc and cgi scripts to talk to ECR Daemon
+# Author:       Andrew@DeFaria.com
+# Created:      Tue Feb 15 09:40:57 PST 2005
+# Modified:
+# Language:     Perl
+#
+# (c) Copyright 2005, LynuxWorks, all rights reserved.
+#
+################################################################################
+use strict;
+use warnings;
+
+use IO::Socket;
+
+package ecrc;
+  require Exporter;
+  @main::ISA = qw (Exporter);
+
+  @main::EXPORT = qw (Connect GetECRRecord Disconnect);
+
+  my $default_server	= (!defined $ENV {ECRDSERVER}) ? "lynx12" : $ENV {ECRDSERVER};
+  my $default_port	= (!defined $ENV {ECRDPORT})   ? 1500     : $ENV {ECRDPORT};
+  my $verbose		= 0;
+  my $debug		= 0;
+  my $command;
+  my $ecrserver;
+
+  # Forwards
+  sub ConnectToServer;
+  sub GetServerAck;
+  sub GetServerList;
+  sub GetServerResponse;
+  sub SendServerAck;
+  sub SendServerCmd;
+
+  BEGIN {
+    my $ecrcversion = "1.1";
+
+    # Reopen STDOUT to make sure it's clear
+    open STDOUT, ">-" or die "Unable to reopen STDOUT\n";
+
+    # Set unbuffered output
+    $| = 1;
+  } # BEGIN
+
+  sub set_verbose {
+    $verbose = 1;
+  } # set_verbose
+
+  sub set_debug {
+    $debug = 1;
+  } # set_debug
+
+  sub verbose {
+    print "@_\n" if $verbose;
+  } # verbose
+
+  sub debug {
+    print "DEBUG: @_\n" if $debug;
+  } # debug
+
+  sub Connect {
+    my $host = shift;
+    my $port = shift;
+
+    my $result;
+
+    $host = $default_server if !defined $host;
+    $port = $default_port   if !defined $port;
+
+    $ecrserver = ConnectToServer $host, $port;
+
+    if ($ecrserver) {
+      verbose "Connected to $host";
+      SendServerAck $ecrserver;
+    } # if
+
+    return $ecrserver;
+  } # Connect
+
+  sub Disconnect {
+    my $msg;
+
+    if ($ecrserver) {
+      if ($command eq "shutdown") {
+	$msg = "Disconnected from server - shutdown server";
+      } else {
+	$command = "quit";
+	$msg     = "Disconnected from server";
+      } # if
+      SendServerCmd $ecrserver, $command;
+      GetServerAck  $ecrserver;
+      verbose "$msg";
+      close $ecrserver;
+      undef $ecrserver;
+    } # if
+  } # Disconnect
+
+  sub GetECRRecord {
+    my $ecr = shift;
+
+    my %fields;
+    my @ecrs;
+
+    if (!$ecrserver) {
+      verbose "Not connected to server yet!";
+      verbose "Attempting connection to $default_server...";
+      if (!Connect $default_server, $default_port) {
+	print "Unable to connect to server $default_server\n";
+	exit 1;
+      } # if
+    } # if
+
+    SendServerCmd $ecrserver, $ecr;
+    GetServerAck  $ecrserver;
+
+    if ($ecr eq "\*") {
+      @ecrs = GetServerList $ecrserver;
+    } else {
+      %fields = GetServerResponse $ecrserver;
+    } # if
+
+   SendServerAck $ecrserver;
+
+    return $ecr eq "\*" ? @ecrs : %fields;
+  } # GetECRRecord
+
+  END {
+    verbose "Sending disconnect command to server";
+    $command = "quit";
+    Disconnect;
+  } # END
+
+  sub ConnectToServer {
+    my $host = shift;
+    my $port = shift;
+
+    # create a tcp connection to the specified host and port
+    return IO::Socket::INET->new(Proto     => "tcp",
+				 PeerAddr  => $host,
+				 PeerPort  => $port);
+  } # ConnectToServer
+
+  sub SendServerAck {
+    my $server = shift;
+
+    print $server "ACK\n";
+  } # SendServerAck
+
+  sub GetServerAck {
+    my $server = shift;
+    my $srvresp;
+
+    while (defined ($srvresp = <$server>)) {
+      chomp $srvresp;
+      if ($srvresp eq "ACK") {
+	return;
+      } # if
+      print "Received $srvresp from server - expected ACK\n";
+    } # while
+  } # GetServerAck
+
+  sub GetServerList {
+    my $server = shift;
+
+    my @ecrs;
+    my $srvresp;
+
+    while (defined ($srvresp = <$server>)) {
+      chomp $srvresp;
+      last if $srvresp eq "ACK";
+      if ($srvresp =~ m/ECR.*was not found/) {
+	return ();
+      } else {
+	push @ecrs, $srvresp;
+      } # if
+    } # while
+
+    return @ecrs;
+  } # GetServerList
+
+  sub GetServerResponse {
+    my $server = shift;
+
+    my %fields;
+    my $srvresp;
+
+    while (defined ($srvresp = <$server>)) {
+      chomp $srvresp;
+      last if $srvresp eq "ACK";
+      if ($srvresp =~ m/ECR.*was not found/) {
+	return ();
+      } else {
+	$srvresp =~ /(^\w+):\s+(.*)/s;
+        my $value = $2;
+	if (defined $value) {
+	  $value =~ s/\\n/\n/g;
+	} else {
+	  $value = "";
+	} # if
+	$fields {$1} = $value;
+      } # if
+    } # while
+
+    return %fields;
+  } # GetServerResponse
+
+  sub SendServerCmd {
+    my $server  = shift;
+    my $command = shift;
+
+    print $server "$command\n";
+  } # SendServerCmd
+
+1;
diff --git a/clients/Salira/CheckinPostop.pl b/clients/Salira/CheckinPostop.pl
new file mode 100644
index 0000000..61147d5
--- /dev/null
+++ b/clients/Salira/CheckinPostop.pl
@@ -0,0 +1,102 @@
+#!/usr/bin/perl -w
+################################################################################
+#
+# File:         CheckinPostop.pl
+# Description:  This script is run on check in post op. It will pick up the
+#		bug IDs from the comment and label the elements that have just
+#		been checked in.
+# Author:       Andrew@DeFaria.com
+# Created:      Fri Oct 26 15:32:12  2001
+# Language:     Perl
+# Modifications:10/22/2002: Changed to not complain about missing bug IDs if
+#		the branch was main.
+#		04/11/2003: Changed to support multiple bug IDs in the comment.
+# (c) Copyright 2003, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+use strict;
+
+BEGIN {
+  # Add the appropriate path to our modules to @INC array. We use ipconfig to
+  # get the current host's IP address then determine whether we are in the US
+  # or China. If neither then we fallback to using T:/Triggers.
+  my @ipconfig = grep (/IP Address/, `ipconfig`);
+  my ($ipaddr) = ($ipconfig[0] =~ /(\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3})/);
+
+  # US is in the subnets of 192 and 172 while China is in the subnet of 10
+  if ($ipaddr =~ /^192|^172/) {
+    unshift (@INC, "//sons-clearcase/Views/official/Tools/lib");
+  } elsif ($ipaddr =~ /^10/) {
+    unshift (@INC, "//sons-cc/Views/official/Tools/lib");
+  } else {
+    die "Internal Error: Unable to find our modules!\n"
+  } # if
+} # BEGIN
+
+use TriggerUtils;
+
+# The following environment variables are set by Clearcase when this
+# trigger is called
+my $comment = $ENV{CLEARCASE_COMMENT};
+my $branch  = $ENV{CLEARCASE_BRTYPE};
+my $pname   = $ENV{CLEARCASE_PN};
+my $user    = $ENV{CLEARCASE_USER};
+
+sub ExtractBugIDs {
+  my $comment = shift;
+
+  my @fields  = split /\W/,$comment;
+
+  # Use associative array to insure uniqueness
+  my %bugids;
+  # Return unique array
+  my @bugids;
+
+  foreach (@fields) {
+    if (/BUGS2[0-9]{8}/) {
+      $bugids{$_} = $_;
+    } # if
+  } # foreach
+
+  foreach (keys %bugids) {
+    push @bugids, $_;
+  }
+
+  return @bugids;
+} # ExtractBugIDs
+
+sub mklabel {
+  my $label = shift;
+
+  my $result = system "cleartool lstype lbtype:$label@\\salira";
+
+  return $result if ($result eq 0);
+
+  $result = system "cleartool mklbtype -nc -shared -pbranch $label@\\salira";
+
+  if ($result eq 0) {
+    clearlog "Created label for $label";
+  } else {
+    clearlogmsg "Unable to mklbtype for $label (Error #: $result)";
+  } # if
+
+  return $result;
+} # mklabel
+
+foreach my $bugid (ExtractBugIDs ($comment)) {
+  if (mklabel ($bugid) eq 0) {
+    my $result = system "cleartool mklabel -replace $bugid \"$pname\"";
+
+    if ($result ne 0) {
+      clearlogmsg "Unable to apply label $bugid to $pname (Error #: $result)";
+      exit 1;
+    } else {
+      clearlog "Attached label $bugid to $pname";
+    } # if
+
+    clearlog "Successful postcheckin of $pname on $branch branch with bug ID $bugid";
+  } # if
+
+} # foreach
+
+exit 0;
diff --git a/clients/Salira/CheckinPreop.pl b/clients/Salira/CheckinPreop.pl
new file mode 100644
index 0000000..94e5a83
--- /dev/null
+++ b/clients/Salira/CheckinPreop.pl
@@ -0,0 +1,293 @@
+#!/usr/bin/perl
+################################################################################
+#
+# File:         CheckinPreop.pl
+# Description:  This trigger script is run when the user is attempting to
+#		checkin. Several checks are performed on the check in comment.
+#		The comment should contain the bug ID, which we will later used
+#		to label this element checkin (See CheckinPostop.pl). We will
+#		also check to insure the bug ID is valid in Clearquest and that
+#		the bug is in the proper state.
+#
+#		If the check in is on the "main" or "trial" branch then we will
+#		consult a file to insure that the bug ID is listed. This is an
+#		additional method for limiting checkins.
+# Assumptions:	Clearprompt is in the users PATH
+# Author:       Andrew@DeFaria.com
+# Created:      Fri Oct 26 15:32:12  2001
+# Language:     Perl
+# Modifications:6/25/2002: Added check to see if a bug ID label exists and it
+#		is locked. If so then that's an indication that we should not
+#		allow the checkin.
+#		6/20/2002: Added interface to cqd to verify that the bug exists
+#		in Clearquest, is of a certain state and has an owner
+#		5/15/2002: Added tests so that bug IDs must exist in
+#		mainbugs.txt or	trialbugs.txt for the main and trial branches.
+#		5/17/2002: Exempted EMS code.
+#		5/31/2002: Exempted hardware code.
+#		10/22/2002: Changed to allow checkins to main branch with no
+#		bug IDs. Removed $mainbugs.
+#		11/20/2002: It was determined to relax restrictions of checkins
+#		for non 1.0 branches such that bug ID's are not required, in fact
+#		they are not allowed.
+#		04/11/2003: Added support for multiple bug IDs in the comment
+#		05/18/2003: Changed code to only check for bug IDs in comments
+#		for check ins on certain branches.
+#
+# (c) Copyright 2003, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+use strict;
+
+my $site;
+
+BEGIN {
+  # Add the appropriate path to our modules to @INC array. We use ipconfig to
+  # get the current host's IP address then determine whether we are in the US
+  # or China.
+  my @ipconfig = grep (/IP Address/, `ipconfig`);
+  my ($ipaddr) = ($ipconfig[0] =~ /(\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3})/);
+
+  # US is in the subnets of 192 and 172 while China is in the subnet of 10
+  if ($ipaddr =~ /^192|^172/) {
+    $site = "US";
+    unshift (@INC, "//sons-clearcase/Views/official/Tools/lib");
+  } elsif ($ipaddr =~ /^10/) {
+    $site = "CN";
+    unshift (@INC, "//sons-cc/Views/official/Tools/lib");
+  } else {
+    die "Internal Error: Unable to find our modules!\n"
+  } # if
+} # BEGIN
+
+use TriggerUtils;
+use cqc;
+
+%cqc::fields;
+
+# The following environment variables are set by Clearcase when this
+# trigger is called
+my $comment = $ENV{CLEARCASE_COMMENT};
+my $branch  = $ENV{CLEARCASE_BRTYPE};
+my $pname   = $ENV{CLEARCASE_PN};
+
+# Which vob we will look up labels in
+my $vob = "salira";
+
+my $bugid;
+
+sub ExtractBugID {
+  my $comment = shift;
+
+  my @fields  = split (/\W/,$comment);
+  my $bugid   = "unknown";
+
+  foreach (@fields) {
+    if (/BUGS2[0-9]{8}/) {
+      $bugid = $_;
+      last;
+    } # if
+  } # foreach
+
+  return $bugid;
+} # ExtractBugID
+
+sub ExtractBugIDs {
+  my $comment = shift;
+
+  my @fields  = split (/\W/,$comment);
+
+  # Use associative array to insure uniqueness
+  my %bugids;
+  # Return unique array
+  my @bugids;
+
+  foreach (@fields) {
+    if (/BUGS2[0-9]{8}/) {
+      $bugids{$_} = $_;
+    } # if
+  } # foreach
+
+  foreach (keys %bugids) {
+    push @bugids, $_;
+  }
+
+  return @bugids;
+} # ExtractBugIDs
+
+sub BugOnList {
+  my $bugid       = shift;
+  my $branch	  = shift;
+
+  my $found_bugid = 0;
+  my $bug         = "unknown";
+
+  # Excempt EMS code
+  return 1 if $pname =~ /salira\\ems/i;
+
+  # Excempt Hardware code
+  return 1 if $pname =~ /salira\\hardware/i;
+
+  # Exempt bug ID 2912
+  return 1 if $bugid eq "BUGS200002912";
+
+  # Exempt bug ID 3035
+  return 1 if $bugid eq "BUGS200003035";
+
+  my $filename;
+
+  if ($site eq "US") {
+    $filename = "//sons-clearcase/Views/official/Tools/bin/clearcase/triggers/data/$branch.lst";
+  } elsif ($site eq "CN") {
+   $filename = "//sons-cc/Views/official/Tools/bin/clearcase/triggers/data/$branch.lst";
+ } else {
+   die "Internal Error: Site not set properly! ($site)\n";
+ } # if
+
+  if (-f $filename) {
+    open (FILE, $filename) || die "Can't open $filename!\n";
+
+    while () {
+      $bug = ExtractBugID $_;
+      next if ($bug eq "unknown");
+      if ($bug eq $bugid) {
+	$found_bugid = 1;
+	last;
+      } # if
+    } # while
+
+    close (FILE);
+  } else {
+    clearlog "Skipping check because $filename does not exist!";
+    # Since there is no file list to check return that the bug id was found
+    $found_bugid = 1;
+  } # if
+
+  return $found_bugid;
+} # BugOnList
+
+sub LabelLocked {
+  # 04/28/2003: Oddity! All of a sudden this subroutine broke! I don't know
+  # why but even though we used to cd to the official view and issue our
+  # cleartool lslock command we started getting "Unable to determine VOB
+  # from pname" errors. Weird! Anyways we have changed to use the @ syntax instead. This means we must now specify the vob
+  # specifically. Fortunately we only have one vob to worry about at this
+  # time. On the plus side we no longer need to rely on the "official" view.
+  my $bugid = shift;
+
+  my $output = `cleartool lslock -short lbtype:$bugid@\\$vob 2>&1`;
+
+  if ($? == 0) {
+    return $output;
+  } else {
+    return 0;
+  } # if
+} # LabelLocked
+
+sub CheckComment {
+  my $comment = shift;
+  my $branch  = shift;
+
+  my @valid_branches = (
+    "main",
+    "rel_1.0",
+    "rel_2.0",
+    "rel_2.1",
+    "rel_2.2",
+    "rel_2.3",
+    "china_1.0",
+    "china_2.0",
+    "china_2.1",
+    "china_2.2",
+    "china_2.3",
+    "2.0_ga"
+  );
+
+  if ($comment eq "") {
+    clearlogmsg "You need to specify checkin comments";
+    return 1;
+  } # if
+
+  if (length $comment <= 4) {
+    clearlogmsg "The comment, '$comment' is too short!";
+    return 1;
+  } # if
+
+  if ($comment !~ m/.*BUGS2[0-9]{8}.*/) {
+    # Bug ID's are only required on certain branches
+    my $found = 0;
+
+    foreach (@valid_branches) {
+      if ($branch eq $_) {
+	$found = 1;
+	last;
+      } # if
+    } # foreach
+
+    if ($found == 1) {
+      clearlogmsg "Could not find bug ID in comment! This is required for the $branch branch";
+      return 1;
+    } # if
+  } # if
+
+  return 0;
+} # CheckComment
+
+sub CheckBugIDs {
+  my @bugs = @_;
+
+  my $result;
+
+  foreach my $bugid (@bugs) {
+    # Check if label is locked
+    if (LabelLocked ($bugid)) {
+      clearlog "Bug id $bugid is locked!";
+      clearmsg "Bug id $bugid is locked!\nSee your Clearcase Admin to unlock it";
+      return 1;
+    } # if
+
+    # Get Clearquest information
+    $result = cqc::GetBugRecord ($bugid, %fields);
+
+    if ($result == 0) {
+      # Make sure bug is owned
+      if ($fields {owner} eq "") {
+	clearlogmsg "No owner specified in Clearquest for bug ID $bugid.";
+	return 1;
+      } # if
+
+      # Make sure bug is in the correct state
+      if ($fields {state} ne "Assigned" and $fields {state} ne "Resolved") {
+	clearlogmsg "Bug ID $bugid is in the wrong state. It is in the " . $fields {state}. " state but should be in Assigned or Resolved state.";
+	return 1;
+      } # if
+    } elsif ($result > 0) {
+      clearlogmsg "Bug ID $bugid is not in Clearquest.";
+      return 1;
+    } else {
+      clearlogmsg "Clearquest Daemon (cqd) is not running!
+Please contact the Clearquest Administrator.";
+      return 1;
+    } # if
+
+    # Check if bug is on a branch list file
+    if (! BugOnList ($bugid, $branch)) {
+      clearlog "Bug ID $bugid is not on the list of acceptable bugs for the $branch branch!";
+      clearmsg "Bug ID $bugid is not on the list\nof acceptable bugs for the $branch branch!";
+      return 1;
+    } # if
+  } # foreach
+} # CheckBugIDs
+
+clearlog "Checkin checks started for $pname on $branch branch";
+
+if (CheckComment ($comment, $branch)) {
+  exit 1;
+} elsif (CheckBugIDs (ExtractBugIDs $comment)) {
+  exit 1;
+} # if
+
+clearlog "Successful precheckin of $pname on $branch branch with bug ID $bugid";
+
+exit 0;
diff --git a/clients/Salira/NotifyTrigger.pl b/clients/Salira/NotifyTrigger.pl
new file mode 100644
index 0000000..e2cbe69
--- /dev/null
+++ b/clients/Salira/NotifyTrigger.pl
@@ -0,0 +1,137 @@
+#!/usr/bin/perl
+################################################################################
+#
+# File:         NotifyTrigger.pl
+# Description:  This script is a generalized notify trigger. It takes one 
+#		parameter, a message file. The format of this file is similar
+#		to an email message. Environment variables will be substituted.
+# Assumptions:	Clearprompt is in the users PATH
+# Author:       Andrew@DeFaria.com
+# Created:      Tue Mar 12 15:42:55  2002
+# Language:     Perl
+# Modifications:
+#
+# (c) Copyright 2002, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+use strict;
+
+use Net::SMTP;
+
+my $mailhost;
+
+BEGIN {
+  # Add the appropriate path to our modules to @INC array. We use ipconfig to
+  # get the current host's IP address then determine whether we are in the US
+  # or China. Also set our mail server.
+  my @ipconfig = grep (/IP Address/, `ipconfig`);
+  my ($ipaddr) = ($ipconfig[0] =~ /(\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3})/);
+
+  # US is in the subnets of 192 and 172 while China is in the subnet of 10
+  if ($ipaddr =~ /^192|^172/) {
+    $mailhost="sons-exch02.salira.com";
+    unshift (@INC, "//sons-clearcase/Views/official/Tools/lib");
+  } elsif ($ipaddr =~ /^10/) {
+    $mailhost="sons-exch03.salira.com";
+    unshift (@INC, "//sons-cc/Views/official/Tools/lib");
+  } else {
+    die "Internal Error: Unable to find our modules!\n"
+  } # if
+} # BEGIN
+
+use TriggerUtils;
+
+# This routine will replace references to environment variables. If an
+# environment variable is not defined then the string  is
+# substituted.
+sub ReplaceText {
+  my $line = shift (@_);
+
+  my ($var, $value);
+
+  while ($line =~ /\$(\w+)/) {
+    $line =~ /\$(\w+)/;
+    $var = $1;
+    if ($ENV{$var} eq "") {
+      $line =~ s/\$$var/\/;
+    } else {
+      $value = $ENV{$var};
+      $value =~ s/\\/\//g;
+      $line =~ s/\$$var/$value/;
+    } # if
+  } # while
+
+  return $line;
+} # ReplaceText
+
+sub error {
+  my $message = shift;
+
+  clearlogmsg $message;
+
+  exit 1;
+} # error 
+
+# First open the message file. If we can't then there's a problem, die!
+open (MSG, $ARGV[0]) || error "Unable to open message file:\n\n$ARGV[0]\n\n($!)";
+
+my @lines = ;
+
+# Connect to mail server
+my $smtp = Net::SMTP->new ($mailhost);
+
+error "Unable to open connection to mail host: $mailhost" if $smtp == undef;
+
+# Compose message
+my $data_sent = "F";
+my $from_seen = "F";
+my $to_seen   = "F";
+my ($line, $from, $to, @addresses);
+
+foreach $line (@lines) {
+  next if $line =~ /^\#/;
+  next if $line =~ /--/;
+
+  $line = ReplaceText $line;
+
+  if ($line =~ /^From:\s+/) {
+    $_ = $line;
+    $from = $line;
+    s/^From:\s+//;
+    $smtp->mail ($_);
+    $from_seen = "T";
+    next;
+  } # if
+
+  if ($line =~ /^To:\s+/) {
+    $_ = $line;
+    $to = $line;
+    s/^To:\s+//;
+    @addresses = split (/,|;| /);
+    $to_seen = "T";
+    foreach (@addresses) {
+      next if ($_ eq "");
+      $smtp->to ($_);
+    } # foreach
+    next;
+  } # if
+
+  if ($data_sent eq "F") {
+    $smtp->data ();
+    $smtp->datasend ($from);
+    $smtp->datasend ($to);
+    $data_sent = "T";
+  } # if
+
+  if ($from_seen eq "T" && $to_seen eq "T" && $data_sent eq "T") {
+    $smtp->datasend ($line);
+  } else {
+    clearlogmsg "Message file ($ARGV[0]) missing From and/or To!";
+    exit 1;
+  } # if
+} # foreach
+
+$smtp->dataend ();
+$smtp->quit;
+
+exit 0;
diff --git a/clients/Salira/RemoveEmptyBranch.pl b/clients/Salira/RemoveEmptyBranch.pl
new file mode 100644
index 0000000..6b1f304
--- /dev/null
+++ b/clients/Salira/RemoveEmptyBranch.pl
@@ -0,0 +1,104 @@
+#!/usr/bin/perl
+################################################################################
+#
+# File:         RemoveEmptyBranch.pl
+# Description:  This trigger script is remove empty branches. If a branch has
+#               no elements (except the 0 element of course) after an uncheckout
+#               or rmver, or the parent of a just-rmbranched branch is now empty,
+#               remove it.
+#
+#		Install like this:
+#
+#		ct mktrtype -element -global -postop uncheckout,rmver,rmbranch \
+#		-c "Remove empty branches after uncheckout, rmver, or rmbranch" \
+#		-exec T:/Triggers/RemoveEmptyBranch RM_EMPTY_BRANCH
+# Assumptions:	Clearprompt is in the users PATH
+# Author:       Andrew@DeFaria.com
+# Created:      Fri May 23 13:23:47 PDT 2003
+# Language:     Perl
+# Modifications:
+#
+# (c) Copyright 2003, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+use strict;
+
+BEGIN {
+  # Add the appropriate path to our modules to @INC array. We use ipconfig to
+  # get the current host's IP address then determine whether we are in the US
+  # or China. If neither then we fallback to using T:/Triggers.
+  my @ipconfig = grep (/IP Address/, `ipconfig`);
+  my ($ipaddr) = ($ipconfig[0] =~ /(\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3})/);
+
+  # US is in the subnets of 192 and 172 while China is in the subnet of 10
+  if ($ipaddr =~ /^192|^172/) {
+    unshift (@INC, "//sons-clearcase/Views/official/Tools/lib");
+  } elsif ($ipaddr =~ /^10/) {
+    unshift (@INC, "//sons-cc/Views/official/Tools/lib");
+  } else {
+    die "Internal Error: Unable to find our modules!\n"
+  } # if
+} # BEGIN
+
+use TriggerUtils;
+
+# The following environment variables are set by Clearcase when this
+# trigger is called
+my $xname  = $ENV{CLEARCASE_XPN};
+my $opkind = $ENV{CLEARCASE_OP_KIND};
+my $xn_sfx = $ENV{CLEARCASE_XN_SFX};
+my $os     = $ENV{OS};
+my $brtype = $ENV{CLEARCASE_BRTYPE};
+#clearlog "Checking to see if the branch is empty and needs to be removed";
+#clearlog "xname  = $xname";
+#clearlog "opkind = $opkind";
+#clearlog "xn_sfx = $xn_sfx";
+#clearlog "os     = $os";
+
+$xname =~ s/\\/\//g if $ENV{OS} eq "Windows_NT";
+
+# For uncheckout, if the remaining version is not 0 then we are done;
+exit 0 if ($opkind eq "uncheckout" && $xname !~ m/\/0$/);
+
+#clearlog "Continuing...";
+my $branch;
+
+($branch = $xname) =~ s/\/[^\/]*$//;
+
+#clearlog "branch = $branch; xname = $xname";
+
+# Don't try to remove the /main branch
+exit 0 if $branch =~ m/\@\@\/main$/;
+
+# Check if there are other versions, branches, labels or checked out versions
+# on this branch. If so don't do anything.
+if (opendir (D, $branch)) {
+  # This opendir succeeds only in a dynamic view
+  #clearlog "In dynamic view!";
+  my @other_stuff = readdir (D);
+  closedir (D);
+
+  # In an empty branch there are four things: ".", "..", "0" an d"LATEST".
+  # If there are more then it isn't an empty branch
+  exit if (scalar (@other_stuff) != 4);
+} else {
+  # Snapshot views.
+  #clearlog "In snapshot view!";
+  my ($pname, $brpath) = split ($xn_sfx, $branch);
+  #clearlog "pname = $pname; brpath = $brpath";
+  # rmbranch will not reload the element...
+  system "cleartool update -log /dev/null \"$pname\"" if ($opkind eq "rmbranch");
+  my @vtree = `cleartool lsvtree -branch $brpath \"$pname\"`;
+  my $latest;
+  chomp ($latest = pop (@vtree));
+  $latest =~ tr/\\/\// if $os eq "Windows_NT";
+  #clearlog "latest = $latest";
+  exit 0 unless $latest =~ m/$brpath\/0$/;
+} # if
+
+# Remove the branch!
+clearlog "After $opkind branch is empty - removing empty branch $brtype";
+#clearlog "About to cleartool rmbranch -force -nc \"$branch\"";
+system "cleartool rmbranch -force -nc \"$branch\"";
+
+exit 0;
diff --git a/clients/Salira/SetOwnershipTrigger.pl b/clients/Salira/SetOwnershipTrigger.pl
new file mode 100644
index 0000000..e7cfd03
--- /dev/null
+++ b/clients/Salira/SetOwnershipTrigger.pl
@@ -0,0 +1,29 @@
+################################################################################
+#
+# File:         SetOwnershipTrigger.pl
+# Description:  This script will set the ownership of Clearcase elements to 
+#		ccadmin when a mkelem is performed. This way all Clearcase
+#		elements will be owned by ccadmin and therefore nobody but
+#		ccadmin will be able to do the destructive rmelem.
+# Author:       Andrew@DeFaria.com
+# Created:      Wed Nov 14 16:41:48  2001
+# Language:     Perl
+# Modifications:
+#
+# (c) Copyright 2001, Andrew@DeFaria.com, all rights reserved
+#
+################################################################################
+$pname = "$ENV{CLEARCASE_PN}";
+$adm   = "ccadmin";
+
+# Get current owner
+$_ = `cleartool describe $pname`;
+if (/User :\s+(\S*)\s*:/) {
+  $owner = $1;
+} else {
+  $owner = "";
+}
+
+if ($owner ne "$adm") {
+ `cleartool protect -chown $adm $ENV{CLEARCASE_PN}`;
+}