Category: utility
Author/Contact Info Dan MacNeil <omacneil@cs.uml.edu>
Description: A tool to set the ip# and hostname on a redhat machien after it has been re-imaged.
#!/usr/bin/perl -w

# script to set IP info for a redhat8 or redhat9 box
# omacneil@cs.uml.edu

# If MAC address matches one in file read hostname &
# IP# from file generated from /etc/hosts on other machine

# Otherwise prompt user for hostname
# if hostname not in file, die otherwise look up ip#

use strict;
use File::Basename;
#my $DATA_FILE = File::Basename::dirname($0) . "/set_net.data";

#####################

# hash indexed by hostname containing ip num and MAC addr
my %host_hash = get_host_hash();

# hash indexed by MAC addr contains hostname
my %mac_hash = get_mac_hash(%host_hash);

my ($MAC) = `/sbin/ifconfig` =~ m|(\w\w\:\w\w\:\w\w\:\w\w\:\w\w\:\w\w)
+|
  or die "couldn't get MAC address\n";

my $host;
if ( !$mac_hash{$MAC} ) {
    $host = prompt("hostname please:");
    die "$host not in data file\n" if ( !$host_hash{$host} );
    $host_hash{$host}{mac} = $MAC;
}
else {
    $host = $mac_hash{$MAC};
}

set_net( $host, $host_hash{$host}{ip} );
save_data(%host_hash);

#######

sub get_host_hash {
   my %result;
    my ( $ip, $host, $mac );

 #   open( IN, $DATA_FILE ) or die " error: $DATA_FILE $!\n";
    while (<DATA>) {
        ( $ip, $host, $mac ) = split;
        $result{$host}{ip}  = $ip;
        $result{$host}{mac} = $mac;
    }
#    close(IN) or die "couldn't close: $DATA_FILE $!\n";

    return %result;
}

sub get_mac_hash {
    my %host_hash = @_;
    my %result;

    foreach my $host ( keys %host_hash ) {
        $result{ $host_hash{$host}{mac} } = $host;
    }
    return %result;
}

sub save_data {
    my $host_hash = @_;

    open( OUT, '>', $DATA_FILE ) or die "error: $DATA_FILE $!\n";
    foreach my $host ( sort keys %host_hash ) {
        print OUT "$host_hash{$host}{ip}\t";
    foreach my $host ( sort keys %host_hash ) {
        print OUT "$host_hash{$host}{ip}\t";
        print OUT "$host\t\t\t";
        print OUT "$host_hash{$host}{mac}" if $host_hash{$host}{mac};
        print OUT "\n";
    }
    close(OUT) or die "after writing couldn't close: $DATA_FILE $!\n";
}

sub prompt {
    my $msg = shift;
    print $msg;
    my $result = <STDIN>;
    chomp $result;
    return $result;
}

sub set_net {
    my $host = shift;
    my $ip   = shift;
    my ( $find, $replace, $file );

    $find    = "^IPADDR.*";
    $replace = "IPADDR=$ip";
    $file    = '/etc/sysconfig/network-scripts/ifcfg-eth0';
    replace_string_in_file( $find, $replace, $file );

    $find    = "^HOSTNAME.*";
    $replace = "HOSTNAME=$host";
    $file    = '/etc/sysconfig/network';
   $replace = "HOSTNAME=$host";
    $file    = '/etc/sysconfig/network';
    replace_string_in_file( $find, $replace, $file );

    $find    = "^127\.0\.0\.1.*";
    $replace = "127\.0\.0\.1  localhost $host $host\.cs\.uml\.edu";
    $file    = '/etc/hosts';
    replace_string_in_file( $find, $replace, $file );
}

# from perldoc perlfaq5 the v5.6.1 version
sub replace_string_in_file {
    my $find    = shift;
    my $replace = shift;
    my $file    = shift;

    my $old = $file;
    my $new = "$file.tmp.$$";
    my $bak = "$file.orig";

    open( OLD, "< $old" ) or die "can't open $old: $!";
    open( NEW, "> $new" ) or die "can't open $new: $!";

    while (<OLD>) {
        s/$find/$replace/;
        ( print NEW $_ ) or die "can't write to $new: $!";
    }

    close(OLD) or die "can't close $old: $!";
    close(NEW) or die "can't close $new: $!";
    close(OLD) or die "can't close $old: $!";
    close(NEW) or die "can't close $new: $!";

    rename( $old, $bak ) or die "can't rename $old to $bak: $!";
    rename( $new, $old ) or die "can't rename $new to $old: $!";
}

# here for info only
__DATA__
192.200.32.92   algol
192.200.32.38   arcturus                00:06:5B:DD:97:F4
192.200.32.23   canopus
192.200.32.22   capella                 00:06:5B:DD:98:10
192.200.32.50   cosette                 00:06:5B:DD:97:15
192.200.32.51   debye
192.200.32.31   draconis                00:06:5B:DD:96:FB
192.200.32.25   eridani                 00:06:5B:DD:91:B8
192.200.32.80   europa                  00:06:5B:DD:92:F5
192.200.16.20   fleet                   00:06:5B:CF:69:53
192.200.32.52   fodera                  00:06:5B:DD:97:EA
192.200.32.53   hansa                   00:06:5B:DD:93:4E
192.200.32.27   hydra                   00:06:5B:DD:92:83
192.200.32.13   hyperion
192.200.32.14   janus                   00:06:5B:DD:97:19
192.200.32.90   metis                   00:06:5B:DD:96:7B