🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.emacs.vm.bug
Article #9135

Re: How to use VM with alternative mailboxes?

#9135
From: Rich Kaul
Date: Thu, 05 Mar 1992 18:13
388 lines
16367 bytes
In article <1992Mar5.165633.6233@spool.cs.wisc.edu> jcargill@oka.cs.wisc.edu (Jon Cargille) writes:
   My mail filter appends mail directly to the vm folders in my ~/Mail
   directory.  Some day, this will probably bite me, if mail arrives
   precisely when I'm saving a folder.  But for me, for the moment, the
   risk is worth it.

Then you must be on lower volume mailing lists than I'm on.  I have
several that if I take more than 15 minutes to get caught up on,
there'll be a new message and I'll have to problem of an inconsistent
mailbox.

   For example, suppose I were to visit folder "some-mailing-list", in my
   "~/Mail" directory, and vm-aux-spool-directory was set to
   "~/Mail/spool".  Then vm would automatically look for a
   "~/Mail/spool/some-mailing-list" spool file, and incorporate any new
   messages into the folder residing in "~/Mail".

That's almost exactly what I do, with a very small perl file and my
~/.vm file.  The modifications are pretty trivial.  I won't say
they're clean, but they're trivial :-)

Since more than a few people have asked about the scripts, I thought
I'd post them as they're pretty short.  All that's required is the
~/.vm file if you can deliver/sort/whatever your incoming mail to your
"spool" directory (I call mine ~/Mail/incoming).  I'll include the
perl script I use for delivering mail (useful in a heterogenous
environment). 

