#!/usr/bin/perl -w $|++; # email to sms gateways: # # AT&T: phonenumber@txt.att.net # ALLTEL: phonenumber@message.alltel.com # Nextel: phonenumber@messaging.nextel.com # Sprint: phonenumber@messaging.sprintpcs.com # Verizon: phonenumber@vtext.com # Cingular: phonenumber@cingularme.com # T-Mobile: phonenumber@tmomail.net # Metrocall: phonenumber@page.metrocall.com # Virgin Mobile: phonenumber@vmobl.com # # from http://www.tech-recipes.com/rx/939/sms_email_cingular_nextel_sprint_tmobile_verizon_virgin/ # and http://www.accutracking.com/sms-email.html # # See http://en.wikipedia.org/wiki/List_of_carriers_providing_Email_or_Web_to_SMS for a more complete list. use strict; use lib '/usr/local/apache/libs'; use CGI::Carp 'fatalsToBrowser'; use DBI; use Data::Dumper; use Database::Hosts; use Digest::MD5 'md5_hex'; use Net::SMTP; my $notes; #my $pid = -1; #my $pid = fork; #if ( ! defined $pid || $pid != 0 ) { # error_page(); # exit if $pid != 0; # $notes .= "Unable to fork.\n"; # #} # wait how many seconds before sending another notification my $wait = 15 * 60; my $dbh = Database::Hosts::connect( 'junk', 'server_errors' ); my $email_sql = qq{SELECT name, address, type FROM contact}; my ( @email, @email2sms ); for my $contact ( @{ $dbh->selectall_arrayref( $email_sql, { 'Slice' => {} } ) } ) { next unless $contact->{ 'type' } =~ /^email(?:2sms)?$/; next unless $contact->{ 'name' } =~ /alan|joseph/i; push @{ $contact->{ 'type' } eq 'email' ? \@email : \@email2sms }, sprintf '"%s" <%s>', @{ $contact }{qw( name address )}; } #chomp( my $hostname = $> == 0 ? `su nobody -c "hostname --fqdn"` : `hostname --fqdn` ); chomp( my $hostname = `hostname --fqdn` ); $hostname ||= 'NoHostName'; my $error = merge( qq{<> <>} ); my $hostip = $ENV{ 'REDIRECT_SERVER_ADDR' } || 'NoHostIP'; my $script = $ENV{ 'REDIRECT_SCRIPT_FILENAME' } || 'NoScript'; my $ssl = exists $ENV{ 'REDIRECT_HTTPS' } && $ENV{ 'REDIRECT_HTTPS' } eq 'on' ? 's' : ''; my $url = merge( qq{http${ssl}://<><>} ); my $md5 = md5_hex( merge( "${hostname}${hostip}<>${script}" ) ); exit if md5_seen(); my $dump = do { my $d = Data::Dumper->new( [ \%ENV ], [ 'ENV' ] ) ; $d->Sortkeys( 1 ) ; $d->Dump }; my $sms = merge( qq{$url $hostname $hostip $script $error}); $sms .= "\n$notes" if $notes; my $email = merge( qq{ URL: $url Host: $hostname $hostip Script: $script Error: $error}); $email .= "\nNotes: $notes" if $notes; $email .= "\nEnvironment Dump:\n$dump"; notify( \@email2sms, $sms ); # Send sms notify( \@email, $email, 1 ); # Send email # End of line. sub error_page { print merge( qq{Content-type: text/html 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

More information about this error may be available in the server error log.


}); } sub merge { no warnings 'uninitialized'; my $string = shift; $string =~ s/<<([^>]*)>>/$ENV{ "REDIRECT_$1" }/g; return $string; } sub md5_seen { # Has this hash been seen yet? or has it been sent in the last 15 minutes? # If yes return 1 otherwise return '' my $seen_sql = qq{ SELECT count, UNIX_TIMESTAMP( touched ) AS touched, UNIX_TIMESTAMP( NOW() ) as now FROM 500_errors WHERE md5 = ? }; my ( $count, $seen, $now ) = $dbh->selectrow_array( $seen_sql, {}, $md5 ); if ( $dbh->err ) { $notes .= sprintf "%s failed: %s\n", $seen_sql, $dbh->errstr; return; }; if ( ! $seen ) { $notes .= "First time this error has been seen.\n"; my $insert_sql = qq{ INSERT INTO 500_errors ( md5, url, hostname, hostip, script, error ) VALUES ( ?, ?, ?, ?, ?, ? ) }; $dbh->do( $insert_sql, {}, $md5, $url, $hostname, $hostip, $script, $error ) or $notes .= sprintf "%s failed: %s\n", $insert_sql, $dbh->errstr; return; } elsif ( $now - $seen > $wait ) { $notes .= sprintf "This error has been occuring for at least %d minutes.\n", ( $count * $wait ) / 60; my $update_sql = qq{UPDATE 500_errors SET count = count + 1 WHERE md5 = ?}; $dbh->do( $update_sql, {}, $md5 ) or $notes .= sprintf "%s failed: %s\n", $update_sql, $dbh->errstr; return; } return 1; } sub notify { my ( $to, $text, $extra_headers ) = @_; my $status = $ENV{ 'REDIRECT_STATUS' } || '000'; #my $smtp = Net::SMTP->new( '208.110.142.84', Debug => 1 ); my $smtp = Net::SMTP->new( '208.110.142.84' ); $smtp->mail( "\"$status Error Notifier\" " ); $smtp->to( @$to, { SkipBad => 1 }); $smtp->data(); if ( $extra_headers ) { $smtp->datasend( "To: $status Error Notifiee\n" ); $smtp->datasend( "From: $status Error Notifier\n" ); $smtp->datasend( "Subject: $status Error Notification\n" ); } else { $smtp->datasend( "To: $status Err\n" ); } $smtp->datasend( "\n" ); $smtp->datasend( $text ); $smtp->dataend(); $smtp->quit; }