Hacking Linux Exposed

About
Authors
Contents
Reviews
Foreword
Purchase

Articles
Books
Sourcecode
Tools
Errata

Home

 


(view this code in a separate window)

#!/usr/bin/perl
#
# Copyright 2001, Bri Hatch
# Released under GPL
#
#
# redhat_update
#
# A simple way to keep your machine up to date.
#
# Theory:   Snag rpm updates via wget off of a ftp or http
#           site, and run 'rpm -F' on each file.
#
# Usage:    You can snag your rpm updates from anywhere, such as
#           an official RedHat mirror, or from an internal
#           repository.  Place URLs that will be recursively
#           mirrored in the file 'urls' in $MIRROR_DIR.  Any
#           lines that don't begin with 'ftp://', 'http://' or
#           'https://' will be ignored, so you can comment to
#           your heart's content.
#
# Caveats:  This runs rpm individually on each rpm file found.
#           This means that any rpm's that have dependencies that
#           aren't yet met may not get applied until this script
#           runs a few times and catches them all.  It's trivial
#           to have it run rpm -F *.rpm which would work around
#           this, but I have no intent to supply such a script to
#           the masses that would blindly follow everything.
#           Besides, it could fail when you have other irrelevant
#           incompatible rpm's already installed.
#
# Warnings: You are grabbing rpms over the network, right?  Do
#           you really really really trust the endpoints?  What
#           if the ftp/http site is compromised and rpm's are
#           replaced with trojan versions?  What if you upgrade
#           to a version that isn't compatible with other locally
#           installed software?  Are you sure you want to run this
#           automatically out of cron?
#
#           Also, unless the rpm scripts take care of shutting down
#           and restarting services, your old buggy versions may still
#           be running, since this script does not attempt any restarts.
#           I.E. you may have just upgraded BIND, but the old version
#           is still running until you manually restart it.
#
# Suggestion: We use this out of cron only in the cases where we
#             have a local internal rpm update repository from which
#             our machines sync.  All rpm updates are tested out on
#             a few machines manually before putting them in the
#             repository for the majority of machines to apply
#             automatically.  We also include a second (alphabetically)
#             rpm file which we create that will stop and start any
#             services that may have been affected.
#
# Url file:   Here's a sample url file you may use if you had a
#             Intel 686 processor, and had Powertools installed
#             as well.
#
#   # Arch non-specific Intel stuff
#   ftp://ftp.valinux.com/pub/mirrors/redhat/redhat/updates/6.2/en/os/i386
#
#   # Arch specific
#   ftp://ftp.valinux.com/pub/mirrors/redhat/redhat/updates/6.2/en/os/i686
#
#   # Powertools?
#   ftp://ftp.valinux.com/pub/mirrors/redhat/redhat/updates/6.2/en/powertools



$WGET='wget';					# put full path if necessary.


# Where do we store our mirrors?  Personally I'd use /var, but
# then again I normally create a separate /var partition with
# sufficient space, whereas RedHat usually puts /var it on /.
# Thus let's use /home, which is good for most RedHat users.
# If you're the kind of person who doesn't use RedHat defaults
# then you're probably using Debian anyway.

$MIRROR_DIR="/home/redhat_updates";
$MIRROR_URLS="$MIRROR_DIR/urls";


# No changes are needed from here on down, unless you want to customize.

sub bail { print STDERR @_; exit 1; }


mkdir $MIRROR_DIR,0700;			# Don't mind errors

@ARGV=$MIRROR_URLS;

while (<>) {

	next unless m#^\s*(https|http|ftp)://(\S+)#;
	$url="$1://$2";
	$dir=$2;

	print "Mirroring $url\n";
	chdir $MIRROR_DIR || bail "Can't cd to $MIRROR_DIR";
	system $WGET, "-m", "-nv", $url;

	chdir $dir or bail "Can't cd to $dir\n";
	for ( <*.rpm> ) {

		# You want to upgrade kernel files automatically
		# from a script?  Are you really sure?  If so,
		# remove this test.  I really really don't suggest it.
		next if /^kern/;

		print STDERR "Upgrading $_\n\n";
		system "rpm", "-F", "$_";
	}

}