#!/usr/athena/bin/perl
#
# Upgrade the RPMS in <dir> from the local directory
#
# Written By:	Derek Atkins <warlord@MIT.EDU>

# Flag bit-field values
$noop = 1;
$delete = 2;
$verbose = 4;

sub CopyRpms {
    local ($toDir, $flags) = @_;
    local ($rpm, $name, $oldrpm);

    shift; shift;

    foreach $rpm (@_) {
	next unless ($rpm =~ /([^\/]*)-[0-9][^-]*-[^-]*\.([^-]*)\.rpm/);
	$name = $1;
	$arch = $2;

	$oldrpm = `echo $toDir/$name-[0-9]*-*.$arch.rpm`;
	chop $oldrpm;

	# Make sure we only remove the appropriate RPMS
	local(@oldRpm) = split (/ /, $oldrpm);
	@oldList = ();
	foreach $tmp (@oldRpm) {
	    next unless ($tmp =~ /(.*)-[0-9][^-]*-[^-]*\.[^-]*\.rpm/);
	    next unless ("$1" eq "$toDir/$name");
	    push (@oldList, $tmp);
	}
	$oldrpm = join (' ', @oldList);

	if ("$oldrpm" eq "$toDir/$rpm") {
#	    print "$rpm already installed.\n";
	    next;
	}

	print "Operation: " if ($flags & $noop);
	print "Copy $rpm\n\tremove $oldrpm\n" if ($flags & $verbose ||
					      $flags & $noop);
	print "\tDeleting $rpm\n" if ($flags & $delete &&
				      ($flags & $verbose || $flags & $noop));
	unless ($flags & $noop) {
	    if ($#oldList) {
		foreach $i (@oldList) {
		    unlink ($i);
		}
	    } else {
		unlink ($oldrpm);
	    }
	    system ("cp", "-p", "$rpm", "$toDir");
	    unlink $rpm if ($flags & $delete);
	}

    }
}

sub BuildLinks {
    local ($flags) = @_;
    local ($rpm, $dest, $name);

    shift;

    foreach $name (@_) {
	$rpm = readlink $name;
	$rpm =~ /(.*)-[0-9][^-]*-[^-]*\.[^-]*\.rpm/;
	$dest = `echo $1-[0-9]*-*.*.rpm`;
	chop $dest;
	print "Relinking $name from $rpm to $dest\n" if ($flags & $verbose ||
							 $flags & $noop);
	unless ($flags & $noop) {
	    unlink $name;
	    symlink ($dest, $name);
	}
    }
}

sub ListDir {
    local (@allfiles);

    opendir (THISDIR, ".");
    @allfiles = grep (!/^\./, readdir (THISDIR));
    closedir (THISDIR);
    return @allfiles;
}

sub Usage {
    print "Usage: upgrade.pl [-n] [-d] [-v] [toDir]\n";
    exit 1;
}

$flags = 0;
$toDir = "";

foreach (@ARGV) {
    if (m/^-n$/) { $flags |= $noop; }
    elsif (m/^-d$/) { $flags |= $delete; }
    elsif (m/^-v$/) { $flags |= $verbose; }
    elsif (! m/^-/ && ! $toDir) { $toDir = $_; }
    else { &Usage; }
}

if ($toDir) {
    # Copy RPMS from current dir to $ARGV[0]
    print "Copying files...\n";
    &CopyRpms ($toDir, $flags, &ListDir);
} else {
    # Rebuild symlinks from current dir
    print "Rebuilding Symlinks...\n";
    &BuildLinks ($flags, &ListDir);
}
