* Various changes for 3.0.0beta1
[BackupPC.git] / bin / BackupPC_sendEmail
index f30c0d3..4b8d652 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/perl -T
+#!/bin/perl
 #============================================================= -*-perl-*-
 #
 # BackupPC_sendEmail: send status emails to users and admins
@@ -13,7 +13,7 @@
 #   Craig Barratt  <cbarratt@users.sourceforge.net>
 #
 # COPYRIGHT
-#   Copyright (C) 2001  Craig Barratt
+#   Copyright (C) 2001-2003  Craig Barratt
 #
 #   This program is free software; you can redistribute it and/or modify
 #   it under the terms of the GNU General Public License as published by
 #
 #========================================================================
 #
-# Version 2.0.0beta2, released 13 Apr 2003.
+# Version 3.0.0beta1, released 30 Jul 2006.
 #
 # See http://backuppc.sourceforge.net.
 #
 #========================================================================
 
 use strict;
+no  utf8;
 use lib "/usr/local/BackupPC/lib";
 use BackupPC::Lib;
 use BackupPC::FileZIO;
@@ -45,10 +46,11 @@ use BackupPC::FileZIO;
 use Data::Dumper;
 use Getopt::Std;
 use DirHandle ();
-use vars qw($Lang $TopDir $BinDir %Conf);
+use vars qw($Lang $TopDir $BinDir $LogDir %Conf);
 
 die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
 $TopDir = $bpc->TopDir();
+$LogDir = $bpc->LogDir();
 $BinDir = $bpc->BinDir();
 %Conf   = $bpc->Conf();
 $Lang   = $bpc->Lang();
@@ -56,24 +58,68 @@ $Lang   = $bpc->Lang();
 $bpc->ChildInit();
 
 use vars qw(%UserEmailInfo);
-do "$TopDir/log/UserEmailInfo.pl";
+do "$LogDir/UserEmailInfo.pl";
 
 my %opts;
