home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume16 / mh-scripts / part01 next >
Internet Message Format  |  1991-02-02  |  50KB

  1. From: jerry@ora.com (Jerry Peek)
  2. Newsgroups: comp.sources.misc
  3. Subject: v16i089:  "MH & xmh: Email for Users and Programmers", Part01/01
  4. Message-ID: <1991Feb2.050758.20285@sparky.IMD.Sterling.COM>
  5. Date: 2 Feb 91 05:07:58 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: c4b584d0 c695b397 2e978d63 b63595db
  8.  
  9. Submitted-by: jerry@ora.com (Jerry Peek)
  10. Posting-number: Volume 16, Issue 89
  11. Archive-name: mh-scripts/part01
  12.  
  13. These files are Bourne shell scripts that use MH electronic mail commands.  
  14. The scripts come from the Nutshell Handbook called "MH & xmh: Email for 
  15. Users and Programmers" published by O'Reilly & Associates, Inc. 
  16. Whether you have the book or not, these scripts should be useful if you
  17. use MH.  (If you don't use MH, look at the kinds of things you could do.)
  18.  
  19. --Jerry Peek, jerry@ora.com
  20.  
  21. # This is a shell archive.  Remove anything before this line,
  22. # then unpack it by saving it in a file and typing "sh file".
  23. #
  24. # NOTE: Tabstops in these files are set at 4-column intervals.
  25. #
  26. # Wrapped by ora!jerry on Sat Jan 12 18:30:42 EST 1991
  27. # Contents:  README append babyl2mh distprompter fixsubj fols incs mhprofile
  28. #    recomp replf resend.fixmsg rmmer scandrafts showpr vmsmail2mh xmhprint
  29.  
  30. echo extracting - README
  31. sed 's/^X//' > "README" <<'X//E*O*F README//'
  32. XINTRODUCTION:  These files are Bourne shell scripts that use MH electronic
  33. Xmail commands.  The scripts come from the Nutshell Handbook called "MH & xmh:
  34. XEmail for Users and Programmers" published by O'Reilly & Associates, Inc. 
  35. XThe book will be available this month (January, 1991).
  36. X
  37. XWhether you have the book or not, these scripts should be useful if you
  38. Xuse MH.  (If you don't use MH, look at the kinds of things you could do.
  39. XBecause MH isn't a "one-mail-program-does-all" system and its programs are
  40. Xall run by the UNIX shell, shell programming with MH is easy.)
  41. XEach file has a comment block that explains the program; individual
  42. Xparts of the scripts are commented, too.  Although the book has complete
  43. Xexplanations, people who have some experience with shell programming and
  44. XMH should be able to use these without the book.
  45. X
  46. X
  47. XDO THEY WORK?:  I developed these scripts under BSD UNIX and SunOS; I've
  48. Xused most of them myself for months or years.  The book's reviewers tested
  49. Xthem on other flavors of UNIX.  Still, there could be some portability or
  50. Xother problems.  If you don't have MH 6.7 installed, you could run into a
  51. Xfew problems there.  There are also some compatibility problems, like
  52. X"echo -n" vs. "echo \c", that I haven't tried to code around; remember
  53. Xthat these are intended more as examples than as portable bulletproof code.
  54. X
  55. XIf you find problems, though, please send me mail.  Of course, some
  56. Xsystem-dependent stuff like variables that hold the pathnames of files and
  57. Xprograms will have to be edited to work on your computer.  Also, some
  58. Xobscure problems and system dependencies are explained in the book.
  59. XBut I'd be GLAD to get your mail (and answer it as soon as I can).
  60. X
  61. XBecause these scripts come directly from the book, I'm not sure what to
  62. Xdo about patches and patchlevel.h files for the comp.sources.misc
  63. Xarchives.  The book versions won't be patched; they'll just be updated.
  64. XThe latest versions should always be available on the uunet.uu.net
  65. Xcomputer for anonymous ftp and uucp; get the tar file named MHxmh.tar.Z
  66. Xfrom the nutshell/MHxmh directory.
  67. X
  68. X
  69. XDESCRIPTIONS:  Here are one-line descriptions of the script files.
  70. XEven if you don't need the capabilities that a particular program gives,
  71. Xyou might want to look at the scripts anyway for examples of MH programming.
  72. X
  73. Xappend        Append file(s) to an MH mail message at "What now?" prompt
  74. Xdistprompter  Replaces "prompter" editor for MH "dist" command
  75. Xfixsubj       Fix (add or change) "Subject:" on a mail message
  76. Xfols          Show list of folders in columns, current folder marked
  77. Xmhprofile     Grab matching line(s) from MH profile file
  78. Xrecomp        Re-compose a draft mesage in MH draft folder
  79. Xreplf         Refile current message into folder, reply to it
  80. Xresend.fixmsg Editor for fixing up returned mail (use with "resend")
  81. Xrmmer         Move mail to DELETE (sub-)folder for "find" to delete later
  82. Xscandrafts    Scan MH draft folder; return to original folder or stay
  83. Xshowpr        Show MH message(s) with pr(1), custom heading
  84. Xxmhprint      Print command for xmh
  85. X
  86. X
  87. XAUTHORSHIP, COPYING, ETC.:  These programs are in the public domain.
  88. XOf course, you use them at your own risk.  I wrote most of them myself.
  89. XI adapted two of them, "append" and "replf", from scripts that come
  90. Xwith the MH distribution; Marshall Rose, John Romine and Bob Desinger
  91. Xwere authors of those scripts, I believe.  If you make changes or fix
  92. Xbugs, I'd really appreciate getting a mail message about that and/or
  93. Xa copy of your fixed script.  If I use the changes, I'll give you
  94. Xcredit... and people who use the scripts will appreciate your help!
  95. X
  96. X--Jerry Peek, jerry@ora.com, +1 617 354-5800
  97. X//E*O*F README//
  98. chmod u=rw,g=r,o=r README
  99.  
  100. echo extracting - append
  101. sed 's/^X//' > "append" <<'X//E*O*F append//'
  102. X#! /bin/sh
  103. X# $Header: /u3/acs/jdpeek/.bin/RCS/append,v 1.10 90/10/13 09:48:04 jdpeek book $
  104. X###    append - append file(s) to an MH mail message
  105. X###    Usage:   What now? e append file [files...]
  106. X##
  107. X##    THIS SCRIPT LETS YOU APPEND ONE OR MORE FILES TO A DRAFT MH MAIL
  108. X##    MESSAGE; IT ALSO ALLOWS WILDCARDS AND ENVARIABLES.
  109. X##    YOU CALL IT AS AN EDITOR, AT THE What now? PROMPT.
  110. X##    FOR EXAMPLE, TO APPEND A COPY OF YOUR FILE report TO YOUR DRAFT:
  111. X##        What now? e append report
  112. X##
  113. X##    AFTER IT APPENDS THE FILE(S), YOU GET ANOTHER What now? PROMPT.
  114. X##    IF YOU WANT TO SEPARATE THE FILES WITH BLANK LINES, ROWS OF DASHES,
  115. X##    OR WHATEVER, AN EASY WAY IS TO MAKE A LITTLE FILE NAMED SOMETHING
  116. X##    LIKE SEP WITH THAT SEPARATOR IN IT.  THIS NEXT EXAMPLE SHOWS HOW TO
  117. X##    APPEND ALL THE FILES FROM THE $HOME/proj DIRECTORY WHOSE NAMES END
  118. X##    WITH .out, THEN YOUR SEPARATOR FILE, THEN THE FILE .signature:
  119. X##        What now? e append $HOME/proj/*.out sep .signature
  120. X#
  121. X# Original, apparently by John Romine, from the paper
  122. X# "MH.5: How to process 200 messages a day and still get some
  123. X# real work done," in the Summer 1985 USENIX Proceedings.
  124. X# Hacked more by Jerry Peek, with hints from John Romine.
  125. X
  126. Xcase $# in
  127. X0)    echo 1>&2 "`basename $0`: shouldn't get here!"; exit 1;;
  128. X1)    echo 1>&2 "Usage: e[dit] `basename $0` file [files...]"; exit 1 ;;
  129. X*)    while :
  130. X    do
  131. X        case $# in
  132. X        1)    msg=$1; break ;;
  133. X        *)    files="$files $1"; shift ;;
  134. X        esac
  135. X    done
  136. X    ;;
  137. Xesac
  138. X
  139. X# eval EXPANDS ENVIRONMENT VARIABLES IN $files; BUT PROTECT >> FROM eval:
  140. Xeval cat $files '>>' $msg
  141. X//E*O*F append//
  142. chmod u=rwx,g=rx,o=rx append
  143.  
  144. echo extracting - babyl2mh
  145. sed 's/^X//' > "babyl2mh" <<'X//E*O*F babyl2mh//'
  146. X#! /bin/sh
  147. X# $Header: /u3/acs/jdpeek/.bin/RCS.Z/babyl2mh,v 1.1 90/03/22 03:57:05 jdpeek Exp $
  148. X###    babyl2mh - slow way to convert Emacs Rmail files to MH
  149. X###    Usage: babyl2mh +mh-folder [RMAIL-FILE]
  150. X
  151. X#    NOTE: PROGRAM HASN'T BEEN TESTED THOROUGHLY.
  152. X#     CHECK THE MESSAGES!
  153. X#    Placed in the public domain.  Use at your own risk.
  154. X#        --Jerry Peek, 22 March 1990
  155. X
  156. Xdfltprot=600    # DEFAULT MESSAGE PROTECTION (IF NONE IN MH PROFILE)
  157. Xfolopts="-fast -nolist -nototal -nopack -norecurse"
  158. Xmh=/usr/local/mh
  159. Xmhprofile=/u3/acs/jdpeek/.bin/mhprofile    # READS MH PROFILE
  160. Xscanopts="-noclear -noheader -noreverse"
  161. X
  162. Xcase "$1" in
  163. X[@+]?*)
  164. X    # IF $1 DOESN'T EXIST, folder WILL CREATE IT (SIGH).
  165. X    # THAT'S BECAUSE stdout IS REDIRECTED AWAY FROM TERMINAL.
  166. X    if $mh/folder $folopts "$1" >/dev/null
  167. X    then
  168. X        # GET PATHNAME OF FOLDER, LAST MESSAGE NUMBER:
  169. X        folpath="`$mh/mhpath`" || exit
  170. X        firstmsg="`$mh/scan -format '%(msg)' last`" || exit
  171. X    else
  172. X        echo "`basename $0`: no folder.  quitting." 1>&2
  173. X        exit 1
  174. X    fi
  175. X    ;;
  176. X*)    echo "Usage: `basename $0` +folder|@folder [file]
  177. X    ('$1' doesn't start with + or @.)" 1>&2
  178. X    exit 1
  179. X    ;;
  180. Xesac
  181. X
  182. Xif [ -n "$2" -a \( ! -r "$2" \) ]
  183. Xthen
  184. X    echo "`basename $0`: quitting: can't read Rmail file '$2'." 1>&2
  185. X    exit 1
  186. Xfi
  187. X
  188. X# GET PROTECTION MODE FROM MH PROFILE (IF NONE, USE $dfltprot):
  189. Xmsgprot="`$mhprofile -b msg-protect`" || msgprot=$dfltprot
  190. X
  191. X# MAKE SHELL ARCHIVE FILE ON awk'S STANDARD OUTPUT.
  192. X# PIPE IT INTO sh TO CREATE THE MESSAGE FILES...
  193. Xawk "BEGIN {
  194. X    folpath=\"$folpath\" # STORE AS STRING, WITH QUOTES
  195. X    msgprot=$msgprot     # STORE AS NUMBER (NO QUOTES)
  196. X    msgnum=$firstmsg"'   # CHANGE FROM DOUBLE- TO SINGLE-QUOTES
  197. X    gotflags=0
  198. X    gotgoodhdr=0
  199. X    gotbadhdr=0
  200. X}
  201. X# SKIP BABYL HEADER:
  202. XNR==1, /\037\014/ {
  203. X    next
  204. X}
  205. X# PROCESS MESSAGES.  USE gotflags, ETC. TO "REMEMBER"
  206. X# WHEN WE HAVE PASSED EACH PART OF EACH MESSAGE.
  207. X{
  208. X    # MESSAGE ENDS WITH CTRL-UNDERSCORE AT START OF A LINE.
  209. X    # PRINT SHELL COMMANDS AND RESET FLAGS:
  210. X    if ($0 ~ /^\037/) {
  211. X        printf "END-OF-%s/%d\n\n", folpath, msgnum
  212. X        # SET PROTECTION (INEFFICIENT; SHOULD DO ALL MSGS. AT ONCE)
  213. X        printf "chmod %d %s/%d\n", msgprot, folpath, msgnum
  214. X        gotflags = 0
  215. X        gotgoodhdr = 0
  216. X        gotbadhdr = 0
  217. X        next
  218. X    }
  219. X    # INSTEAD OF FLAGS LINE (LIKE "1,,"), PRINT START OF ARCHIVE:
  220. X    if (gotflags == 0) {
  221. X        gotflags = 1
  222. X        msgnum += 1
  223. X        printf "/bin/cat > %s/%d << \\END-OF-%s/%d\n", \
  224. X            folpath, msgnum, folpath, msgnum
  225. X        next
  226. X    }
  227. X    # PRINT THE FULL HEADER (UP TO FIRST BLANK LINE):
  228. X    if (gotgoodhdr == 0) {
  229. X        if ($0 !~ /^$/) {
  230. X            print
  231. X            next
  232. X        }
  233. X        else {
  234. X            gotgoodhdr = 1
  235. X            next
  236. X        }
  237. X    }
  238. X    # SKIP THE SHORT HEADER (UP TO NEXT BLANK LINE):
  239. X    if (gotbadhdr == 0 && $0 !~ /^$/)
  240. X        next
  241. X    gotbadhdr = 1
  242. X    # PRINT THE MESSAGE (UP TO ^_):
  243. X    print
  244. X    next
  245. X}' $2 |
  246. X/bin/sh -e    # EXIT ON ANY ERROR
  247. X
  248. Xexit # RETURN STATUS FROM PIPE ABOVE
  249. X//E*O*F babyl2mh//
  250. chmod u=rwx,g=rx,o=rx babyl2mh
  251.  
  252. echo extracting - distprompter
  253. sed 's/^X//' > "distprompter" <<'X//E*O*F distprompter//'
  254. X#! /bin/sh
  255. X# $Header: /u3/acs/jdpeek/.bin/RCS/distprompter,v 1.4 90/10/12 09:03:48 jdpeek book $
  256. X###    distprompter - replaces "prompter" for MH "dist" command
  257. X###    Usage (in .mh_profile):    dist: -editor distprompter
  258. X##
  259. X##    BY DEFAULT, THE MH dist COMMAND USES prompter TO EDIT THE DRAFT
  260. X##    MESSAGE.  FOR dist, THAT'S NOT A GREAT CHOICE BECAUSE:
  261. X##        - IF YOU ACCIDENTALLY TYPE A BODY, THE MESSAGE CAN'T BE SENT
  262. X##        - YOU ALWAYS HAVE TO PRESS CONTROL-D TO SKIP THE BODY
  263. X##
  264. X##    distprompter IS AN EDITOR DESIGNED FOR dist.  IT READS THE
  265. X##    EMPTY HEADER THAT dist GIVES IT, LINE BY LINE.  IF A COMPONENT
  266. X##    IS EMPTY, IT PROMPTS YOU.  IF A COMPONENT IS FINISHED, IT DOESN'T
  267. X##    PROMPT.  IF A COMPONENT IS ILLEGAL (NOT Resent-xxx:), IT COMPLAINS.
  268. X##    WHEN IT'S READ THE HEADER, IT EXITS; YOU DON'T NEED CONTROL-D.
  269. X
  270. Xmyname="`basename $0`"
  271. Xerr=/tmp/DISTPRe$$ header=/tmp/DISTPRd$$
  272. X> $header
  273. Xchmod 600 $header
  274. X
  275. Xstat=1    # DEFAULT EXIT STATUS; RESET TO 0 FOR NORMAL EXITS
  276. Xtrap 'rm -f $header $err; exit $stat' 0
  277. Xtrap 'echo "$myname: Interrupt!  Cleaning up..." 1>&2; exit' 1 2 15
  278. X
  279. Xif [ ! -w "$1" -o -z "$1" ]
  280. Xthen
  281. X    echo 1>&2 "$myname: quitting: missing or unwritable draft
  282. X    '$1'"
  283. X    exit
  284. Xfi
  285. X
  286. X# READ DRAFT (A COPY OF distcomps FILE) LINE-BY-LINE.
  287. X# ACT LIKE prompter, BUT EXIT AFTER WE'VE READ DRAFT FILE
  288. X# (WHEN YOU USE dist, THE DRAFT FILE IS ONLY A HEADER).
  289. Xwhile read label line
  290. Xdo
  291. X    case "$label" in
  292. X    [Rr]esent-?*:)
  293. X        case "$line" in
  294. X        ?*) # SHOW LINE ON SCREEN AND PUT INTO HEADER FILE:
  295. X            echo "$label $line"
  296. X            echo "$label $line" 1>&3
  297. X            ;;
  298. X        *)    # FILL IT IN OURSELVES:
  299. X            echo -n "$label "
  300. X            # stdin IS FROM DRAFT, SO READ DIRECTLY FROM tty:
  301. X            ans="`/usr/ucb/head -1 </dev/tty`"
  302. X            case "$ans" in
  303. X            "") ;;    # EMPTY; DO NOTHING
  304. X            *)    echo "$label $ans" 1>&3 ;;
  305. X            esac
  306. X            ;;
  307. X        esac
  308. X        ;;
  309. X    ""|---*) # END OF HEADER
  310. X        echo "-------" 1>&3
  311. X        break    # PROBABLY NOT NEEDED...
  312. X        ;;
  313. X    *)    echo "$myname: illegal header component
  314. X        '$label $line'" 1>&2
  315. X        break
  316. X        ;;
  317. X    esac
  318. Xdone <$1 2>$err 3>$header
  319. X
  320. X# IF THE ERROR FILE HAD SOMETHING IN IT, SHOW IT AND QUIT:
  321. Xif [ -s $err ]
  322. Xthen
  323. X    /bin/cat $err 1>&2
  324. X    echo "$myname: quitting." 1>&2
  325. Xelse
  326. X    if /bin/cp $header $1
  327. X    then stat=0
  328. X    else echo "$myname: can't replace draft '$1'?"
  329. X    fi
  330. Xfi
  331. Xexit
  332. X//E*O*F distprompter//
  333. chmod u=rwx,g=rx,o=rx distprompter
  334.  
  335. echo extracting - fixsubj
  336. sed 's/^X//' > "fixsubj" <<'X//E*O*F fixsubj//'
  337. X#! /bin/sh
  338. X# $Header: /u3/acs/jdpeek/.bin/RCS/fixsubj,v 1.9 90/10/13 10:01:45 jdpeek book $
  339. X#
  340. X###    fixsubj - fix (add or change) "Subject:" on a mail message
  341. X###    Usage: fixsubj [+folder] [msgnum [msgnums]] -s 'new subj'
  342. X##
  343. X##    SOME PEOPLE DON'T BOTHER TO PUT A Subject: LINE ON THEIR MAIL
  344. X##    MESSAGES.  THAT MAKES IT HARD, LATER, WHEN YOU scan YOUR MAIL.
  345. X##    fixsubj LETS YOU ADD YOUR OWN Subject: LINE TO MESSAGE(S).
  346. X##    YOU CAN USE THE SAME SUBJECT ON MANY MESSAGES BY GIVING ALL NUMBERS.
  347. X##
  348. X##    IF A MESSAGE ALREADY HAS A SUBJECT, fixsubj WILL TELL YOU
  349. X##    AND ASK YOU IF YOU WANT TO EDIT IT BY HAND, USE THE DEFAULT
  350. X##    FROM -s), OR SKIP IT.
  351. X##
  352. X##    TO USE IT, TYPE:
  353. X##        % fixsubj -s 'this is the subject'    (FOR THE CURRENT MESSAGE)
  354. X##    OR SOMETHING LIKE
  355. X##        % fixsubj +foo last -s 'a subject'    (last MESSAGE IN foo FOLDER)
  356. X##        % fixsubj -s 'my day' 23-25 42    (MESSAGES 23, 24, 25, AND 42)
  357. X##    ...AND SO ON.  THE SUBJECT, AFTER THE -s, SHOULD BE "ONE WORD" TO
  358. X##    THE SHELL... YOU'LL USUALLY NEED TO QUOTE IT.  YOU CAN PUT THE
  359. X##    OPTIONAL FOLDER NAME (STARTS WITH A +) AND MESSAGE NUMBERS (NUMBERS,
  360. X##    WORDS LIKE last, first:20, first-33, etc.) IN ANY ORDER.
  361. X
  362. Xeditor=${VISUAL-${EDITOR-/usr/ucb/vi}}   # TEXT EDITOR
  363. Xline="/usr/ucb/head -1"        # READS ONE LINE
  364. Xmh=/usr/local/mh            # WHERE MH COMMANDS LIVE
  365. Xmyname="`basename $0`"        # BASENAME OF THIS PROGRAM
  366. Xscanopts="-noclear -noheader -noreverse" # BYPASS MH PROFILE
  367. Xstat=1    # DEFAULT EXIT STATUS; SET TO 0 BEFORE NORMAL EXIT
  368. Xtemp=/tmp/FIXSUBJ$$
  369. Xtemperr=/tmp/FIXSUBJe$$        # HOLDS ERRORS FROM while LOOP
  370. Xusage="Usage: $myname [+folder] [msgnum] -s 'subject'"
  371. X
  372. Xtrap 'rm -f $temp $temperr; exit $stat' 0 1 2 15
  373. X> $temp
  374. X> $temperr
  375. Xchmod 600 $temp $temperr
  376. X
  377. X# PARSE COMMAND LINE:
  378. Xwhile :
  379. Xdo
  380. X    case "$1" in
  381. X    "")    break ;;    # NO MORE ARGUMENTS
  382. X    -help) echo "$usage" 1>&2; stat=0; exit ;;
  383. X    [@+]*) folder="$1"; shift ;;
  384. X    -s*)
  385. X        case "$2" in
  386. X        "")    echo "$usage
  387. X            (Missing subject.)" 1>&2
  388. X            exit
  389. X            ;;
  390. X        *)    newsubj="$2"
  391. X            shift; shift
  392. X            ;;
  393. X        esac
  394. X        ;;
  395. X    *)    msgs="$msgs $1"; shift ;;
  396. X    esac
  397. Xdone
  398. X
  399. Xcase "$newsubj" in
  400. X"")    echo "$usage
  401. X    (Missing subject.)" 1>&2
  402. X    exit
  403. X    ;;
  404. Xesac
  405. X
  406. X# FOLDER PATH; IF NO $folder GIVEN, DEFAULTS TO CURRENT:
  407. Xfolpath="`$mh/mhpath $folder`" || exit
  408. X
  409. X# MAKE LIST OF MESSAGE NUMBERS AND SUBJECTS, ONE PER LINE.
  410. X# IF NO Subject: IN MESSAGE, $subjnow WILL BE EMPTY.
  411. X# FEED INTO LOOP.  IF NO msgs ON COMMAND LINE, SET TO cur.
  412. X#
  413. X# sh WILL RUN THIS IN A SUB-SHELL, SO exit WILL ONLY END
  414. X# THE LOOP, NOT THE WHOLE SCRIPT.  WORK-AROUND: PUT INTERNAL
  415. X# ERRORS ON FILE DESCRIPTOR 3 AND COLLECT AT END OF LOOP:
  416. X$mh/scan $scanopts -width 200 -format "%(msg) %{subject}" ${msgs=cur} |
  417. Xwhile read msg subjnow
  418. Xdo
  419. X    msgpath=$folpath/$msg
  420. X
  421. X    # IF MESSAGE IS UNREADABLE, scan (MH6.6 AND BEFORE)
  422. X    # WILL PRINT A LINE (TO STANDARD OUTPUT!) LIKE THIS,
  423. X    # WITH LEADING BLANKS UNLESS msgnum > 999:
  424. X    #   <msgnum>  unreadable
  425. X    # IF THERE ARE LEADING BLANKS, SOME BOURNE SHELLS WILL
  426. X    # COPY BOTH THE MESSAGE NUMBER AND THE unreadable INTO
  427. X    # subjnow, AND LEAVE $msg EMPTY.  TRY TO FIX BOTH CASES:
  428. X    case "$msg" in
  429. X    "")    echo "$myname: quitting, message $msg $subjnow" 1>&3; break ;;
  430. X    esac
  431. X    case "$subjnow" in
  432. X    unreadable)
  433. X        echo "$myname: quitting: can't read message '$msg'." 1>&3
  434. X        break
  435. X        ;;
  436. X    "")    # GLUE Subject AND X-Original-Subject TO TOP.
  437. X        # IF YOUR SHELL DOESN'T UNDERSTAND "<<-", REPLACE IT
  438. X        # WITH "<<" AND SHIFT LINES TO LEFT-HAND EDGE:
  439. X        cat - $msgpath > $temp <<- ENDOFHDR
  440. X        Subject: $newsubj
  441. X        X-Original-Subject: (none)
  442. X        ENDOFHDR
  443. X        cp $temp $msgpath || {
  444. X            echo "$myname: quitting: can't replace ${msgpath}?" 1>&3
  445. X            break
  446. X        }
  447. X        ;;
  448. X    *)    # MESSAGE HAS A SUBJECT ALREADY; ASK USER:
  449. X        # LOOP UNTIL GET ANSWER:
  450. X        while :
  451. X        do
  452. X            # SAME NOTE AS ABOVE ABOUT REPLACING "<<-"...
  453. X            cat <<- ENDOFMSG
  454. X
  455. X            Message $msg already has a subject:
  456. X            ... $subjnow
  457. X            Type c to change subject to '$newsubj'
  458. X            Type e to edit the message yourself with $editor
  459. X            Type s to skip this message and go on to the next (if any)
  460. X            Type q to quit and not change any more messages.
  461. X            ENDOFMSG
  462. X            echo -n "And the answer is? " 1>&2
  463. X            ans="`$line </dev/tty`"
  464. X            case "$ans" in
  465. X            s*)    break ;; # CONTINUE OUTER (MESSAGE) LOOP
  466. X            q*)    break 2 ;;
  467. X            e*)    $editor $msgpath </dev/tty >/dev/tty 2>/dev/tty
  468. X                break
  469. X                ;;
  470. X            c*) # NOTE: FIX "<<-" AND LINES IF SHELL NEEDS:
  471. X                ed - $msgpath <<- !ENDOFEDIT! >$temp 2>&1
  472. X                /^Subject: /s/^/X-Original-/
  473. X                i
  474. X                Subject: $newsubj
  475. X                .
  476. X                w
  477. X                q
  478. X                !ENDOFEDIT!
  479. X                if [ ! -s $temp ]
  480. X                then break
  481. X                else
  482. X                    echo "$myname: error editing '$msg':" 1>&2
  483. X                    cat "$temp" 1>&2
  484. X                    echo "Should you edit it by hand?  Try again:
  485. X                    " 1>&2
  486. X                fi
  487. X                ;;
  488. X            *)    echo "Please try again..." 1>&2 ;;
  489. X            esac    # END OF case "$ans"
  490. X        done        # END OF while :
  491. X        ;;
  492. X    esac            # END OF case "$subjnow"
  493. Xdone 3> $temperr    # END OF while read msg subjnow
  494. X
  495. Xif test -s $temperr
  496. Xthen cat $temperr 1>&2
  497. Xelse stat=0
  498. Xfi
  499. Xexit
  500. X//E*O*F fixsubj//
  501. chmod u=rwx,g=rx,o=rx fixsubj
  502.  
  503. echo extracting - fols
  504. sed 's/^X//' > "fols" <<'X//E*O*F fols//'
  505. X#! /bin/sh
  506. X# $Header: /u3/acs/jdpeek/.bin/RCS/fols,v 1.7 90/10/13 08:45:31 jdpeek book $
  507. X###    fols - Show list of folders, in columns, current folder marked
  508. X###    Usage: fols [ -recurse ]  << (just -r is enough...)
  509. X##
  510. X##    THE folder -fast PROGRAM GIVES A LIST OF YOUR TOP-LEVEL FOLDERS
  511. X##    IN ONE COLUMN.  IF YOU HAVE A LOT OF FOLDERS, THIS CAN BE A PAIN
  512. X##    BECAUSE THE LIST CAN SCROLL OFF YOUR SCREEN.  fols REFORMATS THE
  513. X##    folder -fast OUTPUT INTO FOUR COLUMNS.  IT MARKS THE CURRENT FOLDER
  514. X##    WITH A +.  IF ANY FOLDER NAMES ARE TOO LONG FOR A COLUMN, IT
  515. X##    CUTS OUT THE MIDDLE OF THE NAME AND REPLACES IT WITH AN "=".
  516. X##
  517. X##    BY DEFAULT, fols ONLY SHOWS THE TOP-LEVEL FOLDERS.  THE -r SWITCH
  518. X##    MAKES IT RECURSIVE, LIKE folder -recurse -fast.
  519. X##
  520. X##    HERE'S AN EXAMPLE.  THE EXAMPLE WITH -r SHOWS A SET OF SUB-FOLDERS
  521. X##    NINE LEVELS DEEP, STARTING WITH A SUB-FOLDER NAMED test/l1:
  522. X##
  523. X##    % fols
  524. X##    drafts             haha               inbox+             scans
  525. X##    scantest           test               test2              test3
  526. X##    % fols -r
  527. X##    drafts             haha               haha/sub           inbox+
  528. X##    scans              scantest           test               test/MaIlSoRt9818
  529. X##    test/haha          test/l1            test/l1/l2         test/l1/l2/l3
  530. X##    test/l1/l2/l3/l4   test/l1/=/l3/l4/l5 test/l1/=/l4/l5/l6 test/l1/=/l5/l6/l7
  531. X##    test/l1/=/l6/l7/l8 test/l1/=/l7/l8/l9 test2              test3
  532. X
  533. Xfolopts="-fast -nolist -nototal -nopack" # OVERRIDE MH PROFILE
  534. Xmh=/usr/local/mh  # WHERE MH COMMMANDS ARE
  535. Xrec=
  536. X
  537. Xcase "$#$1" in
  538. X0"") ;;
  539. X1-r*) rec=-recurse ;;
  540. X*)    echo "Usage: `basename $0` [ -recurse ] (just -r is enough)" 1>&2
  541. X    exit 1
  542. X    ;;
  543. Xesac
  544. X
  545. X# USE BACKQUOTES TO "PASTE" THE CURRENT FOLDER NAME
  546. X# INTO THE sed EXPRESSION THAT ADDS A + TO END.
  547. X# THEN, IN ANY LINE WHICH HAS AT LEAST 19 CHARACTERS,
  548. X# SAVE FIRST 8 AND LAST 9 CHARACTERS AND REPLACE
  549. X# MIDDLE CHARACTER(S) WITH AN = SIGN.  FINALLY, GIVE
  550. X# TO pr WITH LINE LENGTH OF 1 TO MAKE INTO 4 COLUMNS:
  551. X$mh/folders $rec $folopts |
  552. X/bin/sed -e "s@^`$mh/folder $folopts`\$@&+@" \
  553. X    -e 's/^\(........\)...*\(.........\)$/\1=\2/' |
  554. X/bin/pr -l1 -4 -w78 -t
  555. X//E*O*F fols//
  556. chmod u=rwx,g=rx,o=rx fols
  557.  
  558. echo extracting - incs
  559. sed 's/^X//' > "incs" <<'X//E*O*F incs//'
  560. X#! /bin/sh
  561. X#    $Header: /u1/acs/jdpeek/.bin/RCS/incs,v 1.9 90/07/03 07:18:22 jdpeek Exp $
  562. X#
  563. X###    incs - incorporate messages, then show them
  564. X###    Usage: incs [+folder] [-inc options]
  565. X##
  566. X##    incs DOES AN inc, THEN A show OF ALL MESSAGES inc'D.  IF YOU SET THE
  567. X##    ENVIRONMENT VARIABLE $INCSHOW TO THE NAME OF A PROGRAM (LIKE
  568. X##    mail.review), THEN incs WILL USE IT INSTEAD OF show.
  569. X##
  570. X##    IF YOU GIVE IT A FOLDER NAME, LIKE THIS:
  571. X##        % incs +newmail
  572. X##    IT'LL INCORPORATE THE MAIL INTO THE FOLDER YOU NAME (HERE, newmail).
  573. X
  574. Xumask 077    # MAKE TEMP FILE PRIVATE
  575. Xtemp=/tmp/INCS$$
  576. Xinc=/usr/local/mh/inc
  577. Xstat=1    # DEFAULT EXIT STATUS; RESET TO 0 ON NORMAL EXIT
  578. Xtrap 'rm -f $temp; exit $stat' 0 1 2 15
  579. X
  580. X# ONLY SHOW MESSAGE IF inc ACTUALLY INCORPORATED ONE.
  581. X# BE SURE inc CHANGES CURRENT MESSAGE (OVERRIDE .mh_profile):
  582. Xif $inc -changecur $* > $temp
  583. Xthen
  584. X    cat $temp
  585. X    ${INCSHOW-show} cur-last
  586. X    stat=0
  587. Xfi
  588. X//E*O*F incs//
  589. chmod u=rwx,g=rx,o=rx incs
  590.  
  591. echo extracting - mhprofile
  592. sed 's/^X//' > "mhprofile" <<'X//E*O*F mhprofile//'
  593. X#! /bin/sh
  594. X# $Header: /u3/acs/jdpeek/.bin/RCS/mhprofile,v 1.4 90/10/13 08:41:27 jdpeek book $
  595. X#
  596. X###    mhprofile - show matching line(s) from MH profile file
  597. X###    Usage: mhprofile [-b] component-name
  598. X##
  599. X##    USE mhprofile TO READ A LINE FROM THE .mh_profile FILE.
  600. X##    FOR EXAMPLE, IF YOU WANT TO READ THE "DRAFT-FOLDER" LINE, TYPE:
  601. X##        $ mhprofile draft-folder
  602. X##        Draft-Folder: drafts
  603. X##    THE -b OPTION STRIPS OFF THE COMPONENT NAME.  EXAMPLE:
  604. X##        $ mhprofile -b draft-folder
  605. X##        drafts
  606. X##
  607. X##    RETURNS 0 IF MATCH FOUND, 1 IF NO MATCHES, 2 ON ERRORS
  608. X
  609. Xgrep=/bin/grep    # HAS -i OPTION, HANDLES REGULAR EXPRESSIONS
  610. Xsed=/bin/sed
  611. Xprofile=${MH-${HOME?}/.mh_profile}  # COMPLAIN AND EXIT IF $HOME NOT SET
  612. X
  613. X# GET -b OPTION, IF ANY, AND shift IT AWAY:
  614. Xcase "$1" in
  615. X-b)    stripname=y; shift;;
  616. X-*)    echo "Usage: `basename $0` [-b] component-name
  617. X    (I don't understand '$1')." 1>&2
  618. X    exit 2
  619. X    ;;
  620. Xesac
  621. X
  622. X# ONLY REMAINING ARGUMENT SHOULD BE A COMPONENT NAME:
  623. Xcase $# in
  624. X1)    ;;
  625. X*)    echo "Usage: `basename $0` [-b] component-name
  626. X    (wrong number of arguments)." 1>&2
  627. X    exit 2
  628. X    ;;
  629. Xesac
  630. X
  631. X# IF grep FAILS, RETURN ITS STATUS (1=NO MATCH, 2=ERROR):
  632. Xlines="`$grep -i \"^${1}:\" $profile`" || exit
  633. X
  634. X# IF -b SET, USE sed TO SEARCH AND STRIP OFF LABEL+BLANKS.
  635. X# ASSUME NO BLANKS IN NAME, ":" AND MAYBE BLANKS AFTER NAME:
  636. Xcase "$stripname" in
  637. Xy)    echo "$lines" | $sed -n 's/^[^:]*: *//p' ;;
  638. X*)    echo "$lines" ;;
  639. Xesac
  640. Xexit 0    # A LITTLE PRESUMPTUOUS?
  641. X//E*O*F mhprofile//
  642. chmod u=rwx,g=rx,o=rx mhprofile
  643.  
  644. echo extracting - recomp
  645. sed 's/^X//' > "recomp" <<'X//E*O*F recomp//'
  646. X#! /bin/sh
  647. X# $Header: /u3/acs/jdpeek/.bin/RCS/recomp,v 1.6 90/10/13 08:25:07 jdpeek book $
  648. X###    recomp - re-compose a draft mesage in MH draft folder
  649. X###    Usage: recomp [msgnum]
  650. X#
  651. X##    WHEN YOU TYPE q AT A What now? PROMPT, IT LEAVES THE DRAFT MESSAGE
  652. X##    WITHOUT SENDING IT.  IF YOU HAVE A DRAFT FOLDER, THE COMMAND LINE
  653. X##    YOU'D TYPE TO RE-COMPOSE THE DRAFT IS LONG, LIKE:
  654. X##        comp -use -draftm 3 -draftf +drafts -editor vi.
  655. X##    ALSO, IT CAN BE HARD TO REMEMBER THE DRAFT NUMBER--SO YOU HAVE TO
  656. X##    scan THE DRAFT FOLDER, THEN REMEMBER TO CHANGE YOUR FOLDER BACK.
  657. X##    
  658. X##    THIS SCRIPT HELPS WITH THAT.  IF YOU GIVE IT A MESSAGE NUMBER IN THE
  659. X##    DRAFT FOLDER, IT STARTS comp -use ON THAT MESSAGE WITH YOUR FAVORITE
  660. X##    EDITOR PROGRAM.  WITHOUT A MESSAGE NUMBER, recomp scanS THE DRAFT
  661. X##    FOLDER, THEN LETS YOU ENTER THE NUMBER OF THE MESSAGE YOU WANT TO
  662. X##    RE-COMPOSE AND STARTS comp -use.
  663. X##
  664. X##    WHEN YOU EXIT YOUR EDITOR, YOU GET THE USUAL What now? PROMPT.
  665. X
  666. Xdraftf=+drafts    # NAME OF DRAFT FOLDER
  667. Xfolopts="-fast -norecurse -nolist -nototal -nopack"
  668. Xmh=/usr/local/mh    # WHERE MH PROGRAMS LIVE
  669. X
  670. X# THIS CAN LEAVE US IN THE $draftf FOLDER.  SO, PUSH
  671. X# CURRENT FOLDER ON STACK AND COME BACK AFTER EDITING:
  672. X$mh/folder -push $folopts $draftf >/dev/null || {
  673. X    echo "`basename $0`: quitting: problem with draft folder '$draftf'." 1>&2
  674. X    exit 1
  675. X}
  676. Xstat=1   # DEFAULT EXIT STATUS; RESET TO 0 FOR NORMAL EXITS
  677. Xtrap '$mh/folder -pop $folopts >/dev/null; exit $stat' 0
  678. Xtrap 'echo "`basename $0`: Interrupt!  Cleaning up..." 1>&2' 1 2 15
  679. X
  680. Xcase $# in
  681. X0)    # THEY DIDN'T GIVE MESSAGE NUMBER; SHOW THEM FOLDER:
  682. X    if $mh/scan
  683. X    then
  684. X        echo -n "Which draft message number do you want to re-edit? "
  685. X        read msgnum
  686. X    else
  687. X        echo "`basename $0`: quitting: no messages in your $draftf folder?" 1>&2
  688. X        exit
  689. X    fi
  690. X    ;;
  691. X1)    msgnum="$1" ;;
  692. X*)    echo "I don't understand '$*'.
  693. X    I need the draft message number, if you know it... otherwise, nothing.
  694. X    Usage: `basename $0` [msgnum]" 1>&2
  695. X    exit
  696. X    ;;
  697. Xesac
  698. X
  699. X$mh/comp -use -e ${VISUAL-${EDITOR-${EDIT-vi}}} -draftm $msgnum -draftf $draftf
  700. Xstat=$?   # SAVE comp'S STATUS (IT'S USUALLY 0) FOR OUR exit
  701. X//E*O*F recomp//
  702. chmod u=rwx,g=rx,o=rx recomp
  703.  
  704. echo extracting - replf
  705. sed 's/^X//' > "replf" <<'X//E*O*F replf//'
  706. X#! /bin/sh
  707. X# $Header: /u3/acs/jdpeek/.bin/RCS/replf,v 1.3 90/10/13 08:31:54 jdpeek book $
  708. X###    replf - refile current message into folder, then reply to it
  709. X###    Usage: replf +folder [switches for repl]
  710. X##
  711. X##    DO YOU USE MH FOLDERS A LOT?  YOU PROBABLY inc MAIL INTO YOUR inbox,
  712. X##    THEN YOU replY TO SOME MESSAGES AND refile THE ORIGINALS INTO SOME
  713. X##    OTHER FOLDER.  THE PROBLEM IS THAT IF YOU USE AN Fcc: LINE TO PUT
  714. X##    A COPY OF THE REPLY IN THE DESTINATION FOLDER, IT IS STORED BEFORE
  715. X##    THE ORIGINAL MESSAGE.  ALSO, IT'S A PAIN TO refile THE ORIGINAL,
  716. X##    THEN TYPE THE SAME NAME ON THE Fcc LINE.  SO, IT'D BE CONVENIENT
  717. X##    TO DO ALL THAT IN ONE STEP.  replf LETS YOU DO THAT.
  718. X##
  719. X##    replf USES refile TO MOVE THE *CURRENT* MESSAGE INTO THE FOLDER YOU
  720. X##    NAME.  (IT ONLY WORKS FOR THE CURRENT MESSAGE!)  THEN, IT STARTS
  721. X##    repl WITH THE -fcc +folder SWITCH, SO THAT AN Fcc: OF YOUR MESSAGE
  722. X##    WILL GO INTO THAT FOLDER, TOO.
  723. X##
  724. X##    WATCH OUT: THIS VERSION OF replf HAS ONE PROBLEM:  YOU CAN'T USE
  725. X##        What now? push 
  726. X##    TO SEND THE DRAFT.  THAT'S BECAUSE THE TEMPORARY FILES replf MAKES
  727. X##    ARE REMOVED BEFORE THE MESSAGE IS SENT.  USE send INSTEAD.
  728. X#
  729. X#    Original from Marshall T. Rose and John L. Romine in
  730. X#    MH6.6 distribution.  Revised by Jerry Peek, 2/25/90.
  731. X
  732. Xcontext=/tmp/ctx$$    # COPY OF MH context FILE
  733. Xmh=/usr/local/mh    # WHERE MH COMMANDS LIVE
  734. Xprofile=/tmp/prf$$    # COPY OF .mh_profile FILE
  735. Xstat=1    # DEFAULT EXIT STATUS; RESET TO 0 BEFORE NORMAL exit
  736. X
  737. X/bin/rm -f $profile $context
  738. Xtrap '/bin/rm -f $profile $context; exit $stat' 0 1 2 15
  739. X
  740. X# PARSE COMMAND LINE:
  741. Xfolder=   switches=
  742. Xfor arg
  743. Xdo
  744. X    case "$arg" in
  745. X    +*|@*) # IT'S A FOLDER
  746. X        case "$folder" in
  747. X        "")    folder="$arg" ;;
  748. X        *)    echo "`basename $0`: '$arg'?  Only one folder at a time." 1>&2
  749. X            exit
  750. X            ;;
  751. X        esac
  752. X        ;;
  753. X    *)    switches="$switches $arg" ;;
  754. X    esac
  755. Xdone
  756. X
  757. Xcase "$folder" in
  758. X"")    echo "usage: `basename $0` +folder [switches for repl]" 1>&2
  759. X    exit
  760. X    ;;
  761. Xesac
  762. X
  763. X# MAKE TEMPORARY context AND .mh_profile FILES.
  764. X# THEN, RESET $MH AND $MHCONTEXT UNTIL END OF THIS SCRIPT:
  765. X/bin/cp ${MHCONTEXT-`$mh/mhpath +`/context} $context || exit
  766. X# READ NEXT TWO LINES, PLUS A COPY OF USER'S STANDARD
  767. X# .mh_profile, INTO NEW $profile:
  768. X/bin/cat - ${MH-$HOME/.mh_profile} << \END > $profile || exit
  769. XMH-Sequences:
  770. XPrevious-Sequence: pseq
  771. XEND
  772. X
  773. XMH=$profile MHCONTEXT=$context
  774. Xexport MH MHCONTEXT
  775. X
  776. X# REFILE MESSAGE INTO $folder.
  777. X# NEW MESSAGE NUMBER IS IN THE pseq OF $folder.
  778. X$mh/refile $folder || exit
  779. X$mh/repl $folder pseq -fcc $folder $switches
  780. Xstat=$?        # EXIT WITH STATUS OF repl
  781. Xexit
  782. X//E*O*F replf//
  783. chmod u=rwx,g=rx,o=rx replf
  784.  
  785. echo extracting - resend.fixmsg
  786. sed 's/^X//' > "resend.fixmsg" <<'X//E*O*F resend.fixmsg//'
  787. X#! /bin/sh
  788. X# $Header: /u3/acs/jdpeek/.bin/RCS/resend.fixmsg,v 1.5 90/10/13 09:39:23 jdpeek book $
  789. X###    resend.fixmsg - editor for fixing up returned mail
  790. X###    Usage in .mh_profile:   resend: -editor resend.fixmsg -nodashmunging
  791. X##
  792. X##    TO USE THIS, FIRST MAKE A VERSION OF forw NAMED resend
  793. X##    (MAKE SYMBOLIC LINK TO forw, ETC.).  THEN, ADD THE ENTRY
  794. X##    SHOWN ABOVE TO YOUR .mh_profile.
  795. X##
  796. X##    WHEN YOU START resend, IT BUILDS A DRAFT AND CALLS
  797. X##    resend.fixmsg TO EDIT IT.  resend.fixmsg MAKES THE MESSAGE
  798. X##    LOOK ALMOST EXACTLY AS IT DID THE FIRST TIME YOU COMPOSED
  799. X##    IT, THEN POPS YOU INTO AN EDITOR (DEFAULT: vi) TO FIX THE
  800. X##    ADDRESS.
  801. X
  802. X# $1 IS PATH TO DRAFT MESSAGE (forw SETS THIS).
  803. X# 
  804. X# HERE'S WHAT ed SCRIPT DOES TO THE DRAFT THAT forw BUILT:
  805. X# DELETE LINES THROUGH FIRST "To: (you)".
  806. X# DELETE LINES TO BUT NOT INCLUDING NEXT "To: (original)".
  807. X# ZAP Date:/From:/Sender: LINES THAT MAILER PUT IN MESSAGE.
  808. X# ZAP FROM BLANK LINE BEFORE "---- End of Forwarded Message"
  809. X# THROUGH THE END OF THE FILE.
  810. X/bin/ed - $1 << "END"
  811. X1,/^To: /d
  812. X1,/^To: /-1d
  813. X1,/^$/g/^Date: /d
  814. X1,/^$/g/^From: /d
  815. X1,/^$/g/^Sender: /d
  816. X$
  817. X?^------- End of Forwarded Message?-1,$d
  818. Xw
  819. Xq
  820. XEND
  821. X
  822. X# EDIT WITH $EDITOR (DEFAULT: vi).  exec TO SAVE A PROCESS:
  823. Xexec ${EDITOR-vi} $1
  824. X//E*O*F resend.fixmsg//
  825. chmod u=rwx,g=rx,o=rx resend.fixmsg
  826.  
  827. echo extracting - rmmer
  828. sed 's/^X//' > "rmmer" <<'X//E*O*F rmmer//'
  829. X#! /bin/sh
  830. X# $Header: /u3/acs/jdpeek/.bin/RCS/rmmer,v 3.4 90/11/21 06:52:02 jdpeek Exp $
  831. X###    rmmer - move mail to @DELETE for "find" to clean up
  832. X###    Usage in .mh_profile:    rmmproc: rmmer
  833. X###    rmmer.one_fdr - move mail to +DELETE for "find" to clean up
  834. X###    Usage in .mh_profile:    rmmproc: rmmer.one_fdr
  835. X##
  836. X##    rmmer IS DESIGNED TO BE USED WITH THE MH MAIL rmm COMMAND.
  837. X##    INSTEAD OF JUST ADDING A COMMA (,) TO THE MESSAGE NAME, LIKE
  838. X##    STANDARD rmm DOES, rmmer MOVES THE MESSAGE INTO A SUB-FOLDER
  839. X##    NAMED "DELETE".  A SYSTEM PROGRAM SHOULD CLEAN OUT THAT FOLDER
  840. X##    EVERY SO OFTEN (YOU MAY HAVE TO SET THAT UP, TOO).  ANYHOW,
  841. X##    THE IDEA IS THAT MESSAGES IN A "DELETE" SUB-FOLDER ARE EASY TO
  842. X##    RECOVER IF YOU REMOVED ONE BY ACCIDENT.
  843. X##
  844. X##    FOR EXAMPLE, LET'S SAY YOU JUST DELETED A MESSAGE BY ACCIDENT.
  845. X##    TO GET IT BACK, YOU GO TO THE SUB-FOLDER.  YOUR MESSAGE WILL
  846. X##    BE THE LAST ONE IN THE SUB-FOLDER BECAUSE YOU JUST REMOVED IT.
  847. X##    TO RECOVER THE DELETED MESSAGE, MOVE IT BACK TO THE PARENT FOLDER
  848. X##    (WHERE IT WAS BEFORE) WITH refile.  AFTER YOU RECOVER IT, IT'LL
  849. X##    BE THE LAST MESSAGE IN THE FOLDER.  HERE GOES:
  850. X##        % rmm
  851. X##        % show last @DELETE
  852. X##        (Message inbox/DELETE:25)
  853. X##            (message appears -- this is the one you "deleted")
  854. X##        % refile @..
  855. X##        % show last @..
  856. X##        (Message inbox:54)
  857. X##            (same message appears -- now it's back in the parent folder)
  858. X##
  859. X##    IF YOU DON'T WANT rmmer TO USE A SUB-FOLDER--AND, INSTEAD, PUT
  860. X##    ALL THE MESSAGES IN A CENTRAL "DELETE" FOLDER--YOU CAN CALL THE
  861. X##    PROGRAM WITH THE NAME rmmer.one_fdr AND THAT'LL DO IT.
  862. X
  863. X# TABSTOPS ARE SET AT 4 IN THIS CODE
  864. X
  865. Xtempchr=','         # CHARACTER rmm ADDS TO "REMOVE" MESSAGE
  866. Xmh=/usr/local/mh    # MH COMMANDS ARE IN THIS DIRECTORY
  867. Xmoveto=DELETE        # NAME OF FOLDER FOR DELETED MESSAGES
  868. Xmvdir=/bin            # DIRECTORY WHERE mv COMMAND LIVES
  869. X
  870. Xawk=/bin/awk  mkdir=/bin/mkdir  touch=/bin/touch  tr=/bin/tr
  871. X
  872. X# USE PROGRAM NAME TO SET PATH TO DESTINATION FOLDER:
  873. Xcase "$0" in
  874. X*rmmer) destfol="@$moveto" ;;
  875. X*rmmer.one_fdr) destfol="+$moveto" ;;
  876. X*)    echo "$0 aborting: can't find my name." 1>&2; exit 1 ;;
  877. Xesac
  878. X
  879. Xstat=1    # DEFAULT EXIT STATUS; RESET TO 0 BEFORE NORMAL EXIT
  880. Xtrap 'rm -f $MH; exit $stat' 0
  881. Xtrap 'echo "$0: Interrupt!  $* may not be removed." 1>&2; exit' 1 2 15
  882. X
  883. X# TO AVOID ENDLESS LOOPS WHERE THE rmm IN rmmer RUNS rmmproc,
  884. X# MAKE TEMPORARY .mh_profile TO BYPASS USER'S rmmproc: rmmer.
  885. X# MAKE WHILE MH IS SHELL VARIABLE, THEN export TO USE IT:
  886. XMH=/tmp/RMMER$$
  887. Xecho "Path: `$mh/mhpath +`" > $MH || exit
  888. Xexport MH
  889. X
  890. X# rmm SETS CURRENT DIRECTORY TO FOLDER, SO IT'S EASY TO MAKE
  891. X# NEW SUB-FOLDER.  (LET USER MAKE THEIR OWN "+DELETE" ONCE.)
  892. Xif [ "$destfol" = "@$moveto" -a ! -d "$moveto" ]
  893. Xthen $mkdir $moveto || exit
  894. Xfi
  895. X
  896. X# rmm PUTS SINGLE MESSAGE NUMBERS INTO $* (LIKE 12 13 14).
  897. X# UPDATE LAST-MOD TIME SO find -mtime WON'T DELETE TOO SOON:
  898. X$touch $* >/dev/null 2>&1
  899. X
  900. X$mh/rmm $* || exit    # ADDS $tempchr TO MESSAGE NUMBERS
  901. X
  902. X# IF <= 7 MESSAGES, REFILE EACH WITH mv AND mhpath new.
  903. X# OTHERWISE, SAVE TIME BY GETTING FIRST UNUSED MESSAGE NUMBER
  904. X# IN $destfol AND USING PLAIN mv COMMANDS IN A LOOP:
  905. Xcase $# in
  906. X[1-7])
  907. X    for m
  908. X    do $mvdir/mv ${tempchr}$m `$mh/mhpath new $destfol` || exit
  909. X    done
  910. X    ;;
  911. X*)    newpath="`$mh/mhpath new $destfol`" || exit    # FIRST MSG.
  912. X    PATH=${mvdir}:$PATH; export PATH    # GET THE RIGHT mv
  913. X    # GIVE awk NUMBERS LIKE 23 24, SPLIT ONTO SEPARATE LINES
  914. X    # BY TURNING SPACES INTO NEWLINES.  OUTPUT mv COMMANDS
  915. X    # THAT THE SHELL READS (BY eval) AND RUNS, LIKE THIS:
  916. X    #    mv ,23 /xxx/Mail/inbox/DELETE/99;
  917. X    #    mv ,24 /xxx/Mail/inbox/DELETE/100;
  918. X    # **HUGE** MESSAGE LISTS MAY CAUSE LONG-LINE PROBLEMS.
  919. X    eval `
  920. X    echo $* | $tr ' ' '\012' | $awk '
  921. X    BEGIN {
  922. X        # SPLIT PATH OF FIRST UNUSED MESSAGE INTO part ARRAY:
  923. X        np = split("'$newpath'", part, "/")
  924. X        # BUILD ALL BUT THE LAST PIECE INTO DIRECTORY NAME:
  925. X        for (i = 2; i < np; i++)
  926. X            dir = dir "/" part[i]
  927. X        # LAST part IS FIRST NEW MESSAGE NUMBER; PUT IN new.
  928. X        # MAKE SURE awk TREATS AS INTEGER BY ADDING ZERO:
  929. X        new = part[np] + 0
  930. X    }
  931. X    {
  932. X        # READ MESSAGE NUMBERS, OUTPUT COMMANDS:
  933. X        printf "mv ,%d %s/%d;", $1, dir, new++
  934. X    }'`
  935. X    ;;
  936. Xesac
  937. X
  938. Xstat=0
  939. Xexit
  940. X//E*O*F rmmer//
  941. chmod u=rwx,g=rx,o=rx rmmer
  942.  
  943. echo extracting - scandrafts
  944. sed 's/^X//' > "scandrafts" <<'X//E*O*F scandrafts//'
  945. X#! /bin/sh
  946. X#    $Header: /u3/acs/jdpeek/.bin/RCS/scandrafts,v 1.5 90/10/13 09:08:29 jdpeek book $
  947. X###    scandrafts - scan MH draft folder; return to original folder if no -stay
  948. X###    Usage: scandrafts [-stay] [scan arguments]
  949. X##
  950. X##    THIS SCRIPT IS NICE WHEN YOU'RE WONDERING WHAT'S IN YOUR DRAFT
  951. X##    FOLDER, OR YOU NEED TO WORK IN IT.
  952. X##    
  953. X##    BY DEFAULT, scandrafts SHOWS A LIST OF THE MESSAGES YOU'VE ALREADY
  954. X##    SENT (THESE MESSAGES ARE IN FILES WITH A COMMA OR POUND SIGN BEFORE
  955. X##    THEIR NAMES).  THEN, IT  scanS YOUR DRAFT FOLDER, AND POPS YOU BACK
  956. X##    TO YOUR CURRENT FOLDER.
  957. X##    
  958. X##    IF YOU USE THE -stay OPTION, scandrafts WILL START A SHELL WITH
  959. X##    BOTH THE CURRENT DIRECTORY AND CURRENT FOLDER IN THE DRAFT FOLDER.
  960. X##    THAT WAY, YOU CAN RESTORE ONE OF THE ALREADY-SENT MESSAGES AND/OR
  961. X##    refile IT TO ANOTHER FOLDER (IN CASE YOU FORGOT TO GIVE YOURSELF A
  962. X##    COPY WHEN YOU SENT IT).  OR, YOU CAN DO EXTENSIVE WORK ON THE
  963. X##    DRAFTS, MORE DIRECTLY THAN A SCRIPT LIKE recomp WILL LET YOU.
  964. X##    
  965. X##    HERE'S A DEMONSTRATION:
  966. X##    
  967. X##    $ scandrafts -stay 
  968. X##    Draft message(s) you've already sent:
  969. X##    
  970. X##    ,1:Subject: Re: SC or GA islands
  971. X##    ,5:Subject: Re: our previous message about banners dialups etc
  972. X##    ,6:Subject: Re: Can you help?
  973. X##    ,7:Subject: Out this morning
  974. X##    
  975. X##    To get them back, use 'mv'.
  976. X##    ===================================================================
  977. X##    Draft message(s) you haven't sent:
  978. X##    
  979. X##       1  03/07*To:alison@mvus.cs  Project status<<Alison, the project
  980. X##       2  empty
  981. X##       3+ 03/07*To:kx9cq@cornell.  Scientific Visualization Demo<<I re
  982. X##    
  983. X##        You'll be in a /usr/local/bin/ksh shell in the +drafts folder.
  984. X##        To quit, type control-d.
  985. X##    scandrafts> rmm 2 
  986. X##    scandrafts> mv ,6 6 
  987. X##    scandrafts> scan 
  988. X##       1  03/07*To:alison@mvus.cs  Project status<<Alison, the project
  989. X##       3+ 03/07*To:kx9cq@cornell.  Scientific Visualization Demo<<I re
  990. X##       6  03/04*To:warren          Re: Can you help?<<Warren, you aske
  991. X##    scandrafts> refile 6 +outbox 
  992. X##    scandrafts> ^D 
  993. X##    [folder +inbox now current]
  994. X##    $
  995. X
  996. Xargs=    # RESET IN CASE THERE'S AN args ENVIRONMENT VARIABLE
  997. Xfolopts="-fast -nolist -nototal -nopack"
  998. Xmh=/usr/local/mh
  999. Xmhprf=/XXXXXXXXXXXXXXXXXX/mhprofile   # READS MH PROFILE
  1000. Xpageprog=${PAGER-/usr/ucb/more}    # DISPLAYS SCREEN-BY-SCREEN
  1001. Xstat=1    # DEFAULT EXIT STATUS; RESET TO 0 FOR NORMAL EXITS
  1002. Xtemp=/tmp/SCANDRFTS$$
  1003. X>$temp
  1004. Xchmod 600 $temp
  1005. Xtrap 'rm -f $temp; exit $stat' 0 1 2 15
  1006. X
  1007. X# IF -stay SWITCH IS SET, SET $stay TO y:
  1008. Xfor arg
  1009. Xdo
  1010. X    case "$arg" in
  1011. X    -stay)    stay=y ;;
  1012. X    *)    args="$args $arg" ;;
  1013. X    esac
  1014. Xdone
  1015. X
  1016. X# GET DRAFT FOLDER NAME:
  1017. Xdraftfold="`$mhprf -b draft-folder`" || {
  1018. X    echo "`basename $0`: quitting: can't find your 'Draft-Folder'." 1>&2
  1019. X    exit
  1020. X}
  1021. X
  1022. X$mh/folder $folopts -push +$draftfold >/dev/null || exit
  1023. Xfolpath=`$mh/mhpath +$draftfold` || exit
  1024. Xcd $folpath || exit
  1025. X
  1026. X# IF ANY UN-SENT DRAFTS, SHOW THEM; THEN, scan FOLDER.
  1027. X# PIPE ALL OF IT TO PAGER SO NONE OF IT SCROLLS OFF SCREEN:
  1028. Xgrep "^Subject: " [,#]*[1-9]* >$temp 2>/dev/null
  1029. X(if test -s $temp
  1030. Xthen
  1031. X    echo "Draft message(s) you've already sent:
  1032. X    "
  1033. X    cat $temp
  1034. X    echo
  1035. X    case "$stay" in
  1036. X    y) echo "To get them back, use 'mv'." ;;
  1037. X    *) echo "To get them back, use 'cd $folpath' and 'mv'." ;;
  1038. X    esac
  1039. X    echo "============================================================="
  1040. X    echo "Draft message(s) you haven't sent:
  1041. X    "
  1042. Xfi
  1043. X$mh/scan $args 2>&1) | $pageprog
  1044. X
  1045. X# USE THEIR $SHELL, IF DEFINED... OTHERWISE, USE sh:
  1046. Xcase "$stay" in
  1047. Xy) echo "
  1048. X    You'll be in a ${SHELL-Bourne} shell in the +$draftfold folder.
  1049. X    To quit, type control-d."
  1050. X    PS1="scandrafts> " ${SHELL-sh}
  1051. X    ;;
  1052. Xesac
  1053. X
  1054. X# POP FOLDER BACK; PUT NEWLINE BEFORE MESSAGE:
  1055. Xecho "
  1056. X[folder +`$mh/folder $folopts -pop` now current]"
  1057. Xstat=0
  1058. X//E*O*F scandrafts//
  1059. chmod u=rwx,g=rx,o=rx scandrafts
  1060.  
  1061. echo extracting - showpr
  1062. sed 's/^X//' > "showpr" <<'X//E*O*F showpr//'
  1063. X#! /bin/sh
  1064. X# $Header: /u3/acs/jdpeek/.bin/RCS/showpr,v 2.2 90/10/13 10:30:57 jdpeek book $
  1065. X###    showpr - show MH message(s) with pr(1), custom heading, maybe mhl(1)
  1066. X###    Usage: showpr [fdr] [msgs] [-mhl] [-format 'mh-format-str'] [-pr 'pr-opts']
  1067. X##
  1068. X##    THE EASY WAY TO PRINT MESSAGES IN MH ISN'T ESPECIALLY GREAT.  YOU CAN
  1069. X##    PRINT YOUR MAIL MESSAGES LIKE THIS (ASSUMING YOUR PRINTER PROGRAM IS
  1070. X##    NAMED lpr), BUT ALL THE MESSAGES WILL BE RUN TOGETHER:
  1071. X##        % show 23 24 29 | lpr
  1072. X##    OR, YOU CAN USE pr(1) TO MAKE SIMPLE HEADERS (WITH THE FOLDER AND
  1073. X##    MESSAGE NUMBER), PAGE NUMBERS, AND START EACH MESSAGE ON A NEW PAGE:
  1074. X##        % show -showproc pr 23 24 29 | lpr
  1075. X##    
  1076. X##    THE showpr PROGRAM LETS YOU DO MORE.  IT CAN USE mhl, IF YOU WANT, TO
  1077. X##    CLEAN UP THE MESSAGE BEFORE PRINTING.  YOU CAN CUSTOMIZE THE PAGE HEADING
  1078. X##    -- INCLUDING THE MESSAGE SUBJECT, FOR INSTANCE.  AND YOU CAN PASS OPTIONS TO
  1079. X##    pr, TO TELL IT HOW TO FORMAT YOUR MESSAGE.  FINALLY, YOU CAN STORE DEFAULT
  1080. X##    showpr OPTIONS IN YOUR .mh_profile FILE, BECAUSE showpr CALLS THE mhprofile
  1081. X##    SCRIPT TO GET THEM.
  1082. X##    
  1083. X##    THE COMMAND LINE USES mh-format STRINGS LIKE THE ONES YOU'D GIVE TO
  1084. X##    THE scan COMMAND.  HERE ARE SOME EXAMPLES.  SOME OF THESE MIGHT LOOK
  1085. X##    COMPLICATED, BUT REMEMBER THAT YOU CAN STORE ANY SET OF OPTIONS AS
  1086. X##    DEFAULTS IN YOUR .mh_profile FILE:
  1087. X##    
  1088. X##    TO PRINT THE CURRENT MESSAGE, WITH THE MESSAGE SUBJECT IN EACH PAGE
  1089. X##    HEADING (IF YOU HAVEN'T PUT ANY showpr OPTIONS IN YOUR .mh_profile):
  1090. X##        % showpr | lpr
  1091. X##    TO PRINT THE LAST 3 MESSAGES, WITH THE MESSAGE SUBJECT IN EACH PAGE
  1092. X##    HEADING; FORMAT THE MESSAGES WITH mhl; AND TELL pr TO USE
  1093. X##    ITS OPTIONS -f (SEPARATE PAGES WITH FORMFEEDS) AND -l50
  1094. X##    (MAKE PAGE LENGTH 50 LINES):
  1095. X##        % showpr -mhl -pr '-f -l50' last:3
  1096. X##    (YOU CAN SHORTEN THOSE OPTIONS TO -m AND -p, IF YOU WANT.)
  1097. X##    
  1098. X##    HERE'S MORE.  TO PRINT THE LAST 3 MESSAGES WITH mhl FORMATTING, WITH
  1099. X##    THE "From" ADDRESS AND MESSAGE DATE IN THE HEADING, LIKE THIS:
  1100. X##        Mar 11 08:49 1990  From: al@phlabs.ph.com  Date: 11/23/89  Page 2 
  1101. X##    USE A COMMAND LINE LIKE THIS (SPLIT ONTO TWO LINES FOR READABILITY):
  1102. X##        showpr -m -f 'from: %(friendly{from})  \
  1103. X##            date: %(mon{date})/%(mday{date})/%(year{date})' last:3 | lpr
  1104. X##    TO MAKE THAT EASIER, YOU COULD PUT THE FOLLOWING LINE IN
  1105. X##    YOUR .mh_profile FILE (NOTE: ALTHOUGH IT'S SPLIT ONTO TWO LINES
  1106. X##    HERE, YOU SHOULD PUT IT ALL ON *ONE* LINE IN YOUR .mh_profile FILE):
  1107. X##        showpr: -m -f 'from: %(friendly{from})  \
  1108. X##               date: %(mon{date})/%(mday{date})/%(year{date})'
  1109. X##    THEN GET THAT FORMATTING AND PRINT YOUR MESSAGES WITH:
  1110. X##        % showpr last:3 | lpr
  1111. X##    
  1112. X##    FINALLY, ABOUT mhl.  YOU CAN MAKE AN mhl FORM FILE NAMED mhl.showpr
  1113. X##    AND PUT IT IN YOUR MH DIRECTORY (LIKE /xxx/yyy/Mail/mhl.showpr).
  1114. X##    IF YOU DO, AND IF YOU USE THE -mhl OPTION, THEN showpr WILL
  1115. X##    FORMAT YOUR MESSAGES WITH mhl -form mhl.showpr.
  1116. X##    OTHERWISE, THE -mhl OPTION USES THE STANDARD mhl.format FILE.
  1117. X
  1118. X# NOTE: TABSTOPS ARE SET AT 4 IN THIS CODE.
  1119. X
  1120. Xfolopts="-nolist -nototal -nopack"
  1121. Xmh=/usr/local/mh            # WHERE MOST MH PROGRAMS LIVE
  1122. Xmhl=/usr/local/lib/mh/mhl    # WHERE mhl LIVES
  1123. Xmhprofile=/XXXXXXXXXXXXXXXXXX/mhprofile    # READS MH PROFILE
  1124. Xmyname="`basename $0`"
  1125. Xpr=/bin/pr
  1126. Xprwidth=55    # MAX WIDTH OF -h FIELD IN $pr + 5 FOR MSG NUM
  1127. Xscanopts="-noclear -noheader -noreverse"
  1128. Xstat=1    # DEFAULT EXIT STATUS, RESET TO 0 BEFORE NORMAL EXIT
  1129. Xusage="usage: $myname [fdr] [msgs] [-mhl] [-format 'mh-format-str'] [-pr 'pr-opts']"
  1130. X
  1131. X# RESET "COMMAND LINE" PARAMETERS.  FIRST, AN x, WHICH WE
  1132. X# shift AWAY, IN CASE THERE ARE NO OTHER PARAMETERS.
  1133. X# THEN, MH PROFILE OPTIONS (IGNORE mhprofile RETURN STATUS).
  1134. X# LAST, ORIGINAL COMMAND LINE ARGS (WITH SHELL BUG PATCH):
  1135. Xeval set x `$mhprofile -b $myname` '${1+"$@"}'
  1136. Xshift
  1137. X
  1138. X# PARSE set ARGS.  IF OPTIONS REPEATED, LAST ONES PREVAIL:
  1139. Xwhile :
  1140. Xdo
  1141. X    case "$1" in
  1142. X    "")    break ;;    # NO MORE ARGUMENTS
  1143. X    [+@]*)    newfdr="$1" ;;
  1144. X    -h*) # HELP:
  1145. X        echo "$usage
  1146. X        \$Revision: 2.2 $ \$Date: 90/10/13 10:30:57 $"
  1147. X        exit
  1148. X        ;;
  1149. X    -m*) # SET mhlopts AS FLAG TO USE mhl.
  1150. X        mhlopts="-nobell -noclear -nofaceproc -nomoreproc"
  1151. X        # USE mhl.showpr FILE, IF ANY:
  1152. X        if test -r `$mh/mhpath +`/mhl.showpr
  1153. X        then mhlopts="$mhlopts -form mhl.showpr"
  1154. X        fi
  1155. X        ;;
  1156. X    -f*)
  1157. X        case "$2" in
  1158. X        "")    echo "$usage
  1159. X            (Missing string after '-format')." 1>&2
  1160. X            exit
  1161. X            ;;
  1162. X        *)    format="$2"; shift ;;
  1163. X        esac
  1164. X        ;;
  1165. X    -p*)
  1166. X        case "$2" in
  1167. X        "")    echo "$usage
  1168. X            (Missing string after '-pr')." 1>&2
  1169. X            exit
  1170. X            ;;
  1171. X        +*|-*)    propts="$2"; shift ;;
  1172. X        *)    echo "$usage
  1173. X            (Bad options after '-pr')." 1>&2
  1174. X            exit
  1175. X            ;;
  1176. X        esac
  1177. X        ;;
  1178. X    *)    msgs="$msgs $1" ;;
  1179. X    esac
  1180. X
  1181. X    shift
  1182. Xdone
  1183. X
  1184. X# SET FORMAT OF pr HEADER.  IF NO -format OPTION, AND IF NO
  1185. X# "showpr:" LINE IN MH PROFILE, DEFAULT TO MESSAGE SUBJECT:
  1186. X: ${format='%{subject}'}
  1187. X
  1188. X# CHANGE FOLDER (IF USER GAVE ONE), GET NAME.
  1189. Xfolder="`$mh/folder $folopts -fast $newfdr`"
  1190. Xcd `$mh/mhpath +` || exit    # cd TO MH DIRECTORY
  1191. X
  1192. X# scan ALL MESSAGES; FEED TO LOOP.  IF NONE, DEFAULT TO cur:
  1193. Xscan -width $prwidth $scanopts -format "%(msg) $format" ${msgs-cur} |
  1194. Xwhile read msgnum heading
  1195. Xdo
  1196. X    # IF MESSAGE UNREADABLE, MH 6.6 scan PRINTS (TO stdout!)
  1197. X    # LIKE THIS, WITH LEADING BLANKS UNLESS msgnum > 999:
  1198. X    #   <msgnum>  unreadable
  1199. X    # IF THERE ARE LEADING BLANKS, SOME sh'S WILL COPY BOTH
  1200. X    # MESSAGE NUMBER AND unreadable INTO $heading, AND LEAVE
  1201. X    # $msgnum EMPTY.  TRY TO CATCH BOTH CASES:
  1202. X    case "$msgnum" in
  1203. X    "")    echo "$myname: skipping, message $msgnum $heading" 1>&2; continue ;;
  1204. X    esac
  1205. X    case "$heading" in
  1206. X    unreadable) echo "$myname: skipping unreadable message '$msgnum'." 1>&2; continue ;;
  1207. X    esac
  1208. X
  1209. X    msgpath=$folder/$msgnum
  1210. X    case "$mhlopts" in
  1211. X    "")  $pr $propts -h "$heading" $msgpath || break ;;
  1212. X    *) $mhl $mhlopts $msgpath | $pr $propts -h "$heading" || break ;;
  1213. X    esac
  1214. Xdone
  1215. X
  1216. Xstat=0
  1217. Xexit
  1218. X//E*O*F showpr//
  1219. chmod u=rwx,g=rx,o=rx showpr
  1220.  
  1221. echo extracting - vmsmail2mh
  1222. sed 's/^X//' > "vmsmail2mh" <<'X//E*O*F vmsmail2mh//'
  1223. X#! /bin/sh
  1224. X# $Header: /u3/acs/jdpeek/.bin/RCS.Z/vmsmail2mh,v 1.2 90/03/22 06:53:59 jdpeek Exp $
  1225. X###    vmsmail2mh - split VMS mail messages from EXTRACT/ALL into MH folder
  1226. X###    Usage: vmsmail2mh [+folder] [...vmsmsg-files]
  1227. X##
  1228. X##    AN EASY WAY TO TRANSFER VMS MAIL MESSAGES TO UNIX IS BY EXTRACTING
  1229. X##    ALL THE MESSAGES FROM A VMS MAIL FOLDER INTO A FILE... USE:
  1230. X##        MAIL> EXTRACT/ALL
  1231. X##        _file: FILENAME
  1232. X##    THEN, YOU CAN ftp THEM TO THE SYSTEM RUNNING MH.
  1233. X##
  1234. X##    WHEN YOU GET THEM TO THE MH SYSTEM, vmsmail2mh WILL READ THROUGH
  1235. X##    THE FILE (OR STANDARD INPUT, IF YOU DON'T GIVE A FILENAME):
  1236. X##        - THE MESSAGES ARE SEPARATED BY FORMFEEDS (CONTROL-L).
  1237. X##          vmsmail2mh WILL CUT THEM INTO SEPARATE MH MESSAGES
  1238. X##          IN THE CURRENT FOLDER (OR +folder IF YOU GIVE ONE).
  1239. X##        - THE FORMAT OF THE VMS MAIL MESSAGE IS DIFFERENT.
  1240. X##            * Subj: LINES ARE CONVERTED TO Subject: LINES.
  1241. X##            * From: LINES ARE SPLIT INTO From: AND Date: LINES.
  1242. X##          ONLY THE FIRST Subj: AND From: IN EACH MESSAGE IS CONVERTED.
  1243. X##
  1244. X##    BUG: VMS ADDRESSES LIKE:
  1245. X##        SMTP%"user@host"
  1246. X##        HOST::USER
  1247. X##    AREN'T CONVERTED.  IN FACT, *NO* ADDRESSES ARE CONVERTED.
  1248. X
  1249. X#    NOTE: PROGRAM HASN'T BEEN TESTED THOROUGHLY.
  1250. X#     CHECK THE MESSAGES!
  1251. X#    Placed in the public domain.  Use at your own risk.
  1252. X#        --Jerry Peek, 22 March 1990
  1253. X
  1254. Xdfltprot=600    # DEFAULT MESSAGE PROTECTION (IF NONE IN MH PROFILE)
  1255. Xfolopts="-fast -nolist -nototal -nopack -norecurse"
  1256. Xmh=/usr/local/mh
  1257. Xmhprofile=/u3/acs/jdpeek/.bin/mhprofile    # READS MH PROFILE
  1258. Xscanopts="-noclear -noheader -noreverse"
  1259. X
  1260. Xcase "$1" in
  1261. X[@+]?*)
  1262. X    # IF $1 DOESN'T EXIST, folder WILL CREATE IT (SIGH).
  1263. X    # THAT'S BECAUSE stdout IS REDIRECTED AWAY FROM TERMINAL.
  1264. X    if $mh/folder $folopts "$1" >/dev/null
  1265. X    then
  1266. X        # GET PATHNAME OF FOLDER, LAST MESSAGE NUMBER:
  1267. X        folpath="`$mh/mhpath`" || exit
  1268. X        firstmsg="`$mh/scan -format '%(msg)' last`" || exit
  1269. X    else
  1270. X        echo "`basename $0`: no folder.  quitting." 1>&2
  1271. X        exit 1
  1272. X    fi
  1273. X    ;;
  1274. X*)    echo "Usage: `basename $0` +folder|@folder [file]
  1275. X    ('$1' doesn't start with + or @.)" 1>&2
  1276. X    exit 1
  1277. X    ;;
  1278. Xesac
  1279. X
  1280. Xif [ -n "$2" -a \( ! -r "$2" \) ]
  1281. Xthen
  1282. X    echo "`basename $0`: quitting: can't read VMS file '$2'." 1>&2
  1283. X    exit 1
  1284. Xfi
  1285. X
  1286. X# GET PROTECTION MODE FROM MH PROFILE (IF NONE, USE $dfltprot):
  1287. Xmsgprot="`$mhprofile -b msg-protect`" || msgprot=$dfltprot
  1288. X
  1289. X# MAKE SHELL ARCHIVE FILE ON awk'S STANDARD OUTPUT.
  1290. X# PIPE IT INTO sh TO CREATE THE MESSAGE FILES...
  1291. Xawk "BEGIN {
  1292. X    folpath=\"$folpath\" # STORE AS STRING, WITH QUOTES
  1293. X    msgprot=$msgprot     # STORE AS NUMBER (NO QUOTES)
  1294. X    msgnum=$firstmsg"'   # CHANGE FROM DOUBLE- TO SINGLE-QUOTES
  1295. X    inmsg = 0
  1296. X}
  1297. X# PROCESS MESSAGES.  EACH MESSAGE STARTS WITH CONTROL-L.
  1298. X# HOPE THERE ARE NO LINES WITH JUST A CONTROL-L IN MESSAGES!
  1299. X{
  1300. X    # MESSAGE STARTS WITH CTRL-L ON A LINE BY ITSELF.
  1301. X    # PRINT SHELL COMMANDS AND RESET FLAGS:
  1302. X    if ($0 ~ /^\014$/ && inmsg == 1) {
  1303. X        printf "END-OF-%s/%d\n", folpath, msgnum
  1304. X        # SET PROTECTION (INEFFICIENT; SHOULD DO ALL MSGS. AT ONCE)
  1305. X        printf "chmod %d %s/%d\n\n", msgprot, folpath, msgnum
  1306. X        inmsg = 0
  1307. X    }
  1308. X    # AT START OF MESSAGE, PRINT START OF ARCHIVE AND SET FLAGS:
  1309. X    if (inmsg == 0) {
  1310. X        inmsg = 1
  1311. X        msgnum += 1
  1312. X        printf "/bin/cat > %s/%d << \\END-OF-%s/%d\n", \
  1313. X            folpath, msgnum, folpath, msgnum
  1314. X        didsubj = 0
  1315. X        didfrom = 0
  1316. X        next
  1317. X    }
  1318. X    # TURN Subj: INTO Subject: AND SET FLAG TO MAKE SURE WE DO NOT
  1319. X    # TRASH ANY OTHER Subj: LINES (LIKE IN FORWARDED MESSAGES).
  1320. X    # STRIP DATE (14-MAR-1990 15:31:12.02) OFF END OF THE From: LINE
  1321. X    # AND MOVE IT TO LINE OF ITS OWN, THEN SET FLAG LIKE ABOVE:
  1322. X    if ($1 ~ /^Subj:/ && didsubj == 0) {
  1323. X        $1 = "Subject:"
  1324. X        didsubj = 1
  1325. X        print
  1326. X    }
  1327. X    else if ($1 ~ /^From:/ && didfrom == 0) {
  1328. X        for (i = 1; i <= NF - 3; i++)
  1329. X            printf "%s ", $i
  1330. X        printf "%s\n", $(NF - 2)
  1331. X        printf "Date: %s %s\n", $(NF - 1), $NF
  1332. X        didfrom = 1
  1333. X    }
  1334. X    else
  1335. X        print
  1336. X}' $2 |        # IF NO $2, WILL READ STANDARD INPUT...
  1337. X/bin/sh -e    # EXIT ON ANY ERROR
  1338. X
  1339. Xexit # RETURN STATUS FROM PIPE ABOVE
  1340. X//E*O*F vmsmail2mh//
  1341. chmod u=rwx,g=rx,o=rx vmsmail2mh
  1342.  
  1343. echo extracting - xmhprint
  1344. sed 's/^X//' > "xmhprint" <<'X//E*O*F xmhprint//'
  1345. X#! /bin/sh
  1346. X# $Header: /u3/acs/jdpeek/.bin/RCS/xmhprint,v 1.3 90/10/14 10:43:03 jdpeek book $
  1347. X###    xmhprint - print command for xmh
  1348. X###    Usage (in .Xdefaults): xmh*PrintCommand: xmhprint [-cmd_num]
  1349. X##
  1350. X##    THE PRINTER SUPPORT WITH xmh (X11r3 AND x11r4) ISN'T VERY GOOD.
  1351. X##    IT HANDS ALL YOUR MESSAGE FILES TO A PRINTER COMMAND AT ONCE.
  1352. X##    IT DOESN'T FILTER THEM TO REMOVE UNINTERESTING HEADER LINES.
  1353. X##    YOU CAN'T USE A PIPE AS PART OF THE PRINTER COMMAND BECAUSE xmh 
  1354. X##    PUTS THE MESSAGE FILENAMES AT THE END OF THE PRINTER COMMAND LINE.
  1355. X##    
  1356. X##    THIS PROGRAM, xmhprint, TAKES MESSAGE FILENAMES(S) FROM THE
  1357. X##    COMMAND LINE, AS WELL AS (MAYBE) ONE OPTION.
  1358. X##    THE SHELL SCRIPT GETS THE MESSAGE FILENAMES FROM xmh, AND IT CAN
  1359. X##    PROCESS THEM ANY WAY YOU WANT IT TO.
  1360. X##    THE OPTIONS LET YOU CHANGE YOUR PRINT SETUP EASILY--INSTEAD OF
  1361. X##    STORING A COMPLICATED xmh*PrintCommand IN THE RESOURCE MANAGER,
  1362. X##    JUST CHANGE THE OPTION ON THE xmhprint COMMAND LINE IN .Xdefaults:
  1363. X##        xmh*PrintCommand: xmhprint -2
  1364. X##    
  1365. X##    YOU CAN CUSTOMIZE THIS SCRIPT TO FIT YOUR NEEDS.
  1366. X##    ADD mhl(1) TO CLEAN UP THE MESSAGE HEADERS, USE OTHER PRINTERS,
  1367. X##    USE A POSTSCRIPT FILTER... GO WILD!
  1368. X##
  1369. X##    STORE ANY lpr OPTIONS IN THE $PRINTER ENVIRONMENT VARIABLE.
  1370. X
  1371. X# TABSTOPS IN THIS CODE ARE SET AT 4
  1372. X
  1373. Xerrsubj="xmh*PrintCommand print ERROR" # FOR MAILED ERRORS
  1374. X
  1375. X# APPEND ALL ERRORS TO FILE (NEEDS CLEANING PERIODICALLY)
  1376. Xerrfile=$HOME/.xmh_printerrs
  1377. Xexec >> $errfile 2>&1
  1378. X
  1379. X# GET OPTION (xmh ALWAYS PUTS FILENAMES LAST):
  1380. Xcase "$1" in
  1381. X-1)    # JUST pr; PUTS PATHNAME IN HEADER.  NOTHING FANCY:
  1382. X    shift
  1383. X    pr "$@" | lpr
  1384. X    exit
  1385. X    ;;
  1386. X-2)    # SHOW SUBJECT IN pr HEADER OF EACH MESSAGE:
  1387. X    shift
  1388. X    for f
  1389. X    do
  1390. X        pr -h "`sed -n '/^[sS]ubject: / {
  1391. X            s///p
  1392. X            q
  1393. X        }' $f`" $f
  1394. X    done | lpr
  1395. X    exit
  1396. X    ;;
  1397. X"")    echo "No filenames or command line arguments!?!" |
  1398. X    mail -s "$errsubj" $USER
  1399. X    exit 1
  1400. X    ;;
  1401. X*)    # DEFAULT: SEND ALL OPTIONS AND FILENAMES TO lpr:
  1402. X    lpr "$@"
  1403. X    exit
  1404. X    ;;
  1405. Xesac
  1406. X//E*O*F xmhprint//
  1407. chmod u=rwx,g=rx,o=rx xmhprint
  1408.  
  1409. echo Inspecting for damage in transit...
  1410. temp=/tmp/shar$$; dtemp=/tmp/.shar$$
  1411. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  1412. cat > $temp <<\!!!
  1413.       65     597    3654 README
  1414.       39     277    1521 append
  1415.      103     441    2745 babyl2mh
  1416.       78     375    2209 distprompter
  1417.      163     812    4848 fixsubj
  1418.       50     324    2100 fols
  1419.       28     152     884 incs
  1420.       48     232    1400 mhprofile
  1421.       55     355    2091 recomp
  1422.       76     432    2518 replf
  1423.       37     211    1235 resend.fixmsg
  1424.      111     722    4068 rmmer
  1425.      113     569    3638 scandrafts
  1426.      155     940    5697 showpr
  1427.      117     655    3844 vmsmail2mh
  1428.       61     326    1900 xmhprint
  1429.     1299    7420   44352 total
  1430. !!!
  1431. wc  README append babyl2mh distprompter fixsubj fols incs mhprofile recomp replf resend.fixmsg rmmer scandrafts showpr vmsmail2mh xmhprint | sed 's/^X//' | diff -b $temp - >$dtemp
  1432. if [ -s $dtemp ]
  1433. then echo "Ouch [diff of wc output]:" ; cat $dtemp
  1434. else echo "No problems found."
  1435. fi
  1436. exit 0
  1437.  
  1438. exit 0 # Just in case...
  1439. -- 
  1440. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1441. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1442. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1443. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1444.