/[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

Contents of /upstream/2.1.0/bin/BackupPC_sendEmail

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show 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 #!/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