-if ( !getopts("t", \%opts) || @ARGV != 0 ) {
-    print("usage: $0 [-t]\n");
+if ( !getopts("ctu:", \%opts) || @ARGV != 0 ) {
+    print <<EOF;
+usage: $0 [-t] [-c] [-u userEmail]
+options:
+
+  -t  display the emails that would be sent, without sending them
+
+  -c  check if BackupPC is alive and send an email if not
+
+  -u  send a test email to userEmail
+EOF
     exit(1);
 }
 
 my $err = $bpc->ServerConnect($Conf{ServerHost}, $Conf{ServerPort});
 if ( $err ) {
+    if ( $opts{c} && $Conf{EMailAdminUserName} ne "" ) {
+        my $headers = $Conf{EMailHeaders};
+        $headers .= "\n" if ( $headers !~ /\n$/ );
+        my $mesg = <<EOF;
+To: $Conf{EMailAdminUserName}
+Subject: BackupPC: can't connect to server
+$headers
+Error: cannot connect to BackupPC server.
+
+Regards,
+PC Backup Genie
+EOF
+        SendMail($mesg);
+        exit(1);
+    }
     print("Can't connect to server ($err)\n");
     exit(1);
 }
+exit(0) if ( $opts{c} );
 my $reply = $bpc->ServerMesg("status hosts");
 $reply = $1 if ( $reply =~ /(.*)/s );
 my(%Status, %Info, %Jobs, @BgQueue, @UserQueue, @CmdQueue);
 eval($reply);
 
+###########################################################################
+# Generate test message if required
+###########################################################################
+if ( $opts{u} ne "" ) {
+    my $headers = $Conf{EMailHeaders};
+    $headers .= "\n" if ( $headers !~ /\n$/ );
+    my $mesg = <<EOF;
+To: $opts{u}
+Subject: BackupPC test email
+$headers
+This is a test message from $0.
+
+Regards,
+PC Backup Genie
+EOF
+    SendMail($mesg);
+    exit(0);
+}
+
 ###########################################################################
 # Generate sysadmin warning messages
 ###########################################################################
@@ -81,7 +127,8 @@ my $mesg = "";
 
 my @badHosts = ();
 foreach my $host ( sort(keys(%Status)) ) {
-    next if ( $Status{$host}{reason} ne "backup failed"
+    next if ( ($Status{$host}{reason} ne "Reason_backup_failed"
+               && $Status{$host}{reason} ne "Reason_restore_failed")
            || $Status{$host}{error} =~ /^lost network connection to host/ );
     push(@badHosts, "$host ($Status{$host}{error})");
 }
@@ -120,7 +167,7 @@ my @oldDirs = ();
 my @files = $d->read;
 $d->close;
 foreach my $host ( @files ) {
-    next if ( $host eq "." || $host eq ".." || defined($Status{$host}) );
+    next if ( $host =~ /^\./ || defined($Status{$host}) );
     push(@oldDirs, "$TopDir/pc/$host");
 }
 if ( @oldDirs ) {
@@ -138,19 +185,16 @@ EOF
 }
 
 if ( $mesg ne "" && $Conf{EMailAdminUserName} ne "" ) {
+    my $headers = $Conf{EMailHeaders};
+    $headers .= "\n" if ( $headers !~ /\n$/ );
     $mesg = <<EOF;
 To: $Conf{EMailAdminUserName}
 Subject: BackupPC administrative attention needed
-
+$headers
 ${mesg}Regards,
 PC Backup Genie
 EOF
-    if ( $opts{t} ) {
-        print("#" x 75, "\n");
-        print $mesg;
-    } else {
-       SendMail($mesg);
-    }
+    SendMail($mesg);
 }
 
 ###########################################################################
@@ -168,6 +212,7 @@ foreach my $host ( sort(keys(%Status)) ) {
     my $user = $Hosts->{$host}{user};
     next if ( time - $UserEmailInfo{$user}{lastTime}
                         < $Conf{EMailNotifyMinDays} * 24*3600 );
+    next if ($Conf{XferMethod} eq "archive" );
     my @Backups = $bpc->BackupInfoRead($host);
     my $numBackups = @Backups;
     if ( $numBackups == 0 ) {
@@ -188,6 +233,11 @@ foreach my $host ( sort(keys(%Status)) ) {
     my $numBadOutlook = 0;
     for ( my $i = 0 ; $i < @Backups ; $i++ ) {
         my $fh;
+        #
+        # ignore partials -> only fulls and incrs should be used
+        # in figuring out when the last good backup was
+        #
+        next if ( $Backups[$i]{type} eq "partial" );
         $lastNum = $Backups[$i]{num} if ( $lastNum < $Backups[$i]{num} );
         if ( $Backups[$i]{type} eq "full" ) {
             $lastFull = $Backups[$i]{startTime}
@@ -214,8 +264,8 @@ foreach my $host ( sort(keys(%Status)) ) {
         while ( 1 ) {
             my $s = $fh->readLine();
             last if ( $s eq "" );
-            if ( $s =~ /^Error reading file.*\.pst : ERRDOS - ERRlock/
-                  || $s =~ /^Error reading file.*\.pst\. Got 0 bytes/ ) {
+            if ( $s =~ /^\s*Error reading file.*\.pst : (ERRDOS - ERRlock|NT_STATUS_FILE_LOCK_CONFLICT)/
+                  || $s =~ /^\s*Error reading file.*\.pst\. Got 0 bytes/ ) {
                 $badOutlook = 1;
                 last;
             }
@@ -281,7 +331,8 @@ if ( !$opts{t} ) {
     my $dumpStr = Data::Dumper->Dump(
              [\%UserEmailInfo],
              [qw(*UserEmailInfo)]);
-    if ( open(HOST, ">", "$TopDir/log/UserEmailInfo.pl") ) {
+    if ( open(HOST, ">", "$LogDir/UserEmailInfo.pl") ) {
+       binmode(HOST);
         print(HOST $dumpStr);
         close(HOST);
     }
@@ -299,19 +350,16 @@ sub user2name
 sub sendUserEmail
 {
     my($user, $host, $mesg, $subj, $vars) = @_;
-    $vars->{user}   = $user;
-    $vars->{host}   = $host;
-    $vars->{domain} = $Conf{EMailUserDestDomain};
-    $vars->{CgiURL} = $Conf{CgiURL};
+    $vars->{user}     = $user;
+    $vars->{host}     = $host;
+    $vars->{headers}  = $Conf{EMailHeaders};
+    $vars->{headers} .= "\n" if ( $vars->{headers} !~ /\n$/ );
+    $vars->{domain}   = $Conf{EMailUserDestDomain};
+    $vars->{CgiURL}   = $Conf{CgiURL};
     $subj =~ s/\$(\w+)/defined($vars->{$1}) ? $vars->{$1} : "\$$1"/eg;
     $vars->{subj}   = $subj;
     $mesg =~ s/\$(\w+)/defined($vars->{$1}) ? $vars->{$1} : "\$$1"/eg;
-    if ( $opts{t} ) {
-        print("#" x 75, "\n");
-        print $mesg;
-    } else {
-       SendMail($mesg);
-    }
+    SendMail($mesg);
     $UserEmailInfo{$user}{lastTime} = time;
     $UserEmailInfo{$user}{lastSubj} = $subj;
     $UserEmailInfo{$user}{lastHost} = $host;
@@ -320,14 +368,25 @@ sub sendUserEmail
 sub SendMail
 {
     my($mesg) = @_;
-    my($from) = $Conf{EMailFromUserName};
+    my $from = $Conf{EMailFromUserName};
+    my $utf8 = 1
+        if ( $Conf{EMailHeaders} =~ /Content-Type:.*charset="utf-?8"/i );
     local(*MAIL);
 
+    if ( $opts{t} ) {
+        binmode(STDOUT, ":utf8") if ( $utf8 );
+        print("#" x 75, "\n");
+        print $mesg;
+        return;
+    }
     $from = "-f $from" if ( $from ne "" );
+    print("Sending test email using $Conf{SendmailPath} -t $from\n")
+                if ( $opts{u} ne "" );
     if ( !open(MAIL, "|$Conf{SendmailPath} -t $from") ) {
        printf("Can't run sendmail ($Conf{SendmailPath}): $!\n");
        return;
     }
+    binmode(MAIL, ":utf8") if ( $utf8 );
     print MAIL $mesg;
     close(MAIL);
 }