Open Computing ``Hands-On'': ``Wizard's Grabbag'' Column: April 1994: Listings

Listing 1. A Perl program is suitable to summarize system data. The uuhistory program shown here summarizes the logs written by HoneyDanBer UUCP programs.
  1  #!/usr/bin/perl
  2  # @(#) uuhistory  History log file summary
  3  # Author: Michael P. Brininstool
  4  # Adapted by Becca Thomas, December 1993
  5  #
  6  # Define default log-file path names:
  7  $logdir="/var/uucp/.Log";   # Log files under here
  8  $logcico="$logdir/uucico";  # uucico logs
  9  $loguux="$logdir/uux";      # uux logs
 10  $loguucp="$logdir/uucp";    # uucp logs
 11  $loguuxqt="$logdir/uuxqt";  # uuxqt logs
 12  
 13  $fflag = 0; $logfile = "";
 14  
 15  # Get host names from command line or by running uuname:
 16  if (@ARGV) {                # If command-line arguments
 17    if ($ARGV[0] eq "-f") {   # and if user specifies log file
 18      $fflag++; shift;        # note it, then discard -f flag
 19      $logfile = shift;       # and save file name
 20      die "Can't read $logfile: $!: stopped" unless -r $logfile;
 21      @hosts = ("dummyhost"); # only once around outermost loop
 22    } else {
 23      @hosts=@ARGV;           # The rest should be host names
 24    }
 25  } else {
 26    open(UUNAME,"uuname|")  ||  # Read uuname output?
 27      die "Can't run uuname: $!: stopped";
 28    @hosts=;          # Read them all at once
 29    chop(@hosts);             # Remove newline from each name
 30    close(UUNAME);
 31  }
 32  
 33  # So all output can be sorted by date and time:
 34  open(SORT, "|sort") || die "Can't run sort: $!: stopped";
 35  
 36  # Examine log files:
 37  foreach $host (@hosts) {    # For each host
 38  
 39    # Examine UUCICO log for host:
 40    $logfile = "$logcico/$host" unless $fflag;
 41    if (open(LOG,"$logfile")) {   # Failure isn't fatal
 42      @lines=(grep(/OK|SUCCEEDED|FAILED|CAUGHT|INTREXIT/,));
 43      close(LOG) unless $fflag;
 44  
 45      $sdate="";
 46      # Process each line selected from the uucico log:
 47      foreach $line (@lines) {
 48        chop($line);
 49        ($user, $sys, $date, $files, $statmsg) = $line =~
 50          /^(\S+)\s+(\S+)\s+\((.*),\d+,(\d+)\)(.*)$/;
 51        $date = &formatdate($date);
 52        $_ = $statmsg; # Using $_ simplifies matching test syntax
 53  
 54        # Process entries depending on status messages:
 55        if (/SUCCEEDED/) {  # Outbound call reached target system
 56          $sdate=$date; $direction="->";
 57        } else {        #
 58          if (/startup/) {  # Start of transaction
 59            $direction = "<-" unless $direction eq "->";
 60            $sdate=$date;
 61          } else {      # End of transaction
 62            if (/complete|CAUGHT|INTREXIT/) {
 63              if (/OK/) { # Successful transaction
 64                # Compute transaction time as hh:mm:ss
 65                ($tty, $sec) = /.*\s(\S+)\s(\d+)\)$/;
 66                $hr = int($sec / 3600); $sec -= ($hr * 3600);
 67                 $min = int($sec / 60);  $sec -= ($min * 60);
 68                $time = sprintf("in %2d:%2d:%2d",
 69                  $hr, $min, $sec);
 70                $time =~ tr/ /0/; $time =~ s/in0/in /;
 71              } else {  # FAILED, CAUGHT, INTREXIT, or ???
 72                $tty=""; $time = $statmsg;
 73              }
 74              printf SORT "%s to %s %s %s %s %s files %s\n",
 75                $sdate, $date, $tty, $direction,
 76                $sys, $files, $time;
 77            } else {  # Not "complete", CAUGHT, or INTREXIT
 78              printf SORT "%s %s %s\n", $date, $sys, $statmsg;
 79            }       # End of "complete" or "CAUGHT" section
 80          $direction = ""; $sdate = ""; # Reset before next transaction
 81          }         # End of else "startup" section
 82        }           # End of else /SUCCEEDED/ section
 83      }             # End of foreach $line (@lines)
 84    }               # End of if open $logfile
 85  
 86    # Examine UUCP and UUX logs for host:
 87    if ($fflag) {   # User-specified log file
 88      &report("");  # Log file already open
 89    } else {
 90      $logfile = "$loguux/$host";
 91      &report("$logfile");  # The uux cmd report
 92      $logfile = "$loguucp/$host";
 93      &report("$logfile");  # The uucp cmd report
 94    }
 95  
 96    # Examine uuxqt[RIK: CAP?] log for host:
 97    if ($fflag) {
 98      seek(LOG, 0, 0) ||    # Begin again
 99        die "Can't seek: $!: stopped";
100    } else {
101      $logfile = "$loguuxqt/$host";
102      open(LOG,"$logfile") || next;   # done with this host
103    }
104    @lines=(grep(/XQT/,)); # "XQT" entries only
105    close(LOG);             # Done
106  
107    foreach $line (@lines) {
108      chop($line);
109      ($date, $user, $command) = $line =~
110        /^.*\((.*),\d+,\d+\)\s+(\S+)\s+XQT\s+\(.*;(.*)\)$/;
111      $date = &formatdate($date);
112      printf SORT "%s uuxqt for %s: %s\n",
113        $date, $user, $command;
114    }
115  }   # End of foreach $host (@hosts)
116  close(SORT);              # Flush
117  exit 0;
118  
119  # Generate report from logs written by uucp and/or uux
120  sub report {
121    local($line, $user, $sys, $date, $command);
122    local($file) = @_;
123  
124    if ($file) {            # Log file specified
125      open(LOG,"$file") || return;
126    } else {                # Log opened earlier
127      seek(LOG, 0, 0) ||    # Back to beginning
128        die "Can't seek: $!: stopped\n";
129    }
130    @lines=(grep(/QUEUED/,));  # "QUEUED" entries only
131    close(LOG) if $file;    # Done with named log
132  
133    foreach $line (@lines) {
134      chop($line);
135      ($user, $sys, $date, $command) = $line =~
136        /^(\S+)\s(\S+)\s.*\((.*),\d+,\d+\)\sQUEUED\s\((.*)\)$/;
137      $date = &formatdate($date);
138      printf SORT "%s %s queued for %s: %s\n",
139        $date, $user, $sys, $command;
140    }
141  }
142  
143  # Reformat the date for easier sorting:
144  sub formatdate {
145    local($mon, $day, $hr, $min, $sec);
146    local($date) = @_;
147  
148    ($mon, $day, $hr, $min, $sec) = $date =~
149      /^(\d+)\/(\d+)-(\d+):(\d\d):(\d\d)$/;
150    $fdate = sprintf("%2s/%2s-%2s:%2s:%2s",
151      $mon, $day, $hr, $min, $sec);
152    $fdate =~ tr/ /0/;  # pad with zeros, not spaces
153    $fdate;             # Return this value
154  }

