#! /bin/sh # $Id: forwedit 0.6 1997/06/06 03:33:39 jpeek book4 $ # ### forwedit - editor for MH forw command; makes Subject same as original msg ### Usage (in MH profile): ### forw: -editor forwedit ### optional, name an editor to use after this script: default is prompter(1): ### forwedit: -editor someeditor ### ### forwbatch - same as forwedit, but doesn't run an interactive editor ## ## forwedit sets the Subject: header field of your draft forwarded message ## to be the same as the subject of the original message with (fwd) after. ## If you forward more than one message, it uses "Forwarded messages". ## (You can configure this by setting the $draftsubj shell variable.) ## ## After doing that, forwedit calls an editor for you to compose the draft ## header and body; it tries the MH profile entries "forwedit: -editor xxx" ## and "Editor:", then the environment variables VISUAL and EDITOR. The ## default editor is prompter(1). forwbatch does not invoke an editor. # # Note: there are calls to external utilities in here that could be # replaced with hardcoded values to speed up execution on slow systems: # "echo a | /bin/tr" and two calls to $mhdir/mhparam. # If you have an older MH, you won't have mhparam(1); use the "mhprofile" # script from "MH & xmh" Nutshell Handbook instead... or hardcode an editor. # # After you make a "forwedit" file, make a link to it named "forwbatch". # # Tabstops in this code are set at 4 (in vi, use ":se ts=4 sw=4"). # # Thanx to David Goodwin, Dan Eisenbud, and Axel Belinfante # for bug reports and patches. # # USE AT YOUR OWN RISK. SEEMS TO WORK, BUT IT'S YOUR RESPONSIBILITY! # Please tell me about bugs and fixes: Jerry Peek # # NO WARRANTY # # BECAUSE THIS PROGRAM IS AVAILABLE FREE OF CHARGE, THERE IS NO WARRANTY # FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN # OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES # PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED # OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS # TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE # PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, # REPAIR OR CORRECTION. # # IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING # WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR # REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, # INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING # OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED # TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY # YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER # PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE # POSSIBILITY OF SUCH DAMAGES. # Note: $draftsubj is set toward middle of script; configure if you want mhdir=/usr/local/mh # Where MH binaries like mhparam live msgedit=/bin/ed # For editing draft header myname=`basename $0` # Name of this program showbad="/bin/cat -v" # Command to show non-printable characters case $# in 1) draft="$1" if [ ! -r "$draft" -o ! -w "$draft" -o ! -s "$draft" ]; then echo "$myname aborting: can't read/write draft '$draft'" 1>&2 exit 1 fi ;; *) echo "$myname aborting: I need one command line argument; I got $#: '$*'" 1>&2 exit 1 ;; esac # Scan message number(s) from $mhmessages environment variable # (only set with "forw -annotate"; else we scan cur). Store subject(s). # If multiple messages, $mhmessages can look like "1-5 23"; let scan(1) # break those up. origsubj=`$mhdir/scan -width 1000 -format '%{subject}' ${mhmessages-cur}` || { echo "$myname aborting: 'scan ${mhmessages-cur}' failed?" 1>&2 exit 1 } # Get subject for forwarded message draft. # If $origsubj contains a newline, there were multiple messages (and # "forw -annotate" was used... no way to get this info without -annotate). # If subject already has "(fwd)", don't add another. # (To get fancier here, use expr(1) or echo|sed to customize subject.) case "$origsubj" in *" "*) draftsubj="Forwarded messages" ;; *"(fwd)"*) draftsubj="$origsubj" ;; *) draftsubj="$origsubj (fwd)" ;; esac # Edit draft by finding first Subject: line and gluing in $draftsubj. # This works because ed(1) starts at end of draft; search will wrap # forward to start of draft and find Subject: in draft header. # # ed(1) should be silent. If it returns any errors, complain and quit. # Note: ed(1) can bomb on really big messages. # If this is a problem, replace with sed(1) and a temporary file. # # Start by storing a control-A character in $A. This makes a delimiter # for ed that's almost surely not in $draftsubj (else, ed could bomb). # Using echo and tr means we don't have to hardcode a control character here: A=`echo a | /bin/tr a '\001'` scmd="/^[Ss]ubject:/s${A}\$${A}$draftsubj${A}" # substitute command for ed(1) # echo $scmd, a newline, and a "w" (write) command to ed(1); # save stderr and stdout, if any, in $edout: edout=`echo "$scmd w" | $msgedit - $draft 2>&1` # Test exit status ($?) and ed output ($edout); should be 0 and empty. # If not, complain and show editing command we tried: case "$?$edout" in 0"") # Test name script was invoked with to decide if editor should be called: case "$myname" in forwedit) # Find editor to use on draft (default: prompter(1)) and run it: profline=`$mhdir/mhparam "$myname"` if editor=`expr "$profline" : '.*-editor *\([^ ]*\)'` then : elif editor=`$mhdir/mhparam editor` then : else editor=${editor:-${VISUAL-${EDITOR-$mhdir/prompter}}} fi exec $editor "$draft" # Save a process by execing editor # Always an error if we get here: exec failed. echo "$myname aborting: 'exec $editor $draft' failed" 1>&2 exit 1 ;; forwbatch) ;; # Don't run interactive editor *) echo "$0: Fatal error: bad invocation name." 1>&2; exit 1;; esac ;; *) # non-zero exit status or ed output. Complain and quit: echo "$myname: '$msgedit - $draft' failed with editor command: $scmd" | $showbad 1>&2 echo "Output, if any, was: $edout" 1>&2 exit 1 ;; esac