karl@triceratops.cis.ohio-state.edu (Karl Kleinpaste) (05/17/89)
I got some very helpful changes from Steve Popovich <popovich@park.cs.columbia.edu> regarding how to convince one GNUS to do both news and mail. His changes worked (mostly, anyway - one or two minor glitches) but still didn't provide both news and mail at the same time, which is what I really wanted. So I spent most of the last day or two hacking GNUS on and off until it got to where it will do this for me. The following is a shar file, containing a README description of what's needed, plus sample shell scripts and one very small change to nnspool.el to make your mail and news turn into one logical type of communication that can be read with GNUS. Enjoy, --Karl #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # .emacs-hooks # .forward # make-active # nnspool.el.diff # pmd # This archive created: Tue May 16 16:15:11 1989 export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(2162 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^X//' << \gnus-hacks > 'README' XThis file documents a scheme for using GNUS to read both news and mail Xin a single GNUS incarnation. Several steps are needed, and some Xchanges will almost certainly be needed in any new environment. X X[1] Create a personal mail delivery program of some sort. In the shar Xfile in which this README came, there is a csh script called `pmd' Xwhich knows how to deliver mail to a directory subhierarchy under X~/Memos. In that directory are subdirs such as personal, list, and so Xforth. Pmd knows how to find a file .last, which contains an integer Xrepresenting the number of the last mail item saved in that directory. XPmd saves the mail, locks the .last file, increments to the next one, Xand saves the mail in the appropriate directory. Have your mail sent Xthrough this delivery filter via a .forward file such as that Xenclosed. X X[2] Create a symlink to /usr/spool/news in the top-level mail Xdirectory, e.g.: X ln -s /usr/spool/news ~/Memos/netnews X X[3] Install the very small enclosed patch to nnspool.el, and recompile Xit. This makes nnspool look for a personalized routine for choosing Xan active file, rather than blindly taking the system default. Note Xthat it will still operate in its old fashion if no such function is Xdefined. X X[4] Take the enclosed .emacs-hooks file, and install it in your own X.emacs with local changes as appropriate. This will probably mean Xthat you will need to change how nnspool-personal-active-file works Xunless you take mine raw. It works, but it's by no means the last Xword. The csh script make-active is used by nnspool-personal-active- Xfile; it generates a file ~/Memos/active in the usual form, but Xincludes one's personal mail subhierarchy as part of the active file. XNote that nnspool-spool-directory must have a trailing `/'. X X[5] Save a copy of your .newsrc to forestall catastrophe, and then Xedit .newsrc to add "netnews." to the beginning of each line. X X[6] Take a deep breath, start a fresh Emacs to get the .emacs changes, Xand invoke GNUS. It'll go hack up an active file, and then show you Xall your news and mail as though it were all news. X XSuggestions, improvements, bug fixes are all most welcome. X X--Karl gnus-hacks if test 2162 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 2162 characters)' fi fi # end of overwriting check echo shar: extracting "'.emacs-hooks'" '(1980 characters)' if test -f '.emacs-hooks' then echo shar: will not over-write existing file "'.emacs-hooks'" else sed 's/^X//' << \gnus-hacks > '.emacs-hooks' X;; I always load it up directly, rather than autoloading it. X(load "gnus") X;; X;; Extra ignorable headers. X(setq gnus-ignored-headers X (concat gnus-ignored-headers X "\\|^Errors-To:\\|^Precedence:\\|^Received:\\|^UNIX-From:")) X;; X;; Set your private mail directory as the news spool area. X(setq nnspool-spool-directory "~/Memos/") ; note trailing `/' X;; X;; The following 2 defvars are strictly personalized; X;; used in the function following. Roll your own... X(defvar karl-active-file-maker "~/bin/make-active" X "*Personalized active file generator") X(defvar karl-active-file "~/Memos/active" X "*Personalized active file") X;; X;; This is the function needed by nnspool-pick-active-file X;; in order to discriminate between ordinary netnews reading X;; and modified news-and-mail reading. It must create a X;; file in the same format as the netnews active file, and X;; then return that file's filename to the caller. X(defun nnspool-personal-active-file () X "Returns a filename string for a personal active file." X (message "Hacking personalized active file...") X (call-process karl-active-file-maker nil nil nil X ; remaining stuff is args to the active file maker. X nnspool-spool-directory "personal" "list") X (message "Hacking personalized active file...done.") X karl-active-file X) X;; X;; If you want an RMAIL-like forwarding X;; function, use the rest of this. X(defun gnus-Subject-forward () X "Forward the current message to another user." X (interactive) X (switch-to-buffer gnus-Article-buffer) X (let ((forward-buffer gnus-Article-buffer) ; used to be (current-buffer) X (subject (concat "[" X (mail-strip-quoted-names (mail-fetch-field "From")) X ": " (or (mail-fetch-field "Subject") "") "]"))) X ;; There are always 2 buffers visible; use this window. X (mail nil nil subject) X (save-excursion X (goto-char (point-max)) X (forward-line 1) X (insert-buffer forward-buffer)))) X(define-key gnus-Subject-mode-map "F" 'gnus-Subject-forward) gnus-hacks if test 1980 -ne "`wc -c < '.emacs-hooks'`" then echo shar: error transmitting "'.emacs-hooks'" '(should have been 1980 characters)' fi fi # end of overwriting check echo shar: extracting "'.forward'" '(27 characters)' if test -f '.forward' then echo shar: will not over-write existing file "'.forward'" else sed 's/^X//' << \gnus-hacks > '.forward' X"|/usr/local/bin/pmd karl" gnus-hacks if test 27 -ne "`wc -c < '.forward'`" then echo shar: error transmitting "'.forward'" '(should have been 27 characters)' fi fi # end of overwriting check echo shar: extracting "'make-active'" '(947 characters)' if test -f 'make-active' then echo shar: will not over-write existing file "'make-active'" else sed 's/^X//' << \gnus-hacks > 'make-active' X#!/bin/csh -f X# X# Script to generate an active file on the fly. X# Builds a pseudoactive file which represents personal mail under X# $1 plus pseudonews in $1/netnews (a symlink to the real news area). X# Xset dir=$1 Xshift Xset active=$dir/active Xset nactive=/usr/lib/news/active Xif ($#argv < 1) then X echo make-active: usage: make-active directory subdirs... X exit 99 Xendif X# X# Find directories and their associated .last files. Then take X# base dirnames, change to newsgroup name format, and build the X# mail-based active file out of it all. X# Xcd $dir Xset list=(`find $* -name .last -print`) Xset count=$#list Xset nlist=() Xforeach i ($list) X set j=$i:h X set nlist=($nlist `echo $j | tr / .`) Xend Xcp /dev/null $active X@ i = 1 Xwhile ($i <= $count) X echo $nlist[$i] `cat $list[$i]` 00000 y >> $active X @ i ++ Xend X# X# Now add the whole canonical active file, X# prefixing every group with "netnews.". Xsed -e 's/^/netnews./' < $nactive >> $active X# Xexit 0 gnus-hacks if test 947 -ne "`wc -c < 'make-active'`" then echo shar: error transmitting "'make-active'" '(should have been 947 characters)' fi chmod +x 'make-active' fi # end of overwriting check echo shar: extracting "'nnspool.el.diff'" '(1090 characters)' if test -f 'nnspool.el.diff' then echo shar: will not over-write existing file "'nnspool.el.diff'" else sed 's/^X//' << \gnus-hacks > 'nnspool.el.diff' X*** nnspool.el.old Tue May 16 14:38:40 1989 X--- /usr/local/lib/emacs/lisp/nnspool.el Tue May 16 14:30:15 1989 X*************** X*** 242,248 **** X (defun nntp-request-list () X "List valid newsgoups." X (save-excursion X! (nnspool-find-file nnspool-active-file))) X X (defun nntp-request-last () X "Set current article pointer to the previous article X--- 242,248 ---- X (defun nntp-request-list () X "List valid newsgoups." X (save-excursion X! (nnspool-find-file (nnspool-pick-active-file)))) X X (defun nntp-request-last () X "Set current article pointer to the previous article X*************** X*** 351,353 **** X--- 351,361 ---- X (setq idx (1+ idx))) X (concat (file-name-as-directory nnspool-spool-directory) group "/") X )) X+ X+ (defun nnspool-pick-active-file () X+ "Return a filename string for the active file." X+ ;; If the user has defined his own active file creator, X+ ;; use it. Otherwise, return the "standard" active file. X+ (if (fboundp 'nnspool-personal-active-file) X+ (nnspool-personal-active-file) X+ nnspool-active-file)) gnus-hacks if test 1090 -ne "`wc -c < 'nnspool.el.diff'`" then echo shar: error transmitting "'nnspool.el.diff'" '(should have been 1090 characters)' fi fi # end of overwriting check echo shar: extracting "'pmd'" '(1917 characters)' if test -f 'pmd' then echo shar: will not over-write existing file "'pmd'" else sed 's/^X//' << \gnus-hacks > 'pmd' X#!/bin/csh -f X# X# Personal mail delivery. X# This saves mail to a personal area where one can happily X# run GNUS on it, rather than use a normal mailer. X# X# Configuration. Xumask 077 Xset path=(/usr/local/bin /usr/ucb /bin /usr/bin /etc /usr/etc) Xset dir=~/Memos Xset tmp=/tmp/pmd-$$ X# X# Save the mail momentarily, and set a Lines: count in it. Xcat - > $tmp Xset totlen=`wc -l < $tmp` Xset lines=(`sed '1,/^$/d' < $tmp | wc -l`) X@ headerlen = $totlen - $lines Xed - $tmp << EOF >& /dev/null X$headerlen Xi XLines: $lines X. Xw Xq XEOF X# X# Deduce headers appropriately. Xset nonomatch Xset from=(`head -1 $tmp`) Xif ($#from < 2) then X echo Bogus mail: From line has $#from items. X exit 23 Xendif Xset from=(`echo "$from[2]" | sed -e 's/@.*//' -e 's/\(.*\)!\(.*\)/\2/'`) Xif ("$from" =~ *-[Rr][Ee][Qq][Uu][Ee][Ss][Tt]*) then X set subdir=list/general Xelse if ("$from" =~ *[Mm][Aa][Ii][Ll][Ee][Rr]-[Dd][Aa][Ee][Mm][Oo][Nn]*) then X # Mailer-Daemon bounces. X set subdir=mailer-daemon Xelse X # Personal mail X if ((-e $dir/personal/"$from") && (-d $dir/personal/"$from")) then X set subdir=personal/"$from" X else X set subdir=personal/general X endif Xendif Xunset nonomatch X# X# Now save the mail appropriately. X# X# Lock. Xset keyf=$dir/$subdir/KEY Xset seqfile=$dir/$subdir/.last Xset success=no X@ retry = 0 Xwhile (($retry < 10) && ($success == no)) X rm $keyf X if ($status == 0) then X # The key was there when we wanted it. X set success=yes X else X # The key was not there - someone else X # had already taken it. Wait and retry. X sleep 10 X @ retry ++ X endif Xend X# X# If we fall out to here without success, we failed 10 times to X# get the key. Result: Who cares? We'll go forward anyway, X# and re-assert the key when we're done. X# X# Get next filenumber. Xset seq=(`cat $seqfile`) X@ seq ++ Xecho $seq > $seqfile X# X# Unlock and save. Xtouch $keyf Xsed -e '1s/^From /UNIX-From: /' < $tmp > $dir/"$subdir"/$seq X# X# Clean up and exit. Xrm -f $tmp Xexit 0 gnus-hacks if test 1917 -ne "`wc -c < 'pmd'`" then echo shar: error transmitting "'pmd'" '(should have been 1917 characters)' fi chmod +x 'pmd' fi # end of overwriting check # End of shell archive exit 0