/[BackupPC]/upstream/2.1.0/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 /upstream/2.1.0/bin/BackupPC_sendEmail

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Jun 22 19:12:04 2005 UTC (17 years ago) by dpavlin
File size: 11337 byte(s)
import of version 2.1.0

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     # Version 2.1.0, released 20 Jun 2004.
35     #
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     next if ( $Status{$host}{reason} ne "backup failed"
86     || $Status{$host}{error} =~ /^lost network connection to host/ );
87     push(@badHosts, "$host ($Status{$host}{error})");
88     }
89     if ( @badHosts ) {
90     my $badHosts = join("\n - ", sort(@badHosts));
91     $mesg .= <<EOF;
92     The following hosts had an error that is probably caused by a
93     misconfiguration. Please fix these hosts:
94     - $badHosts
95    
96     EOF
97     }
98    
99     #
100     # Report if we skipped backups because the disk was too full
101     #
102     if ( $Info{DUDailySkipHostCntPrev} > 0 ) {
103     my $n = $Info{DUDailySkipHostCntPrev};
104     my $m = $Conf{DfMaxUsagePct};
105     $mesg .= <<EOF;
106     Yesterday $n hosts were skipped because the file system containing
107     $TopDir was too full. The threshold in the
108     configuration file is $m%, while yesterday the file system was
109     up to $Info{DUDailyMaxPrev}% full. Please find more space on the file system,
110     or reduce the number of full or incremental backups that we keep.
111    
112     EOF
113     }
114    
115     #
116     # Check for bogus directories (probably PCs that are no longer
117     # on the backup list)
118     #
119     my $d = DirHandle->new("$TopDir/pc") or die("Can't read $TopDir/pc: $!");
120     my @oldDirs = ();
121     my @files = $d->read;
122     $d->close;
123     foreach my $host ( @files ) {
124     next if ( $host eq "." || $host eq ".." || defined($Status{$host}) );
125     push(@oldDirs, "$TopDir/pc/$host");
126     }
127     if ( @oldDirs ) {
128     my $oldDirs = join("\n - ", sort(@oldDirs));
129     $mesg .= <<EOF;
130     The following directories are bogus and are not being used by
131     BackupPC. This typically happens when PCs are removed from the
132     backup list. If you don't need any old backups from these PCs you
133     should remove these directories. If there are machines on this
134     list that should be backed up then there is a problem with the
135     hosts file:
136     - $oldDirs
137    
138     EOF
139     }
140    
141     if ( $mesg ne "" && $Conf{EMailAdminUserName} ne "" ) {
142     $mesg = <<EOF;
143     To: $Conf{EMailAdminUserName}
144     Subject: BackupPC administrative attention needed
145    
146     ${mesg}Regards,
147     PC Backup Genie
148     EOF
149     if ( $opts{t} ) {
150     print("#" x 75, "\n");
151     print $mesg;
152     } else {
153     SendMail($mesg);
154     }
155     }
156    
157     ###########################################################################
158     # Generate per-host warning messages sent to each user
159     ###########################################################################
160     my $Hosts = $bpc->HostInfoRead();
161    
162     foreach my $host ( sort(keys(%Status)) ) {
163     next if ( $Hosts->{$host}{user} eq "" );
164     #
165     # read any per-PC config settings (allowing per-PC email settings)
166     #
167     $bpc->ConfigRead($host);
168     %Conf = $bpc->Conf();
169     my $user = $Hosts->{$host}{user};
170     next if ( time - $UserEmailInfo{$user}{lastTime}
171     < $Conf{EMailNotifyMinDays} * 24*3600 );
172     next if ($Conf{XferMethod} eq "archive" );
173     my @Backups = $bpc->BackupInfoRead($host);
174     my $numBackups = @Backups;
175     if ( $numBackups == 0 ) {
176     my $subj = defined($Conf{EMailNoBackupEverSubj})
177     ? $Conf{EMailNoBackupEverSubj}
178     : $Lang->{EMailNoBackupEverSubj};
179     my $mesg = defined($Conf{EMailNoBackupEverMesg})
180     ? $Conf{EMailNoBackupEverMesg}
181     : $Lang->{EMailNoBackupEverMesg};
182     sendUserEmail($user, $host, $mesg, $subj, {
183     userName => user2name($user)
184     }) if ( !defined($Jobs{$host}) );
185     next;
186     }
187     my $last = my $lastFull = my $lastIncr = 0;
188     my $lastGoodOutlook = 0;
189     my $lastNum = -1;
190     my $numBadOutlook = 0;
191     for ( my $i = 0 ; $i < @Backups ; $i++ ) {
192     my $fh;
193     $lastNum = $Backups[$i]{num} if ( $lastNum < $Backups[$i]{num} );
194     if ( $Backups[$i]{type} eq "full" ) {
195     $lastFull = $Backups[$i]{startTime}
196     if ( $lastFull < $Backups[$i]{startTime} );
197     } else {
198     $lastIncr = $Backups[$i]{startTime}
199     if ( $lastIncr < $Backups[$i]{startTime} );
200     }
201     $last = $Backups[$i]{startTime}
202     if ( $last < $Backups[$i]{startTime} );
203     my $badOutlook = 0;
204     my $file = "$TopDir/pc/$host/SmbLOG.$Backups[$i]{num}";
205     my $comp = 0;
206     if ( !-f $file ) {
207     $file = "$TopDir/pc/$host/XferLOG.$Backups[$i]{num}";
208     if ( !-f $file ) {
209     $comp = 1;
210     $file = "$TopDir/pc/$host/SmbLOG.$Backups[$i]{num}.z";
211     $file = "$TopDir/pc/$host/XferLOG.$Backups[$i]{num}.z"
212     if ( !-f $file );
213     }
214     }
215     next if ( !defined($fh = BackupPC::FileZIO->open($file, 0, $comp)) );
216     while ( 1 ) {
217     my $s = $fh->readLine();
218     last if ( $s eq "" );
219     if ( $s =~ /^\s*Error reading file.*\.pst : ERRDOS - ERRlock/
220     || $s =~ /^\s*Error reading file.*\.pst\. Got 0 bytes/ ) {
221     $badOutlook = 1;
222     last;
223     }
224     }
225     $fh->close();
226     $numBadOutlook += $badOutlook;
227     if ( !$badOutlook ) {
228     $lastGoodOutlook = $Backups[$i]{startTime}
229     if ( $lastGoodOutlook < $Backups[$i]{startTime} );
230     }
231     }
232     if ( time - $last > $Conf{EMailNotifyOldBackupDays} * 24*3600 ) {
233     my $subj = defined($Conf{EMailNoBackupRecentSubj})
234     ? $Conf{EMailNoBackupRecentSubj}
235     : $Lang->{EMailNoBackupRecentSubj};
236     my $mesg = defined($Conf{EMailNoBackupRecentMesg})
237     ? $Conf{EMailNoBackupRecentMesg}
238     : $Lang->{EMailNoBackupRecentMesg};
239     my $firstTime = sprintf("%.1f",
240     (time - $Backups[0]{startTime}) / (24*3600));
241     my $days = sprintf("%.1f", (time - $last) / (24 * 3600));
242     sendUserEmail($user, $host, $mesg, $subj, {
243     firstTime => $firstTime,
244     days => $days,
245     userName => user2name($user),
246     numBackups => $numBackups,
247     }) if ( !defined($Jobs{$host}) );
248     next;
249     }
250     if ( $numBadOutlook > 0
251     && time - $lastGoodOutlook > $Conf{EMailNotifyOldOutlookDays}
252     * 24 * 3600 ) {
253     my($days, $howLong);
254     if ( $lastGoodOutlook == 0 ) {
255     $howLong = eval("qq{$Lang->{howLong_not_been_backed_up}}");
256     } else {
257     $days = sprintf("%.1f", (time - $lastGoodOutlook) / (24*3600));
258     $howLong = eval("qq{$Lang->{howLong_not_been_backed_up_for_days_days}}");
259     }
260     my $subj = defined($Conf{EMailOutlookBackupSubj})
261     ? $Conf{EMailOutlookBackupSubj}
262     : $Lang->{EMailOutlookBackupSubj};
263     my $mesg = defined($Conf{EMailOutlookBackupMesg})
264     ? $Conf{EMailOutlookBackupMesg}
265     : $Lang->{EMailOutlookBackupMesg};
266     my $firstTime = sprintf("%.1f",
267     (time - $Backups[0]{startTime}) / (24*3600));
268     my $lastTime = sprintf("%.1f",
269     (time - $Backups[$#Backups]{startTime}) / (24*3600));
270     sendUserEmail($user, $host, $mesg, $subj, {
271     days => $days,
272     firstTime => $firstTime,
273     lastTime => $lastTime,
274     numBackups => $numBackups,
275     userName => user2name($user),
276     howLong => $howLong,
277     serverHost => $Conf{ServerHost},
278     }) if ( !defined($Jobs{$host}) );
279     }
280     }
281     if ( !$opts{t} ) {
282     $Data::Dumper::Indent = 1;
283     my $dumpStr = Data::Dumper->Dump(
284     [\%UserEmailInfo],
285     [qw(*UserEmailInfo)]);
286     if ( open(HOST, ">", "$TopDir/log/UserEmailInfo.pl") ) {
287     binmode(HOST);
288     print(HOST $dumpStr);
289     close(HOST);
290     }
291     }
292    
293     sub user2name
294     {
295     my($user) = @_;
296     my($name) = (getpwnam($user))[6];
297     $name =~ s/\s.*//;
298     $name = $user if ( $name eq "" );
299     return $name;
300     }
301    
302     sub sendUserEmail
303     {
304     my($user, $host, $mesg, $subj, $vars) = @_;
305     $vars->{user} = $user;
306     $vars->{host} = $host;
307     $vars->{domain} = $Conf{EMailUserDestDomain};
308     $vars->{CgiURL} = $Conf{CgiURL};
309     $subj =~ s/\$(\w+)/defined($vars->{$1}) ? $vars->{$1} : "\$$1"/eg;
310     $vars->{subj} = $subj;
311     $mesg =~ s/\$(\w+)/defined($vars->{$1}) ? $vars->{$1} : "\$$1"/eg;
312     if ( $opts{t} ) {
313     print("#" x 75, "\n");
314     print $mesg;
315     } else {
316     SendMail($mesg);
317     }
318     $UserEmailInfo{$user}{lastTime} = time;
319     $UserEmailInfo{$user}{lastSubj} = $subj;
320     $UserEmailInfo{$user}{lastHost} = $host;
321     }
322    
323     sub SendMail
324     {
325     my($mesg) = @_;
326     my($from) = $Conf{EMailFromUserName};
327     local(*MAIL);
328    
329     $from = "-f $from" if ( $from ne "" );
330     if ( !open(MAIL, "|$Conf{SendmailPath} -t $from") ) {
331     printf("Can't run sendmail ($Conf{SendmailPath}): $!\n");
332     return;
333     }
334     print MAIL $mesg;
335     close(MAIL);
336     }

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26