Diff for /loncom/build/check-rpms between versions 1.1 and 1.4

version 1.1, 2002/02/24 22:33:45 version 1.4, 2002/08/01 04:57:18
Line 1 Line 1
 #!/usr/bin/perl  #!/usr/bin/perl
 #  #
 # check-rpms, version 2.1.0  # check-rpms, version 2.1.1
 # Martin Siegert, SFU, siegert@sfu.ca, Feb 02  # Martin Siegert, SFU, siegert@sfu.ca, Feb 02
 #  #
   # documentation and minor patches,
   # Scott Harrison sharrison@users.sourceforge.net 2002
   
   =pod
   
   =head1 NAME
   
   check-rpms - compare installed rpms with up-to-date distribution
   
   =head1 DESCRIPTION
   
   I<check-rpms> compares installed RPM packages (listed by the command
   "rpm -qa") on a Linux system with an up-to-date distribution. That
   distribution may either reside in a local directory (possibly NFS
   mounted) or on a ftp server.  If the B<-ftp> option is specified,
   I<check-rpms> retrieves directory listings from the I<ftpserver>'s
   I<directory>/<arch> directories, where <arch> is set to noarch, i386,
   i586, i686, and athlon consecutively. If I<ftpserver/directory> is
   not specified, $FTPSERVER/$FTPUPDATES is used. The $FTPSERVER and
   $FTPUPDATES variables can be set in the configuration file. If
   either of the two is not set, the default server "updates.redhat.com"
   and the default directory "$RHversion/en/os" is used,
   where $RHversion is obtained from the /etc/redhat-release file. If
   run with the B<-ftp> option, all rpm packages that need to be downloaded
   (see the B<--download>, B<--recheck>, and B<--update> options) will
   be downloaded into the directory specified by the B<-d> directory
   option. If that option is omitted the $RPMDIR directory is used.
   The $RPMDIR variable that can be set in the configuration file. If
   $RPMDIR variable is not set either, the default directory
   "/mnt/redhat/RedHat/RPMS" is used.
   
   If the B<-ftp> is omitted, it is assumed that B<-d> I<directory> specifies
   a local directory that contains up-to-date rpm packages. If B<-d>
   I<directory> is omitted as well, the $RPMDIR directory is used. If
   $RPMDIR is not set, the default directory "/mnt/redhat/Red-
   Hat/RPMS" is used.
   
   I<check-rpms> uses a lexical sort on the version string and the
   release string of the package in order to decide whether the
   installed package or the package form the distribution is newer.
   I<check-rpms> lists packages of the distribution that are found to be
   newer than the installed packages or, if B<--update> is specified,
   will update the packages using the "rpm -Fvh <list of packages>"
   command. In the latter case I<check-rpms> must be run as root. Fur-
   thermore, the $RPMUSER variable should be set to a non-root user-
   name (see the B<-c> option below). I<check-rpms> will switch to that
   user and run most of the script under that user id.Only the
   final "rpm -Fvh ..." command will be run as root. If $RPMUSER is
   not set, the "nobody" user id will be used. It is recommended to
   set $RPMUSER to an ordinary username (such as yourself). Further-
   more, if a ftp server is used, create the download directory
   (which is specified in the B<-d> directory option or in the $RPMDIR
   variable), change the owner ship of that directory to that user,
   and set the permissions to 700 before running I<check-rpms> with the
   B<--update> option. Note, that B<--update> implies the B<--no-kernel>
   option, i.e., I<check-rpms> refuses to update the kernel directly.
   
   =cut
   
 # ************ WARNING *****************************************************  # ************ WARNING *****************************************************
 # THIS PROGRAM IS PROVIDED "AS IS" WITHOUT  # THIS PROGRAM IS PROVIDED "AS IS" WITHOUT
 # WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLICIT.  # WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLICIT.
