Annotation of loncom/build/CHECKRPMS_custom, revision 1.1

1.1     ! harris41    1: #!/usr/bin/perl
        !             2: 
        !             3: =pod
        !             4: 
        !             5: =head1 CAVEAT USER
        !             6: 
        !             7: This is a modified version of CHECKRPMS, and should be installed
        !             8: as a file named "CHECKRPMS_custom".  Generally, this file should
        !             9: be placed at /usr/local/CHECKRPMS/bin/.  A file named
        !            10: "check-rpms" also needs to be at /usr/local/CHECKRPMS/bin/.
        !            11: 
        !            12: An example crontab entry might be:
        !            13: 
        !            14: 10 4 * * *    www    /usr/local/CHECKRPMS/bin/CHECKRPMS_custom --cronmail:j@b
        !            15: 
        !            16: You should substitute j@b with your desired e-mail address (or a
        !            17: comma-separated list of e-mail addresses with no whitespace).
        !            18: 
        !            19: =head1 NAME
        !            20: 
        !            21: B<CHECKRPMS> - automated status report about RPMs on a system
        !            22: 
        !            23: =head1 SYNOPSIS
        !            24: 
        !            25: ./B<CHECKRPMS> [I<modeflag>]
        !            26: 
        !            27: or
        !            28: 
        !            29: B<perl> B<CHECKRPMS> [I<modeflag>]
        !            30: 
        !            31: If I<modeflag> is left blank, the mode is "interactive".  Otherwise,
        !            32: other modes can be specified as shown in the listing below:
        !            33: 
        !            34: =over 4
        !            35: 
        !            36: =item DEFAULT
        !            37: 
        !            38: When left blank, the script runs in interactive mode.  First, a proposed
        !            39: list of RPMs is presented to the user.  Then, the user is asked if he or
        !            40: she wants to download the RPMs to /tmp/loncapa_rpm_updates/.
        !            41: 
        !            42: =item view
        !            43: 
        !            44: A proposed list of RPMs to update is presented to the user.
        !            45: 
        !            46: =item download
        !            47: 
        !            48: A proposed set of RPMs to update are downloaded into /tmp/loncapa_rpm_updates/.
        !            49: Note that prior information inside /tmp/loncapa_rpm_updates/ is removed.
        !            50: 
        !            51: =item redownload
        !            52: 
        !            53: A proposed set of RPMs to update are downloaded into /tmp/loncapa_rpm_updates/.
        !            54: Note that prior information inside /tmp/loncapa_rpm_updates/ is not removed.
        !            55: (This helps support continual attempts from dialup connections.)
        !            56: 
        !            57: =item html
        !            58: 
        !            59: Similar to view mode. XHTML-formatted output is delivered; presumably
        !            60: to a web client.  html mode is automatically chosen if $ENV{'QUERY_STRING'} is
        !            61: defined.
        !            62: 
        !            63: =back
        !            64: 
        !            65: =head1 DESCRIPTION
        !            66: 
        !            67: This file automates the usage of Martin Siegert's "check-rpms"
        !            68: script.  It runs through a list of possible mirror sites
        !            69: until it finds one with a reasonably good FTP connection.
        !            70: 
        !            71: For instructions on usage, see L<SYNOPSIS>.
        !            72: 
        !            73: =head1 AUTHOR
        !            74: 
        !            75: Scott Harrison, sharrison@users.sourceforge.net, 2002
        !            76: 
        !            77: =cut
        !            78: 
        !            79: # ================================================== READ IN COMMAND ARGUMENTS.
        !            80: 
        !            81: # ---------------------------------------------------- Process download option.
        !            82: my $argument = shift(@ARGV);
        !            83: my $document;
        !            84: my $mode;
        !            85: my $cronmailaddress;
        !            86: if ($argument eq '--download' or $argument eq '--redownload')
        !            87:   {
        !            88:     if ($< != 0) # Download mode requires 'root'.
        !            89:       {
        !            90:         print(
        !            91: 	      '**** ERROR **** Download mode needs to be run as root'."\n");
        !            92: 	exit(0); # Exit.
        !            93:       }
        !            94:     `rm -Rf /tmp/loncapa_rpm_updates` if $argument eq '--download';
        !            95:     $download='-v -dl -d /tmp/loncapa_rpm_updates'; # Part of check-rpms args.
        !            96:     $mode = 'download';
        !            97:   }
        !            98: elsif ($argument eq '--view')
        !            99:   {
        !           100:     $mode = 'view';
        !           101:   }
        !           102: elsif ($argument eq '--cronmail')
        !           103:   {
        !           104:     $mode = 'cronmail';
        !           105:   }
        !           106: elsif ($argument =~ /^--cronmail/)
        !           107:   {
        !           108:     $mode = 'cronmail';
        !           109:     $argument =~ /^--cronmail\:(.*)/;
        !           110:     my $email = $1;
        !           111:     if ($email =~ /\@/)
        !           112:       {
        !           113: 	$cronmailaddress = $email;
        !           114:       }
        !           115:   }
        !           116: elsif ($ENV{'QUERY_STRING'} or $argument eq '--html')
        !           117:   {
        !           118:     $mode = 'html';
        !           119:   }
        !           120: else
        !           121:   {
        !           122:     $mode = 'interactive';
        !           123:   }
        !           124: 
        !           125: # ================================================== GENERAL INITIAL VARIABLES.
        !           126: my $command_name=$0;
        !           127: 
        !           128: # ---------------- The FTP servers (and their directory paths) to check against
        !           129: my @serverpaths_to_try = 
        !           130:   (
        !           131:     'ftpmirror:loncapa@install.lon-capa.org/pub/redhat/linux/updates/',
        !           132:     'mirror.pa.msu.edu/linux/redhat/linux/updates/',
        !           133:     'distro.ibiblio.org/pub/linux/distributions/redhat/updates/',
        !           134:     'limestone.uoregon.edu/redhat/updates/',
        !           135:     'rufus.w3.org/linux/redhat/linux/updates/',
        !           136:   );
        !           137: 
        !           138: # -------------------------------------------- Use check-rpms command this way.
        !           139: my $checkcommand = 'check-rpms '.$download.' --rpmuser www -ftp';
        !           140: 
        !           141: my $FTPSERVER; # ------------------------- the server portion of the serverpath
        !           142: my $FTPUPDATES; # ----------------------------- the actual update root location
        !           143: my @rpms; # ---------------------------------- this will store the list of RPMs
        !           144: my $goodoutput; # ------------------------------------ good stuff was returned!
        !           145: my $reallygoodoutput; # ------------------------------- you are 100% up-to-date
        !           146: 
        !           147: # ===================================================== Control flow of output.
        !           148: my $out = \*STDOUT; # Default: go to standard output (directly to terminal).
        !           149: 
        !           150: if ($mode eq 'cronmail') # If cronmail mode, then save to file.
        !           151:   {
        !           152:     open(FOUT,'>/tmp/CHECKRPMS.'.$$);
        !           153:     $out = \*FOUT;
        !           154:   }
        !           155: 
        !           156: $| = 1; # Flush to output whenever possible.
        !           157: 
        !           158: # ========================================== Variables that must be defineable.
        !           159: 
        !           160: # --------------------------------------------------- Determine RedHat version.
        !           161: my $RHversion = (split /\s/, `cat /etc/redhat-release`)[4]; # - 6.2 or 7.3 or ?
        !           162: 
        !           163: unless ($RHversion)
        !           164:   {
        !           165:     terminate($mode,$out,
        !           166: 	      '**** ERROR **** /etc/redhat-release not found'."\n".
        !           167: 	      'This script does not appear to be running on RedHat.'."\n");
        !           168:   }
        !           169: 
        !           170: # ----------------------------------------- Find the check-rpms script location
        !           171: if (-e '/usr/local/CHECKRPMS/bin/check-rpms')
        !           172:   {
        !           173:     $commandpre='perl /usr/local/CHECKRPMS/bin/'; # Use /usr/local dir.
        !           174:   }
        !           175: else # Cannot find check-rpms, so abort.
        !           176:   {
        !           177:     terminate($mode,$out,
        !           178: 	      '**** ERROR **** CANNOT FIND THE check-rpms SCRIPT'."\n");
        !           179:   }
        !           180: 
        !           181: # Define check-rpms invocation based on the path to the check-rpms command.
        !           182: $checkcommand = $commandpre.$checkcommand;
        !           183: 
        !           184: # ============================================================= Initial output.
        !           185: 
        !           186: print($out <<END) if $mode eq 'html';
        !           187: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        !           188:  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        !           189: <html>
        !           190: <head>
        !           191: <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
        !           192: <title>CHECKRPMS STATUS REPORT</title>
        !           193: </head>
        !           194: <body bgcolor="white">
        !           195: <h1>CHECKRPMS STATUS REPORT</h1>
        !           196: <hr />
        !           197: <pre>
        !           198: END
        !           199: 
        !           200: # Notify user of current action.
        !           201: print($out <<END);
        !           202: THIS SCRIPT IS NOW PROBING SEVERAL FTP SERVERS....
        !           203: PLEASE BE PATIENT, THIS MAY TAKE A FEW MINUTES.
        !           204: END
        !           205: 
        !           206: # ============== Go through all the servers until a decent connection is found.
        !           207: SERVERLOOP: foreach my $serverpath (@serverpaths_to_try)
        !           208:   {
        !           209:     $serverpath=~/^(.*?)\//; # Pattern match the ip name.
        !           210:     $FTPSERVER=$1; # Set to the ip name.
        !           211:     $FTPSERVER_noauth=$FTPSERVER;
        !           212:     $FTPSERVER_noauth=~s/^.*?\@//;
        !           213:     print($out
        !           214: 	  "Trying $FTPSERVER_noauth...\n"); # Notify of attempts with ip name.
        !           215:     `ping -c 1 $FTPSERVER_noauth 2>/dev/null`; # Ping ftp server (you there?).
        !           216:     if ($?==0) # If the ftp server can be pinged.
        !           217:       {
        !           218: 	print($out "$FTPSERVER found...\n"); # Tell user ftp server is found.
        !           219: 	`ncftpls ftp://$FTPSERVER`; # Try to access server with ftp protocol.
        !           220: 	if ($?==0) # If the ftp server can be accessed with the ftp protocol.
        !           221:           {
        !           222: 	    $FTPUPDATES="$serverpath$RHversion/en/os"; # The full update path.
        !           223: 	    # Print the check-rpms command that will be executed.
        !           224: 	    print($out $checkcommand.' '.$FTPUPDATES."\n");
        !           225: 	    if ($mode eq 'download') # Was CHECKRPMS run in download mode?
        !           226:               {
        !           227: 		$|=1; # Try to send things immediately to stdout; err umm....
        !           228: 		# Tell the user about the /tmp/loncapa_rpm_updates directory.
        !           229: 		print($out '**** NOTE **** '.
        !           230: 		      'To check the status of the download, you can '.
        !           231: 		      'periodically inspect the contents of the '.
        !           232: 		      '/tmp/loncapa_rpm_updates directory.  '.
        !           233: 		      'Please be patient; this download may take a while.'.
        !           234: 		      "\n");
        !           235: 		# Do the download.
        !           236: 		print($out `$checkcommand $FTPUPDATES 2>\&1`);
        !           237: 		# Tell the user about what action they need to take with the
        !           238: 		# downloaded RPMs.
        !           239: 		print($out
        !           240: 		      'You may now wish to visit the /tmp/loncapa_rpm_updates'.
        !           241: 		      ' directory and upgrade the RPMs.  '."\n".
        !           242: 		      'If this is a critical server (it is currently being'.
        !           243: 		      ' used for classes) and you do not know how to upgrade'.
        !           244: 		      ' RPMs, you should consult someone who has experience '.
        !           245: 		      'with the "rpm" command.'."\n");
        !           246: 		clean_exit($mode,$out,0); # Assume everything is okay and exit.
        !           247: 	      }
        !           248: 	    @rpms=`$checkcommand $FTPUPDATES 2>\&1`; # Read in list of RPMs.
        !           249: 	    # Create a text string that can be pattern matched.
        !           250: 	    my $rpmtext=join('',@rpms);
        !           251: 	    if ($rpmtext=~/You do not seem to have a/) # No www?
        !           252:               {
        !           253: 		print($out "You do not have a 'www' user on your system.\n".
        !           254: 		      "Please add this user and try this command again.\n");
        !           255: 		clean_exit($mode,$out,0);
        !           256: 	      }
        !           257: 	    if ($rpmtext=~/This account is currently not/) # ------------ uh-oh
        !           258: 	      {
        !           259: 		print($out "...strange error, moving on ($FTPSERVER)\n");
        !           260: 	      }
        !           261: 	    else # --------------------------------------- the output is "good"
        !           262: 	      {
        !           263: 		$goodoutput=$rpmtext;
        !           264: 		unless (@rpms) # If there are no RPMs to update.
        !           265: 		  {
        !           266: 		    $reallygoodoutput = <<END;
        !           267: **** NOTE **** All RPMS on your system appear to be up to date.
        !           268: END
        !           269:                     $goodoutput = ' ';
        !           270: 		  }
        !           271: 		last SERVERLOOP;
        !           272: 	      }
        !           273: 	  }
        !           274: 	print($out '...cannot establish an ftp session with '.$FTPSERVER."\n");
        !           275:       }
        !           276:     else
        !           277:       {
        !           278: 	print($out "...cannot find $FTPSERVER on the network\n");
        !           279:       }
        !           280:   }
        !           281: if (!$goodoutput) # If never received any useable output, assume "no server".
        !           282:   {
        !           283:     print($out '**** ERROR **** Cannot find a working ftp server.'."\n");
        !           284:     clean_exit($mode,$out,0);
        !           285:   }
        !           286: elsif ($reallygoodoutput) # Everything is peachy keen and up-to-date already.
        !           287:   {
        !           288:     print($out $reallygoodoutput);
        !           289:   }
        !           290: else # There are RPMs that need to be updated; show list to user.
        !           291:   {
        !           292:     my $rpmcount=scalar(@rpms); # Count up size of RPM list.
        !           293:     print($out <<END); # Print out an advisory warning to user.
        !           294: **** WARNING **** You need to update at least $rpmcount RPMS shown in
        !           295: the list below.  THIS IS IMPORTANT FOR SECURITY.
        !           296: 
        !           297: END
        !           298:     print($out $goodoutput); # Output the RPM list.
        !           299:     if ($mode eq 'interactive')
        !           300:       {
        !           301: 	print($out <<END);
        !           302: Do you want to download the RPMs listed above (y/n)?
        !           303: END
        !           304:         my $in=<>;
        !           305: 	if ($in=~/^y/)
        !           306: 	  {
        !           307:             print($out 'Please be patient... downloading into '.
        !           308: 		  '/tmp/loncapa_rpm_updates'."\n");
        !           309:             print($out `perl $command_name --download`);
        !           310:             clean_exit($mode,$out,0);
        !           311: 	  }
        !           312:       }
        !           313:     print($out <<END); # Output instructions to user about taking action.
        !           314: 
        !           315: Please visit ftp://$FTPUPDATES
        !           316: and download the RPMS you need.
        !           317: For instructions on working with (and upgrading) RPMS, please
        !           318: visit http://www.rpm.org/max-rpm/.
        !           319: To automatically download these RPMs to /tmp/loncapa_rpm_updates/,
        !           320: run the CHECKRPMS_custom command as "./CHECKRPMS_custom --download"
        !           321: END
        !           322:     if ($mode eq 'cronmail')
        !           323:       {
        !           324: 	print($out <<END); # Output more instructions to user.
        !           325: CHECKRPMS_custom should be located in /usr/local/CHECKRPMS/bin/.
        !           326: END
        !           327:       }
        !           328:   }
        !           329: 
        !           330: clean_exit($mode,$out,0);
        !           331: 
        !           332: # ================================================================ Subroutines.
        !           333: 
        !           334: sub clean_exit
        !           335:   {
        !           336:     my ($mode,$out,$code)=@_;
        !           337: 
        !           338:     if ($mode eq 'cronmail') # If cronmail mode, then mail LON-CAPA sys admin.
        !           339:       {
        !           340:         close(FOUT);
        !           341: 
        !           342: 	# Read in configuration to get e-mail addresses.
        !           343: 	my $perlvarref = read_conf('loncapa.conf');
        !           344: 	my %perlvar = %{$perlvarref};
        !           345: 	undef $perlvarref;
        !           346: 	delete $perlvar{'lonReceipt'}; # remove since sensitive
        !           347: 	delete $perlvar{'lonSqlAccess'}; # remove since sensitive
        !           348: 
        !           349: 	# Set metadata for the e-mail.
        !           350:         my $emailto = "$perlvar{'lonAdmEMail'}";
        !           351: 
        !           352: 	my $subj=$perlvar{'lonHostID'}.', RPMS to upgrade';
        !           353: 
        !           354: 	# Make the e-mail's subject header to describe whether up-to-date.
        !           355: 	if ($reallygoodoutput)
        !           356: 	  {
        !           357: 	    $subj = 'happy_lon: '.$subj; # Machine is up-to-date.
        !           358: 	  }
        !           359: 	else
        !           360: 	  {
        !           361: 	    $subj = 'ALERT_lon: '.$subj; # There are out-of-date RPMs.
        !           362: 	  }
        !           363: 
        !           364: 	# Send the e-mail.
        !           365: 	system(
        !           366: 	       'metasend -b -t '.$emailto.' -s '.
        !           367: 	       "'$subj' -f /tmp/CHECKRPMS.$$ -m text/plain");
        !           368:       }
        !           369: 
        !           370:     print($out <<END) if $mode eq 'html'; # If html mode, print ending tags.
        !           371: </pre>
        !           372: </body>
        !           373: </html>
        !           374: END
        !           375:     exit($code);
        !           376:   }
        !           377: 
        !           378: sub terminate
        !           379:   {
        !           380:     my ($mode,$out,$output);
        !           381:     if ($mode eq 'html')
        !           382:       {
        !           383:         print($out <<END);
        !           384: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        !           385:  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        !           386: <html>
        !           387: <head>
        !           388: <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
        !           389: <title>CHECKRPMS ERROR</title>
        !           390: </head>
        !           391: <body bgcolor="white">
        !           392: <h1>CHECKRPMS ERROR</h1>
        !           393: <hr />
        !           394: <p><font color="red"><font size="+1">
        !           395: END
        !           396:       }
        !           397:     print($out $output);
        !           398:     if ($mode eq 'html')
        !           399:       {
        !           400:         print($out <<END);
        !           401: </font></font></p></body></html>
        !           402: END
        !           403:       }
        !           404:   }
        !           405: 
        !           406: 
        !           407: # - read_conf: read LON-CAPA server configuration, especially PerlSetVar values
        !           408: sub read_conf
        !           409:   {
        !           410:     my (@conf_files)=@_;
        !           411:     my %perlvar;
        !           412:     $perlvar{'lonAdmEMail'} = $cronmailaddress;
        !           413:     $perlvar{'lonHostID'} = `hostname`;
        !           414:     chomp($perlvar{'lonHostID'});
        !           415:     my $perlvarref=\%perlvar;
        !           416:     return ($perlvarref);
        !           417:   }
        !           418: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>