#!/usr/local/bin/perl # # This script takes advantage of the "rn" and "trn" # save to pipe ("s |" or just "|") option at the article # level. "fnews" allows editing the article. # # Written by Bob DeBula # Tue Spe 18 07:56:30 EDT 1990 # # Rewritten in PERL and modified to pickup the # article subject & make that the mail subject # with a "FNEWS" prefix. Also, added the -c # (confirmation) option. # Thu Oct 15 15:45:56 EDT 1992 # # Modified by Rob Funk April 27 1995 # -made intro to message less stilted # -recognize NAME environment variable # -commented out `clear's because they're annoying # # Modified by Rob Funk December 1 1996 # -add X-Original-Newsgroups header # -change default editor to vi # # Modified by Rob Funk April 7 1997 # -don't include From: header -- let sendmail take care of that # # Modified by Rob Funk May 14 1998 # -use mutt aliases from .muttrc and files sourced by it # # Modified by Rob Funk July 10 1998 # -add -m option for MIME-forwarding with message/news type # # Recommended .rnmac (without the `#'): #^F %(%m=[pa]?|fnews -c %"Forward to: "\n:^F) # Get options require "getopts.pl"; $usage = "Usage: $0 [-c] [-d] [-e] [-r] [-m]\n"; &Getopts('cedrm') || die $usage; $pto = join(',', @ARGV); @article = (); close(STDIN); open(STDIN, "/dev/tty"); if ( $pto !~ /^\S+/ ) { &clear($opt_r); print "Whom would you like to forward the news article to\n"; print "\(separate e-mail addresses with commas if more than one\)\?\n"; print "\nEnter address(es): "; chop($pto = ); } $pto =~ tr/A-Z/a-z/; @to = split(/,/, $pto); $subject = (grep(/^Subject:\s+.*$/, @article))[0]; $subject = ( $subject =~ /^Subject:\s+(.*)$/ ) ? "FNEWS -> $1" : "FNEWS -> Forwarded news article"; $newsgroups = ((grep(/^Newsgroups:\s+.*$/, @article))[0] || (grep(/^X-Mailing-List:\s+.*$/, @article))[0]); $newsgroups = ($newsgroups =~ /^(Newsgroups|X-Mailing-List):\s+(.*)$/) ? "$2" : "(none)"; chop($host = ( -x "/usr/ucb/hostname" ) ? `/usr/ucb/hostname` : `/bin/hostname`); ($userid,$name,$HOME) = (getpwuid($<))[0,6,7]; # get rid of extraneous stuff in gecos $name =~ s/,.*$//; # Let the user choose their name $name = $ENV{'NAME'} if (defined($ENV{'NAME'})); #$from = $userid."@".scalar((gethostbyname($host))[0])." ($name)"; #$from =~ s/^($userid\@)$host\.(magnus\..*)$/$1$2/; # Set editor based on environment. Default to vi if not set # $EDITOR = ( defined($ENV{'EDITOR'} )) ? $ENV{'EDITOR'} : "/bin/vi"; # # Resolve aliases # if ( $opt_d ) { print "userid = $userid, name = $name, home = $HOME\n"; print "\nPress enter to continue: "; ; } ### foreach $tto (@to) { &muttalias(\%define); &elmalias(\%define); $tto = &mailrcalias($tto); $tto = &mmalias($tto); if ( $opt_d ) { print "In @to loop pre assoc array, tto = $tto\n"; print "\nPress enter to continue: "; ; } $tto = $define{$tto} if ( defined $define{$tto} ); $tto =~ tr/A-Z/a-z/; if ( $opt_d ) { print "In @to loop post xlate, tto = $tto\n"; print "\nPress enter to continue: "; ; } } if ( $opt_d ) { print "\@to array:\n", @to; print "\nPress enter to continue: "; ; } $to = join(',', @to); if ( $opt_d ) { print "To: $to\n"; print "\nPress enter to continue: "; ; } if (defined($opt_m)) { $boundary=sprintf("%0x%0x%s%0x%0x",$$,time,($0=~m,.*?/?([^/]+)$,),$$,time); push(@article, ("\n", "--$boundary--\n", "\n")); unshift(@article, ("--$boundary\n", "Content-Type: message/news\n", "\n")); } unshift(@article, ("I thought you might be interested in this.\n\n--- $name\n", "\n")); if (defined($opt_m)) { unshift(@article, ("--$boundary\n", "Content-Type: text/plain; charset=US-ASCII\n", "Content-Transfer-Encoding: 7bit\n", "\n")); } unshift(@article,"\n"); # separate headers and body if (defined($opt_m)) { unshift(@article, ("Mime-Version: 1.0\n", "Content-Type: multipart/mixed; boundary=\"$boundary\"\n")); } unshift(@article, ("To: $to\n", #"From: $from\n", "Subject: $subject\n", "X-Original-Newsgroups: $newsgroups\n", "X-Delivered-By-The-Graces-Of: The fnews mail script\n")); # # Edit the posting if "-e" option specified # CONFIRM: while (defined($opt_e) || defined($opt_c)) { if ( defined $opt_e ) { $fname = "/tmp/fnews_tmp$$"; open(FNEWS_OUT, ">$fname") || die "Could not open fnews tmp file\n"; print FNEWS_OUT @article; close FNEWS_OUT; system("$EDITOR $fname"); open(FNEWS_OUT, $fname) || die "Could not open fnews tmp file\n"; @article = (); @article = (); close FNEWS_OUT; unlink( $fname ); undef $opt_e; } $confirm = "x"; # next line seems to be emitting an extra `|'..... why? while ( (defined $opt_c) && ($confirm !~ /f|e|c|\s+/ )) { &clear($opt_r); print "\nForward(f), edit(e), or cancel(c) (default is forward)? "; $confirm = ; &clear($opt_r); exit 0 if ( $confirm =~ /^c/ ); if ( $confirm =~ /^e/i ) { $opt_e = 1; next CONFIRM; } } undef $opt_c; } # # Now send the message to the intended recipient(s) using sendmail # &clear($opt_r); print "\nForwarding news article via e-mail.....\n"; open(MAIL, "|/usr/lib/sendmail -t -oi $to") || die "Cannot use sendmail to forward msg\n"; print MAIL @article; close MAIL; &clear($opt_r); #close DEBUG if ( $opt_d ); exit 0; #### sub muttalias { # # build mutt alias table (if any mutt aliases) # # does not currently handle aliases referencing other aliases, # but does chase files that are sourced local(*define,$file,$input) = @_; # using recursion described in Camel book local($cmd,$rest,$next,$synon,$address,$_); $file = "$HOME/.muttrc" unless $file; $input++; # string increment if ( -e $file ) { open($input,$file) or return 0; # fail silently if unsuccessful while(<$input>) { chop; next if (/^\s*\#/); next if (/^\s*$/); while (/\\$/) { # trailing backslash, get next line $next = <$input>; break if (! defined($next)); chop($next); $_ .= $next; } ($cmd, $rest) = /^(\w)+\s*([^\#]*)/; # keep comments out of $rest $_ = $rest; # we're messing with $_ from now on s/\s*$//; # delete trailing whitespace if ($cmd eq "alias") { # grab alias from $rest ($synon,$address) = /(\w+|\"[^\"]*\")\s+(.*)/; $synon =~ tr/A-Z/a-z/; $address =~ tr/A-Z/a-z/; next if ( $synon eq $address ); $define{$synon} = $address; } elsif ($cmd eq "source") { # try again with different file s/^\"//; s/\"$//; # remove any quotes s.^~/.$HOME/.; # change ~ to $HOME # now assume $_ is file to read &muttalias(\%define,$_,$input); } } } else { # file doesn't exist return; } close $input; } sub elmalias { # # build elm alias table (if any elm aliases) # local(*define,$file) = @_; $file = "$HOME/.elm/aliases.text" unless $file; local($synon,$address,@alias,$stop,$ak,$key,$_); if ( -e $file ) { open(ELM,$file); while() { chop($_); ($synon, $address) = /^(.+)\s+\=\s+.*\s*\=\s+(.*)$/; $synon =~ tr/A-Z/a-z/; next if ( $synon eq $address ); @alias = split(/[, ]/,$synon); $address =~ s/,\s+/,/g; $address =~ s/[\r\n\t\f]//g; $address =~ s/\s+/,/g; $address =~ tr/A-Z/a-z/; foreach (@alias) { $define{$_} = $address if (( $_ !~ /^\s+$/ ) && ( $_ ne "" )); } } $stop = 1; while ( $stop > 0 ) { $stop = 0; foreach $ak (keys %define) { $define{$ak} =~ s/[\r\n\t\f]//; if (( $define{$ak} =~ s/\s+/,/g ) || ( $define{$ak} =~ /^.*\,.*/ )) { @address = split(',',$define{$ak}); foreach (@address) { next if (( $_ =~ /^\s+$/ ) || ( $_ eq "" )); if ( $define{$_} ) { $_ = $define{$_}; $stop = 1; } } $define{$ak} = join(',',@address); } else { $address = $define{$ak}; if ( $define{$address} ) { $define{$ak} = $define{$address}; $stop = 1; } } } } if ( $opt_d ) { #open(DEBUG, "|/usr/local/bin/less") || die "No less found\n"; foreach $key (sort(keys %define)) { print "key = \*\*$key**, Element = **$define{$key}**\n"; } print "\nPress enter to continue: "; ; } } } sub mailrcalias { # # Resolve mailx/Mail/mail .mailrc aliases # local($tto) = @_; local(%mrcalias,$mrc,$_); open(MAILRC, "$HOME/.mailrc") || $mrc == 1; if ( !defined $mrc ) { while() { $mrcalias{$2} = $3 if ( $_ =~ /^a(lias)?\s+(\S+)\s*(.*)\s*$/i ); $tto = $mrcalias{$tto} if ( defined $mrcalias{$tto} ); } } return $tto; } sub mmalias { # # Resolve MM aliases (if any) # local($tto) = @_; local($mmi,$mmalias,$mmlist,@boing,@MMLIST); open(MMINIT, "$HOME/.mminit") || $mmi == 1; if ( !defined $mmi ) { while() { if ( /^define\s+$tto\s+.*$/ ) { ($mmalias, $mmlist) = /^define\s+(\S+)\s+(.*)/; if ( $mmlist =~ /^.*@@(.*)$/ ) { @boing = split('/', $1); if ( $boing[0] eq "~" ) { $boing[0] = "$HOME"; } elsif ( (substr($boing[0], 0, 1) ) eq "~" ) { $boing[0] = (getpwnam(substr($boing[0],1)))[7]; } else { $boing[0] = "/$boing[0]"; } open(ATLIST, join('/', @boing)) || next; @MMLIST = (); while(push(@MMLIST, split(/[ ,\t\s\n]+/, ))) {}; $mmlist = join(',',@MMLIST); } else { $mmlist = join(',', split(/[ ,\t\s\n]+/, $mmlist)); } $tto = $mmlist; } } } return $tto; } sub clear { local($opt) = @_; if ($opt) { if ( -x "/usr/ucb/clear" ) { system("/usr/ucb/clear"); } else { system("/bin/clear"); } } }