#!/bin/ksh
# @(#) allmail.ksh 2.0 93/11/22
# 1990 john h. dubois iii (john@armory.com)
# 93/04/03 read from smallest to largest.
# 93/07/01 Use ksh sorting to avoid need to invoke sort.
#          Use command line args & rcfile.
# 93/11/07 Print names of mailboxes remaining before each mail invokation
# 93/11/22 Print remaining mailboxes without $MAILDIR

name=${0##*/}
if [ -f $HOME/.allmail ]; then
    . $HOME/.allmail || exit 1
fi
[ -z "$MAILDIR" ] && MAILDIR=$HOME/mail
[ -z "$MAILPROG" ] && MAILPROG="mail -f"

typeset -i notfolders=0 boxnum=0

alias istrue="test 0 -ne"
alias isfalse="test 0 -eq"

Usage="Usage: $name [-hn] [-d maildir] [-p mailprog] [folder|file ...]"

while getopts :d:hnp: opt; do
    case $opt in
    h)
	echo \
"$name: read all mail folders.
$Usage
$name is used to read a set of mail folders.  It reads initialization
information from the environment and its rcfile, \$HOME/.allmail.  Folders
are read in order of their size, smallest first.  Folders that do not have
any mail in them are skipped.
The following variables can be set in the environment or in the rcfile.
Values in the environment override those in the rcfile.  Options given on
the command line override the variables.
MAILPROG: A program to use to read mail instead of the default, \"mail -f\".
MAILDIR: Where to find mail folders given with relative paths, \$HOME/mail
by default.
FOLDERS: The list of folders to read, if none are given on the command line.
NOTFOLDERS: The folder list is set to be all of the files in MAILDIR that
are mail folders and are not given in NOTFOLDERS.
If no folders are given on the command line and neither FOLDERS nor NOTFOLDERS
is set, the behaviour is as for NOTFOLDERS except that no folders are skipped.
Options:
-d <maildir>: <maildir> overrides the value of MAILDIR.
-h: Print this help.
-n: The files named on the command line are files that should be skipped,
    as with NOTFOLDERS.
-p <mailprog>: <mailprog> overrides the value of MAILPROG."
       exit 0
       ;;
    d)
	MAILDIR=$OPTARG
	;;
    n)  notfolders=1
	;;
    p)
	MAILPROG=$OPTARG
	;;
    +?)
	echo "$name: options should not be preceded by a '+'."
	exit 1
	;;
    ?) 
	echo "$name: $OPTARG: bad option.  Use -h for help."
	exit 1
	;;
    esac
done
 
# remove args that were options
let OPTIND=OPTIND-1
shift $OPTIND

[ -z "$MAILDIR" ] && MAILDIR=$HOME/mail
if cd "$MAILDIR"; then :; else
    echo "$name: $MAILDIR: no such directory."
    exit 1
fi

if isfalse notfolders; then
    [ $# -eq 0 ] && set -- $FOLDERS
    if [ $# -eq 0 -a -n "$NOTFOLDERS" ]; then
	set -- $NOTFOLDERS
	notfolders=1
    fi
fi

if istrue notfolders || [ $# -eq 0 ]; then
    if istrue notfolders; then
	OIFS=$IFS
	IFS=\|
	set -- "$@"
	NotPat="@($*)"
	IFS=$OIFS
    fi
    [ -z "$NotPat" ] && NotPat=.
    FOLDERS=
    for file in *; do
	if eval \
	[[ -f '"$file" && -r "$file" && -s "$file" && "$file"' != "$NotPat" ]];
	then
	    read line < "$file"
	    if [ "$line" =  ]; then
		FOLDERS="$FOLDERS $file"
	    fi
	fi
    done
    set -- $FOLDERS
fi


if [ $# -eq 0 ]; then
    print "No mail folders found."
    exit 0
fi

typeset -Z9 size
l -d "$@" 2>/dev/null |
while read line; do
    set -- $line
    [ $# -eq 0 ] && continue
    size=$5
    shift $(($#-1))
    file=$1
    # Make filenames absolute so they'll be found when we cd back to orig dir
    [[ "$file" != /* ]] && file="$MAILDIR/$file"
    # Make sort be a list of space-separated size,mailboxname pairs,
    # with elements of the list separated by newlines
    sort="$sort
$size $file"
done

cd -

# Set IFS to newline-only so pairs will be sorted together
IFS="
"
set -- $sort
set -s

# Set IFS to space so size & mailboxname can be separated
IFS=" "
set -- $*

# Pick out the mailbox names
while [ $# -gt 0 ]; do
    Mailboxes[boxnum]=$2
    let boxnum+=1
    shift 2
done

set -- "${Mailboxes[@]}"

while [ $# -gt 0 ]; do
    echo -n "Remaining: "
    for mailfile; do
	print -n -- "${mailfile##$MAILDIR/} "
    done
    echo ""
    $MAILPROG "$1"
    shift
done
