#!/usr/bin/perl
#
# kirs.pl
# 
# RPM installation.  Keeping It Ridiculously Simple.

# YEAR=2001
# 10/1 Scott Harrison

# Brief essay:
#
# This program automates what SHOULD be automated
# in an RPM upgrade process.  That is to say, it
# automatically tells the system administrator
# what should be updated.  In addition to a streaming
# terminal output, it creates two files:
# updatenow.txt - a list of rpms that should upgrade
#                  on the system with no problems
# updateproblems.txt - a list of rpms with potential upgrade
#                       problems such as dependencies and/or
#                       file conflicts
#
# What this program does not do, is make the decisions based
# on dependencies, file conflicts, or even the decision to
# update an RPM.
#
# Why?  Because in my experience, the implementation of rpm
# information is often buggy, the actual rpm information is often
# buggy, and taking care of exceptional cases (such as kernel
# rpm's) is buggy.  And, in principle, I view it as serious
# business when it comes to keeping a server in a well-defined
# state that is not screwed up by unknown bugs.
#
# Usage, can be non-root: perl kirs.pl
#
# As befits the name, a very simple invocation.
#
# After running the program, as root, the administrator
# can:
#
# cat updatenow.txt | xargs rpm -Uvh 
# and then
# look at the contents of updateproblems.txt in an editor
# and make appropriate decisions
#
# This program relies on the following executables
# to be in the path: cat, grep, rpm
#
# And for the bad attributes of this program:
# * It downloads the ENTIRE i386 update RPM directory
#   (specific to the redhat release)
# * It is hardcoded to use 
#   ftp://mirror.pa.msu.edu/linux/redhat/linux/updates/RELEASENUM/en/os/i386/
#   where RELEASENUM is 6.2, 7.1, etc
# * It creates a lot of files in the current directory in which it
#   resides (basically all the update *.rpm's)
#
# WARNING
# THIS PROGRAM IS PROVIDED "AS IS" WITHOUT
# WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLICIT.
# IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

my $issue=`cat /etc/issue`;
$issue=~/Linux release (\S+)/;
my $releasenum=$1;
print "Detecting a RedHat version $releasenum system\n";

open NOW,">updatenow.txt";
open PROBLEMS,">updateproblems.txt";

my $ftpbase="ftp://mirror.pa.msu.edu/linux/redhat/linux/updates/";

$|=1;
print "Downloading update repository...$ftpbase...\n";
system('wget','-q',
       "$ftpbase$releasenum/en/os/i386/*.rpm");
die "bad ftp connection" if $?;
print "Finished downloading\n";

my @list=`rpm -qp *.rpm --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm\t%{NAME}\t%{VERSION}-%{RELEASE}\n"`;

for (@list) {
    chop;
    next if /^kernel/;
    my ($file,$name,$version)=split(/\t/);
    my $currentversion=`rpm -q $name --queryformat="\%{VERSION}-%{RELEASE}"`;
    if ($currentversion!~/is not installed/) {
	if ($version ne $currentversion) {
	    print "$name compare $currentversion to $version\n";
	    my $status=`rpm -Uvh --test $file 2>&1| grep -v ^Preparing`;
	    system("rpm -Uvh --test $file 1>/dev/null");
	    if ($?) {
		print PROBLEMS "$file\n$status";
	    }
	    else {
		print NOW "$file\n";
	    }
	    print $status;
	}
    }
}
close PROBLEMS;
close NOW;

print <<END;
# The program has completed.  As root, the administrator
# can now:
#
# cat updatenow.txt | xargs rpm -Uvh 
# and then
# look at the contents of updateproblems.txt in an editor
# and make appropriate decisions
END
