home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / perl / 5410 < prev    next >
Encoding:
Internet Message Format  |  1992-08-21  |  5.8 KB

  1. Path: sparky!uunet!dtix!darwin.sura.net!convex!convex!tchrist
  2. From: tchrist@convex.COM (Tom Christiansen)
  3. Newsgroups: comp.lang.perl
  4. Subject: Re: Perl "mail munger"
  5. Message-ID: <1992Aug21.132846.19292@news.eng.convex.com>
  6. Date: 21 Aug 92 13:28:46 GMT
  7. References: <1992Aug20.222728.26772@puma.ATL.GE.COM>
  8. Sender: usenet@news.eng.convex.com (news access account)
  9. Reply-To: tchrist@convex.COM (Tom Christiansen)
  10. Organization: Convex Computer Corporation, Colorado Springs, CO
  11. Lines: 220
  12. Originator: tchrist@pixel.convex.com
  13. Nntp-Posting-Host: pixel.convex.com
  14. X-Disclaimer: This message was written by a user at CONVEX Computer
  15.               Corp. The opinions expressed are those of the user and
  16.               not necessarily those of CONVEX.
  17.  
  18. From the keyboard of rsnyder@atl.ge.com (Bob Snyder):
  19. :Does anyone have a perl "mail munger" that goes thorugh the mail spool
  20. :directory, and chops up a user's mail file if it is too large, and moves
  21. :that piece someplace else?
  22. :
  23. :This seems like something perl should be good at (I'm learning perl slowly, and
  24. :disecting a script like this would be beneficial).
  25.  
  26. Consider this....
  27.  
  28. --tom
  29.  
  30. #!/usr/bin/perl
  31. # forwmail -- tchrist@convex.com
  32.  
  33. # ===========   begin configuration section
  34.  
  35. $DOMAIN  = '\.convex\.com';     # remember to turn off regexp magic
  36. $ALIASES = '/usr/lib/aliases';
  37. $SPOOL   = '/usr/spool/mail';
  38.  
  39. # ===========   end configuration section
  40.  
  41. ($program = $0) =~ s,.*/,,;
  42.  
  43. $| = 1;
  44.  
  45.  
  46. &source('stat.pl');
  47. &source('getopts.pl');
  48.  
  49. &Getopts('nv') || die "usage: $program [-nv]\n";
  50.  
  51. $verbose = $opt_v;
  52. $doit    = !$opt_n;
  53.  
  54. chop($hostname = `hostname`);
  55. ($host = $hostname) =~ s/$DOMAIN//;  # chop domainname
  56.  
  57. print "running $program on $host";
  58. print " ($hostname)" if $host ne $hostname;
  59. print "\n";
  60.  
  61. chdir $SPOOL || die "absurd chdir failure to $SPOOL: $!";
  62.  
  63. unless (-f "$ALIASES.pag" && dbmopen(aliases, $ALIASES, 0644)) {
  64.     $slow++;
  65.     print "no dbm file: doing aliases the hard way\n";
  66.     print STDERR "can't open dbm file $ALIASES: $!\n";
  67.     open ALIASES || die "couldn't read $ALIASES: $!";
  68.     while (<ALIASES>) {
  69.     next if /^#/ || ! /^(\S+)\s*:\s+(.*)/;
  70.     $aliases{$1} = $2;
  71.     } 
  72.     close ALIASES;
  73. }
  74.  
  75. foreach $mbox ( <*> ) {
  76.     
  77.     unless (&Stat($mbox)) {
  78.     print STDERR "couldn't stat $mbox: $!\n";
  79.     next;
  80.     } 
  81.  
  82.     if (!($alias = $aliases{$slow ? $mbox : "$mbox\000" })) {
  83.     if ($st_size == 0) {
  84.         print "deleting zero-length non-mbox $mbox\n";
  85.         if ($doit) {
  86.         unlink($mbox) || print STDERR "can't unlink $mbox: $!\n";
  87.         }
  88.         next;
  89.     } 
  90.     print "forwarding bogus mbox $mbox to postmaster\n";
  91.     if ($doit) {
  92.         unless (rename($mbox, "$mbox.$$")) {
  93.         print STDERR "can't rename $mbox to $mbox.$$: $!\n";
  94.         next;
  95.         }
  96.         system "Mail -s 'bogus mailbox from $mbox@$host' postmaster < $mbox.$$";
  97.         unlink("$mbox.$$") || print STDERR "can't unlink $mbox.$$: $!\n";
  98.     }
  99.     next;
  100.     }  
  101.  
  102.     chop($alias) unless $slow;
  103.     $alias =~ s/^\s*(.*)\s*$/$1/g;
  104.     $alias =~ s/$DOMAIN//g;
  105.  
  106.     if ($alias eq "$host!$mbox"  ||     # uucp style alias to me
  107.     $alias eq "$mbox@$host"  ||     # inet style alias to me
  108.     $alias eq $mbox          ||     # no host specified
  109.     $alias eq "localhost!$host")     # strange alias
  110.     {
  111.     print "ok for $mbox to live on $host, as alias is $alias\n" 
  112.         if $verbose;
  113.     next;
  114.      } 
  115.  
  116.     if ($st_size == 0) {
  117.     print "deleting zero-length mbox $mbox\n";
  118.     if ($doit) {
  119.         unlink($mbox) || print STDERR "can't unlink $mbox: $!\n";
  120.     }
  121.     next;
  122.     } 
  123.  
  124.  
  125.     print "forwarding misdelivered $mbox to $alias "; 
  126.  
  127.     unless ($doit) {
  128.     print "\n";
  129.     next;
  130.     } 
  131.  
  132.     $alias = $mbox if $alias =~ /\|/;
  133.  
  134.     unless (rename($mbox, "$mbox.$$")) {
  135.     print STDERR "can't rename $mbox to $mbox.$$: $!\n";
  136.     next;
  137.     }
  138.  
  139.     unless (open(mbox, "$mbox.$$")) {
  140.     print STDERR "can't read $mbox: $!\n";
  141.     next;
  142.     }
  143.  
  144.     $mail = '';
  145.     $count = 0;
  146.     $status = 0;
  147.     while (<mbox>) {
  148.     if (/^From\s/) {
  149.         if ($mail) {
  150.         chop($mail);
  151.         $status |= &send($mail, $alias);
  152.         $mail = '';
  153.         } 
  154.     } else {
  155.         $mail .= $_;
  156.     } 
  157.     } 
  158.     $status |= &send($mail, $alias) if $mail;
  159.  
  160.     printf "%d piece%s\n", $count, $count == 1 ? "" : "s";
  161.  
  162.     printf "\ttotal size %d, age %s\n", $st_size, &dtime(time - $st_mtime) 
  163.     if $verbose;
  164.  
  165.     if ($status) {
  166.     print STDERR "bad status from mail: $status\n";
  167.     next;
  168.     } 
  169.  
  170.     unlink("$mbox.$$") || print "$mbox.$$ disappeared!\n";
  171. }
  172.  
  173.  
  174. ###########################################################################
  175. sub source {
  176.     local($file) = @_;
  177.     local($return) = 0;
  178.  
  179.     $return = do $file;
  180.     die "couldn't parse $file: $@" if $@;
  181.     die "couldn't do $file: $!" unless defined $return;
  182.     die "couldn't run $file" unless $return;
  183.     $return;
  184. }
  185.  
  186. ###########################################################################
  187.  
  188. sub dtime {
  189.     local($seconds) = $_[0];
  190.     local($days,$hours,$minutes, $retval);
  191.  
  192.     $days =  int($seconds  / (24 * 3600));
  193.     $seconds -= $days * (24 * 3600);
  194.  
  195.     $hours =  int($seconds / 3600);
  196.     $seconds -= $hours * 3600;
  197.  
  198.     $minutes =  int($seconds / 60);
  199.     $seconds -= $minutes * 60;
  200.  
  201.     $retval =  "$days days" if $days;
  202.  
  203.     if ($hours) {
  204.     $retval .= ", " if $retval;
  205.     $retval .= "$hours hours";
  206.     }
  207.  
  208.     if ($minutes) {
  209.     $retval .= ", " if $retval;
  210.     $retval .= "$minutes minutes";
  211.     }
  212.  
  213.     if ($seconds) {
  214.     $retval .= ", " if $retval;
  215.     $retval .= "$seconds seconds";
  216.     }
  217.  
  218.     $retval;
  219.  
  220. sub send {
  221.     local($text, $whom) = @_;
  222.     $count++;
  223.  
  224.     printf "\tpiece %d, size %-5d\n", $count, length($text) if $verbose;
  225.  
  226.     open (PIPE, "|/usr/lib/sendmail -odq -oi -t");
  227.     print PIPE "Resent-to: $alias\n";
  228.     print PIPE "Resent-comment: lost mail for $mbox found on $host\n";
  229.     print PIPE $text;
  230.     !close PIPE;
  231. -- 
  232.     Tom Christiansen      tchrist@convex.com      convex!tchrist
  233. There are probably better ways to do that, but it would make the parser
  234. more complex.  I do, occasionally, struggle feebly against complexity...  :-)
  235.             --Larry Wall in <7886@jpl-devvax.JPL.NASA.GOV>
  236.