#!/usr/bin/perl -w

#
# DNSSet by Acri Emanuele (crossbower@gmail.com)
# Automatically set DNS server for internet connection
#
# Released under BSD license. 17/07/2009.
#

use strict;
use warnings;

use Getopt::Std;
use File::Copy;

my %options=();

my $author  = 'Acri Emanuele';
my $email   = 'crossbower@gmail.com';
my $version = '0.4.0';

my $dns_list        = 'dns.list';
my $dns_list_etc    = '/etc/dns.list';
my $dns_list_url    = 'http://dnsset.sourceforge.net/dns.list';
my $resolv_conf     = '/etc/resolv.conf';
my $resolv_conf_old = '/etc/resolv.conf.old.setdns';

# print usage
sub print_usage {
    print "DNSSet " . $version . " - " . $author . " (" . $email . ")\n";
    print "Automatically set DNS server for internet connection\n\n";
    print "Usage:\n";
    print "\tdnsset [options] [servername]\n\n";
    print "Options:\n";
    print "\t-s\tSet DNS server (default).\n";
    print "\t-r\tRestore previous DNS servers.\n";
    print "\t-l\tList known DNS servers.\n";
    print "\t-u\tUpdate DNS server list.\n";
    print "\t-h\tPrint this help screen.\n\n";
    print "Example:\n";
    print "\tdnsset fooldns\n";
    
    exit(0);
}

# set selected dns server
sub set_dns {
    my $found = 0;

    # get the selected server
    my $sel_server = shift;

    # open the DNS list
    open DNSLIST, "<", $dns_list or
    open DNSLIST, "<", $dns_list_etc or
        die "Could not open dns.list for reading\n";
    
    # file loop
    while ( <DNSLIST> ) {
        my @line = split(/\s+/,$_);
        
        # skip if empty
        next if (scalar(@line) == 0);
        
        # discard comments
        next if $line[0]=~/^\s*#/;
        
        # check name
        if ($line[0] eq $sel_server) {
        
            # move resolv.conf
            if ( not (-e $resolv_conf_old)) {
                move($resolv_conf, $resolv_conf_old) or
                    die "Could not move " . $resolv_conf . "\n";
            }
            
            # set dns server
            open RESOLVCONF, ">", $resolv_conf or
                die "Could not open " . $resolv_conf . " for writing\n";
            
            shift(@line);
            foreach (@line) {
                print RESOLVCONF "nameserver " . $_ . "\n";
            }
            
            close(RESOLVCONF);
            
            $found = 1;
            
            last;
        }
    }
    
    close(DNSLIST);
    
    if ( $found == 0 ) {
        die "DNS server not found: " . $sel_server . "\n";
    }
}

# restore previous dns servers
sub restore_dns {

    # restore old resolv.conf
    if (-e $resolv_conf_old) {
        move($resolv_conf_old, $resolv_conf) or
            die "Could not move " . $resolv_conf_old . "\n";
    }
    else {
        die "Previous resolv.conf file not found\n";
    }
}

# list dns servers avalaible
sub list_dns {

    # open the DNS list
    open DNSLIST, "<", $dns_list or
    open DNSLIST, "<", $dns_list_etc or
        die "Could not open dns.list for reading\n";
    
    # file loop
    while ( <DNSLIST> ) {
        print $_;
    }
    
    close(DNSLIST);
}

# update dns list
sub update_list {
    system("cd /etc/; rm " . $dns_list_etc . "; wget " . $dns_list_url);
}

# THE PROGRAM STARTS HERE

# get user options
getopts("s:rluh",\%options);

# use the appropriate function
if (defined $options{s}) {
    set_dns($options{s});
}
elsif (defined $options{r}) {
    restore_dns();
}
elsif (defined $options{l}) {
    list_dns();
}
elsif (defined $options{u}) {
    update_list();
}
elsif (defined $options{h}) {
    print_usage();
}
elsif ($#ARGV == 0) {
    set_dns($ARGV[0]);
}
else {
    print_usage();
}

exit (0);

