DB2 ist ein Produkt der
IBM Corporation. Bitte Copyright- und Trademark-Hinweise beachten!
#!/usr/local/bin/perl -w
################################################################################
# xmp DBA Perl Funktions-Package:
# - Einbau mit "use xmpPerl;"
# - Nutzung mit "xmpPerl::fn(...);", wobei fn=Funktion
#-------------------------------------------------------------------------------
# @|$ = trim(@|$);Cut-off Leading/Trailing Blanks
# $ = doCmdOut($);Run External Command and return Output
# $ = doDB2CmdOut(db u p cmd); Run DB2 Command and return Output, incl. Connect
# $ = getSqllibPath(); DB2 Path suchen in PATH und z’ckgeben
# $ = getTimestamp(); Datum/Uhrzeit im DB2 Timestamp Format
# $ = getTime(); Uhrzeit
# - = LogLine(@|$); Meldung in Log protokollieren, ruft ...File|Table
# - = LogLineFile(@|$); Meldung in Log File protokollieren
# - = LogLineTable(@|$); Meldung in Log Table protokollieren
# $ = getProcDescr(); Für Process ID den Process Namen und Argumente
# $ = getDBMCfgValue(var); Liefert Wert eines DBM Config Parameters
# $ = getDBCfgValue(db,var); Liefert Wert eines Database Config Parameters
# $ = getDBAUser(); Liefert Wert der lP_LUS Umgebungsvariablen
# $ = getDBAPsw(); Liefert Wert der lP_LPW Umgebungsvariablen
# $ = getDBALog(); Liefert Wert der lP_LOG Umgebungsvariablen oder Default
# $ = getDBALDB(); Liefert Wert der lP_LDB Umgebungsvariablen oder Default
# $ = getCTRL(); Liefert Wert der lP_CTRL Umgebungsvariablen oder Default
# - = prtHeaderDB2($); Gibt einen Informationblock aus für Scripts mit DB2
# - = chkDB2(); Prüft Existenz von DB2
# $ = getDB2Version(); Liefert DB2 Version und Release
# $ = MailText(); Sendet Text via sendmail
#-------------------------------------------------------------------------------
# Changes - GR / 10.01.00 erste Version
# G.Ruban / 02.02.2000V1.1neue Funktion getDBCfgValue und getDBMCfgValue,
# getDBALog
# G.Ruban / 02.02.2000V1.1in LogLineTable den Empfang der Argumente korrigiert
# G.Ruban / 29.05.2000V1.2getDBAUser/getDBAPsw: User und Passwort aus Umgebungs-
# variablen, doDB2CmdOut um Parms -u und -p erweitert,
# G.Ruban / 31.05.2000V1.3neue Funktion prtHeader(), getINSTHOME, chkDB2
# und getDBALDB angelegt, LogLine...'s überarbeitet
# G.Ruban / 13.07.2000V1.3.1Logging in DBA Control DB problematisch, deswegen
# nur Logging in File, getProcDescr geändert
# G.Ruban / 28.08.2000V1.3.2Log Path für xmpdba.log aus ENV Variable, falls vorh.
# G.Ruban / 29.08.2000V1.3.2chmod für xmpdba.log wg. Permissions, sysopen wirkungslos
# G.Ruban / 17.07.2001V1.3.3neue Funktion getDB2Version()
# G.Ruban / 05.12.2001V1.3.4neue Funktion MailText(), neue Variable lP_CTRL
# G.Ruban / 11.12.2001V1.3.5neue Funktion getTime()
# G.Ruban / 19.12.2001 V1.3.5 Korrektur beim Einlesen von Recipient Lists
# G.Ruban / 30.01.2002 V1.3.6 Delete temporary file if work has been done
# G.Ruban / 12.02.2002 V1.3.6 Fixed problem with temp files
#-------------------------------------------------------------------------------
# Comments - $drh = DBI Driver Handle
# $dbh = DBD Database Handle
# $sth = SQL Statement Handle
# - PERL5LIB Environment Variable muss auf Perl Module Pfad zeigen,
# damit dieses Modul in Perl Scripts eingebunden werden kann.
################################################################################
package xmpPerl;
use vars qw(@ISA @EXPORT @EXPORT_OK);
use Exporter;
use Fcntl;# V1.3.2 File Constants
use strict;# strikte semantische/syntaktische Prüf.
use File::Basename;# V1.3.6
################################################################################
# Konstanten {Prefix lP für alle Package Variablen}
################################################################################
my $lP_VER = "1.3.6";# Package Version
my $lP_PRG = "xmpPerl.PM"; # Program Name
# Logging Variablen: ###################
my $lP_LTB = "TLX90000";# Logging Table by package
my $lP_LTC = "xmpDBA";# Logging Table Creator function
my $lP_LOG = "/opt/xmpdba/log/xmpdba.log";# Logging File
my $lP_CTRL= "/opt/xmpdba/ctrl";# Control File Path
################################################################################
# Export von Variablen (würden die Funktionsnamen ebensfalls aufgeführt, dann
# könnte in den nutzenden Moduln das Prefix "xmpPerl::" entfallen!
################################################################################
@ISA = ('Exporter');
@EXPORT = qw($lP_VER $lP_PRG $lP_LDB $lP_LTB $lP_LTC $lP_LUS $lP_LPW $lP_LOG $lP_CTRL);
################################################################################
# getDBALog: liefert Inhalt der Variablen lP_LOG zurück (Pfad für DBA-Meldungen)
################################################################################
sub getDBALog {
my $OS = ucfirst $^O;
if (! defined $ENV{lP_LOG}) {
if (! defined $ENV{xmpDBADIR})
{ if ($OS eq "Aix") { return "/opt/xmpdba/log/xmpdba.log";}
if ($OS eq "Solaris") { return "/opt/xmpdba/log/xmpdba.log";}
}
else { return trim($ENV{xmpDBADIR}."/log/xmpdba.log") }
}
else { return trim($ENV{lP_LOG});
}
}
################################################################################
# getCTRL: liefert Inhalt der Variablen lP_CTRL zurück (Pfad für Control Files)
################################################################################
sub getCTRL {
my $OS = ucfirst $^O;
if (! defined $ENV{lP_CTRL}) {
if (! defined $ENV{xmpDBADIR})
{ if ($OS eq "Aix") { return "/opt/xmpdba/ctrl";}
if ($OS eq "Solaris") { return "/opt/xmpdba/ctrl";}
}
else { return trim($ENV{xmpDBADIR}."/ctrl") }
}
else { return trim($ENV{lP_CTRL});
}
}
################################################################################
# getDBAUser: liefert Inhalt der Variablen lP_LUS (autorisierte DB2 User) zurück
################################################################################
sub getDBAUser {
if (! defined $ENV{lP_LUS})
{ return "";}
else
{ return trim($ENV{lP_LUS});}
}
################################################################################
# getDBAPsw: liefert Inhalt der Variablen lP_LPW (Password DB2 User) zurück
################################################################################
sub getDBAPsw {
if (! defined $ENV{lP_LPW})
{ return "";}
else
{ return trim($ENV{lP_LPW});}
}
################################################################################
# getDBALDB: liefert Inhalt der Variablen lP_LDB (DBA Logging Database) zurück
################################################################################
sub getDBALDB {
if (! defined $ENV{lP_LDB})
{ return "";}
else
{ return trim($ENV{lP_LDB});}
}
################################################################################
# trim: Cut-off Leading/Trailing Blanks
################################################################################
sub trim {
my @out = @_;
for (@out) {
s/^\s+//;
s/\s+$//;
}
return wantarray ? @out : $out[0];
}
################################################################################
# doCmdOut: Run External Command and return Output
################################################################################
sub doCmdOut {
my $output;
open(xmptmp,"@_ |") or die ">>>Kann externen Command nicht ausführen!\n".
"RC=$!\nCMD=@_\n";
while(<xmptmp>) {
$output .= $_; # concat Output Lines
}
close(xmptmp);
return $output;
}
################################################################################
# doDB2CmdOut: Run DB2 Command and return Output, Connect to DB if necessary
################################################################################
sub doDB2CmdOut {
my ($opt_d, $opt_u, $opt_p, $opt_c);
my $output;
my $connect = 0;
my $work;
################################################################################
# get database and db2 command
################################################################################
($opt_d , $opt_u, $opt_p, $opt_c ) = @_;
################################################################################
# already connected or not
################################################################################
$work = &doCmdOut("db2 connect");
if ( $work =~ "SQLSTATE=08003") {# connection does not exist
$work = "db2 connect to $opt_d user $opt_u using $opt_p";
$output = &doCmdOut($work);
if ($output !~ "Connection Information") {
return $output;}# connect failed
}
else {$connect = 1 }# already connected
################################################################################
# execute DB2 command
################################################################################
$output = &doCmdOut($opt_c);
################################################################################
# disconnect, if necessary
################################################################################
if ($connect == 1) {$work = &doCmdOut("db2 connect reset")}
return $output;
}
################################################################################
# getSqllibPath: DB2 Library Path ermitteln
################################################################################
sub getSqllibPath {
use Env;
my $work;
my @work;
my $LP = "";
$work = trim($ENV{PATH});# Environment Variable set by DB2
@work = split(/:/,$work);# remove separator
foreach $work (@work) {# search list for sqllib
if ($work =~ /sqllib/) {
$LP = $work;
last;
}
}
return $LP;# undefined if not found
}
################################################################################
# getTimestamp: Datum im DB2 Timestamp Format ermitteln
################################################################################
sub getTimestamp {
my $TS;
$TS = `date +%Y-%m-%d-%H.%M.%S`;# yyyy-mm-dd-hh.mm.ss
$TS = &trim($TS);
$TS.= ".000000";# milliseconds = 0
return $TS;
}
################################################################################
# getTime: Datum im DB2 Timestamp Format ermitteln
################################################################################
sub getTime {
my ($s,$m,$h);
($s,$m,$h) = (localtime)[0,1,2];# Local Time
$s = sprintf("%02u",$s);# rechtsbündig mit 0
$m = sprintf("%02u",$m);# rechtsbündig mit 0
$h = sprintf("%02u",$h);# rechtsbündig mit 0
return "$h:$m:$s";# hh:mm:ss
}
################################################################################
# LogLine: Message in DBA Log File und Table schreiben
################################################################################
sub LogLine {
&LogLineFile(@_);
#&LogLineTable(@_);inaktiviert 11.07.2000/GR
}
################################################################################
# getDB2Version: Provide DB2 Release and Version Information 17.07.01
################################################################################
sub getDB2Version {
my $V="";
my $Vl;
my @VA;
# db2licm -v works fine with V6 and V7, but not with V5
$V = &doCmdOut("db2level");
@VA = split(" ",$V);
$V = &trim($VA[16]);# 17th word
$Vl = length($V);
$V = substr($V,1,$Vl-3);# skip 1, cut off 2(+1)
return $V;
}
################################################################################
# LogLineFile: Message in DBA Log File schreiben
################################################################################
sub LogLineFile {
my $hMSGLOG; # Log Datei Handle
my $UDT;
# Auf Message Log schreiben, sofern möglich ############################
$UDT = &getTimestamp();
$UDT = substr($UDT,0,19);
if ( open(hMSGLOG, ">> $lP_LOG") ) {
print hMSGLOG "$UDT @_\n";
close(hMSGLOG);
chmod 0664,$lP_LOG;
return 0;}
else { print ">>> $lP_PRG Es kann nicht in $lP_LOG geschrieben werden.\n";
print ">>> $lP_PRG Letzte Meldung lautete: $UDT @_\n";
return 8;}
}
################################################################################
# LogLineTable: Message in DBA Log Table schreiben
# Arguments : (1) Application
# (2) State
# (3) Message
################################################################################
sub LogLineTable {
# Modules ####################################################################
use DBI;
use DBD::DB2::Constants;
use DBD::DB2;
use Sys::Hostname;
my ($hostname,$udt,$stmt);
use Getopt::Std;
use vars qw($opt_a $opt_s $opt_t $opt_d $opt_u $opt_p);
# Argumente ############################################################
getopts("a:s:t:d:u:p:");
if ( (! defined $opt_a )# Application
or (! defined $opt_s ) # Severity
or (! defined $opt_d ) # DBA Database
or (! defined $opt_u ) # User
or (! defined $opt_p ) ) {# Password
&LogLineFile(">>> $lP_PRG Problem mit Connect to $opt_d");
&LogLineFile(">>> $lP_PRG ".$DBI::errstr);
&LogLineFile("@_");
return 8;
}
# DBI Switches #########################################################
my $switch = DBI->internal;
$switch->debug(0); # 1=normal debug, 2=detailed handle trace
# Connect to Database ##################################################
my $dbh = DBI->connect("dbi:DB2:$opt_d",
$opt_u,
$opt_p,
{ PrintError => 0, # don't print error by default
RaiseError => 0, # don't print error and die by default
AutoCommit => 1, # don't commit after each statement
ChopBlanks => 0, # don't remove trailing blanks on CHAR-Types
} );
if (!$dbh) {
&LogLineFile(">>> $lP_PRG Problem mit Connect to $opt_d");
&LogLineFile(">>> $lP_PRG ".$DBI::errstr);
&LogLineFile("@_");
return 8;
}
else {
# Build and Execute SQL Statement ######################################
$hostname = hostname();
$udt = &getTimestamp();
$stmt = "INSERT INTO $lP_LTC.$lP_LTB
(HOST, APPLICATION, STATE,
MESSAGE, TIMESTAMP)
VALUES ('$hostname','$opt_a', '$opt_s','$opt_t','$udt')";
my $sth = $dbh->prepare($stmt);
$sth->execute();
if ( $dbh->err ) {
&LogLineFile(">>> $lP_PRG Problem mit Insert into $opt_d");
&LogLineFile(">>> $lP_PRG ".$DBI::errstr);
&LogLineFile("@_");
#return 8;
}
# Disconnect from Database #####################################
$sth->finish();
$dbh->disconnect();
}
}
################################################################################
# getProcDescr: zu einer Process ID den Command und Argument verschaffen
################################################################################
sub getProcDescr {
my $id;
# execute PS command, ignore Output line containing the word COMMAND ###
$id = &doCmdOut("ps -p " . getppid . " -f | grep -v CMD");
$id = "PS=".&trim($id);
return $id;
}
################################################################################
# getDBMCfgValue: zu einem DBM Config Parameter den Wert ermitteln
################################################################################
sub getDBMCfgValue {
my $work;
my @work;
my $var;
my $val;
################################################################################
# Beschaffen der Datenbank Manager Configurationsvariablen
################################################################################
$work = &doCmdOut("db2 get dbm cfg");
@work = split("\n",$work);
#print "$#work lines returned from DB2 GET DBM CFG Command.\n";
foreach $work (@work) {
($var,$val) = split("=",$work);
if (! defined $var) {$var = "";}
if (! defined $val) {$val = "";}
$var = uc &trim($var);
#$val = uc &trim($val);
#######################################################################
if ($var =~ "@_") {# gesuchte Variable gefunden
$val = &trim($val);# nochmals Blanks entfernen
return $val;# Ja, denn Wert zur’ckgeben
}
}
return;
}
################################################################################
# getDBCfgValue: zu einer Datenbank von einem Config Parameter den Wert ermitteln
################################################################################
sub getDBCfgValue {
my $work;
my @work;
my $var;
my $val;
my ($opt_d, $opt_v);
################################################################################
# Argument sind Database und Database Cfg Variable (z.B. MAXAPPLS)
################################################################################
($opt_d , $opt_v ) = @_;
################################################################################
# Beschaffen der Datenbank Configurationsvariablen
################################################################################
$work = &doCmdOut("db2 get db cfg for $opt_d");
@work = split("\n",$work);
#print "$#work lines returned from DB2 GET DB CFG FOR $opt_d Command.\n";
foreach $work (@work) {
($var,$val) = split("=",$work);
if (! defined $var) {$var = "";}
if (! defined $val) {$val = "";}
$var = uc &trim($var);
#$val = uc &trim($val);
#######################################################################
if ($var =~ "$opt_v") {# gesuchte Variable gefunden
$val = &trim($val);# nochmals Blanks entfernen
return $val;# Ja, denn Wert zur’ckgeben
}
}
return;
}
################################################################################
# prtHeaderDB2: Gibt Informationsblock für Scripts mit DB2 Nutzung aus
################################################################################
sub prtHeaderDB2 {
use Env;
use Sys::Hostname;
my $DB2INSTANCE;
my $DB2Version;# 17.07.2001
my $UDT;
my $SSID;
my $HOST;
my $OS;
########################################################################
# Environment and Shell Variables
########################################################################
$UDT = &trim(getpwuid($<)." ".`date`);# get user name
$HOST = hostname();
$OS = ucfirst $^O;
$DB2Version = &getDB2Version();# 17.07.2001
########################################################################
# Clear Bildschirm und Infoblock ausgeben
########################################################################
system("clear");
print "##############################\n";
print "@_\n";
print "Current User/Date/Time ......: $UDT\n";
print "Current and Parent Process ID: $$ ".getppid."\n";
if (&getSqllibPath() ne "") {
$SSID = &trim(`db2set DB2SYSTEM -g`);# DB2 System ID
print "Current System / OS / SSID...: $HOST / $OS / $SSID \n";
$DB2INSTANCE = &trim($ENV{DB2INSTANCE});# DB2 Instance
print "Current Instance and Version : $DB2INSTANCE / DB2 V$DB2Version\n";
print "Current Instance Home Dir ...: ".&getSqllibPath()."\n";
}
else {
print "Current System / OS .........: $HOST / $OS\n";
}
}
################################################################################
# chkDB2: Prüft Existenz von DB2
################################################################################
sub chkDB2 {
########################################################################
# Wurde 'sqllib' im Pfad (PATH) gefunden?
########################################################################
if (&getSqllibPath() eq "")
{die ">>>Kann DB2 Instanz-Pfad .../sqllib/... nicht finden\n".
">>>DB2 Instance Path nicht gesetzt - ABEND";
}
}
################################################################################
# MailText: Sends Text (File) using Recipient (List File)
# returns recipient(s) ID
################################################################################
sub MailText {
my ($opt_a, $opt_v, $opt_t);
my ($rlist, $text, $dmr, $dmt);
my $tempfile;
my $work;
my $hFile;
my ($pak,$script,$line) = caller(0);
########################################################################
# Get arguments: Application Name, Recipient (File), Text (File)
########################################################################
($opt_a, $opt_v , $opt_t ) = @_;
#print "a=$opt_a v=$opt_v t=$opt_t\n";
if ( (! defined $opt_a )# Application
or (! defined $opt_v ) # Recipient (File)
or (! defined $opt_t ) # Text (File)
or ($opt_a eq "" )# Application
or ($opt_v eq "" )) {# Recipient (File)
print ">>>xmpPerm.pm: Invalid options specified for function MailText()\n";
exit 16;
}
########################################################################
# Recipient is single ID or name of a recipient file
########################################################################
$dmr = "";
if (-r $opt_v) {
$dmr = $opt_v;# correct file name
}
else {
#####################################################################
# File exists in /opt/xmpdba/ctrl ?
#####################################################################
if (-r &getCTRL()."/".$opt_v) {# file in /opt/xmpdba/ctrl?
$dmr = &getCTRL()."/".$opt_v;
}
}
#print "opt_v->$dmr\n";
########################################################################
# Text is a string or name of a text file
########################################################################
$text = $opt_t;
$dmt = "";
if (-r $opt_t) {
$dmt = $opt_t;# correct file name
}
########################################################################
# Open temporary file to create mail text file, add recipient(s)
########################################################################
$script = basename($script);
$tempfile="/tmp/$script.$$-0";
#print "==> TEMPFILE=$tempfile\n";
if (! open(hFile, "> $tempfile") ) {
die ">>>$0 cannot write into $tempfile. \n".
"abends";
}
########################################################################
# Argument contains recipient file name or single recipient mail id
########################################################################
if ($dmr ne "") {# Yes, it is a file
#####################################################################
# Read recipient id's from file
#####################################################################
$/ = "\n";# input record separator
if (! open(xmptmp,"<$dmr") ) {
die ">>>$0: Cannot read recipient file in function MailText()!\n".
">>>File=$dmr\n";
}
$rlist = "";
while(<xmptmp>) {
next if /#/;# skip comment line
next if /^$/;# skip blank line
print hFile "$_";# print line to text file
$rlist .= $_;# concat lines
}
close(xmptmp);
if ($rlist eq "") {
print ">>>$0 read $dmr successfully\n".
">>>but did not determine any E-Mail ID - please check file!\n".
">>>Program sendmail will fail with 'No recipient addresses found in header'\n";
}
#####################################################################
# Attention: Do not allow blank lines between To:, Cc:, Bcc:, Subject:
#####################################################################
}
else {
print hFile "To:$opt_v\n";# print id to text file
$rlist = "To:$opt_v";
}
########################################################################
print hFile "Subject: ". uc hostname().": '$opt_a' at ".&getTimestamp()."\n";
print hFile "-----------------------------------------------------------\n";
print hFile "Automatic generated Mail Messsage from ...\n";
print hFile "Host ..........: ". uc hostname()."\n";
print hFile "Application ...: $opt_a\n";
print hFile "Created at ....: ".&getTimestamp()."\n";
print hFile "-----------------------------------------------------------\n";
########################################################################
# Text is a string or name of a text file
########################################################################
if ($dmt ne "") {# Yes, it is a file
open(xmptmp,"<$dmt") or die ">>>xmpPerl.pm: Cannot read mail text file ".
"in function MailText()!\n".
"File=$dmt\n";
while(<xmptmp>) {
print hFile "$_"; # each line
}
close(xmptmp);
}
else {
print hFile "$text\n";# only text passed
}
print hFile ".\n";# end of mail
close(hFile);# close tempfile
########################################################################
# Send mail using sendmail program
########################################################################
system("/usr/lib/sendmail -t < $tempfile");
die ">>>xmpPerl.pm: /usr/lib/sendmail -t < $tempfile ends with RC=$?\n" unless $?==0;
unlink($tempfile);
return $rlist;
}
1;
© Gernot Ruban