#! /bin/sh # $Header: /home/jerry/.bin/RCS/fixsubj,v 1.11 92/08/09 23:26:29 jerry mh_contrib $ # ### fixsubj - fix (add or change) "Subject:" on a mail message ### Usage: fixsubj [+folder] [msgnum [msgnums]] -s 'new subj' ## ## SOME PEOPLE DON'T BOTHER TO PUT A Subject: LINE ON THEIR MAIL ## MESSAGES. THAT MAKES IT HARD, LATER, WHEN YOU scan YOUR MAIL. ## fixsubj LETS YOU ADD YOUR OWN Subject: LINE TO MESSAGE(S). ## YOU CAN USE THE SAME SUBJECT ON MANY MESSAGES BY GIVING ALL NUMBERS. ## ## IF A MESSAGE ALREADY HAS A SUBJECT, fixsubj WILL TELL YOU ## AND ASK YOU IF YOU WANT TO EDIT IT BY HAND, USE THE DEFAULT ## FROM -s), OR SKIP IT. ## ## TO USE IT, TYPE: ## % fixsubj -s 'this is the subject' (FOR THE CURRENT MESSAGE) ## OR SOMETHING LIKE ## % fixsubj +foo last -s 'a subject' (last MESSAGE IN foo FOLDER) ## % fixsubj -s 'my day' 23-25 42 (MESSAGES 23, 24, 25, AND 42) ## ...AND SO ON. THE SUBJECT, AFTER THE -s, SHOULD BE "ONE WORD" TO ## THE SHELL... YOU'LL USUALLY NEED TO QUOTE IT. YOU CAN PUT THE ## OPTIONAL FOLDER NAME (STARTS WITH A +) AND MESSAGE NUMBERS (NUMBERS, ## WORDS LIKE last, first:20, first-33, etc.) IN ANY ORDER. # # NOTE TO HACKERS: TABSTOPS ARE SET AT 4 IN THIS CODE # # USE AT YOUR OWN RISK. SEEMS TO WORK, BUT IT'S YOUR RESPONSIBILITY! # PLEASE TELL ME ABOUT BUGS AND FIXES: Jerry Peek, jerry@ora.com editor=${VISUAL-${EDITOR-/usr/ucb/vi}} # TEXT EDITOR line="/usr/ucb/head -1" # READS ONE LINE (USE /bin/line IF YOU HAVE IT) mh=/usr/local/mh # WHERE MH COMMANDS LIVE myname="`basename $0`" # BASENAME OF THIS PROGRAM scanopts="-noclear -noheader -noreverse" # BYPASS MH PROFILE stat=1 # DEFAULT EXIT STATUS; SET TO 0 BEFORE NORMAL EXIT temp=/tmp/FIXSUBJ$$ temperr=/tmp/FIXSUBJe$$ # HOLDS ERRORS FROM while LOOP usage="Usage: $myname [+folder] [msgnum] -s 'subject'" trap 'rm -f $temp $temperr; exit $stat' 0 1 2 15 > $temp > $temperr chmod 600 $temp $temperr # PARSE COMMAND LINE: while : do case "$1" in "") break ;; # NO MORE ARGUMENTS -help) echo "$usage" 1>&2; stat=0; exit ;; [@+]*) folder="$1"; shift ;; -s*) case "$2" in "") echo "$usage (Missing subject.)" 1>&2 exit ;; *) newsubj="$2" shift; shift ;; esac ;; *) msgs="$msgs $1"; shift ;; esac done case "$newsubj" in "") echo "$usage (Missing subject.)" 1>&2 exit ;; esac # FOLDER PATH; IF NO $folder GIVEN, DEFAULTS TO CURRENT: folpath="`$mh/mhpath $folder`" || exit # MAKE LIST OF MESSAGE NUMBERS AND SUBJECTS, ONE PER LINE. # IF NO Subject: IN MESSAGE, $subjnow WILL BE EMPTY. # FEED INTO LOOP. IF NO msgs ON COMMAND LINE, SET TO cur. # # sh WILL RUN THIS IN A SUB-SHELL, SO exit WILL ONLY END # THE LOOP, NOT THE WHOLE SCRIPT. WORK-AROUND: PUT INTERNAL # ERRORS ON FILE DESCRIPTOR 3 AND COLLECT AT END OF LOOP: $mh/scan $scanopts -width 200 -format "%(msg) %{subject}" ${msgs=cur} | while read msg subjnow do msgpath=$folpath/$msg # IF MESSAGE IS UNREADABLE, scan (MH6.6 AND BEFORE) # WILL PRINT A LINE (TO STANDARD OUTPUT!) LIKE THIS, # WITH LEADING BLANKS UNLESS msgnum > 999: # unreadable # IF THERE ARE LEADING BLANKS, SOME BOURNE SHELLS WILL # COPY BOTH THE MESSAGE NUMBER AND THE unreadable INTO # subjnow, AND LEAVE $msg EMPTY. TRY TO FIX BOTH CASES: case "$msg" in "") echo "$myname: quitting, message $msg $subjnow" 1>&3; break ;; esac case "$subjnow" in unreadable) echo "$myname: quitting: can't read message '$msg'." 1>&3 break ;; "") # GLUE Subject AND X-Original-Subject TO TOP. # IF YOUR SHELL DOESN'T UNDERSTAND "<<-", REPLACE IT # WITH "<<" AND SHIFT LINES TO LEFT-HAND EDGE: cat - $msgpath > $temp <<- ENDOFHDR Subject: $newsubj X-Original-Subject: (none) ENDOFHDR cp $temp $msgpath || { echo "$myname: quitting: can't replace ${msgpath}?" 1>&3 break } ;; *) # MESSAGE HAS A SUBJECT ALREADY; ASK USER: # LOOP UNTIL GET ANSWER: while : do # SAME NOTE AS ABOVE ABOUT REPLACING "<<-"... cat <<- ENDOFMSG Message $msg already has a subject: ... $subjnow Type c to change subject to '$newsubj' Type e to edit the message yourself with $editor Type s to skip this message and go on to the next (if any) Type q to quit and not change any more messages. ENDOFMSG echo -n "And the answer is? " 1>&2 ans="`$line $temp 2>&1 /^Subject: /s/^/X-Original-/ i Subject: $newsubj . w q !ENDOFEDIT! if [ ! -s $temp ] then break else echo "$myname: error editing '$msg':" 1>&2 cat "$temp" 1>&2 echo "Should you edit it by hand? Try again: " 1>&2 fi ;; *) echo "Please try again..." 1>&2 ;; esac # END OF case "$ans" done # END OF while : ;; esac # END OF case "$subjnow" done 3> $temperr # END OF while read msg subjnow if test -s $temperr then cat $temperr 1>&2 else stat=0 fi exit