Skip to content

Instantly share code, notes, and snippets.

@erhhung
Last active May 26, 2020 21:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erhhung/a0875f0d77c88fb0198b4d4d6d0ff757 to your computer and use it in GitHub Desktop.
Save erhhung/a0875f0d77c88fb0198b4d4d6d0ff757 to your computer and use it in GitHub Desktop.
Perl script from eons ago for adding/deleting entries in /etc/hosts
#!/usr/bin/perl
#
# chip - add/change/delete IP entry in "/etc/hosts"
#
# Usage: add/change: chip [-q] {host_name} {ip_address}
# delete: chip {host_name} -
#
# -q: quiet - don't validate if Data::Validate::IP
# module cannot be found
#
# Author: Erhhung Yuan (erhhung@alum.mit.edu)
#
# Notes: either run using sudo or chmod 666 /etc/hosts
use feature qw(say);
use strict;
my $quiet = 0;
my $host = shift(@ARGV);
if ($host eq "-q") {
$quiet = 1;
$host = shift(@ARGV);
}
my $ip = shift(@ARGV);
# check proper usage
unless ($host && $ip)
{
say "chip - add/change/delete IP address in \"/etc/hosts\"";
say "Usage: add/change: chip [-q] {host_name} {ip_address}";
say " delete: chip {host_name} -";
say " -q: quiet - don't validate if Data::Validate::IP";
die " module cannot be found\n";
}
# validate host name
unless ($host =~ /^(\w|[.\-~])+$/) {
die "Host name is not valid!\n";
}
# also add bare name if FQDN
if ($host =~ /^([^.]+)\./) {
$host = "$1 $host";
}
$host = lc($host);
eval {
require Data::Validate::IP;
Data::Validate::IP->import(qw(is_ipv4 is_ipv6));
};
if ($@) {
unless ($quiet) {
say "Data::Validate::IP module not found!";
die "Run: cpan install Data::Validate::IP\n";
}
sub is_ipv4 { return 1; }
}
# validate IP address
unless (is_ipv4($ip) ||
is_ipv6($ip) ||
$ip eq "-") {
die "IP address is not valid!\n";
}
unless (open(HOSTS, "<", "/etc/hosts")) {
die "Cannot read from \"/etc/hosts\"!\n";
}
my $pattern = quotemeta($host);
my @lines;
my $added;
sub add_ip
{
unless ($ip eq "-") {
push(@lines, sprintf("%-15s %s", $ip, $host));
$added = 1;
}
}
# read & filter hosts file
while (my $line = <HOSTS>) {
chomp($line);
if ($line !~ /^#.*/ &&
$line =~ /^\S+\s+$pattern$/) {
&add_ip();
} else {
push(@lines, $line);
}
}
close(HOSTS);
# truncate leading & trailing empty lines
shift(@lines) while ($#lines >= 0 && length($lines[0]) == 0);
pop(@lines) while ($#lines >= 0 && length($lines[$#lines]) == 0);
# add IP if didn't replace
&add_ip() unless ($added);
unless (open(HOSTS, ">", "/etc/hosts")) {
die "Cannot write to \"/etc/hosts\"!\n";
}
# write updated hosts file
say HOSTS $_ foreach (@lines);
close(HOSTS);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment