#!/usr/bin/perl # Script to obtain Slackware's current changelog information, and mail # reports to local recipients if there's been a change. # # Originally bash script written 2006/01/18 Sylvain Robitaille # Adapted to perl 2012-03-24 TTK Ciar # # TTK here -- You should edit at least MAILRECIPS and DOMAIN, then put this # file in your /etc/cron.daily/ directory. It will send a delta of the # Slackware ChangeLog.txt to the MAILRECIPS daily. use LWP::Simple; use Sys::Syslog qw(:standard); use File::Slurp; # Boilerplate command line argument parsing: my @DOCLIST = (); my %OPT = (); foreach my $arg ( @ARGV ) { if ( $arg =~ /^\-+(.+?)\=(.*)/ ) { $OPT{$1} = $2; } elsif ( $arg =~ /^\-+(.+)/ ) { $OPT{$1} = -1; } else { push ( @DOCLIST, $arg ); } } # The local mail recipient(s): my @MAILRECIPS = ( 'your-name@your-domain.com', 'other-name@other-domain.org' ); # The program we use to send mail: my $MAILPROG = "/usr/bin/mutt -x"; # The name of our bot user account and local domain: my $BOTNAME = "slackware"; my $DOMAIN = "your-domain.com"; # zzapp -- FIXME: derive this automatically. # Where the changelog resides: my $CHLOGURL = "ftp://ftp.osuosl.org/pub/slackware/slackware64-current/ChangeLog.txt"; # Preferred scratch space: # Recommended to NOT use /tmp, as common administrative practice is to # clear /tmp out periodically, and we want $OLD_LOG to persist. my $TMP_PATH = "/var/tmp"; # If you want to pass more options to your mail client, put them here. my $MORE_OPTIONS = ""; # If you want to pass optional configuration to the mail client, put its path here. # If not, comment out this line or set it to the empty string (""). my $MAIL_RC_PATH = "/root/.muttrc.slackware"; my $MAIL_RC_OPT = "-F"; # option to pass $MAIL_RC_PATH to client # You probably will not need to change anything below this line. my $OLD_LOG = "$TMP_PATH/ChangeLog.txt"; my $NEW_LOG = "$TMP_PATH/ChangeLog.txt.new"; my $DIF_LOG = "$TMP_PATH/ChangeLog.txt.diff"; # zzapp -- TODO: Change this to something more exciting if we detect a new release: my $SUBJECT = "Slackware ChangeLog Update"; # Clean up after previous partial failures: unlink($NEW_LOG); # Get a copy of the current pages (or not): errlog ("failed to download $CHLOGURL to $TMP_PATH","fatal") unless (getstore($CHLOGURL, $NEW_LOG) && (-e $NEW_LOG)); # If this is the first time the program has run, just put ChangeLog.txt # where we expect it, note it in the log, and exit. if (!-e $OLD_LOG) { rename ($NEW_LOG, $OLD_LOG); errlog ("Initialized $OLD_LOG","exiting normally"); } # Diff the file: system ("/usr/bin/diff -wiBaE $OLD_LOG $NEW_LOG 2>\&1 | /bin/grep '^>' | cut -b 3- > $DIF_LOG"); unless (-s $DIF_LOG > 0) { unlink ($NEW_LOG, $DIF_LOG); errlog ("no change between $OLD_LOG and $NEW_LOG","exiting normally"); } # zzapp -- TODO: insert logic here to characterize and/or massage the content # * especially: identify a new release (and update $SUBJECT) # * highlight security patches and PV's personal notes # * summarize new packages and package upgrades and regressions File::Slurp::write_file($DIF_LOG, {append => 1}, ( "", "Sent to you as a courtesy by Slackware Update Robot\n", "If you do not want to recieve these notifications, please email $BOTNAME\@$DOMAIN\n", "(Not officially affiliated with the Slackware Linux distribution)\n")); unlink("$OLD_LOG.bup"); rename($OLD_LOG, "$OLD_LOG.bup"); if (rename($NEW_LOG, $OLD_LOG)) { unlink("$OLD_LOG.bup"); } else { errlog("Failed to copy $NEW_LOG -> $OLD_LOG, reverting to previous copy"); rename("$OLD_LOG.bup", $OLD_LOG); } # Mail the report: if (defined($MAIL_RC_PATH) && ($MAIL_RC_PATH ne '')) { $MORE_OPTIONS .= " $MAIL_RC_OPT $MAIL_RC_PATH"; init_mail_rc($MAIL_RC_PATH) unless (-e $MAIL_RC_PATH); } system("$MAILPROG $MORE_OPTIONS -s '$SUBJECT' ".join(" ", @MAILRECIPS)." < $DIF_LOG"); exit(0); sub errlog { my ($msg, $is_fatal) = @_; my $say_fatal = ''; $say_fatal = " ($is_fatal)" if (defined($is_fatal)); Sys::Syslog::syslog("debug", "$msg$say_fatal"); if ($OPT{'show-log'}) { my $tm = time(); my $lt = localtime($tm); print ("$lt $tm [$$]\t$msg$say_fatal\n"); } exit(1) if (defined($is_fatal)); return; } sub init_mail_rc { my ($f) = @_; File::Slurp::write_file($f, "my_hdr From: $BOTNAME\@$DOMAIN (Slackware Notification Robot)\n" . "my_hdr Return-Path: $BOTNAME\@$DOMAIN\n" . "my_hdr Reply-To: $BOTNAME\@$DOMAIN\n" . "my_hdr Bcc: $BOTNAME\@$DOMAIN\n" . "set envelope_from\n"); return; }