Listing 2. The krand Korn shell script generates a random number in a specified range with an optionally specified ``seed'' value.

 1  #!/bin/ksh
 2  # @(#) krand  Produces a random number within integer limits
 3  # Author: Peter Turnbull, May 1993
 4  # Modified by: Becca Thomas, January 1994
 5  $DBG_SH         # dormant debugging directive (Apr. 92)
 6  Usage="Usage: `basename $0` lower-limit upper-limit [seed]"
 7  
 8  Seed=$$         # Initialize random-number seed value with PID
 9  # Process command-line arguments:
10  case $# in
11      2)  Lower=$1; Upper=$2 ;;
12      3)  Lower=$1; Upper=$2; Seed=$3 ;;
13      *)  echo $Usage >&2 ; exit 1 ;;
14  esac
15  
16  # Check that specified values are integers:
17  expr "$Lower" + 0 >/dev/null 2>&1
18  [ $? -eq 2 ] && { echo "Lower ($Lower) not an integer" >&2; exit 2;}
19  
20  expr "$Upper" + 0 >/dev/null 2>&1
21  [ $? -eq 2 ] && { echo "Upper ($Upper) not an integer" >&2; exit 2;}
22  
23  expr "$Seed" + 0 >/dev/null 2>&1
24  [ $? -eq 2 ] && { echo "Seed ($Seed) not an integer" >&2; exit 2;}
25  
26  # Check that values are in the correct range:
27  [ "$Lower" -lt 0 -o `expr "$Lower" : '.*'` -gt 5 ] &&
28      { echo "Lower limit ($Lower) less than zero" >&2; exit 2;}
29  
30  [ "$Upper" -gt 32767 -o `expr "$Upper" : '.*'` -gt 5 ] &&
31      { echo "Upper limit ($Upper) greater than 32767" >&2; exit 2;}
32  
33  [ "$Seed" -lt 0 -o "$Seed" -gt 32767 -o `expr "$Seed" : '.*'` -gt 5 ] &&
34      { echo "Seed value ($Seed) out of range (0 to 32767)" >&2; exit 2;}
35  
36  [ "$Upper" -le "$Lower" ] &&
37      { echo "Upper ($Upper) <= lower value ($Lower)" >&2; exit 2;}
38  
39  # Seed the random-number generator:
40  RANDOM=$Seed
41  
42  # Compute value, scaled within range:
43  let rand="$RANDOM % ($Upper - $Lower + 1) + $Lower"
44  
45  # Report result:
46  echo $rand

Copyright © 1995 The McGraw-Hill Companies, Inc. All Rights Reserved.
Edited by Becca Thomas / Online Editor / UnixWorld Online / beccat@wcmh.com

[Go to Contents] [Search Editorial]

Last Modified: Tuesday, 22-Aug-95 16:23:41 PDT