#!/bin/sh # vminc --- incorporate new mail into VM inbox # Copyright (C) 1993, 1995 Noah S. Friedman # Author: Noah Friedman # Created: 1993-12-31 # Public domain # $Id: vminc,v 1.4 1996/03/03 23:01:58 friedman Exp $ # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, you can either send email to this # program's maintainer or write to: The Free Software Foundation, # Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA. # Commentary: # Code: # Name by which this script was invoked. progname=`echo "$0" | sed -e 's/[^\/]*\///g'` # To prevent hairy quoting and escaping later. bq='`' eq="'" usage="Usage: $progname {options} Options are: -D, --debug Turn on shell debugging (${bq}set -x$eq). -c, --crash-file CFILE Temporary crash recovery folder. -h, --help You're looking at it. -i, --inbox-file IFILE VM primary incoming message folder pathname. -m, --mail-file MFILE Mail spool file (for new mail). -n, --no-vmincrc Do not read vminc init file. -V, --vminrc-file VFILE vminc init file (default $bq~/.vmincrc$eq). -v, --verbose Report operations as they occur. Parameters can be set in the file specified by the VMINCRC environment variable (which defaults to ~/.vmincrc). The useful parameters to set include MAIL, VMINBOX, VMCRASH, and perhaps PATH. The syntax is bourne shell, e.g. # To include path of ${bq}movemail$eq PATH=/usr/local/lib/emacs/etc:\$PATH VMINBOX=\$HOME/mail/INBOX " # Usage: eval "$getopt"; value=$optarg # or optarg_optional=t; eval "$getopt"; value=$optarg # # This function automatically shifts the positional args as appropriate. # The argument to an option is optional if the variable `optarg_optional' # is non-empty. Otherwise, the argument is required and getopt will cause # the program to exit on an error. optarg_optional is reset to be empty # after every call to getopt. The argument (if any) is stored in the # variable `optarg'. # # Long option syntax is `--foo=bar' or `--foo bar'. 2nd argument # won't get used if first long option syntax was used. # # Note: because of broken bourne shells, using --foo=bar syntax can # actually screw the quoting of args that end with trailing newlines. # Specifically, most shells strip trailing newlines from substituted # output, regardless of quoting. getopt=' { optarg= case "$1" in --*=* ) optarg=`echo "$1" | sed -e "1s/^[^=]*=//"` shift ;; * ) case ${2+set} in set ) optarg="$2" shift shift ;; * ) case "$optarg_optional" in "" ) case "$1" in --*=* ) option=`echo "$1" | sed -e "1s/=.*//;q"` ;; * ) option="$1" ;; esac exec 1>&2 echo "$progname: option $bq$option$eq requires argument." echo "$progname: use $bq--help$eq to list option syntax." exit 1 ;; esac ;; esac ;; esac optarg_optional= }' # Initialize variables. # Don't use `unset' since old bourne shells don't have this command. # Instead, assign them an empty value. debug= verbose= inhibit_vmincrc= # Parse command line arguments. # Make sure that all wildcarded options are long enough to be unambiguous. # It's a good idea to document the full long option name in each case. # Long options which take arguments will need a `*' appended to the # canonical name to match the value appended after the `=' character. while test $# != 0; do case "$1" in -D | --debug | --d* ) debug=t shift ;; -c | --crash-file* | --c* ) eval "$getopt" VMCRASH=$optarg ;; -h | --help | --h ) echo "$usage" 1>&2 exit 1 ;; -i | --inbox-file* | --i* ) eval "$getopt" VMINBOX=$optarg ;; -m | --mail-file* | --c* ) eval "$getopt" MAIL=$optarg ;; -n | --no-vmincrc | --n* ) inhibit_vmincrc=t shift ;; -V | --vmincrc-file* | --vm* ) eval "$getopt" VMINCRC=$optarg ;; -v | --verbose | --ve* ) verbose=t shift ;; -- ) # Stop option processing shift break ;; -? | --* ) case "$1" in --*=* ) arg=`echo "$1" | sed -e 's/=.*//'` ;; * ) arg="$1" ;; esac exec 1>&2 echo "$progname: unknown or ambiguous option $bq$arg$eq" echo "$progname: Use $bq--help$eq for a list of options." exit 1 ;; -??* ) # Split grouped single options into separate args and try again optarg="$1" shift set fnord `echo "x$optarg" | sed -e 's/^x-//;s/\(.\)/-\1 /g'` ${1+"$@"} shift ;; * ) break ;; esac done case "$debug" in t ) set -x ;; esac # Precedence for defs (highest->lowest): options, env, ~/.vmincrc, default VMINCRC=${VMINCRC-$HOME/.vmincrc} # Save env case "${MAIL+set}" in set ) env_MAIL=$MAIL ;; esac case "${VMINBOX+set}" in set ) env_VMINBOX=$VMINBOX ;; esac case "${VMCRASH+set}" in set ) env_VMCRASH=$VMCRASH ;; esac # Set defaults # TODO: Implement an inline frob which runs emacs, loads your .vm, and has # some other elisp commands to emit bourne shell code setting these # environment variables from the elisp defaults, which is evaled. # # Since setting MAIL is expensive, don't try to calculate the default # unless there really wasn't one inherited from the environment (which # would override anyway) case "$MAIL" in '' ) USER=${USER-${LOGNAME-`{ id | sed -ne 's/.*uid=[0-9]*(// s/).*// p' } \ || { (whoami) 2> /dev/null; }`}} for dir in /var/spool/mail /var/mail /usr/spool/mail /usr/mail; do if test -d "$dir" ; then MAIL=$dir/$USER if test -s "$MAIL" ; then break fi fi done ;; esac VMINBOX=$HOME/INBOX VMCRASH=$HOME/CRASH # Read from ~/.vmincrc if it exists if test ".$inhibit_vmincrc" != .t -a -f "$VMINCRC" ; then case "$verbose" in t ) echo "Reading $VMINCRC" ;; esac . "$VMINCRC" fi # Restore env MAIL=${env_MAIL-$MAIL} VMINBOX=${env_VMINBOX-$VMINBOX} VMCRASH=${env_VMCRASH-$VMCRASH} # Abort if there is an autosave for the inbox file and the autosave is newer. { set fnord `echo "$VMINBOX" \ | sed -ne 's,/$,,g;s,\(.*\)/\(.*\),\1/ \2,p'` shift vminbox_autosave="$1#$2#" set fnord `ls -t "$VMINBOX" "$vminbox_autosave" 2> /dev/null` shift case "$1" in "$vminbox_autosave" ) exec 1>&2 echo "$progname: Inbox autosave is newer than actual file. Aborting." ls -ltd "$vminbox_autosave" "$VMINBOX" exit 1 ;; esac } # If there is a crashbox already, incorporate it first. { if test -f "$VMCRASH" ; then case "$verbose" in t ) echo "Incorporating existing crashbox into inbox." echo "${PS4-+} cat $VMCRASH >> $VMINBOX" ;; esac cat "$VMCRASH" >> "$VMINBOX" exitstat=$? case $exitstat in 0 ) case "$verbose" in t ) echo "${PS4-+} rm $VMCRASH" ;; esac if rm "$VMCRASH"; then : else exec 1>&2 echo "$progname: Deletion of existing crashbox failed. Aborting." ls -ld "$VMCRASH" exit 1 fi ;; * ) exec 1>&2 echo "$progname: Incorporation of existing crashbox failed. Aborting." ls -ld "$VMCRASH" "$VMINBOX" exit $exitstat ;; esac fi } # If spool file is empty or nonexistent, stop now. { if test -s "$MAIL" ; then : else exec 1>&2 if test -f "$MAIL"; then echo "$progname: Mail spool file is empty; nothing to incorporate." ls -ld "$MAIL" 2> /dev/null else echo "$progname: Mail spool file is nonexistent; nothing to incorporate." fi exit 0 fi } # Incorporate new mail. { case "$verbose" in t ) echo "Incorporating new mail." echo "${PS4-+} ${MOVEMAIL-movemail} $MAIL $VMCRASH" ;; esac ${MOVEMAIL-movemail} "$MAIL" "$VMCRASH" \ && { case "$verbose" in t ) echo "${PS4-+} cat $VMCRASH >> $VMINBOX" ;; esac cat "$VMCRASH" >> "$VMINBOX" } \ && { case "$verbose" in t ) echo "${PS4-+} rm $VMCRASH" ;; esac rm "$VMCRASH" } } # vminc ends here