Line 33  my $retval = &GetOptions("verbose|v","lm Line 92  my $retval = &GetOptions("verbose|v","lm
                          "dir|d=s","ftp:s","noftp","download|dl","recheck|r",                           "dir|d=s","ftp:s","noftp","download|dl","recheck|r",
                          "nk|no-kernel","update","c=s");                           "nk|no-kernel","update","c=s");
   
   =pod
   
   =head1 OPTIONS
   
   =over 4
   
   =item B<-v> B<--verbose>
   
   verbose  mode:  prints  additional  progress information on
   standard output
   
   =item B<-ftp> [I<ftpserver/directory>]
   
   compare the installed packages with the rpm packages found
   on the ftp server I<ftpserver> in the directories I<directory>/<arch>,
   where arch is set to noarch, i386, i586, i686,
   and athlon consecutively. If I<ftpserver/directory> is not
   specified, the $FTPSERVER and $FTPUPDATES variables are
   checked. These variables can be set in the configuration
   file (see the B<-c> option below). If those variables are not
   set either, the default server "updates.redhat.com" and the
   default directory "$RHversion/en/os" is used, where $RHversion
   is obtained from the I</etc/redhat-release> file.
   
   =item B<-noftp>
   
   use  a  local  directory as the source for new rpm packages
   even if the $FTP veriable is set to 1 in the  configuration
   file.
   
   =item B<-d> I<directory> B<--rpm-directory> I<directory>
   
   if B<-ftp> is specified download all rpm packages that need to
   be downloaded into I<directory>. If B<-ftp> is not specified,
   regard the rpm packages found in I<directory> as an up-to-date
   distribution against which the installed packages are
   compared to.
   
   =item B<-lm> B<--list-missing>
   
   list installed packages that do not have an equivalent in
   the up-to-date distribution. This will generate lots of
   output when the comparison is made with the updates directory
   of a ftp server.
   
   =item B<-lq> B<--list-questionable>
   
   list packages for which the lexical sort algorithm does not
   give a conclusive result on whether the installed package
   is older than the package in the distribution. These are
   packages that have version and/or release strings that contain
   letters. For example, it is not absolutely clear
   whether the version 1.2.3b is actually newer or older than
   1.2.3. The lexical sort would classify 1.2.3b to be newer
   than 1.2.3; with B<-lq> specified the package would be listed
   in any case. See also B<--recheck> below.
   
   =item B<-dl> B<--download>
   
   download packages from the remote ftp server that are found
   to be newer than installed packages into the directory that
   is specified in the B<-d> I<directory> option or in the $RPMDIR
   variable or, if neither of the two are specified, into
   "/mnt/redhat/RedHat/RPMS". If the download directory does
   not exist, I<check-rpms> will create it.
   
   =item B<-r> B<--recheck>
   
   Use the "rpm -Uvh --test --nodeps <package>" command to
   check all packages that have letters in their version
   and/or release string; B<--recheck> implies B<--list-questionable>
   (see above). At the time of writing (Feb. 2002) there
   is one known case for which the lexical sort algorithm
   fails to detect a new package: mutt-1.2.5.1 was released to
   replace mutt-1.2.5i, however, the lexical sort algorithm
   incorrectly classifies mutt-1.2.5i to be  newer  than
   mutt-1.2.5.1. In this case using the B<--recheck> option is
   essential. In all other cases it is not. It is nevertheless
   probably a good idea to use B<--recheck> at least once in a
   while. B<--recheck> can increase the run-time of I<check-rpms>
   substantially, particularly if a ftp server is used. In
   that case the questionable packages must be downloaded from
   the server into a directory I<directory> (as specified in the
   -d option or the $RPMDIR variable) which will be created,
   if it does not exist.
   
   =item B<-nk> B<--no-kernel>
   
   do not list kernel packages. That is, kernel, kernel-smp,
   kernel-enterprise, kernel-BOOT, and kernel-debug will not
   be checked and listed. However, kernel-headers and kernel-source
   will be checked. The B<--update> option (see below)
   implies B<--no-kernel>.
   
   =item B<--update>
   
   update all packages that were found to have newer versions.
   For this to work I<check-rpms> must be run as root and a suitable
   $RPMUSER must exist (see DESCRIPTION above). It is
   strongly advisable to do a dry run B<check-rpms -v -lq> before
   running B<check-rpms --update>.
   
   =item B<-c> I<configurationfile>
   
   The optional configuration file to use. This file can be
   used to specify the $RPMDIR variable, the $FTP, $FTPSERVER,
   and $FTPUPDATES, variables, and the $RPMUSER variable. An
   example configuration file is given below. If the B<-c> option
   is omitted, I<check-rpms> will use the default configuration
   file I</usr/local/etc/check-rpms.conf>, if it exists.
   
   =back
   
   =head1 EXAMPLES
   
   =over 4
   
   =item check-rpms
   
   will 1) check whether /usr/local/etc/check-rpms.conf exists; 2) if
   it does it will read the variables specified in that file, if it
   doesn't exist, $RPMDIR is set to /mnt/redhat/RedHat/RPMS; 3) if
   $RPMDIR is set, this directory will be regarded as the source of
   the up-to-date distribution, unless $FTP is set to 1. In that latter
   case the $FTPSERVER and $FTPUPDATES are used, if those variables are
   set. Otherwise "updates.redhat.com" and "<RHversion>/en/os"
   will be used; 4) the installed packages are compared
   
   =item check-rpms -v -lq -d /mnt/redhat/7.1/RedHat/RPMS
   
   will use the distribution in the directory /mnt/redhat/7.1/RedHat/RPMS
   for comparison with the installed packages. The command
   will give more detailed information on its progress and will list
   the packages that need upgrading and in another section it will
   list packages they may need to be upgraded.
   
   =item check-rpms -v -lq -ftp updates.redhat.com/7.1/en/os
   
   same as above, but the directories 7.1/en/os/noarch,
   7.1/en/os/i386, 7.1/en/os/i586, 7.1/en/os/i686, and
   7.1/en/os/athlon on updates.redhat.com will be searched for new
   packages.
   
   =item check-rpms -v -r --updates
   
   will use the default location for updated packages (determined as
   indicated in the first example); if a ftp server is used, it will
   download all newer and all packages with letters in the version
   and/or release strings (i.e., "questionable" packages) from that
   ftp server, recheck the questionable packages, and finally update
   all packages that need to be updated.
   
   =back
   
   =cut
   
 if ( $retval == 0 ) {  if ( $retval == 0 ) {
     usage();      usage();
 }  }
