#!/usr/bin/perl -w

use strict;
use Getopt::Std;
use File::Basename;
use Cisco::CopyConfig ();

my $scriptname = basename($0);
my %opts;
$Getopt::Std::STANDARD_HELP_VERSION = 1;
$Getopt::Std::OUTPUT_HELP_VERSION = \*STDERR;
$main::VERSION = "0.6";

sub HELP_MESSAGE() {
	print STDERR <<EOF;
Usage: $scriptname [OPTION]... <hostname>...

	-m <tftpfile>	copy <tftpfile> from tftp server to running-config
	-s		copy running-config to startup-config
	-c		copy running-config to tftp server
	-p <tftppath>	destination path on tftp server for -c option, overriding
			configuration file entry
	-q		suppress all normal output
	-h		help
EOF
	exit 0;

}

getopts('m:scp:qh', \%opts);
HELP_MESSAGE() if $opts{h};

use vars qw($config);
require '/etc/ciscocopy.conf';

sub copyconfig($) {
	my $host = shift;
	my $ciscocopy = undef;
	$ciscocopy = Cisco::CopyConfig->new(
		host		=> $host,
		( (defined($config->{community}) and length($config->{community}) > 0) ? (
			ver => 1,
			comm => $config->{community},
		) : (
			ver          => 3,
			username     => $config->{username},
			authprotocol => $config->{authproto},
			privprotocol => $config->{privproto},
			authpassword => $config->{authpw},
			privpassword => $config->{privpw},
		))
	);
	return $ciscocopy;
}

sub ciscocopy($$) {
	my $tftppath = shift;
	my $host = shift;
	my $ciscocopy = copyconfig($host);

	printf "%s#copy running-config tftp://%s/%s/%s%s\n",
		$host, $config->{tftpserver}, $tftppath, $host, $config->{extension} unless $opts{q};
	$ciscocopy->copy($config->{tftpserver}, $tftppath."/".$host.$config->{extension})
		or print STDERR $ciscocopy->error();
}

sub ciscomerge($$) {
	my $tftpfile = shift;
	my $host = shift;
	my $ciscocopy = copyconfig($host);

	printf "%s#copy tftp://%s/%s running-config\n",
		$host, $config->{tftpserver}, $tftpfile unless $opts{q};
	$ciscocopy->merge($config->{tftpserver}, $tftpfile)
		or print STDERR $ciscocopy->error();

}

sub ciscosave($) {
	my $host = shift;
	my $ciscocopy = copyconfig($host);

	printf "%s#copy running-config startup-config\n", $host unless $opts{q};
	$ciscocopy->save()
		or print STDERR $ciscocopy->error();

}

# old script names for backwards compatibility
if ($scriptname eq "ciscomerge") {
	die "Usage: $0 <filename> <net_device_hostname>...\n" if (scalar @ARGV < 2);
	my $filename = shift;
	foreach my $host (@ARGV) {
		ciscomerge($filename,$host);
	}
	exit 0;
} elsif ($scriptname eq "ciscosave") {
	die "Usage: $0 <net_device_hostname>...\n" if (scalar @ARGV < 1);
	foreach my $host (@ARGV) {
		ciscosave($host);
	}
	exit 0;
} elsif ($scriptname eq "ciscocopy") {
	die "Usage: $0 <tftp-dir> <net_device_hostname>...\n" if (scalar @ARGV < 2);
	my $dirname = shift;
	foreach my $host (@ARGV) {
		ciscocopy($dirname,$host);
	}
	exit 0;
}

# current syntax

if ((!$opts{m} && !$opts{s} && !$opts{c}) || (scalar @ARGV < 1)) {
	HELP_MESSAGE();
}

my $tftppath;

if ($opts{c}) {
	if ($opts{p}) {
		$tftppath = $opts{p};
	} elsif ($config->{tftppath}) {
		$tftppath = $config->{tftppath};
	} else {
		die "tftppath argument or configuration variable missing\n";
	}
}

foreach my $host (@ARGV) {
	ciscomerge($opts{m},$host) if $opts{m};
	ciscosave($host) if $opts{s};
	ciscocopy($tftppath,$host) if $opts{c};
}	

exit 0;
