#!/usr/bin/perl
#: Diff my active crontab against a given file.
#======================================================================
# Sean M. Burke <sburke@cpan.org> 2000-12-06
## Last Modified Time-stamp: "2012-05-02 02:54:20 MDT sburke@cpan.org"

#======================================================================
# Output looks like:
#   "<" on a line that's in the existing crontab, missing in the new crontab
#   ">" on a line that's in the new crontab, missing in the existing crontab


use constant CRON => defined $ENV{'MAILTO'};
use strict;
my $x;
unless(@ARGV == 1 and defined($x = $ARGV[0]) and length $x
  and -e $x and -f _
) {
  require File::Basename;
  die "Usage: ", File::Basename::basename($0), " filespec\n";
}
Main();
exit;

my(@content,  # lines from the current crontab
   $temp,     # filespec of the temp file
   @diffy,    # lines of output from the diff command
);
sub Main {
  Get_Content();
  Dump_Current_Crontab();
  Diff_The_Two();
  Final_Report();
}

#======================================================================

sub Final_Report {

  sleep 0;
  unlink $temp or warn "Can't unlink $temp: $!";  # nix temp file
  if(@diffy) {
    print @diffy;
    exit 1;
  } else {
    print "(No differences)\n" unless CRON;
    exit;
  }

}
#======================================================================

sub Get_Content {
  @content = (`crontab -l 2>&1`);   # Get the current crontab
  if(!@content
    or ( @content == 1 and $content[0] =~ m<^no crontab>s )
  ) { 
    print("[No crontab is installed!]\n");
    exit 2;
  }
  
  splice @content, 0, 3  # remove the hoohah that might be there.
     if @content >= 3
    and $content[0] =~ m<^# DO NOT EDIT THIS FILE>s
    and $content[1] =~ m<^# \(.* installed on>s
    and $content[2] =~ m<^# \(Cron version>s
  ;
  return;
}

#======================================================================
use File::Temp qw(tempfile);

sub Dump_Current_Crontab {
  my $TFH;
  ($TFH, $temp) = tempfile( 'diff_XXXXXXX' );
  print $TFH @content or die "Can't print to tempfile $temp - $!";
  close($TFH) or die "Can't close channel to $temp: $!";
  return;
}

#======================================================================
sub Diff_The_Two {
  open my $DIFF, "-|", "diff", $temp, $x
   or die "Can't open channel from diff $temp $x - $!";
  @diffy = readline($DIFF);
  close($DIFF);
}

#======================================================================
