#!/usr/bin/perl -w 

$main::debug	= 0;

use SNMP;

$main::spool	= "/export/home/ipadman/ubehandlet/";
$main::done	= "/export/home/ipadman/behandlet/";
$main::failed	= "/export/home/ipadman/fejlede/";

$main::tftpdir	= "/tftpboot/";
$main::tftpfile	= "autoconfig.tmp";
$main::sendmail	= "/usr/lib/sendmail -t";
$main::from_email	= "autoconfig\@domain";

$main::tftpserver	= "1.1.1.1";
$main::community	= "secret";

$main::log	= "/var/log/autoconfig.log";
$main::lockfile	= "/tmp/autoconfig.LCK";

&lock($main::lockfile);

##########

open(LS,"/bin/ls -F ".$main::spool."|") || die("Cannot list directory ".$main::spool.": ".$!."\n");
while(<LS>) {
  print STDERR "Fil: ".$_	if ( $main::debug > 8 );
  chomp;
  next 	if ( /\/$/ );
  next	if ( /\*$/ );
  my $file_short	= $_;
  my $file		= $main::spool.$file_short;
  if ( -f $file && -r $file ) {
    &log("Call do on ".$file_short)	if ( $main::debug > 3 );
    my ($res,$txt,$operator,$email,$router,$lineid) = &do($main::spool,$file_short);
    &log("Return from do with res=".$res." txt=".$txt." email=".$email)	if ( $main::debug > 3 );
    if ( $res ) {
      my $new_file	= $main::done.$file_short;
      &log($operator." configued ".$router." lineid=".$lineid." all ok (".$new_file.")");
      rename($file,$new_file);
      next;
    } else {
      my $new_file	= $main::failed.$file_short;
      &log($operator." configured ".$router." lineid=".$lineid." not ok (".$new_file.")");
      rename($file,$new_file);
      &mail($txt,$operator,$email,$new_file);
    }
  } 
}
close(LS);

&unlock($main::lockfile);

##########

sub do {
  my $dir	= $_[0];
  my $file	= $_[1];

  print STDERR "do called with ".$_[0].$_[1]."\n"	if ( $main::debug > 5 );

  #
  # Check of filename, should be routername-circuitid-time
  # our routernames match [a-zA-Z0-9\-]+nx[a-z][0-9]+
  #

  unless ( $file =~ /^([a-zA-Z0-9\-]+nx[a-z][0-9]+)\-/ ) {
    return(0,"the file ".$file." not in a correct filename.","","","","");
  }
  my $router	= $1;

  print STDERR " router=".$router."\n"	if ( $main::debug > 5 );

  my ($operator,$email,$lineid);

  $file		= $dir.$file;

  open(FIL,$file) || return(0,"Cannot open the file ".$file,"","",$router,"");
  open(TFTP,">".$main::tftpdir.$main::tftpfile) || return(0,"Cannot write to the tftp file ".$main::tftpfile,"","",$router,"");
  while(<FIL>) {
    if ( /^\s*!/ ) {
      if ( /^\s*!\s*Operator\s*=\s*([^\s]+)\s*$/ ) {
        &log("Found operator=".$1)	if ( $main::debug );
        $operator	= $1;
      } elsif ( /^\s*!\s*Email\s*=\s*([^\s]+)\s*$/ ) {
        &log("Found email=".$1)	if ( $main::debug );
        $email		= $1;
      } elsif ( /^\s*!\s*Ano\s*=\s*([^\s]+)\s*$/ ) {
        &log("Found lineid=".$1)	if ( $main::debug );
        $lineid		= $1;
      } elsif ( /^\s*!\s*$/ ) {
        next;
      } else {
        &log($0.": unknown comment ".$_." in the file ".$file);
      }
    } else {
      print STDERR " not a comment: ".$_	if ( $main::debug > 8 );
      print TFTP $_;
      print STDERR " ".$_	if ( $main::debug > 5 );
    }
  }
  close(TFTP);
  close(FIL);

  $sess = new SNMP::Session  (DestHost        => $router,
                              Community       => $main::community,
                              Retries         => 1,
                              Timeout         => 20000000,
                              Version         => '1' );
 
  my $oid	= ".1.3.6.1.4.1.9.2.1.50.".$main::tftpserver;

  $sess->set([ [ "$oid", "" , $main::tftpfile, "OCTETSTR" ] ]);
  if ( $sess->{ErrorStr} ) {
     &log("config of ".$router." SNMP error: ".$sess->{ErrorStr});
     return(0,"config af ".$router." SNMP error: ".$sess->{ErrorStr},$operator,$email,$router,$lineid);
  }

  #
  # write net
  #

  $oid		= ".1.3.6.1.4.1.9.2.1.55.".$main::tftpserver;
  my $file_name	= $router."-confg";
  $sess->set([ [ "$oid", "" , $file_name, "OCTETSTR" ] ]);
  if ( $sess->{ErrorStr} ) {
     &log("'copy run tftp' on ".$router." failed SNMP error: ".$sess->{ErrorStr});
     return(0,"'copy run tftp' on ".$router." failed SNMP error: ".$sess->{ErrorStr},$operator,$email,$router,$lineid);
  }
  #
  # write mem
  #

  $oid		= ".1.3.6.1.4.1.9.2.1.54.0";
  $sess->set([ [ "$oid", "" , 1, "INTEGER" ] ]);
  if ( $sess->{ErrorStr} ) {
     &log("'copy run start' on ".$router." failed SNMP error: ".$sess->{ErrorStr});
     return(0,"'copy run start' on ".$router." failed SNMP error: ".$sess->{ErrorStr},$operator,$email,$router,$lineid);
  }
  undef($sess);
  return(1,"",$operator,$email,$router,$lineid);
}

sub log {
  my $clock	= localtime(time);
  open (LOG,">>".$main::log) || print STDERR "Cannot append to log file ".$main::log.": ".$!."\n";
  print LOG $clock." ".$_[0]."\n";
  close(LOG);
}

sub unlock {
  unlink($_[0]);
}

sub lock {
  my $lockfil=$_[0];
  my $out="";
  if ( -f $lockfile ) {
    open(LOCK, $lockfile );
    $pid=<LOCK>;
    chomp($pid);
    close(LOCK);
    $buf=`ps -ef | grep $pid | grep -v grep`;
    if ( $buf =~ /perl/ ) {
      exit(0);
    }   
    &log($0." locked by $pid, but $pid is dead ...");
    unlink( $lockfile );
  }
  open(LOCK,"> ".$lockfile) || &log("Unable to create lockfile: ".$lockfile.": ".$!."\n");
  print LOCK $$."\n";
  close(LOCK);
}

sub mail {
  my ($txt,$operator,$email,$new_file)	= @_;

  &log("mail ind txt=".$txt." operator=".$operator." email=".$email." new_file=".$new_file)	if ( $main::debug > 5 );

  if ( $email !~ /@/ ) {
    print STDERR "no email adress (".$email."), and ".$txt."\n";
    return;
  }

  open(MAIL,"|".$main::sendmail) || &log("Cannot open sendmail: ".$!);
  print MAIL "From: AutoConfig <".$main::from_email.">\n";
  print MAIL "To: ".$operator." <".$email.">\n";
  print MAIL "Subject: ".$txt."\n\n";
  print MAIL "The configuration below is not configured correct.\n\n";
  open(FIL,$new_file) ||  &log("Cannot open the file ".$new_file.": ".$!);
  while(<FIL>) {
    print MAIL $_;
  }
  print MAIL ".\n";
  close(FIL);
  close(MAIL);
}

