#!/usr/bin/perl -w # # Copyright (c) 1999 by Bennet Yee # # 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 # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # # mail_page, bsy@cs.ucsd.edu, 6/22/99. cleaned up and made available # for public consumption. this is intended for use in .procmailrc # to automatically transform some email into shorter messages that are # sent to an email-to-paging/SMS gateway. for example, i match email # from my girlfriend so i'll get the gist of the email... or at least # know to read the email in its uncompressed form. # # in my .procmailrc, i have an entry of the form: # # :0 c # *^From:EMAIL-ADDR # | /home/bsy/bin/mail_page SMS-NUMBER@PAGER-COMPANY.COM # # BUGS # # this program doesn't handle MIME data at all # $in_header = 1; $lines_sent = 0; $chars_sent = 0; $line_limit = 32; $char_limit = 256; $compress = 1; $discard_quoted = 1; $debug = 0; $english_compress_orig_word_lower_bound = 3; $english_compress_result_word_lower_bound = 3; $prefix_line = ""; $keephdr{"Subject:"} = undef; $to_body{"Subject:"} = "S:"; $intro_lines = ""; $stdout = 0; sub usage { print STDERR "usage: $0 [-kbBcCsulLpqQiod]\n"; print STDERR " [--keep header-tag]\n"; print STDERR " [--body header-tag-to-move-to-body]\n"; print STDERR " [--body-as header-tag short-form]\n"; print STDERR " [--compress] [--no-compress]\n"; print STDERR " [--short-threshold no-compress-char-count]\n"; print STDERR " [--unrecognized-threshold too-short-result-char-count]\n"; print STDERR " [--limit-char n] [--limit-line n] [-prefix str]\n"; print STDERR " [--keep-quoted] [--discard-quoted]\n"; print STDERR " [--intro-line str] [--stdout] [--debug]\n"; } arg: for ($i = 0; $i < @ARGV; $i++) { if ($ARGV[$i] eq "-k" || $ARGV[$i] eq "--keep") { ++$i < @ARGV || die "$ARGV[$i-1] requires header tag argument\n"; $keephdr{$ARGV[$i]} = $ARGV[$i]; } elsif ($ARGV[$i] eq "-b" || $ARGV[$i] eq "--body") { ++$i < @ARGV || die "$ARGV[$i-1] requires header tag argument\n"; $to_body{$ARGV[$i]} = $ARGV[$i]; } elsif ($ARGV[$i] eq "-B" || $ARGV[$i] eq "--body-as") { ++$i < @ARGV || die "$ARGV[$i-1] requires header tag argument\n"; ++$i < @ARGV || die "$ARGV[$i-1] requires short-form tag argument\n"; $to_body{$ARGV[$i-1]} = $ARGV[$i]; } elsif ($ARGV[$i] eq "-c" || $ARGV[$i] eq "--compress") { $compress = 1; } elsif ($ARGV[$i] eq "-C" || $ARGV[$i] eq "--no-compress") { $compress = 0; } elsif ($ARGV[$i] eq "-d" || $ARGV[$i] eq "--debug") { ++$debug; } elsif ($ARGV[$i] eq "-s" || $ARGV[$i] eq "--short-threshold") { ++$i < @ARGV || die "$ARGV[$i-1] requires numeric argument\n"; $ARGV[$i] =~ /^\d+$/ || die "$ARGV[$i-1] requires numeric argument\n"; $english_compress_orig_word_lower_bound = $ARGV[$i]; } elsif ($ARGV[$i] eq "-u" || $ARGV[$i] eq "--unrecognizable-threshold") { ++$i < @ARGV || die "$ARGV[$i-1] requires numeric argument\n"; $ARGV[$i] =~ /^\d+$/ || die "$ARGV[$i-1] requires numeric argument\n"; $english_compress_result_word_lower_bound = $ARGV[$i]; } elsif ($ARGV[$i] eq "-l" || $ARGV[$i] eq "--limit-char") { ++$i < @ARGV || die "$ARGV[$i-1] requires numeric argument\n"; $ARGV[$i] =~ /^\d+$/ || die "$ARGV[$i-1] requires numeric argument\n"; $char_limit = $ARGV[$i]; } elsif ($ARGV[$i] eq "-L" || $ARGV[$i] eq "--limit-line") { ++$i < @ARGV || die "$ARGV[$i-1] requires numeric argument\n"; $ARGV[$i] =~ /^\d+$/ || die "$ARGV[$i-1] requires numeric argument\n"; $line_limit = $ARGV[$i]; } elsif ($ARGV[$i] eq "-p" || $ARGV[$i] eq "--prefix") { ++$i < @ARGV || die "$ARGV[$i-1] requires prefix argument\n"; $prefix_line = $ARGV[$i]; } elsif ($ARGV[$i] eq "-q" || $ARGV[$i] eq "--keep-quoted") { $discard_quoted = 0; } elsif ($ARGV[$i] eq "-Q" || $ARGV[$i] eq "--discard-quoted") { $discard_quoted = 1; } elsif ($ARGV[$i] eq "-i" || $ARGV[$i] eq "--intro-line") { ++$i < @ARGV || die "$ARGV[$i-1] requires intro string argument\n"; $intro_lines = $intro_lines . $ARGV[$i] . "\n"; } elsif ($ARGV[$i] eq "-o" || $ARGV[$i] eq "--stdout") { $stdout = 1; } elsif ($ARGV[$i] =~ /^-/) { &usage(); exit 0; } else { last arg; } } die "at least one email addr argument required\n" unless $i < @ARGV || $stdout == 1; $email_addr = ""; for (; $i < @ARGV; $i++) { ($addr = $ARGV[$i]) =~ s/'/'"'"'/g; # ' <-- 4 xemacs font-lock mode. $email_addr = $email_addr . "'". $addr . "' "; } @ARGV = (); $pager = "PAGER"; if ($debug == 0) { if ($stdout == 0) { open $pager, "|/usr/sbin/sendmail $email_addr"; } else { $pager = \*STDOUT; } } else { if (defined $ENV{"TMPDIR"}) { $dir = $ENV{"TMPDIR"}; } else { $dir = "/tmp"; } open $pager, "> $dir/pager.txt"; print $pager "email addr list $email_addr\n"; # testing } $body_hdr = ""; sub compress_addr { my($addr) = @_; $addr =~ s/^\s+//; $addr =~ s/\s+$//; if ($addr =~ /<([^@]+@[^>]+)>/) { return $1; } return $addr; } sub compress_english { my($line) = @_; my($w,$sw,$outl,$sep); $line =~ s/^\s+//; $line =~ s/\s+$//; $outl = ""; $sep = ""; # do standard per-word substitutions foreach $w (split /\s+/, $line) { print "Debug: word $w\n" if $debug > 1; if ($w =~ /^http:/) { $sw = $w; # do not compress URLs } else { $sw = $w; if (length($w) >= $english_compress_orig_word_lower_bound) { $sw =~ s/[aeiou]//g; } if (length($sw) < $english_compress_result_word_lower_bound) { $sw = $w; } } $outl = $outl . $sep . $sw; $sep = " "; } return $outl; } sub send_text { my($line) = @_; print $pager $line; print STDERR "Sent $line\n" if $debug; $chars_sent += length($line); $lines_sent += length($line =~ s/[^\n]//g); } $fr = (getpwuid($<))[0] || "auto-reply daemon "; LINE: while (defined($line = <>)) { chop $line; if ($in_header) { if ($line eq "") { $in_header = 0; if (defined($to_body{"From:"})) { &send_text("\n".$to_body{"From:"}.&compress_addr($fr)."\n"); } else { &send_text("From: ".&compress_addr($fr)."\n\n"); } &send_text($intro_lines) if ($intro_lines ne ""); &send_text($body_hdr); next LINE; } elsif ($line =~ /^From:/) { ($fr = $line) =~ s/^From://; } else { ($tag = $line) =~ s/^([^:]*:)\W*(.*)/$1/; if (defined($keephdr{$tag})) { &send_text($line."\n"); } elsif (defined($to_body{$tag})) { if ($to_body{$tag} ne $tag) { $body_hdr = $body_hdr . $to_body{$tag} . &compress_english($2) . "\n"; } else { $body_hdr = $body_hdr . $line . "\n"; } } } } else { if ($line ne "") { if ($line =~ /^\s*>/ && $discard_quoted == 1) { &send_text($prefix_line . ">\n"); next LINE; } if ($chars_sent < $char_limit && $lines_sent < $line_limit) { &send_text($prefix_line . &compress_english($line)."\n"); } } } }