-rich

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  .vm ppmd
# Wrapped by kaul@ee.eng.ohio-state.edu on Tue Mar  3 21:41:25 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f '.vm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'.vm'\"
else
echo shar: Extracting \"'.vm'\" \(5646 characters\)
sed "s/^X//" >'.vm' <<'END_OF_FILE'
X; Rich Kaul's .vm file for customization of the VM emacs mailer
X;
X; Use all you want, however:
X; (a) use at your own risk
X; (b) don't use features you don't understand
X; (c) edit liberally to remove features you can't use
X
X;  Quick Summary: Use vm for mail reading since it uses Unix-style mailboxes
X;  All these lines serve to set up various functions.
X(autoload 'vm "vm" nil t)
X(autoload 'vm-visit-folder "vm" nil t)
X(setq vm-folder-directory "~/Mail/")	; default mail directory
X(setq vm-crash-box "~/Mail/.crashbox")	; airbag if system crashes ;-)
X(setq vm-flush-interval nil)		; disable timers
X(setq vm-inhibit-startup-message t)
X(setq vm-delete-after-saving t)
X(setq vm-group-by "subject")		; for discussions and mailing lists
X(setq vm-delete-empty-folders t)	; be tidy
X(setq vm-preview-lines nil)
X(setq vm-follow-summary-cursor t)
X(setq vm-startup-with-summary "ok")	; read mail more like news
X(setq vm-reply-subject-prefix "Re: ")	; keep the Re: for people
X;(setq vm-included-text-attribution-format nil)
X(setq vm-strip-reply-headers t)
X(setq vm-primary-inbox (expand-file-name "~/Mail/IMPSTUFF"))
X
X;; Upon startup in vm-mode, I want to bind keys to make getting at
X;; sub-mailboxes easier.  This should do it.
X(setq vm-mode-hooks
X  '(lambda()
X    (make-local-variable 'version-control)
X    (setq version-control 'never)	; keep minimal backups
X    (local-unset-key "\C-cn")		; set to system mailbox
X    (local-set-key "\C-cn" 'vm-normal)
X    (local-unset-key "\C-cp")		; keystroke to get to personal mbox
X    (local-set-key "\C-cp"	'vm-personal)
X    (local-unset-key "\C-c\C-f")	; keystroke to firearms mbox
X    (local-set-key "\C-c\C-f"	'vm-firearms)
X    (local-unset-key "\C-cc")		; keystroke to connectionists list
X    (local-set-key "\C-cc"	'vm-connect)
X    (local-unset-key "\C-cs")		; to get to *ugh* system stuff
X    (local-set-key "\C-cs"	'vm-system)
X    (local-unset-key "\C-cm")		; other mailing lists
X    (local-set-key "\C-cm"	'vm-misc)))
X
X(defun vm-normal ()
X  "Set up reading from the default mail box"
X  (interactive)
X  (setq vm-primary-inbox "~/Mail/IMPBOX")
X  (setq vm-spool-files (list (expand-file-name "/var/spool/mail/kaul")))
X  (vm-visit-folder "~/Mail/IMPBOX"))
X  
X(defun vm-personal ()
X  "Set up reading of the personal mail buffer"
X  (interactive)
X  (setq vm-primary-inbox "~/Mail/PBOX")
X  (setq vm-spool-files (list (expand-file-name "~/Mail/incoming/personal")))
X  (vm-visit-folder "~/Mail/PBOX"))
X
X(defun vm-firearms ()
X  "Set up reading of the firearms mail buffer"
X  (interactive)
X  (setq vm-primary-inbox "~/Mail/FIREBOX")
X  (setq vm-spool-files (list (expand-file-name "~/Mail/incoming/firearms")))
X  (vm-visit-folder "~/Mail/FIREBOX"))
X
X(defun vm-system ()
X  "Set up reading of the systems mail buffer"
X  (interactive)
X  (setq vm-primary-inbox "~/Mail/SYSBOX")
X  (setq vm-spool-files (list (expand-file-name "~/Mail/incoming/system")))
X  (vm-visit-folder "~/Mail/SYSBOX"))
X
X(defun vm-connect ()
X  "Set up reading of the Connectionist's mail buffer"
X  (interactive)
X  (setq vm-primary-inbox "~/Mail/CONNECTBOX")
X  (setq vm-spool-files (list (expand-file-name "~/Mail/incoming/connect")))
X  (vm-visit-folder "~/Mail/CONNECTBOX"))
X
X(defun vm-misc ()
X  "Set up reading of the misc mailing lists mail buffer"
X  (interactive)
X  (setq vm-primary-inbox "~/Mail/MISCBOX")
X  (setq vm-spool-files (list (expand-file-name "~/Mail/incoming/misc")))
X  (vm-visit-folder "~/Mail/MISCBOX"))
X
X; Try and get the incoming and outgoing stuff done prettily
X;(setq vm-auto-folder-case-fold-search t
X;      mail-archive-file-name (concat vm-folder-directory "INBOX"))
X(setq vm-auto-folder-alist
X  '(
X    ("from"
X      ("\\([^<(@%]*\\)" .
X       (string-remove-chars
X        '(32 9 10 13)           ;SPC,TAB,LFD,RET
X        (vm-afa-match-format "%s" 1)))
X    )
X    ("to"
X      ("\\([^<(@%]*\\)" .
X       (string-remove-chars
X        '(32 9 10 13)           ;SPC,TAB,LFD,RET
X        (vm-afa-match-format "%s" 1)))
X    )
X   )
X)
X
X;; Some utils:
X(defun string-remove-chars (list-of-chars a-string)
X  "Function: Removes the characters in LIST-OF-CHARS from A-STRING"
X  (cond ((zerop (length a-string)) a-string)
X        (t
X         (if (memq (string-to-char a-string) list-of-chars)
X             (string-remove-chars list-of-chars (substring a-string 1))
X           ;;;ELSE:
X           (concat
X            (substring a-string 0 1)
X            (string-remove-chars
X             list-of-chars
X             (substring a-string 1)))))));
X
X;;;
X;;; The util below is defined by Noah Friedman (friedman@ai.mit.edu)
X;;;--------------------------------------------------------------------
X(defun vm-afa-match-format (format-str &rest match-values)
X  "Creates a string of the format FORMAT-STR by getting
Xbuffer-substrings determined by the &rest values MATCH-VALUES.  This
Xfunction is meant to be used when setting vm-auto-folder-alist.  It
Xallows you to construct filenames from saved regexp patterns.
X
XExample:
X   (setq vm-auto-folder-alist
X         '(\"To\"
X           (\"fsf-\\\\([^@%]*\\\\)\" . (vm-afa-match-format-format
X\"fsf-%s\" 1))
X           (\"foo-\\\\(bar\\\\)@\\\\(baz\\\\)\" . (vm-afa-match-format
X\"foo%s@%s\" 1 2))))
X
XThus, a To: line addressed to fsf-staff@gnu.ai.mit.edu would be saved
Xby
Xdefault in a folder called \"fsf-staff\", and mail addressed to
Xfoo-bar@baz would go in a folder called \"foobar@baz\"."
X  (apply 'format format-str
X         (mapcar
X          (function
X           (lambda (match-value)
X             (buffer-substring (match-beginning match-value)
X                               (match-end match-value))))
X          match-values)))
X;;;--------------------------------------------------------------------
END_OF_FILE
if test 5646 -ne `wc -c <'.vm'`; then
    echo shar: \"'.vm'\" unpacked with wrong size!
fi
# end of '.vm'
fi
if test -f 'ppmd' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ppmd'\"
else
echo shar: Extracting \"'ppmd'\" \(6007 characters\)
sed "s/^X//" >'ppmd' <<'END_OF_FILE'
X#!/usr/local/bin/perl
X
X# A perl mail agent.  The basic premise is that mail from certain
X# people demands attention immediately, so it gets put in the normal
X# system mailbox.  All other mail is sorted based on who it's from and
X# placed in the appropriate files in a different directory.  This is,
X# of course, easily customizable.
X#
X# To use this, create a .forward file like (complete WITH quotes):
X# "|/home4/kaul/bin/ppmd /home4/kaul kaul >> /home4/kaul/.maillog 2>&1"
X# and configure this file in the CONFIGURE HERE section.
X#
X# Author:	Rich Kaul (kaul@icarus.eng.ohio-state.edu)
X# Date:		12/2/90
X#
X# The credit where credit is due department:  the core of the message
X# parsing is based on Larry Wall's mailagent script.
X
X# These two values are gotten from the second and third arguments on
X# the command line in your ~/.forward file.
X($HOME, $USER) = @ARGV;
X
X# We use file locking to make sure that no more than one process is
X# writing to the mail box at a given time.
X$LOCK_SH = 1;				# Values for flock() calls.
X$LOCK_EX = 2;
X$LOCK_NB = 4;
X$LOCK_UN = 8;
X
Xumask(077);				# Get a little privacy.
X
X# Now run and get the headers.  We have to parse the headers before we
X# can figure out delivery.  All headers are available for view; they are
X# prefixed by $H and the header name is set to lower case.  For
X# example, valid header references are $Hto, $Hdate, etc.
Xwhile (<stdin>) {
X
X    # Do this on the From_ line only.  What it does is set $from to
X    # the name of the person who sent the mail.  It strips everything
X    # after the @ in the address and before the ! to find the name.
X    if (1 .. 1) {
X	if (/^From\s+(\S+)\s+[^\n]*(\w{3}\s+\d+\s+\d+:\d+)/) { $from = $1; }
X	$from =~ s/@.*//;		# remove trailing @machine
X	$from =~ s/%.*//;		# remove trailing %machine
X	$from = $1 if $from =~ /.*!([^\n]+)/; # remove leading ! paths
X    }
X
X    # This section operates on the header of the message.  We create
X    # an array of header keys to work on later.
X    if (1 .. /^\s*$/) {
X	s/^From: ([^<]*)\s+<(.*)>$/From: $2 ($1)/;	# rewrite ugly header
X	$header .= $_;
X	chop;
X	if (/^\s*$/) {
X	    foreach $key (keys(header)) {
X		eval "\$H$key = \$header{'$key'}";
X	    }
X	}
X	else {
X	    if (s/^([-\w]+):\s*//) {
X		($headline = $1) =~ y/A-Z-/a-z_/;
X		$header{$headline} .= "\n" if $header{$headline} ne '';
X	    }
X	    else {
X		s/^\s+/ /;
X	    }
X	    $header{$headline} .= $_;
X	}
X    }
X    # And here we make the body of the message.
X    else {
X	$body .= $_;
X	}
X}
X
X###################################################################
X# CONFIGURE HERE
X###################################################################
X#
X# This section does several things.  It sets a value $root where I put
X# my incoming mail files.  It also sets $box to the default system
X# mail box (where xbiff and the like can find it), an emergency
X# dumping box for cases where delivery to the desired mbox isn't
X# possible.  It also sets the default destination $dest to a "generic"
X# mail box.  Configure to your own setup.
X$root = "$HOME/Mail/incoming";		# root of personal mail tree.
X$box = "/usr/spool/mail/$USER";		# default mail box.
X$GIVE_UP_BOX = "$box";			# emergency dumping box.
X$dest = "$root/personal";		# where things go by default
X#
X# This is the section that determines where mail is sent.  You do this
X# by looking for patterns in the header (or body *shudder*) and
X# setting the variable $dest to the appropriate mail box.  In case you
X# don't know, the easiest way to do this in perl is via the
X# =~ /pattern/mod  syntax, where pattern is the pattern you're looking
X# for in the header and mod is a modifier.  Typically the only
X# modifier you'll want to use is i to make the comparison case
X# insensitive. 
X#
X# Order is very important here, since this is one giant if/then/else
X# and the structure is exited upon the first match.  Note that if
X# nothing is matched, the mail is delivered to the default mbox set in
X# $dest above.
X#
X# This is a sample section showing how I parse my mail. First, junk
X# to/from the system is routed to the system inbox.
Xif($from =~ /root/ || $from =~ /news/) { $dest = "$root/system";}
Xelsif($Hto =~ /site/i || $Hcc =~/site/i) { $dest = "$root/system";}
X# Now mailer junk
Xelsif($Hfrom =~ /Mailer-Daemon/i) { $dest = "$root/mailer-daemon";}
X# Handle mailing lists.  Lower volume ones don't get their own files.
Xelsif($from =~ /firearms/i || $Hcc =~ /firearms/i) {$dest = "$root/firearms";}
Xelsif($Hto =~ /connection/i || $Hcc =~ /connection/i) {
X    $dest = "$root/connect";}
Xelsif($from =~ /freemacs/i || $Hcc =~ /freemacs/i) {$dest = "$root/misc";}
Xelsif($Hto =~ /gnuplot/ || $Hcc =~ /gnuplot/) {$dest = "$root/misc";}
Xelsif($Hto =~ /linkers/ || $Hcc =~ /linkers/) {$dest = "$root/linkers";}
X# List the people who can crash into the system mailbox, seting off
X# all my mail flags and getting my immediate attention.
Xelsif($from =~ /alden/ || $from =~ /monty/ || $from=~/yarri/) {$dest = $box;}
Xelsif($from =~ /bibyk/ || $from =~ /adkins/ || $from =~ /zaka/) {$dest = $box;}
Xelsif($from =~ /kaul/) {$dest = $box;}
X###########################################################################
X# END CONFIGURE HERE
X###########################################################################
X
X# Now we do the delivery.  It's to a *file*.
X$all = $header . $body;
Xopen(BOX, ">>$dest") || do gag ("Can't open $dest ($< $>): $!");
X
X# Lock the box before we do delivery.
Xdo flocker(BOX,$LOCK_EX);
Xprint BOX $all,"\n\n";
Xdo flocker(BOX,$LOCK_UN);
X
X# File locking subroutine.
Xsub flocker {
X    local ($file, $mode) = @_;
X    eval 'flock($file,$mode);';
X    seek($file, 0, 2);		# in case it was appended while we were waiting
X}
X
X# For some reason mail couldn't get delivered.  Dump the message in the
X# emergency mailbox and exit.
Xsub gag {
X    open(ERR_BOX, ">>$GIVE_UP_BOX") || die "I'm really hosed.  I can't even open the emergency box $GIVE_UP_BOX\n";
X
X    print @_;
X    do flocker(ERR_BOX,$LOCK_EX);
X    print ERR_BOX $all,"\n\n";
X    do flocker(ERR_BOX,$LOCK_UN);
X    exit 1;
X}
X    
END_OF_FILE
if test 6007 -ne `wc -c <'ppmd'`; then
    echo shar: \"'ppmd'\" unpacked with wrong size!
fi
chmod +x 'ppmd'
# end of 'ppmd'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
--
Rich Kaul                  | "A NeXT is the only Unix workstation where you
kaul@ee.eng.ohio-state.edu | sit a salesman down and expect him to do any
kaul.2@osu.edu		   | work." -- a certain MorningStar programmer
Technical Details
Message-ID: <KAUL.92Mar5131322@nile.ee.eng.ohio-state.edu>
Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!sample.eng.ohio-state.edu!ee.eng.ohio-state.edu!kaul
References: <KAUL.92Mar3194425@amazon.ee.eng.ohio-state.edu> <p0msrINNgsr@hilbert.math.ksu.edu> <9203041537.AA15068@wendy-fate.UU.NET> <1992Mar5.165633.6233@spool.cs.wisc.edu>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f6829,309a564d2a891328
X-Google-Attributes: gidf6829,public
X-Google-ArrivalTime: 1992-03-05 17:09:35 PST
Newsgroups: gnu.emacs.vm.bug
Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!sample.eng.ohio-state.edu!ee.eng.ohio-state.edu!kaul
From: kaul@ee.eng.ohio-state.edu (Rich Kaul)
Subject: Re: How to use VM with alternative mailboxes?
In-Reply-To: jcargill@oka.cs.wisc.edu's message of Thu, 5 Mar 1992 16:56:33 GMT
Message-ID: <KAUL.92Mar5131322@nile.ee.eng.ohio-state.edu>
Sender: news@ee.eng.ohio-state.edu
Organization: The Ohio State University Dept of Electrical Engineering
References: <KAUL.92Mar3194425@amazon.ee.eng.ohio-state.edu>
 <p0msrINNgsr@hilbert.math.ksu.edu>
 <9203041537.AA15068@wendy-fate.UU.NET>
 <1992Mar5.165633.6233@spool.cs.wisc.edu>
Date: Thu, 5 Mar 1992 18:13:22 GMT