home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / lang / perl / 5043 < prev    next >
Encoding:
Text File  |  1992-07-30  |  17.2 KB  |  623 lines

  1. Path: sparky!uunet!dtix!darwin.sura.net!uvaarpa!mmdf
  2. From: aks%anywhere@hub.ucsb.edu (Alan Stebbens)
  3. Newsgroups: comp.lang.perl
  4. Subject: Re: Perl-Users Digest #471
  5. Message-ID: <1992Jul30.204015.27966@uvaarpa.Virginia.EDU>
  6. Date: 30 Jul 92 20:40:15 GMT
  7. Sender: mmdf@uvaarpa.Virginia.EDU (Mail System)
  8. Reply-To: aks%anywhere@hub.ucsb.edu
  9. Organization: The Internet
  10. Lines: 611
  11.  
  12. I've been using the audit.pl script for a few weeks, and I've cobbled
  13. together some minor changes, added a Makefile to install things, and
  14. created a sample .audit script which I've been installing for various
  15. users who have expressed needs like (a) handling mail while on vacation,
  16. (b) throwing away junk mail from noisy mailing lists.
  17.  
  18. What follows is the script, and then a diff to the original audit
  19. release.  If anyone wants the complete distribution, it's available via
  20. anonymouse ftp on hub.ucsb.edu:/pub/mail/audit.tar.Z
  21.  
  22. I apologize to the author for not mailing this directly; I can't seem to
  23. find your email address anywhere within the distribution, and I've long
  24. since lost the original mail from which it came.
  25.  
  26. Enjoy.
  27.  
  28. Alan Stebbens        <aks@hub.ucsb.edu>             (805) 893-3221
  29.      Center for Computational Sciences and Engineering (CCSE)
  30.           University of California, Santa Barbara (UCSB)
  31.            3111 Engineering I, Santa Barbara, CA 93106
  32.  
  33.  
  34. ============================= cut here ===================================
  35. #!/eci/bin/perl
  36. #
  37. # $Date: 1992/07/30 19:55:42 $
  38. # $Revision: 1.1 $
  39.  
  40. # Tailor this for yourself
  41.  
  42. @MyNames = ('FIRSTNAME', 'LASTNAME');
  43.  
  44. # This is a sample audit script.  It looks for a file with the
  45. # name "~/.vacation.msg", and if it exists, assumes that the user
  46. # is on vacation, and operates under "vacation mode", otherwise,
  47. # works under "work mode".
  48. #
  49. # In either case, mail from the mailer daemon, or any mail addressed
  50. # directly to the user is assumed to be important, and is not
  51. # filtered for junk mail.  In vacation mode, the mail is answered
  52. # automatically, using the ".vacation.msg" file as the reply message.
  53. # Then, the mail is simply dropped in the system mailbox.
  54. #
  55. # If the mail is not directly addressed, then it is coming from a 
  56. # mailing list, and is filtered through the junk mail lists, which
  57. # are determined by one of two files, depending upon the mode.  In
  58. # work mode, the file is ".junkmail.work"; in vacation mode, the
  59. # file is ".junkmail.vacation".
  60. #
  61. # The junkmail lists contain names of mailing lists which are to be
  62. # subject to junking; that is, mail with headers having one of these
  63. # junk mailing list names in either the To: or Cc: header, and NOT 
  64. # directly addressed to the user are junked.
  65. #
  66. # As part of the junking, a log file is kept, called ".junkmail.log";
  67. # the From:, Date:, To:, Cc:, and Subject: lines are recorded.
  68. #
  69. # The ".junkmail.work" is especially useful for those occasions when
  70. # a particular mailing list gets crowded with some emotional issue
  71. # for which you have no interest.  Rather than having your name removed
  72. # from the mailing list, just filter it until the signal-to-noise
  73. # ratio improves (which can be deteremined by scanning the log file
  74. # periodically).
  75. #
  76. ($Prog = $0) =~ s=^/.*([^/]+)$=$1=; # get plain program name
  77.  
  78. require 'audit.pl' || die "~/.audit: cannot include audit.pl: $@";
  79.  
  80. # Only if you need some of the mh functions
  81. # require 'mh.pl'  || die "~/.audit: cannot include mh.pl: $@";
  82.  
  83. &initialize();
  84.  
  85. $HOME = $ENV{'HOME'};
  86. $VacaJunkMail = "$HOME/.junkmail.vacation";
  87. $WorkJunkMail = "$HOME/.junkmail.work";
  88. $JunkLogFile =    "$HOME/.junkmail.log";
  89.  
  90. $OnVacation = -f "$HOME/.vacation.msg";
  91. $AtWork = ! $OnVacation;
  92.  
  93. # If this message came from the MAILER, deliver it to me directly
  94. # and do nothing else.
  95.  
  96. ($from =~ /MAILER/) && do { &deliver(); exit; };
  97.  
  98. # If the sender's name is in the password file, the organization
  99. # is local
  100.  
  101. $local_org = $ENV{'ORGANIZATION'};
  102. chop($local_org = `cat $HOME/.organization`) 
  103.     if -f "$HOME/.organization" && !length($local_org);
  104.  
  105. if ($local_org) {
  106.     $organization = $local_org if ($logname = (getpwnam($from))[0]);
  107. }
  108.  
  109. # If I am specifically named on the To or Cc line, do the default.
  110.  
  111. unshift(@MyNames,$user);
  112.  
  113. foreach $name (@MyNames) {
  114.     if (grep(/^$name/i, @to, @cc)) {
  115.     &deliver();            # deposit in my mailbox
  116.     &vacation() if $OnVacation;    # do the vacation response (maybe)
  117.     exit;
  118.     }
  119. };
  120.  
  121. # The mail wasn't sent directly to me, so, if I'm at work, look for 
  122. # any junkmail list names
  123.  
  124. if ($AtWork) {
  125.     foreach $junkname (&ReadNames($WorkJunkMail)) {
  126.     $junkname =~ s/([-+.])/\\$1/g;    # make grep-safe
  127.     &Junk if grep(/^$junkname/i, @to, @cc);
  128.     }
  129. }
  130.     
  131. # this mail was not sent to me directly, nor was it on the at-work junk 
  132. # mailing list, so now check for at-vacation junk mails, if I'm on vacation.
  133.  
  134. if ($OnVacation) {
  135.     foreach $junkname (&ReadNames($VacaJunkMail)) {
  136.     $junkname =~ s/([-+.])/\\$1/g;    # make grep-safe
  137.     &Junk if grep(/^$junkname/i, @to, @cc);
  138.     }
  139. }
  140.  
  141. # Oh well, some mailing list which might be important.
  142.  
  143. &deliver();
  144. exit;
  145.  
  146. # Subroutine ReadNames -- opens a file and reads all the names within it,
  147. # allowing for comments lines and commented lines
  148.  
  149. sub ReadNames {
  150.     local($file) = @_;
  151.     local($_);
  152.     local(@names,$name);
  153.     return () unless -f $file;
  154.     if (open(LIST,$file)) {
  155.     while (<LIST>) {
  156.         next if /^\s*#/;
  157.         s/\s*\#.*$//;    # strip comments
  158.         next if /^\s*$/;    # ignore empty lines
  159.         push(@names,split(' '));
  160.     }
  161.     close LIST;
  162.     } else {
  163.     warn "$Prog: can't read $file because $!\n";
  164.     }
  165.     @names;
  166. }
  167.  
  168. sub Junk {
  169.     local($hdr) = "%-9s %s\n";
  170.     if (open(LOG,">>$JunkLogFile")) {
  171.     $friendly = '' if $friendly eq 'unknown';
  172.     $organization = '' if $organization eq 'unknown';
  173.     $from = '"'.$friendly.'"' if $friendly;
  174.     $from .= ' <'.$address.'>';
  175.     $from .= ' ('.$organization.')' if $organization;
  176.     printf LOG $hdr,'From:',$from;
  177.     printf LOG $hdr,'Date:',$headers{'date'};
  178.     printf LOG $hdr,'To:',join(', ',@to) if $#to >= $[;
  179.     printf LOG $hdr,'Cc:',join(', ',@cc) if $#cc >= $[;
  180.     printf LOG $hdr,'Subject:',$subject;
  181.     printf LOG "\n";
  182.     close LOG;
  183.     }
  184.     exit;
  185. }
  186. ============================= cut here ===================================
  187. diff -r -c audit.ref/CHANGES audit/CHANGES
  188. *** audit.ref/CHANGES    Thu Jul 30 18:41:23 1992
  189. --- audit/CHANGES    Thu Jul 30 19:32:01 1992
  190. ***************
  191. *** 1,3 ****
  192. --- 1,13 ----
  193. + Changes file ($Revision$)
  194. + Added code to chown newly created files to be owned by $user, rather than
  195. + the uid of the running process, if running as root.
  196. + Create a Makefile to install things; the Makefile needs site-configuration
  197. + of course.
  198. + Modified mh.pl to ease site-configuration.
  199.   V0.2 Changes 
  200.   ============
  201.   
  202. diff -r -c audit.ref/Makefile audit/Makefile
  203. *** audit.ref/Makefile    Thu Jul 30 19:17:07 1992
  204. --- audit/Makefile    Thu Jul 30 19:30:04 1992
  205. ***************
  206. *** 0 ****
  207. --- 1,42 ----
  208. + # Makefile for the audit.pl package
  209. + #
  210. + # $Author: aks $ $Date: 1992/07/30 19:30:02 $
  211. + # $Revision: 1.1 $
  212. + # Set LIB_DIR to the directory in which to install "audit.pl" and "mh.pl"
  213. + LIB_DIR = /eci/share/lib/perl
  214. + # BIN_DIR should be the path in which to install the executable scripts; these
  215. + # scripts can be shared across architectures
  216. + BIN_DIR = /eci/share/bin
  217. + # If PERL_PATH is set, the first line of each script will be set to this
  218. + # pathname in order to invoke Perl
  219. + PERL_PATH = /eci/bin/perl
  220. + LIB_FILES = audit.pl mh.pl
  221. + SCRIPTS = refileto rfolder
  222. + INSTALL = /usr/ucb/install
  223. + INSTALL_BIN =    sed -e '1s=^\(.!\)/.*=\1$(PERL_PATH)=' $? > $@ ; chmod 755 $@
  224. + INSTALL_LIB =    $(INSTALL) -c -m 444 $? $@
  225. + INSTALL_LINK =    ( cd $(@D) ; ln -s $(?F) $(@F) )
  226. + install:    libs    scripts    links
  227. + libs:        $(LIB_DIR) $(LIB_DIR)/audit.pl $(LIB_DIR)/mh.pl
  228. + $(LIB_DIR)/audit.pl:    audit.pl ;        $(INSTALL_LIB)
  229. + $(LIB_DIR)/mh.pl:    mh.pl ;            $(INSTALL_LIB)
  230. + scripts:    $(BIN_DIR) $(BIN_DIR)/refileto $(BIN_DIR)/rfolder
  231. + $(BIN_DIR)/refileto:    refileto ;        $(INSTALL_BIN)
  232. + $(BIN_DIR)/rfolder:    rfolder     ;        $(INSTALL_BIN)
  233. + links:        $(BIN_DIR)/refilefrom    $(BIN_DIR)/rfolders
  234. + $(BIN_DIR)/refilefrom:    $(BIN_DIR)/refileto ;    $(INSTALL_LINK)
  235. + $(BIN_DIR)/rfolders:    $(BIN_DIR)/rfolder ;    $(INSTALL_LINK)
  236. + $(LIB_DIR) $(BIN_DIR): ; mkdir $@
  237. Only in audit: RCS
  238. diff -r -c audit.ref/audit.pl audit/audit.pl
  239. *** audit.ref/audit.pl    Thu Jul 30 19:23:03 1992
  240. --- audit/audit.pl    Thu Jul 30 19:24:22 1992
  241. ***************
  242. *** 1,7 ****
  243.   #
  244.   #
  245. ! # $Revision: 1.13 $
  246. ! # $Date: 1992/05/12 14:34:18 $
  247.   #
  248.   #
  249.   
  250. --- 1,7 ----
  251.   #
  252.   #
  253. ! # $Revision: 1.14 $
  254. ! # $Date: 1992/07/30 19:24:07 $
  255.   #
  256.   #
  257.   
  258. ***************
  259. *** 19,25 ****
  260.       $ENV{'USER'} = $user;
  261.       $ENV{'HOME'} = $home;
  262.       $ENV{'SHELL'} = $shell;
  263. !     $ENV{'TERM'} = "vt100";
  264.   
  265.       &parse_message(STDIN);
  266.   }
  267. --- 19,28 ----
  268.       $ENV{'USER'} = $user;
  269.       $ENV{'HOME'} = $home;
  270.       $ENV{'SHELL'} = $shell;
  271. !     if (!$> && !$uid) {        # root and user isn't?
  272. !     $< = $uid; $> = $uid;
  273. !     $( = $gid; $) = $gid;
  274. !     }
  275.   
  276.       &parse_message(STDIN);
  277.   }
  278. ***************
  279. *** 275,285 ****
  280. --- 278,291 ----
  281.   
  282.   # =====
  283.   #    Put the incoming mail into the specified mail drop (file)
  284. + #    [Alan Stebbens, UCSB, 7/30/92]
  285. + #    Be sure to make the file owned by the user, if possible.
  286.   #
  287.   sub deposit {
  288.       local($drop) = @_;
  289.       local($LOCK_EX) = 2;
  290.       local($LOCK_UN) = 8;
  291. +     local($needchown) = ! -f $drop;    # flag if chown is needed
  292.   
  293.       open(MAIL, ">> $drop") || die "open: $!\n";
  294.       flock(MAIL, $LOCK_EX);
  295. ***************
  296. *** 290,295 ****
  297. --- 296,305 ----
  298.   
  299.       flock(MAIL, $LOCK_UN);
  300.       close(MAIL);
  301. +     if ($needchown) {
  302. +     local($fgid) = (stat($drop))[5];    # get file's current gid
  303. +     chown $uid,$fgid,$drop;
  304. +     }
  305.   }
  306.   
  307.   
  308. diff -r -c audit.ref/mh.pl audit/mh.pl
  309. *** audit.ref/mh.pl    Thu Jul 30 18:41:24 1992
  310. --- audit/mh.pl    Thu Jul 30 19:25:43 1992
  311. ***************
  312. *** 1,5 ****
  313. --- 1,11 ----
  314. + # $Date: 1992/07/30 19:25:42 $
  315. + # $Revision: 1.2 $
  316.   
  317. + # Configure this for your site
  318.   
  319. + $MH_BIN = '/eci/mh/bin';
  320. + $MH_LIB = '/eci/mh/lib';
  321.   # =====
  322.   # Subroutine mh_profile
  323.   #    Parse the user's .mh_profile and get arguments and settings
  324. ***************
  325. *** 32,38 ****
  326.   sub rcvstore {
  327.       local($folder) = @_;
  328.   
  329. !     &openpipe("/usr/local/bin/mh/lib/rcvstore +$folder -create");
  330.   }
  331.   
  332.   
  333. --- 38,44 ----
  334.   sub rcvstore {
  335.       local($folder) = @_;
  336.   
  337. !     &openpipe("$MH_LIB/rcvstore +$folder -create");
  338.   }
  339.   
  340.   
  341. ***************
  342. *** 45,51 ****
  343.   sub rcvdist {
  344.       local($recips) = @_;
  345.   
  346. !     &openpipe("/usr/local/bin/mh/lib/rcvdist $recips");
  347.   }
  348.   
  349.   
  350. --- 51,57 ----
  351.   sub rcvdist {
  352.       local($recips) = @_;
  353.   
  354. !     &openpipe("$MH_LIB/rcvdist $recips");
  355.   }
  356.   
  357.   
  358. ***************
  359. *** 56,62 ****
  360.   #
  361.   sub rcvtty {
  362.   
  363. !     &openpipe("/usr/local/bin/mh/lib/rcvtty");
  364.   }
  365.   
  366.   
  367. --- 62,68 ----
  368.   #
  369.   sub rcvtty {
  370.   
  371. !     &openpipe("$MH_LIB/rcvtty");
  372.   }
  373.   
  374.   
  375. ***************
  376. *** 70,76 ****
  377.       local($recips); 
  378.       local(@list) = ();
  379.   
  380. !     $recips = `/usr/local/bin/mh/ali $alias`;
  381.       chop $recips;
  382.       return(@list) if ($alias eq $recips);
  383.   
  384. --- 76,82 ----
  385.       local($recips); 
  386.       local(@list) = ();
  387.   
  388. !     $recips = `$MH_BIN/ali $alias`;
  389.       chop $recips;
  390.       return(@list) if ($alias eq $recips);
  391.   
  392. diff -r -c audit.ref/refilefrom audit/refilefrom
  393. *** audit.ref/refilefrom    Thu Jul 30 18:41:24 1992
  394. --- audit/refilefrom    Thu Jul 30 19:30:12 1992
  395. ***************
  396. *** 1,5 ****
  397. --- 1,8 ----
  398.   #!/usr/bin/perl
  399.   
  400. + # $Date: 1992/07/30 19:30:10 $
  401. + # $Revision: 1.1 $
  402.   $program = $0;
  403.   $program =~ s|.*/||;
  404.   $| = 1;
  405. diff -r -c audit.ref/refileto audit/refileto
  406. *** audit.ref/refileto    Thu Jul 30 18:41:24 1992
  407. --- audit/refileto    Thu Jul 30 19:30:12 1992
  408. ***************
  409. *** 1,5 ****
  410. --- 1,8 ----
  411.   #!/usr/bin/perl
  412.   
  413. + # $Date: 1992/07/30 19:30:10 $
  414. + # $Revision: 1.1 $
  415.   $program = $0;
  416.   $program =~ s|.*/||;
  417.   $| = 1;
  418. diff -r -c audit.ref/rfolder audit/rfolder
  419. *** audit.ref/rfolder    Thu Jul 30 18:41:24 1992
  420. --- audit/rfolder    Thu Jul 30 19:30:12 1992
  421. ***************
  422. *** 1,5 ****
  423. --- 1,8 ----
  424.   #!/usr/bin/perl
  425.   
  426. + # $Date: 1992/07/30 19:30:10 $
  427. + # $Revision: 1.1 $
  428.   $program = $0;
  429.   $program =~ s|.*/||;
  430.   $| = 1;
  431. diff -r -c audit.ref/rfolders audit/rfolders
  432. *** audit.ref/rfolders    Thu Jul 30 18:41:24 1992
  433. --- audit/rfolders    Thu Jul 30 19:30:12 1992
  434. ***************
  435. *** 1,5 ****
  436. --- 1,8 ----
  437.   #!/usr/bin/perl
  438.   
  439. + # $Date: 1992/07/30 19:30:10 $
  440. + # $Revision: 1.1 $
  441.   $program = $0;
  442.   $program =~ s|.*/||;
  443.   $| = 1;
  444. diff -r -c audit.ref/sample.audit audit/sample.audit
  445. *** audit.ref/sample.audit    Thu Jul 30 19:57:15 1992
  446. --- audit/sample.audit    Thu Jul 30 19:55:43 1992
  447. ***************
  448. *** 0 ****
  449. --- 1,151 ----
  450. + #!/eci/bin/perl
  451. + #
  452. + # $Date: 1992/07/30 19:55:42 $
  453. + # $Revision: 1.1 $
  454. + # Tailor this for yourself
  455. + @MyNames = ('FIRSTNAME', 'LASTNAME');
  456. + # This is a sample audit script.  It looks for a file with the
  457. + # name "~/.vacation.msg", and if it exists, assumes that the user
  458. + # is on vacation, and operates under "vacation mode", otherwise,
  459. + # works under "work mode".
  460. + #
  461. + # In either case, mail from the mailer daemon, or any mail addressed
  462. + # directly to the user is assumed to be important, and is not
  463. + # filtered for junk mail.  In vacation mode, the mail is answered
  464. + # automatically, using the ".vacation.msg" file as the reply message.
  465. + # Then, the mail is simply dropped in the system mailbox.
  466. + #
  467. + # If the mail is not directly addressed, then it is coming from a 
  468. + # mailing list, and is filtered through the junk mail lists, which
  469. + # are determined by one of two files, depending upon the mode.  In
  470. + # work mode, the file is ".junkmail.work"; in vacation mode, the
  471. + # file is ".junkmail.vacation".
  472. + #
  473. + # The junkmail lists contain names of mailing lists which are to be
  474. + # subject to junking; that is, mail with headers having one of these
  475. + # junk mailing list names in either the To: or Cc: header, and NOT 
  476. + # directly addressed to the user are junked.
  477. + #
  478. + # As part of the junking, a log file is kept, called ".junkmail.log";
  479. + # the From:, Date:, To:, Cc:, and Subject: lines are recorded.
  480. + #
  481. + # The ".junkmail.work" is especially useful for those occasions when
  482. + # a particular mailing list gets crowded with some emotional issue
  483. + # for which you have no interest.  Rather than having your name removed
  484. + # from the mailing list, just filter it until the signal-to-noise
  485. + # ratio improves (which can be deteremined by scanning the log file
  486. + # periodically).
  487. + #
  488. + ($Prog = $0) =~ s=^/.*([^/]+)$=$1=; # get plain program name
  489. + require 'audit.pl' || die "~/.audit: cannot include audit.pl: $@";
  490. + # Only if you need some of the mh functions
  491. + # require 'mh.pl'  || die "~/.audit: cannot include mh.pl: $@";
  492. + &initialize();
  493. + $HOME = $ENV{'HOME'};
  494. + $VacaJunkMail = "$HOME/.junkmail.vacation";
  495. + $WorkJunkMail = "$HOME/.junkmail.work";
  496. + $JunkLogFile =    "$HOME/.junkmail.log";
  497. + $OnVacation = -f "$HOME/.vacation.msg";
  498. + $AtWork = ! $OnVacation;
  499. + # If this message came from the MAILER, deliver it to me directly
  500. + # and do nothing else.
  501. + ($from =~ /MAILER/) && do { &deliver(); exit; };
  502. + # If the sender's name is in the password file, the organization
  503. + # is local
  504. + $local_org = $ENV{'ORGANIZATION'};
  505. + chop($local_org = `cat $HOME/.organization`) 
  506. +     if -f "$HOME/.organization" && !length($local_org);
  507. + if ($local_org) {
  508. +     $organization = $local_org if ($logname = (getpwnam($from))[0]);
  509. + }
  510. + # If I am specifically named on the To or Cc line, do the default.
  511. + unshift(@MyNames,$user);
  512. + foreach $name (@MyNames) {
  513. +     if (grep(/^$name/i, @to, @cc)) {
  514. +     &deliver();            # deposit in my mailbox
  515. +     &vacation() if $OnVacation;    # do the vacation response (maybe)
  516. +     exit;
  517. +     }
  518. + };
  519. + # The mail wasn't sent directly to me, so, if I'm at work, look for 
  520. + # any junkmail list names
  521. + if ($AtWork) {
  522. +     foreach $junkname (&ReadNames($WorkJunkMail)) {
  523. +     $junkname =~ s/([-+.])/\\$1/g;    # make grep-safe
  524. +     &Junk if grep(/^$junkname/i, @to, @cc);
  525. +     }
  526. + }
  527. +     
  528. + # this mail was not sent to me directly, nor was it on the at-work junk 
  529. + # mailing list, so now check for at-vacation junk mails, if I'm on vacation.
  530. + if ($OnVacation) {
  531. +     foreach $junkname (&ReadNames($VacaJunkMail)) {
  532. +     $junkname =~ s/([-+.])/\\$1/g;    # make grep-safe
  533. +     &Junk if grep(/^$junkname/i, @to, @cc);
  534. +     }
  535. + }
  536. + # Oh well, some mailing list which might be important.
  537. + &deliver();
  538. + exit;
  539. + # Subroutine ReadNames -- opens a file and reads all the names within it,
  540. + # allowing for comments lines and commented lines
  541. + sub ReadNames {
  542. +     local($file) = @_;
  543. +     local($_);
  544. +     local(@names,$name);
  545. +     return () unless -f $file;
  546. +     if (open(LIST,$file)) {
  547. +     while (<LIST>) {
  548. +         next if /^\s*#/;
  549. +         s/\s*\#.*$//;    # strip comments
  550. +         next if /^\s*$/;    # ignore empty lines
  551. +         push(@names,split(' '));
  552. +     }
  553. +     close LIST;
  554. +     } else {
  555. +     warn "$Prog: can't read $file because $!\n";
  556. +     }
  557. +     @names;
  558. + }
  559. + sub Junk {
  560. +     local($hdr) = "%-9s %s\n";
  561. +     if (open(LOG,">>$JunkLogFile")) {
  562. +     $friendly = '' if $friendly eq 'unknown';
  563. +     $organization = '' if $organization eq 'unknown';
  564. +     $from = '"'.$friendly.'"' if $friendly;
  565. +     $from .= ' <'.$address.'>';
  566. +     $from .= ' ('.$organization.')' if $organization;
  567. +     printf LOG $hdr,'From:',$from;
  568. +     printf LOG $hdr,'Date:',$headers{'date'};
  569. +     printf LOG $hdr,'To:',join(', ',@to) if $#to >= $[;
  570. +     printf LOG $hdr,'Cc:',join(', ',@cc) if $#cc >= $[;
  571. +     printf LOG $hdr,'Subject:',$subject;
  572. +     printf LOG "\n";
  573. +     close LOG;
  574. +     }
  575. +     exit;
  576. + }
  577.