Line 48  $DEFCONF = "/usr/local/etc/check-rpms.co Line 263  $DEFCONF = "/usr/local/etc/check-rpms.co
 $DEFRPMDIR = "/mnt/redhat/RedHat/RPMS";  $DEFRPMDIR = "/mnt/redhat/RedHat/RPMS";
 $DEFFTPSERVER = "updates.redhat.com";  $DEFFTPSERVER = "updates.redhat.com";
 $DEFFTPUPDATES = "$RHversion/en/os";  $DEFFTPUPDATES = "$RHversion/en/os";
 $DEFRPMUSER = "nobody";  $DEFRPMUSER = "harris41";
   
 $RPMDIR=$DEFRPMDIR;  $RPMDIR=$DEFRPMDIR;
   
Line 61  if ($opt_c) { Line 276  if ($opt_c) {
    $CONF = $DEFCONF;     $CONF = $DEFCONF;
 }  }
   
   =pod
   
   =head1 The Configuration File
   
   All variables must be defined using perl syntax, i.e., in the form
   
   $variable = value;
   
   (do not forget the semicolon at the  end  of  a  line).   Comments
   start with "#" and blank lines may be included as well.
   
   Example configuration file:
   
    # check-rpms configuration file
   
    # $RPMDIR is the directory where up-to-date RPMs can be found and/or
    # rpm packages are downloaded into.
    $RPMDIR = "/mnt/redhat/RedHat/RPMS";
   
    # $RPMUSER is the user name that check-rpms switches to for most of
    # the script when run as root
    $RPMUSER = "harris41";
   
    # $FTPSERVER and $FTPUPDATES are the hostname of a ftp server and the
    # directory where RPM updates can be found without the <arch> directory.
    # I.e., $FTPUPDATES should be set to something like pub/7.2, if the RPMs
    # are located in pub/7.2/i386, pub/7.2/i686, etc.
    # $FTPSERVER and $FTPUPDATES are used if -ftp is specified or if the following
    # line is uncommented.
    # $FTP = 1;
    $FTPSERVER = "updates.redhat.com";
    $FTPUPDATES = "7.2/en/os";
   
   =cut
   
 if ( -f $CONF) {  if ( -f $CONF) {
    require($CONF);     require($CONF);
 } else {  } else {
Line 124  if (defined $opt_ftp || $FTP) { Line 374  if (defined $opt_ftp || $FTP) {
   
    if ($download || $recheck) {     if ($download || $recheck) {
        if ( ! -d $RPMDIR) {         if ( ! -d $RPMDIR) {
           $retval = system("mkdir -p $RPMDIR; chmod 700 $RPMDIR");            if ($verbose) { print "Creating $RPMDIR ...\n"; }
             if ($< == 0) {
                $retval = system("su $RPMUSER -c \'mkdir -p $RPMDIR\'; chmod 700 $RPMDIR");
             } else {
                $retval = system("mkdir -p $RPMDIR; chmod 700 $RPMDIR");
             }
           if ($retval) { die "error: could not create $RPMDIR\n"; }            if ($retval) { die "error: could not create $RPMDIR\n"; }
       }        }
    }     }
Line 140  if (defined $opt_update || defined $opt_ Line 395  if (defined $opt_update || defined $opt_
     $no_kernel=1;      $no_kernel=1;
 }  }
   
 $PROC = `grep -i athlon /proc/cpuinfo`;  $PROC = `grep -i "athlon\|amd" /proc/cpuinfo`;
 if ( ! "$PROC" ) {  if ( ! "$PROC" ) {
     $PROC = `uname -m`;      $PROC = `uname -m`;
     chomp($PROC);      chomp($PROC);
Line 211  if ($ftp) { Line 466  if ($ftp) {
 $giveup = 0;  $giveup = 0;
 for (@templist) {  for (@templist) {
    ($rpm, $pkg, $pver, $arch) = m/(([^ ]*)-([^- ]+-[^-]+\.(\w+)\.rpm))/;     ($rpm, $pkg, $pver, $arch) = m/(([^ ]*)-([^- ]+-[^-]+\.(\w+)\.rpm))/;
      if (! defined $local_rpm{$pkg}) { next; }
    if ($remote_rpm{$pkg}) {     if ($remote_rpm{$pkg}) {
       # problem: there are several versions of the same package.        # problem: there are several versions of the same package.
       # this means that the package exists for different architectures        # this means that the package exists for different architectures
Line 293  for (@local_rpm_list) { Line 549  for (@local_rpm_list) {
             push(@q_updates, $rpm);              push(@q_updates, $rpm);
         } elsif ( $vcmp < 0 ) {          } elsif ( $vcmp < 0 ) {
             # local version is lower              # local version is lower
             if ( $qflag ) {              push(@updates, $rpm);
                push(@q_updates, $rpm);  
             } else {  
                push(@updates, $rpm);  
             }  
  }   }
     } elsif ($list_missing) {      } elsif ($list_missing) {
  print "Package '$pkg' missing from remote repository\n";   print "Package '$pkg' missing from remote repository\n";
Line 451  sub pkg_compare($$$) { Line 703  sub pkg_compare($$$) {
    }     }
    my $serial1 = `rpm -qp --queryformat '%{SERIAL}' $RPMDIR/$pkg1`;     my $serial1 = `rpm -qp --queryformat '%{SERIAL}' $RPMDIR/$pkg1`;
    my $serial2 = `rpm -qp --queryformat '%{SERIAL}' $RPMDIR/$pkg2`;     my $serial2 = `rpm -qp --queryformat '%{SERIAL}' $RPMDIR/$pkg2`;
    ($serial2 > $serial1) ? return 1 : return 0;     if ($serial2 > $serial1) {
         remove_pkg("$RPMDIR/$pkg1");
         return 1;
      } else {
         remove_pkg("$RPMDIR/$pkg2");
         return 0;
      }
   }
   
   sub remove_pkg($) {
      my ($pkg) = @_;
      if ($verbose) {
         print "Removing $pkg ...\n";
      }
      my $status = system("rm -f $pkg");
      if ($status) {
         printf STDERR "error: could not remove $pkg. You must remove this file before updating.\n";
         if ($update) { $giveup = 1; }
      }
 }  }
   
 sub mulpkg_msg($$$) {  sub mulpkg_msg($$$) {
Line 548  sub usage(){ Line 818  sub usage(){
        "                  [-lq | --list-questionable] [-r | --recheck ]\n",         "                  [-lq | --list-questionable] [-r | --recheck ]\n",
        "                  [-nk | --no-kernel] [--update] [-c configurationfile]\n";         "                  [-nk | --no-kernel] [--update] [-c configurationfile]\n";
 }  }
   
   =pod
   
   =head1 SEE ALSO
   
   rpm(8), ncftpls(1), ncftpget(1)
   
   =head1 AUTHOR
   
   Martin Siegert, Simon Fraser University, siegert@sfu.ca
   
   =cut

Removed from v.1.1  
changed lines
  Added in v.1.4


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