/[BackupPC]/trunk/bin/BackupPC_sendEmail
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/bin/BackupPC_sendEmail

Parent Directory Parent Directory | Revision Log Revision Log


Revision 316 - (hide annotations)
Mon Jan 30 13:37:17 2006 UTC (18 years, 4 months ago) by dpavlin
File size: 11429 byte(s)
 r9152@llin:  dpavlin | 2006-01-30 14:11:45 +0100
 update to upstream 2.1.2

1 dpavlin 1 #!/bin/perl
2     #============================================================= -*-perl-*-
3     #
4     # BackupPC_sendEmail: send status emails to users and admins
5     #
6     # DESCRIPTION
7     #
8     # BackupPC_sendEmail: send status emails to users and admins.
9     # BackupPC_sendEmail is run by BackupPC_nightly, so it runs
10     # once every night.
11     #
12     # AUTHOR
13     # Craig Barratt <cbarratt@users.sourceforge.net>
14     #
15     # COPYRIGHT
16     # Copyright (C) 2001-2003 Craig Barratt
17     #
18     # This program is free software; you can redistribute it and/or modify
19     # it under the terms of the GNU General Public License as published by
20     # the Free Software Foundation; either version 2 of the License, or
21     # (at your option) any later version.
22     #
23     # This program is distributed in the hope that it will be useful,
24     # but WITHOUT ANY WARRANTY; without even the implied warranty of
25     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26     # GNU General Public License for more details.
27     #
28     # You should have received a copy of the GNU General Public License
29     # along with this program; if not, write to the Free Software
30     # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31     #
32     #========================================================================
33     #
34 dpavlin 316 # Version 2.1.2, released 5 Sep 2005.
35 dpavlin 1 #
36     # See http://backuppc.sourceforge.net.
37     #
38     #========================================================================
39    
40     use strict;
41     no utf8;
42     use lib "__INSTALLDIR__/lib";
43     use BackupPC::Lib;
44     use BackupPC::FileZIO;
45    
46     use Data::Dumper;
47     use Getopt::Std;
48     use DirHandle ();
49     use vars qw($Lang $TopDir $BinDir %Conf);
50    
51     die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
52     $TopDir = $bpc->TopDir();
53     $BinDir = $bpc->BinDir();
54     %Conf = $bpc->Conf();
55     $Lang = $bpc->Lang();
56    
57     $bpc->ChildInit();
58    
59     use vars qw(%UserEmailInfo);
60     do "$TopDir/log/UserEmailInfo.pl";
61    
62     my %opts;
63     if ( !getopts("t", \%opts) || @ARGV != 0 ) {
64     print("usage: $0 [-t]\n");
65     exit(1);
66     }
67    
68     my $err = $bpc->ServerConnect($Conf{ServerHost}, $Conf{ServerPort});
69     if ( $err ) {
70     print("Can't connect to server ($err)\n");
71     exit(1);
72     }
73     my $reply = $bpc->ServerMesg("status hosts");
74     $reply = $1 if ( $reply =~ /(.*)/s );
75     my(%Status, %Info, %Jobs, @BgQueue, @UserQueue, @CmdQueue);
76     eval($reply);
77    
78     ###########################################################################
79     # Generate sysadmin warning messages
80     ###########################################################################
81     my $mesg = "";
82    
83     my @badHosts = ();
84     foreach my $host ( sort(keys(%Status)) ) {
85 dpavlin 316 next if ( ($Status{$host}{reason} ne "Reason_backup_failed"
86     && $Status{$host}{reason} ne "Reason_restore_failed")
87 dpavlin 1 || $Status{$host}{error} =~ /^lost network connection to host/ );
88     push(@badHosts, "$host ($Status{$host}{error})");
89     }
90     if ( @badHosts ) {
91     my $badHosts = join("\n - ", sort(@badHosts));
92     $mesg .= <<EOF;
93     The following hosts had an error that is probably caused by a
94     misconfiguration. Please fix these hosts:
95     - $badHosts
96    
97     EOF
98     }
99    
100     #
101     # Report if we skipped backups because the disk was too full
102     #
103     if ( $Info{DUDailySkipHostCntPrev} > 0 ) {
104     my $n = $Info{DUDailySkipHostCntPrev};
105     my $m = $Conf{DfMaxUsagePct};
106     $mesg .= <<EOF;
107     Yesterday $n hosts were skipped because the file system containing
108     $TopDir was too full. The threshold in the
109     configuration file is $m%, while yesterday the file system was
110     up to $Info{DUDailyMaxPrev}% full. Please find more space on the file system,
111     or reduce the number of full or incremental backups that we keep.
112    
113     EOF
114     }
115    
116     #
117     # Check for bogus directories (probably PCs that are no longer
118     # on the backup list)
119     #
120     my $d = DirHandle->new("$TopDir/pc") or die("Can't read $TopDir/pc: $!");
121     my @oldDirs = ();
122     my @files = $d->read;
123     $d->close;
124     foreach my $host ( @files ) {
125 dpavlin 316 next if ( $host =~ /^\./ || defined($Status{$host}) );
126 dpavlin 1 push(@oldDirs, "$TopDir/pc/$host");
127     }
128     if ( @oldDirs ) {
129     my $oldDirs = join("\n - ", sort(@oldDirs));
130     $mesg .= <<EOF;
131     The following directories are bogus and are not being used by
132     BackupPC. This typically happens when PCs are removed from the
133     backup list. If you don't need any old backups from these PCs you
134     should remove these directories. If there are machines on this
135     list that should be backed up then there is a problem with the
136     hosts file:
137     - $oldDirs
138    
139     EOF
140     }
141    
142     if ( $mesg ne "" && $Conf{EMailAdminUserName} ne "" ) {
143     $mesg = <<EOF;
144     To: $Conf{EMailAdminUserName}
145     Subject: BackupPC administrative attention needed
146    
147     ${mesg}Regards,
148     PC Backup Genie
149     EOF
150     if ( $opts{t} ) {
151     print("#" x 75, "\n");
152     print $mesg;
153     } else {
154     SendMail($mesg);
155     }
156     }
157    
158     ###########################################################################
159     # Generate per-host warning messages sent to each user
160     ###########################################################################
161     my $Hosts = $bpc->HostInfoRead();
162    
163     foreach my $host ( sort(keys(%Status)) ) {
164     next if ( $Hosts->{$host}{user} eq "" );
165     #
166     # read any per-PC config settings (allowing per-PC email settings)
167     #
168     $bpc->ConfigRead($host);
169     %Conf = $bpc->Conf();
170     my $user = $Hosts->{$host}{user};
171     next if ( time - $UserEmailInfo{$user}{lastTime}
172     < $Conf{EMailNotifyMinDays} * 24*3600 );
173     next if ($Conf{XferMethod} eq "archive" );
174     my @Backups = $bpc->BackupInfoRead($host);
175     my $numBackups = @Backups;
176     if ( $numBackups == 0 ) {
177     my $subj = defined($Conf{EMailNoBackupEverSubj})
178     ? $Conf{EMailNoBackupEverSubj}
179     : $Lang->{EMailNoBackupEverSubj};
180     my $mesg = defined($Conf{EMailNoBackupEverMesg})
181     ? $Conf{EMailNoBackupEverMesg}
182     : $Lang->{EMailNoBackupEverMesg};
183     sendUserEmail($user, $host, $mesg, $subj, {
184     userName => user2name($user)
185     }) if ( !defined($Jobs{$host}) );
186     next;
187     }
188     my $last = my $lastFull = my $lastIncr = 0;
189     my $lastGoodOutlook = 0;
190     my $lastNum = -1;
191     my $numBadOutlook = 0;
192     for ( my $i = 0 ; $i < @Backups ; $i++ ) {
193     my $fh;
194     $lastNum = $Backups[$i]{num} if ( $lastNum < $Backups[$i]{num} );
195     if ( $Backups[$i]{type} eq "full" ) {
196     $lastFull = $Backups[$i]{startTime}
197     if ( $lastFull < $Backups[$i]{startTime} );
198     } else {
199     $lastIncr = $Backups[$i]{startTime}
200     if ( $lastIncr < $Backups[$i]{startTime} );
201     }
202     $last = $Backups[$i]{startTime}
203     if ( $last < $Backups[$i]{startTime} );
204     my $badOutlook = 0;
205     my $file = "$TopDir/pc/$host/SmbLOG.$Backups[$i]{num}";
206     my $comp = 0;
207     if ( !-f $file ) {
208     $file = "$TopDir/pc/$host/XferLOG.$Backups[$i]{num}";
209     if ( !-f $file ) {
210     $comp = 1;
211     $file = "$TopDir/pc/$host/SmbLOG.$Backups[$i]{num}.z";
212     $file = "$TopDir/pc/$host/XferLOG.$Backups[$i]{num}.z"
213     if ( !-f $file );
214     }
215     }
216     next if ( !defined($fh = BackupPC::FileZIO->open($file, 0, $comp)) );
217     while ( 1 ) {
218     my $s = $fh->readLine();
219     last if ( $s eq "" );
220 dpavlin 316 if ( $s =~ /^\s*Error reading file.*\.pst : (ERRDOS - ERRlock|NT_STATUS_FILE_LOCK_CONFLICT)/
221 dpavlin 1 || $s =~ /^\s*Error reading file.*\.pst\. Got 0 bytes/ ) {
222     $badOutlook = 1;
223     last;
224     }
225     }
226     $fh->close();
227     $numBadOutlook += $badOutlook;
228     if ( !$badOutlook ) {
229     $lastGoodOutlook = $Backups[$i]{startTime}
230     if ( $lastGoodOutlook < $Backups[$i]{startTime} );
231     }
232     }
233     if ( time - $last > $Conf{EMailNotifyOldBackupDays} * 24*3600 ) {
234     my $subj = defined($Conf{EMailNoBackupRecentSubj})
235     ? $Conf{EMailNoBackupRecentSubj}
236     : $Lang->{EMailNoBackupRecentSubj};
237     my $mesg = defined($Conf{EMailNoBackupRecentMesg})
238     ? $Conf{EMailNoBackupRecentMesg}
239     : $Lang->{EMailNoBackupRecentMesg};
240     my $firstTime = sprintf("%.1f",
241     (time - $Backups[0]{startTime}) / (24*3600));
242     my $days = sprintf("%.1f", (time - $last) / (24 * 3600));
243     sendUserEmail($user, $host, $mesg, $subj, {
244     firstTime => $firstTime,
245     days => $days,
246     userName => user2name($user),
247     numBackups => $numBackups,
248     }) if ( !defined($Jobs{$host}) );
249     next;
250     }
251     if ( $numBadOutlook > 0
252     && time - $lastGoodOutlook > $Conf{EMailNotifyOldOutlookDays}
253     * 24 * 3600 ) {
254     my($days, $howLong);
255     if ( $lastGoodOutlook == 0 ) {
256     $howLong = eval("qq{$Lang->{howLong_not_been_backed_up}}");
257     } else {
258     $days = sprintf("%.1f", (time - $lastGoodOutlook) / (24*3600));
259     $howLong = eval("qq{$Lang->{howLong_not_been_backed_up_for_days_days}}");
260     }
261     my $subj = defined($Conf{EMailOutlookBackupSubj})
262     ? $Conf{EMailOutlookBackupSubj}
263     : $Lang->{EMailOutlookBackupSubj};
264     my $mesg = defined($Conf{EMailOutlookBackupMesg})
265     ? $Conf{EMailOutlookBackupMesg}
266     : $Lang->{EMailOutlookBackupMesg};
267     my $firstTime = sprintf("%.1f",
268     (time - $Backups[0]{startTime}) / (24*3600));
269     my $lastTime = sprintf("%.1f",
270     (time - $Backups[$#Backups]{startTime}) / (24*3600));
271     sendUserEmail($user, $host, $mesg, $subj, {
272     days => $days,
273     firstTime => $firstTime,
274     lastTime => $lastTime,
275     numBackups => $numBackups,
276     userName => user2name($user),
277     howLong => $howLong,
278     serverHost => $Conf{ServerHost},
279     }) if ( !defined($Jobs{$host}) );
280     }
281     }
282     if ( !$opts{t} ) {
283     $Data::Dumper::Indent = 1;
284     my $dumpStr = Data::Dumper->Dump(
285     [\%UserEmailInfo],
286     [qw(*UserEmailInfo)]);
287     if ( open(HOST, ">", "$TopDir/log/UserEmailInfo.pl") ) {
288     binmode(HOST);
289     print(HOST $dumpStr);
290     close(HOST);
291     }
292     }
293    
294     sub user2name
295     {
296     my($user) = @_;
297     my($name) = (getpwnam($user))[6];
298     $name =~ s/\s.*//;
299     $name = $user if ( $name eq "" );
300     return $name;
301     }
302    
303     sub sendUserEmail
304     {
305     my($user, $host, $mesg, $subj, $vars) = @_;
306     $vars->{user} = $user;
307     $vars->{host} = $host;
308     $vars->{domain} = $Conf{EMailUserDestDomain};
309     $vars->{CgiURL} = $Conf{CgiURL};
310     $subj =~ s/\$(\w+)/defined($vars->{$1}) ? $vars->{$1} : "\$$1"/eg;
311     $vars->{subj} = $subj;
312     $mesg =~ s/\$(\w+)/defined($vars->{$1}) ? $vars->{$1} : "\$$1"/eg;
313     if ( $opts{t} ) {
314     print("#" x 75, "\n");
315     print $mesg;
316     } else {
317     SendMail($mesg);
318     }
319     $UserEmailInfo{$user}{lastTime} = time;
320     $UserEmailInfo{$user}{lastSubj} = $subj;
321     $UserEmailInfo{$user}{lastHost} = $host;
322     }
323    
324     sub SendMail
325     {
326     my($mesg) = @_;
327     my($from) = $Conf{EMailFromUserName};
328     local(*MAIL);
329    
330     $from = "-f $from" if ( $from ne "" );
331     if ( !open(MAIL, "|$Conf{SendmailPath} -t $from") ) {
332     printf("Can't run sendmail ($Conf{SendmailPath}): $!\n");
333     return;
334     }
335     print MAIL $mesg;
336     close(MAIL);
337     }

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26