diff -Nur pine3.96.dist/README.dg pine3.96.local/README.dg
--- pine3.96.dist/README.dg	Wed Dec 31 16:00:00 1969
+++ pine3.96.local/README.dg	Sat Feb  7 20:22:57 1998
@@ -0,0 +1,39 @@
+version 4
+
+- merge in maildir support from Eric Green <thrytis@imaxx.net>.
+
+- fix maildir support for proper "new message" detection -- this makes it
+    useful for your inbox collection
+
+- add "Recipients" support to maildir
+
+- No more /tmp lockfiles, move them to $TMPDIR if defined or $HOME otherwise.
+    Nobody on my system uses shared folders, and bezerk is not a format I'd
+    advocate for shared folders anyhow.  It'd be much better to get maildir
+    to work with correct permissions.  So I'd rather not have the symlink
+    attacks.
+
+version 3
+
+- (written by "Randall S. Winchester" <rsw@Glue.umd.edu>) Add a "Recipients"
+    option to the aggregate selection -- similar to doing a selection by To
+    and then broadening with a selction by Cc... useful when you want to
+    know all the messages that a certain address received.
+
+- defines ALLOW_CHANGING_FROM in pine/osdep/os-lnx.h so that From can be
+    changed
+
+- adds a new define ALLOW_DISABLE_SENDER which enables a new option
+    disable-sender, suppressing the generation of Sender: and X-Sender:.
+    (defined in pine/osdep/os-lnx.h as well)
+
+- adds a new define QMAIL_RETURN_PATH which enables a new option
+    qmail-return-path which uses the qmail feature whereby the envelope
+    sender can be set by putting a Return-Path header into the message.
+    By default the Return-Path: will contain a copy of the From:, but if
+    you add Return-Path to your customized headers you can use any
+    combination of From: and envelope sender you want.
+    (defined in pine/osdep/os-lnx.h as well)
+
+You will need to define those features in whatever osdep file is appropriate
+for your system to make use of them.
Binary files pine3.96.dist/bin/imapd and pine3.96.local/bin/imapd differ
Binary files pine3.96.dist/bin/mtest and pine3.96.local/bin/mtest differ
Binary files pine3.96.dist/bin/pico and pine3.96.local/bin/pico differ
Binary files pine3.96.dist/bin/pilot and pine3.96.local/bin/pilot differ
Binary files pine3.96.dist/bin/pine and pine3.96.local/bin/pine differ
diff -Nur pine3.96.dist/imap/ANSI/c-client/Makefile pine3.96.local/imap/ANSI/c-client/Makefile
--- pine3.96.dist/imap/ANSI/c-client/Makefile	Tue Oct 15 15:28:55 1996
+++ pine3.96.local/imap/ANSI/c-client/Makefile	Thu Jan 29 00:59:05 1998
@@ -35,10 +35,10 @@
 ARRC=ar rc
 BINARIES=mail.o bezerk.o mtx.o tenex2.o mbox.o mh.o mmdf.o imap2.o pop3.o \
 	news.o nntpcunx.o phile.o dummy.o smtp.o nntp.o rfc822.o misc.o \
-	osdep.o sm_unix.o newsrc.o
+	osdep.o sm_unix.o newsrc.o maildir.o
 CC=cc
 CFLAGS=$(EXTRACFLAGS)
-DEFAULTDRIVERS=imap nntp pop3 mh tenex mtx mmdf bezerk news phile dummy
+DEFAULTDRIVERS=maildir imap nntp pop3 mh tenex mtx mmdf bezerk news phile dummy
 LN=ln -s
 MAKE=make
 MV=mv
@@ -427,6 +427,7 @@
 smtp.o: mail.h smtp.h rfc822.h misc.h osdep.h
 rfc822.o: mail.h rfc822.h misc.h
 tenex2.o: mail.h tenex2.h rfc822.h misc.h dummy.h osdep.h
+maildir.o: mail.h maildir.h misc.h osdep.h rfc822.h
 
 # OS-dependent module
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/bezerk.c pine3.96.local/imap/ANSI/c-client/bezerk.c
--- pine3.96.dist/imap/ANSI/c-client/bezerk.c	Tue Oct 15 15:21:57 1996
+++ pine3.96.local/imap/ANSI/c-client/bezerk.c	Thu Jan 29 01:01:32 1998
@@ -774,6 +774,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = bezerk_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = bezerk_search_string (bezerk_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = bezerk_search_seen;
@@ -2047,6 +2049,13 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char bezerk_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return bezerk_search_to (stream,msgno,d,n) ||
+    bezerk_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/bezerk.h pine3.96.local/imap/ANSI/c-client/bezerk.h
--- pine3.96.dist/imap/ANSI/c-client/bezerk.h	Wed Apr 12 22:38:11 1995
+++ pine3.96.local/imap/ANSI/c-client/bezerk.h	Thu Jan 29 01:01:32 1998
@@ -284,6 +284,7 @@
 char bezerk_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
 char bezerk_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
 char bezerk_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char bezerk_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
 char bezerk_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
 
 typedef char (*search_t) (MAILSTREAM *stream,long msgno,char *d,long n);
diff -Nur pine3.96.dist/imap/ANSI/c-client/env_unix.c pine3.96.local/imap/ANSI/c-client/env_unix.c
--- pine3.96.dist/imap/ANSI/c-client/env_unix.c	Fri Feb 21 10:17:11 1997
+++ pine3.96.local/imap/ANSI/c-client/env_unix.c	Sat Feb  7 20:09:08 1998
@@ -46,7 +46,7 @@
 static int blackBox = NIL;	/* is a black box */
 static long mbx_protection = 0600;
 static long sub_protection = 0600;
-static long lock_protection = 0666;
+static long lock_protection = 0600;
 static long disableFcntlLock =	/* flock() emulator is a no-op */
 #ifdef SVR4_DISABLE_FLOCK
   T
@@ -393,9 +393,20 @@
 {
   char *s = strrchr (fname,'/');
   struct stat sbuf;
+  char *e, *e1;
+
+  e = getenv("TMPDIR");
+  if (!e) e = getenv("HOME");
+  if (!e || *e == '\0') {
+    e = "/tmp/";
+    e1 = "";
+  } else {
+    e1 = e + strlen(e) - 1;
+    e1 = (*e1 == '/') ? "" : "/";
+  }
   if (stat (fname,&sbuf))	/* get file status */
-    sprintf (tmp,"/tmp/.%s",s ? s : fname);
-  else sprintf (tmp,"/tmp/.%hx.%lx",sbuf.st_dev,sbuf.st_ino);
+    sprintf (tmp,"%s%s.%s", e, e1, s ? s : fname);
+  else sprintf (tmp,"%s%s.%hx.%lx", e, e1, sbuf.st_dev, sbuf.st_ino);
   return chk_notsymlink (tmp,T) ? tmp : NIL;
 }
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/maildir.c pine3.96.local/imap/ANSI/c-client/maildir.c
--- pine3.96.dist/imap/ANSI/c-client/maildir.c	Wed Dec 31 16:00:00 1969
+++ pine3.96.local/imap/ANSI/c-client/maildir.c	Sat Feb  7 19:44:34 1998
@@ -0,0 +1,1618 @@
+/*
+ * Program:	Maildir routines
+ *
+ * Author:      Eric Green
+ *              Bloodhounds International Inc.
+ *              thrytis@imaxx.net
+ *
+ * Additional contributions from:
+ *              Aidas Kasparas (kaspar@soften.ktu.lt)
+ *
+ * Date:        27 April 1997
+ * Last Edited: 13 June 1997
+ *
+ * Based (heavily) on mh.c and other c-client library files by Mark Crispin:
+ *
+ *      	Mark Crispin
+ *		Networks and Distributed Computing
+ *		Computing & Communications
+ *		University of Washington
+ *		Administration Building, AG-44
+ *		Seattle, WA  98195
+ *		Internet: MRC@CAC.Washington.EDU
+ *
+ * Copyright 1995 by the University of Washington
+ *
+ *  Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appears in all copies and that both the
+ * above copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the University of Washington not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  This software is made
+ * available "as is", and
+ * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+ * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
+ * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+extern int errno;		/* just in case */
+#include "mail.h"
+#include "osdep.h"
+#include <pwd.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include "maildir.h"
+#include "rfc822.h"
+#include "misc.h"
+
+/* Maildir routines */
+
+
+/* Driver dispatch used by MAIL */
+
+DRIVER maildirdriver = {
+  "maildir",			/* driver name */
+  (DRIVER *) NIL,		/* next driver */
+  maildir_valid,		/* mailbox is valid for us */
+  maildir_parameters,		/* manipulate parameters */
+  maildir_find,			/* find mailboxes */
+  maildir_find_bboards,		/* find bboards */
+  maildir_find_all,		/* find all mailboxes */
+  maildir_find_all_bboards,	/* find all bboards */
+  maildir_subscribe,		/* subscribe to mailbox */
+  maildir_unsubscribe,		/* unsubscribe from mailbox */
+  maildir_subscribe_bboard,	/* subscribe to bboard */
+  maildir_unsubscribe_bboard,	/* unsubscribe from bboard */
+  maildir_create,		/* create mailbox */
+  maildir_delete,		/* delete mailbox */
+  maildir_rename,		/* rename mailbox */
+  maildir_open,			/* open mailbox */
+  maildir_close,		/* close mailbox */
+  maildir_fetchfast,		/* fetch message "fast" attributes */
+  maildir_fetchflags,		/* fetch message flags */
+  maildir_fetchstructure,	/* fetch message structure */
+  maildir_fetchheader,		/* fetch message header only */
+  maildir_fetchtext,		/* fetch message body only */
+  maildir_fetchbody,		/* fetch message body section */
+  maildir_setflag,		/* set message flag */
+  maildir_clearflag,		/* clear message flag */
+  maildir_search,		/* search for message based on criteria */
+  maildir_ping,			/* ping mailbox to see if still alive */
+  maildir_check,		/* check for new messages */
+  maildir_expunge,		/* expunge deleted messages */
+  maildir_copy,			/* copy messages to another mailbox */
+  maildir_move,			/* move messages to another mailbox */
+  maildir_append,		/* append string message to mailbox */
+  maildir_gc			/* garbage collect stream */
+};
+
+				/* prototype stream */
+MAILSTREAM maildirproto = {&maildirdriver};
+
+/* Maildir validate mailbox
+ * Accepts: mailbox name
+ * Returns: our driver if name is valid, NIL otherwise
+ */
+
+DRIVER *maildir_valid (char *name)
+{
+  return maildir_isvalid(name,T) ? &maildirdriver : NIL;
+}
+
+/* Maildir test for valid mailbox
+ * Accepts: mailbox name
+ *          name only test flag
+ * Returns: T if valid, NIL otherwise
+ */
+
+int maildir_isvalid (char *name,long justname)
+{
+  char tmp[MAILTMPLEN];
+  struct stat sbuf;
+  
+  if (!name || (!*name) || 
+      ((*name == '#') && 
+       (*(name+1) == 0 ||
+	(*(name+1) != 'm' && *(name+1) != 'M') ||
+	(*(name+2) != 'd' && *(name+1) != 'D') ||
+	*(name+3) != '/')))
+    return NIL;
+  
+  				/* If we are requested only to check 
+  				   if the name is appropriate then we
+  				   have done! */
+  if (justname && *name == '#') return T;
+  
+				/* must be valid local mailbox */
+  if ((*name != '*') && (*name != '{') &&
+      maildir_file (tmp,name) &&
+				/* assume its maildir if its a dir */
+      stat (tmp,&sbuf) == 0 && S_ISDIR (sbuf.st_mode))
+    return T;
+
+				/* INBOX is for default Maildir */
+  if (!strcmp (ucase (strcpy (tmp,name)), "INBOX") &&
+      (stat (maildir_file (tmp,name),&sbuf) == 0) &&
+      S_ISDIR (sbuf.st_mode))
+    return T;
+
+  return NIL;
+}
+
+
+/* Maildir manipulate driver parameters
+ * Accepts: function code
+ *	    function-dependent value
+ * Returns: function-dependent return value
+ */
+
+void *maildir_parameters (long function,void *value)
+{
+  return NIL;
+}
+
+/* Maildir find list of subscribed mailboxes
+ * Accepts: mail stream
+ *	    pattern to search
+ */
+
+void maildir_find (MAILSTREAM *stream,char *pat)
+{
+  void *s = NIL;
+  char *t;
+
+				/* read subscription database */
+  if (stream) while (t = sm_read (&s))
+    if (pmatch (t,pat) && maildir_isvalid (t,NIL)) mm_mailbox (t);
+}
+
+/* Maildir find list of subscribed bboards
+ * Accepts: mail stream
+ *	    pattern to search
+ */
+
+void maildir_find_bboards (MAILSTREAM *stream,char *pat)
+{
+  /* always a no-op */
+}
+
+/* Maildir find list of all mailboxes
+ * Accepts: mail stream
+ *	    pattern to search
+ */
+
+void maildir_find_all (MAILSTREAM *stream,char *pat)
+{
+  DIR *dirp;
+  struct direct *d;
+  char file[MAILTMPLEN];
+  char *s,*t;
+  int i = 0;
+  if (*pat == '{') return;	/* local only */
+  if (s = strrchr (pat,'/')) {	/* directory specified in pattern? */
+    strncpy (file,pat,i = (++s) - pat);
+    file[i] = '\0';		/* tie off prefix */
+    t = file;
+  }
+  else t = myhomedir ();	/* use home directory to search */
+  if (dirp = opendir (t)) {	/* now open that directory */
+    while (d = readdir (dirp))	/* for each directory entry */
+      if ((d->d_name[0] != '.') ||
+	  (d->d_name[1] && ((d->d_name[1] != '.') || d->d_name[2]))) {
+	strcpy (file + i,d->d_name);
+	if (pmatch (file,pat)) mm_mailbox (file);
+      }
+    closedir (dirp);		/* flush directory */
+  }
+				/* always an INBOX */
+  if (pmatch ("INBOX",pat)) mm_mailbox ("INBOX");
+}
+
+/* Maildir find list of all bboards
+ * Accepts: mail stream
+ *	    pattern to search
+ */
+
+void maildir_find_all_bboards (MAILSTREAM *stream,char *pat)
+{
+  /* Always a no-op */
+}
+
+/* Maildir subscribe to mailbox
+ * Accepts: mail stream
+ *	    mailbox to add to subscription list
+ * Returns: T on success, NIL on failure
+ */
+
+long maildir_subscribe (MAILSTREAM *stream,char *mailbox)
+{
+  return sm_subscribe (mailbox);
+}
+
+
+/* Maildir unsubscribe to mailbox
+ * Accepts: mail stream
+ *	    mailbox to delete from subscription list
+ * Returns: T on success, NIL on failure
+ */
+
+long maildir_unsubscribe (MAILSTREAM *stream,char *mailbox)
+{
+  return sm_unsubscribe (mailbox);
+}
+
+
+/* Maildir subscribe to bboard
+ * Accepts: mail stream
+ *	    bboard to add to subscription list
+ * Returns: T on success, NIL on failure
+ */
+
+long maildir_subscribe_bboard (MAILSTREAM *stream,char *mailbox)
+{
+  return NIL;			/* always fails */
+}
+
+
+/* Maildir unsubscribe to bboard
+ * Accepts: mail stream
+ *	    bboard to delete from subscription list
+ * Returns: T on success, NIL on failure
+ */
+
+long maildir_unsubscribe_bboard (MAILSTREAM *stream,char *mailbox)
+{
+  return NIL;			/* always fails */
+}
+
+/* Maildir create mailbox
+ * Accepts: mail stream
+ *	    mailbox name to create
+ *	    driver type to use
+ * Returns: T on success, NIL on failure
+ */
+
+long maildir_create (MAILSTREAM *stream,char *mailbox)
+{
+  char tmp[MAILTMPLEN];
+  char err[MAILTMPLEN];
+  int fnlen, i;
+  char *subdir_names[] = {"/cur","/new","/tmp",NULL};
+
+				/* must not already exist */
+  if (access (maildir_file (tmp,mailbox),F_OK) == 0) {
+    sprintf (err,"Can't create mailbox %s: mailbox already exists",mailbox);
+    mm_log (err,ERROR);
+    return NIL;
+  }
+  
+  maildir_file (tmp,mailbox);	/* get file name */
+  fnlen = strlen (tmp);
+  tmp[fnlen - 4] = '\0';	/* making main directory's name */
+  fnlen -= 4;
+
+  if (mkdir (tmp,0700)) {	/* try to make new dir */
+    sprintf (err,"Can't create mailbox %s: %s %s",
+	     mailbox,tmp,strerror (errno));
+    mm_log (err,ERROR);
+    return NIL;
+  }
+
+  for (i = 0; subdir_names[i]; i++) {
+    strcpy (tmp + fnlen,subdir_names[i]);
+
+    if (mkdir (tmp,0700)) {	/* try to make new dir */
+      sprintf (err,"Can't create mailbox %s: %s %s",
+	       mailbox,tmp,strerror (errno));
+      mm_log (err,ERROR);
+      return NIL;
+    }
+  }
+
+  return T;			/* return success */
+}
+
+
+/* Maildir delete mailbox
+ * Accepts: mail stream
+ *	    mailbox name to delete
+ * Returns: T on success, NIL on failure
+ */
+
+long maildir_delete (MAILSTREAM *stream,char *mailbox)
+{
+  DIR *dirp;
+  struct direct *d;
+  int i,j;
+  char tmp[MAILTMPLEN],err[MAILTMPLEN];
+  char *subdir_names[] = {"cur/","new/","tmp/",NULL};
+
+				/* check if mailbox even exists */
+  if (!maildir_isvalid (mailbox,NIL)) {
+    sprintf (tmp,"Can't delete mailbox %s: no such mailbox",mailbox);
+    mm_log (tmp,ERROR);
+    return NIL;
+  }
+
+				/* get name of directory */
+  i = strlen (maildir_file (tmp,mailbox)) + 1;
+  for (j = 0; subdir_names[j]; j++) {
+    strcpy (tmp + i - 4,subdir_names[j]);
+    if (dirp = opendir (tmp)) {	/* open directory */
+      while (d = readdir (dirp))	/* empty the directory */
+	if (strcmp (d->d_name,".") && strcmp (d->d_name,"..")) {
+	  strcpy (tmp + i,d->d_name);
+	  unlink (tmp);
+	}
+      closedir (dirp);		/* flush directory */
+    }
+				/* remove the subdir */
+    tmp[i + 3] = '\0';
+    if (rmdir (tmp)) {
+      sprintf (err,"Can't delete directory %s: %s",tmp,strerror (errno));
+      mm_log (err,ERROR);
+    }
+  }
+
+				/* try to remove the directory */
+  *(tmp + i - 5) = '\0';
+  if (rmdir (tmp)) {
+    sprintf (err,"Can't delete mailbox %s: %s",mailbox,strerror (errno));
+    mm_log (err,ERROR);
+    return NIL;
+  }
+  return T;			/* return success */
+}
+
+
+/* Mail rename mailbox
+ * Accepts: mail stream
+ *	    old mailbox name
+ *	    new mailbox name
+ * Returns: T on success, NIL on failure
+ */
+
+long maildir_rename (MAILSTREAM *stream,char *old,char *new)
+{
+  char tmp[MAILTMPLEN],tmpnew[MAILTMPLEN];
+
+				/* old mailbox name must be valid */
+  if (!maildir_isvalid (old,NIL)) {
+    sprintf (tmp,"Can't rename mailbox %s: no such mailbox",old);
+    mm_log (tmp,ERROR);
+    return NIL;
+  }
+
+				/* new mailbox name must not exist */
+  if (access (maildir_file (tmp,new),F_OK) == 0) {
+    sprintf (tmp,"Can't rename to mailbox %s: destination already exists",new);
+    mm_log (tmp,ERROR);
+    return NIL;
+  }
+
+				/* try to rename the directory */
+  if (rename (maildir_file (tmp,old),maildir_file (tmpnew,new))) {
+    sprintf (tmp,"Can't rename mailbox %s to %s: %s",old,new,strerror (errno));
+    mm_log (tmp,ERROR);
+    return NIL;
+  }
+  return T;			/* return success */
+}
+
+/* Maildir open
+ * Accepts: stream to open
+ * Returns: stream on success, NIL on failure
+ */
+
+MAILSTREAM *maildir_open (MAILSTREAM *stream)
+{
+  int fd;
+  char tmp[MAILTMPLEN],tmp2[MAILTMPLEN];
+  struct stat sbuf;
+				/* OP_PROTOTYPE call */
+  if (!stream) return &maildirproto;
+  if (LOCAL) {			/* close old file if stream being recycled */
+    maildir_close (stream);	/* dump and save the changes */
+    stream->dtb = &maildirdriver; /* reattach this driver */
+    mail_free_cache (stream);	/* clean up cache */
+  }
+
+  stream->local = fs_get (sizeof (MAILDIRLOCAL));
+				/* note if an INBOX or not */
+  LOCAL->inbox = !strcmp (ucase (strcpy (tmp,stream->mailbox)),"INBOX") ||
+      !strcmp (stream->mailbox,maildir_file (tmp2,"INBOX"));
+  LOCAL->dir = cpystr (maildir_file (tmp,stream->mailbox)); /* copy dir name */
+				/* make temporary buffer */
+  LOCAL->buf = (char *) fs_get ((LOCAL->buflen = MAXMESSAGESIZE) + 1);
+  LOCAL->scantime = 0;		/* not scanned yet */
+  LOCAL->hdr = NIL;
+  stream->sequence++;		/* bump sequence number */
+  stream->nmsgs = stream->recent = 0;
+
+  /* do it twice so that we can check for new messages correctly */
+  maildir_ping_core(stream);
+  if (maildir_ping (stream) && !(stream->nmsgs || stream->silent))
+    mm_log ("Mailbox is empty",(long) NIL);
+
+  maildir_clean (LOCAL->dir);	/* clean out tmp qmail dir */
+  return stream;		/* return stream to caller */
+}
+
+
+/* Maildir close
+ * Accepts: MAIL stream
+ */
+
+void maildir_close (MAILSTREAM *stream)
+{
+  MESSAGECACHE *elt;
+  int i;
+  mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL);
+  
+				/* clean out the cached paths */
+  for (i = 1; i <= stream->nmsgs; i++)
+    if ((elt = (MESSAGECACHE *) (*mc) (stream,i,CH_ELT)) && elt->data1)
+      fs_give ((void **) &elt->data1);
+  
+  if (LOCAL) {			/* only if a stream is open */
+    if (LOCAL->dir) fs_give ((void **) &LOCAL->dir);
+    maildir_gc (stream,GC_TEXTS); /* free local cache */
+				/* free local scratch buffer */
+    if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
+				/* nuke the local data */
+    fs_give ((void **) &stream->local);
+    stream->dtb = NIL;		/* log out the DTB */
+  }
+}
+
+/* Maildir fetch fast information
+ * Accepts: MAIL stream
+ *	    sequence
+ */
+
+void maildir_fetchfast (MAILSTREAM *stream,char *sequence)
+{
+  long i;
+				/* ugly and slow */
+  if (stream && LOCAL && mail_sequence (stream,sequence))
+    for (i = 1; i <= stream->nmsgs; i++)
+      if (mail_elt (stream,i)->sequence)
+	maildir_fetchheader (stream,i);
+}
+
+
+/* Maildir fetch flags
+ * Accepts: MAIL stream
+ *	    sequence
+ */
+
+void maildir_fetchflags (MAILSTREAM *stream,char *sequence)
+{
+  return;			/* no-op for local mail */
+}
+
+
+/* Maildir fetch envelope
+ * Accepts: MAIL stream
+ *	    message # to fetch
+ *	    pointer to return body
+ * Returns: envelope of this message, body returned in body value
+ */
+
+ENVELOPE *maildir_fetchstructure (MAILSTREAM *stream,long msgno,BODY **body)
+{
+  char *h,*t;
+  LONGCACHE *lelt;
+  ENVELOPE **env;
+  STRING bs;
+  BODY **b;
+  if (stream->scache) {		/* short cache */
+    if (msgno != stream->msgno){/* flush old poop if a different message */
+      mail_free_envelope (&stream->env);
+      mail_free_body (&stream->body);
+    }
+    stream->msgno = msgno;
+    env = &stream->env;		/* get pointers to envelope and body */
+    b = &stream->body;
+  }
+  else {			/* long cache */
+    lelt = mail_lelt (stream,msgno);
+    env = &lelt->env;		/* get pointers to envelope and body */
+    b = &lelt->body;
+  }
+  if ((body && !*b) || !*env) {	/* have the poop we need? */
+    mail_free_envelope (env);	/* flush old envelope and body */
+    mail_free_body (b);
+    h = maildir_fetchheader (stream,msgno);
+				/* can't use fetchtext since it'll set seen */
+    t = stream->text ? stream->text : "";
+    INIT (&bs,mail_string,(void *) t,strlen (t));
+				/* parse envelope and body */
+    rfc822_parse_msg (env,body ? b : NIL,h,strlen (h),&bs,mylocalhost (),
+		      LOCAL->buf);
+  }
+  if (body) *body = *b;		/* return the body */
+  return *env;			/* return the envelope */
+}
+
+
+/* Maildir fetch message header
+ * Accepts: MAIL stream
+ *	    message # to fetch
+ * Returns: message header in RFC822 format
+ */
+
+char *maildir_fetchheader (MAILSTREAM *stream,long msgno)
+{
+  unsigned long i,hdrsize;
+  int fd;
+  char *s,*b;
+  char tmp[MAILTMPLEN];
+  struct stat sbuf;
+  struct tm *tm;
+  MESSAGECACHE *elt = mail_elt (stream,msgno);
+
+  if (stream->msgno != msgno) {
+    maildir_gc (stream,GC_TEXTS); /* invalidate current cache */
+				/* build message file name */
+    sprintf (tmp,"%s/%s",LOCAL->dir,(char *) elt->data1);
+    if ((fd = open (tmp,O_RDONLY,NIL)) >= 0) {
+      fstat (fd,&sbuf);		/* get size of message */
+				/* make plausible IMAPish date string */
+      tm = gmtime (&sbuf.st_mtime);
+      elt->day = tm->tm_mday; elt->month = tm->tm_mon + 1;
+      elt->year = tm->tm_year + 1900 - BASEYEAR;
+      elt->hours = tm->tm_hour; elt->minutes = tm->tm_min;
+      elt->seconds = tm->tm_sec;
+      elt->zhours = 0; elt->zminutes = 0;
+				/* slurp message */
+      read (fd,s = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);
+      s[sbuf.st_size] = '\0';	/* tie off file */
+      close (fd);		/* close file */
+
+      for (i = 0,b = s; *b && !(i && (*b == '\n')); i = (*b++ == '\n'));
+      hdrsize = (*b ? ++b:b)-s;	/* number of header bytes */
+      elt->rfc822_size =	/* size of entire message in CRLF form */
+	strcrlfcpy (&LOCAL->hdr,&i,s,hdrsize) +
+	strcrlfcpy (&stream->text,&i,b,sbuf.st_size - hdrsize);
+      fs_give ((void **) &s);
+    }
+  }
+  
+  return LOCAL->hdr ? LOCAL->hdr : "";
+}
+
+/* Maildir fetch message text (body only)
+ * Accepts: MAIL stream
+ *	    message # to fetch
+ * Returns: message text in RFC822 format
+ */
+
+char *maildir_fetchtext (MAILSTREAM *stream,long msgno)
+{
+  MESSAGECACHE *elt = mail_elt (stream,msgno);
+				/* snarf message if don't have it yet */
+  if (stream->msgno != msgno) maildir_fetchheader (stream,msgno);
+  if (!elt->seen) maildir_elt_setflag(stream,elt,fSEEN); /* mark as seen */
+  return stream->text ? stream->text : "";
+}
+
+
+/* Maildir fetch message body as a structure
+ * Accepts: Mail stream
+ *	    message # to fetch
+ *	    section specifier
+ * Returns: pointer to section of message body
+ */
+
+char *maildir_fetchbody (MAILSTREAM *stream,long m,char *s,unsigned long *len)
+{
+  BODY *b;
+  PART *pt;
+  unsigned long i;
+  char *base;
+  unsigned long offset = 0;
+  MESSAGECACHE *elt = mail_elt (stream,m);
+				/* make sure have a body */
+  if (!(maildir_fetchstructure (stream,m,&b) && b && s && *s &&
+	((i = strtol (s,&s,10)) > 0) && (base = maildir_fetchtext (stream,m))))
+    return NIL;
+  do {				/* until find desired body part */
+				/* multipart content? */
+    if (b->type == TYPEMULTIPART) {
+      pt = b->contents.part;	/* yes, find desired part */
+      while (--i && (pt = pt->next));
+      if (!pt) return NIL;	/* bad specifier */
+				/* note new body, check valid nesting */
+      if (((b = &pt->body)->type == TYPEMULTIPART) && !*s) return NIL;
+      offset = pt->offset;	/* get new offset */
+    }
+    else if (i != 1) return NIL;/* otherwise must be section 1 */
+				/* need to go down further? */
+    if (i = *s) switch (b->type) {
+    case TYPEMESSAGE:		/* embedded message */
+      offset = b->contents.msg.offset;
+      b = b->contents.msg.body;	/* get its body, drop into multipart case */
+    case TYPEMULTIPART:		/* multipart, get next section */
+      if ((*s++ == '.') && (i = strtol (s,&s,10)) > 0) break;
+    default:			/* bogus subpart specification */
+      return NIL;
+    }
+  } while (i);
+				/* lose if body bogus */
+  if ((!b) || b->type == TYPEMULTIPART) return NIL;
+  if (!elt->seen) maildir_elt_setflag(stream,elt,fSEEN); /* mark as seen */
+  return rfc822_contents (&LOCAL->buf,&LOCAL->buflen,len,base + offset,
+			  b->size.ibytes,b->encoding);
+}
+
+
+/* Maildir set flag
+ * Accepts: MAIL stream
+ *	    sequence
+ *	    flag(s)
+ */
+
+void maildir_setflag (MAILSTREAM *stream,char *sequence,char *flag)
+{
+  MESSAGECACHE *elt;
+  long i;
+  short f = maildir_getflags (stream,flag);
+  if (!f) return;		/* no-op if no flags to modify */
+				/* get sequence and loop on it */
+
+  if (mail_sequence (stream,sequence)) for (i = 1; i <= stream->nmsgs; i++)
+    if ((elt = mail_elt (stream,i))->sequence)
+				/* set all requested flags */
+      maildir_elt_setflag (stream,elt,f);
+}
+
+
+/* Maildir clear flag
+ * Accepts: MAIL stream
+ *	    sequence
+ *	    flag(s)
+ */
+
+void maildir_clearflag (MAILSTREAM *stream,char *sequence,char *flag)
+{
+  MESSAGECACHE *elt;
+  long i = stream->nmsgs;
+  int changed = NIL;
+  short f = maildir_getflags (stream,flag);
+  if (!f) return;		/* no-op if no flags to modify */
+				/* get sequence and loop on it */
+  if (mail_sequence (stream,sequence)) for (i = 1; i <= stream->nmsgs; i++)
+    if ((elt = mail_elt (stream,i))->sequence) {
+				/* clear all requested flags */
+      if (f&fSEEN && elt->seen) {
+	elt->seen = NIL;
+	changed = T;
+      }
+      if (f&fDELETED && elt->deleted) {
+	elt->deleted = NIL;
+	changed = T;
+      }
+      if (f&fFLAGGED && elt->flagged) {
+	elt->flagged = NIL;
+	changed = T;
+      }
+      if (f&fANSWERED && elt->answered) {
+	elt->answered = NIL;
+	changed = T;
+      }
+
+      if (changed)		/* write new flags to disk */
+	maildir_write_flags (stream,elt);
+    }
+}
+
+/* Maildir search for messages
+ * Accepts: MAIL stream
+ *	    search criteria
+ */
+
+void maildir_search (MAILSTREAM *stream,char *criteria)
+{
+  long i,n;
+  char *d;
+  search_t f;
+				/* initially all searched */
+  for (i = 1; i <= stream->nmsgs; ++i) mail_elt (stream,i)->searched = T;
+				/* get first criterion */
+  if (criteria && (criteria = strtok (criteria," "))) {
+				/* for each criterion */
+    for (; criteria; (criteria = strtok (NIL," "))) {
+      f = NIL; d = NIL; n = 0;	/* init then scan the criterion */
+      switch (*ucase (criteria)) {
+      case 'A':			/* possible ALL, ANSWERED */
+	if (!strcmp (criteria+1,"LL")) f = maildir_search_all;
+	else if (!strcmp (criteria+1,"NSWERED")) f = maildir_search_answered;
+	break;
+      case 'B':			/* possible BCC, BEFORE, BODY */
+	if (!strcmp (criteria+1,"CC"))
+	  f = maildir_search_string (maildir_search_bcc,&d,&n);
+	else if (!strcmp (criteria+1,"EFORE"))
+	  f = maildir_search_date (maildir_search_before,&n);
+	else if (!strcmp (criteria+1,"ODY"))
+	  f = maildir_search_string (maildir_search_body,&d,&n);
+	break;
+      case 'C':			/* possible CC */
+	if (!strcmp (criteria+1,"C")) 
+	  f = maildir_search_string (maildir_search_cc,&d,&n);
+	break;
+      case 'D':			/* possible DELETED */
+	if (!strcmp (criteria+1,"ELETED")) f = maildir_search_deleted;
+	break;
+      case 'F':			/* possible FLAGGED, FROM */
+	if (!strcmp (criteria+1,"LAGGED")) f = maildir_search_flagged;
+	else if (!strcmp (criteria+1,"ROM"))
+	  f = maildir_search_string (maildir_search_from,&d,&n);
+	break;
+      case 'K':			/* possible KEYWORD */
+	if (!strcmp (criteria+1,"EYWORD"))
+	  f = maildir_search_flag (maildir_search_keyword,&d);
+	break;
+      case 'N':			/* possible NEW */
+	if (!strcmp (criteria+1,"EW")) f = maildir_search_new;
+	break;
+
+      case 'O':			/* possible OLD, ON */
+	if (!strcmp (criteria+1,"LD")) f = maildir_search_old;
+	else if (!strcmp (criteria+1,"N"))
+	  f = maildir_search_date (maildir_search_on,&n);
+	break;
+      case 'R':			/* possible RECENT */
+	if (!strcmp (criteria+1,"ECENT")) f = maildir_search_recent;
+	else if (!strcmp (criteria+1, "ECIPIENT"))
+	    f = maildir_search_string (maildir_search_recipient,&d,&n);
+	break;
+      case 'S':			/* possible SEEN, SINCE, SUBJECT */
+	if (!strcmp (criteria+1,"EEN")) f = maildir_search_seen;
+	else if (!strcmp (criteria+1,"INCE"))
+	  f = maildir_search_date (maildir_search_since,&n);
+	else if (!strcmp (criteria+1,"UBJECT"))
+	  f = maildir_search_string (maildir_search_subject,&d,&n);
+	break;
+      case 'T':			/* possible TEXT, TO */
+	if (!strcmp (criteria+1,"EXT"))
+	  f = maildir_search_string (maildir_search_text,&d,&n);
+	else if (!strcmp (criteria+1,"O"))
+	  f = maildir_search_string (maildir_search_to,&d,&n);
+	break;
+      case 'U':			/* possible UN* */
+	if (criteria[1] == 'N') {
+	  if (!strcmp (criteria+2,"ANSWERED")) f = maildir_search_unanswered;
+	  else if (!strcmp (criteria+2,"DELETED")) f = maildir_search_undeleted;
+	  else if (!strcmp (criteria+2,"FLAGGED")) f = maildir_search_unflagged;
+	  else if (!strcmp (criteria+2,"KEYWORD"))
+	    f = maildir_search_flag (maildir_search_unkeyword,&d);
+	  else if (!strcmp (criteria+2,"SEEN")) f = maildir_search_unseen;
+	}
+	break;
+      default:			/* we will barf below */
+	break;
+      }
+      if (!f) {			/* if can't determine any criteria */
+	sprintf (LOCAL->buf,"Unknown search criterion: %s",criteria);
+	mm_log (LOCAL->buf,ERROR);
+	return;
+      }
+				/* run the search criterion */
+      for (i = 1; i <= stream->nmsgs; ++i)
+	if (mail_elt (stream,i)->searched && !(*f) (stream,i,d,n))
+	  mail_elt (stream,i)->searched = NIL;
+    }
+				/* report search results to main program */
+    for (i = 1; i <= stream->nmsgs; ++i)
+      if (mail_elt (stream,i)->searched) mail_searched (stream,i);
+  }
+}
+
+
+/* Maildir ping mailbox
+ * Accepts: MAIL stream
+ * Returns: T if stream alive, else NIL
+ * No-op for readonly files, since read/writer can expunge it from under us!
+ *
+ * Note: this depends on qmail naming of messages
+ */
+
+long maildir_ping_core (MAILSTREAM *stream)
+{
+  char tmp[MAILTMPLEN];
+  MESSAGECACHE *elt;
+  struct stat sbuf;
+  DIR *dir;
+  struct direct *d;
+  int reloadall = NIL;
+  long i;
+  long nmsgs = stream->nmsgs;
+  long recent = 0;
+  char *s;
+  mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL);
+
+  if (stat (LOCAL->dir,&sbuf) < 0) {
+    sprintf (tmp,"Unable to open maildir: %s",strerror (errno));
+    mm_log (tmp,ERROR);
+    return NIL;
+  }
+  
+  if (sbuf.st_ctime != LOCAL->scantime) {
+    /* update the message list */
+    struct direct **names = NIL;
+    nmsgs = scandir (LOCAL->dir,&names,maildir_select,maildir_namesort);
+
+    mm_critical (stream);	/* go critical */
+    LOCAL->scantime = sbuf.st_ctime;
+
+				/* check if old files same */
+    for (i = 0; i < stream->nmsgs; i++)
+      if (strcmp ((char *) mail_elt (stream, i + 1)->data1,
+		  names[i]->d_name)) {
+	reloadall = T;
+	break;
+      }
+
+    if (reloadall) {		/* files are out of order, rebuild cache */
+      i = 1;
+      while (i <= stream->nmsgs)
+				/* clean out cache */
+	if ((elt = (MESSAGECACHE *) (*mc) (stream,i,CH_ELT))) {
+	  fs_give ((void **) &elt->data1);
+	  mail_expunged (stream,i);
+	}
+	else
+	  i++;
+      
+      mm_log ("Warning: Mailbox has changed in an unexpected way.  Reloading.",
+	      WARN);
+      stream->nmsgs = 0;
+    }
+    
+    for (i = stream->nmsgs; i < nmsgs; i++) {
+				/* if newly seen, add to list */
+      (elt = mail_elt (stream, i + 1))->data1 = (long) cpystr (names[i]->d_name);
+      elt->valid = T;
+      elt->recent = T;
+      recent++;
+
+      /* grab the flags */
+      if ((s = strstr (names[i]->d_name,":2,"))) {
+	s += 3;
+	if (strchr (s,'F'))
+	  elt->flagged = T;
+	if (strchr (s,'R'))
+	  elt->answered = T;
+	if (strchr (s,'S'))
+	  elt->seen = T;
+	if (strchr (s,'T'))
+	  elt->deleted = T;
+      }
+    }
+    mm_nocritical (stream);	/* release critical */
+				/* free the names stuff */
+    for (i = 0; i < nmsgs; i++)
+      fs_give ((void **) &names[i]);
+    if (names)
+      fs_give ((void **) &names);
+  }
+  mail_exists (stream,nmsgs);	/* notify upper level of mailbox size */
+  if (!reloadall) mail_recent (stream,recent);
+  return T;			/* return that we are alive */
+}
+
+long maildir_ping (MAILSTREAM *stream)
+{
+  maildir_copynew (LOCAL->dir);
+  return maildir_ping_core(stream);
+}
+  
+
+/* Maildir check mailbox
+ * Accepts: MAIL stream
+ * No-op for readonly files, since read/writer can expunge it from under us!
+ */
+
+void maildir_check (MAILSTREAM *stream)
+{
+  /* Perhaps in the future this will preserve flags */
+  if (maildir_ping (stream)) mm_log ("Check completed",(long) NIL);
+}
+
+
+/* Maildir expunge mailbox
+ * Accepts: MAIL stream
+ */
+
+void maildir_expunge (MAILSTREAM *stream)
+{
+  MESSAGECACHE *elt;
+  unsigned long i = 1;
+  unsigned long n = 0;
+  unsigned long recent = stream->recent;
+  
+  maildir_gc (stream,GC_TEXTS);	/* invalidate texts */
+  mm_critical (stream);		/* go critical */
+  while (i <= stream->nmsgs) {	/* for each message */
+				/* if deleted, need to trash it */
+    if ((elt = mail_elt (stream,i))->deleted) {
+      sprintf (LOCAL->buf,"%s/%s",LOCAL->dir,(char *) elt->data1);
+      if (unlink (LOCAL->buf)) {/* try to delete the message */
+	sprintf (LOCAL->buf,"Expunge of message %ld failed, aborted: %s",i,
+		 strerror (errno));
+	mm_log (LOCAL->buf,WARN);
+	break;
+      }
+				/* free the cached filename */
+      if (elt->data1) fs_give ((void **) &elt->data1);
+      if (elt->recent) --recent;/* if recent, note one less recent message */
+      mail_expunged (stream,i);	/* notify upper levels */
+      n++;			/* count up one more expunged message */
+    }
+    else i++;			/* otherwise try next message */
+  }
+  if (n) {			/* output the news if any expunged */
+    sprintf (LOCAL->buf,"Expunged %ld messages",n);
+    mm_log (LOCAL->buf,(long) NIL);
+  }
+  else mm_log ("No messages deleted, so no update needed",(long) NIL);
+  mm_nocritical (stream);	/* release critical */
+				/* notify upper level of new mailbox size */
+  mail_exists (stream,stream->nmsgs);
+  mail_recent (stream,recent);
+}
+
+/* Maildir copy message(s)
+ * Accepts: MAIL stream
+ *	    sequence
+ *	    destination mailbox
+ * Returns: T if copy successful, else NIL
+ */
+
+long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox)
+{
+  STRING st;
+  MESSAGECACHE *elt;
+  struct stat sbuf;
+  int fd;
+  long i;
+  char *s,tmp[MAILTMPLEN];
+				/* copy the messages */
+  if (mail_sequence (stream,sequence)) for (i = 1; i <= stream->nmsgs; i++)
+    if ((elt = mail_elt (stream,i))->sequence) {
+      sprintf (LOCAL->buf,"%s/%s",LOCAL->dir,(char *) elt->data1);
+      if ((fd = open (LOCAL->buf,O_RDONLY,NIL)) < 0) return NIL;
+      fstat (fd,&sbuf);		/* get size of message */
+				/* slurp message */
+      read (fd,s = (char *) fs_get (sbuf.st_size +1),sbuf.st_size);
+      s[sbuf.st_size] = '\0';	/* tie off file */
+      close (fd);		/* flush message file */
+      INIT (&st,mail_string,(void *) s,sbuf.st_size);
+      sprintf (LOCAL->buf,"%s%s%s%s%s)",
+	       elt->seen ? " \\Seen" : "",
+	       elt->deleted ? " \\Deleted" : "",
+	       elt->flagged ? " \\Flagged" : "",
+	       elt->answered ? " \\Answered" : "",
+	       (elt->seen || elt->deleted || elt->flagged || elt->answered) ?
+	       "" : " ");
+      LOCAL->buf[0] = '(';	/* open list */
+      mail_date (tmp,elt);	/* generate internal date */
+      if (!maildir_append (stream,mailbox,LOCAL->buf,tmp,&st)) {
+	fs_give ((void **) &s);	/* give back temporary space */
+	return NIL;
+      }
+      fs_give ((void **) &s);	/* give back temporary space */
+    }
+  return T;			/* return success */
+}
+
+
+/* Maildir move message(s)
+ * Accepts: MAIL stream
+ *	    sequence
+ *	    destination mailbox
+ * Returns: T if move successful, else NIL
+ */
+
+long maildir_move (MAILSTREAM *stream,char *sequence,char *mailbox)
+{
+  MESSAGECACHE *elt;
+  if (maildir_copy (stream,sequence,mailbox)) return NIL;
+				/* delete all requested messages */
+  maildir_setflag (stream,sequence,"\\Deleted");
+  return T;
+}
+
+/* Maildir append message string
+ * Accepts: mail stream
+ *	    destination mailbox
+ *	    optional flags
+ *	    optional date
+ *	    stringstruct of message to append
+ * Returns: T on success, NIL on failure
+ */
+
+long maildir_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date,
+		   STRING *message)
+{
+  int fd;
+  char c,*s;
+  char tmp[MAILTMPLEN],file[MAILTMPLEN],path1[MAILTMPLEN],path2[MAILTMPLEN];
+  MESSAGECACHE elt;
+  long i;
+  long size = 0;
+  long ret = LONGT;
+  short uf = 0;
+  
+  /*  
+     This is intentionaly made static.  Users can ask to save a LOT of messages
+     at once and this program can do that within one second. Dan's assumption
+     that time+pid+hostname always will be unique stops being true in this
+     case. So we will add yet another number to host part of message file's
+     name. Hostname is used only to make filename unique and Dan  explicitly
+     says that "<...>  Other than this [skipping filenames starting at dot] ,
+     readers should not attempt to parse filenames. <...>". Therefore this 
+     addition should be no problem. Am I right, Dan?   --AK
+  */ 
+  
+  static unsigned int transact = 0;
+
+  if (flags) 			/* get flags if given */
+    uf = maildir_getflags (user_flags (&maildirproto),flags);
+
+  if (date) {			/* want to preserve date? */
+				/* yes, parse date into an elt */
+    if (!mail_parse_date (&elt,date)) {
+      sprintf (tmp,"Bad date in append: %s",date);
+      mm_log (tmp,ERROR);
+      return NIL;
+    }
+  }
+				/* N.B.: can't use LOCAL->buf for tmp */
+				/* make sure valid mailbox */
+  if (!maildir_isvalid (mailbox, NIL)) {
+    sprintf (tmp,"Not a valid Maildir mailbox: %s",mailbox);
+    mm_log (tmp,ERROR);
+    return NIL;
+  }
+				/* build file name we will use */
+  sprintf (file,"%u.%d.%09u.%s:2,%s%s%s%s",
+	   time (0),getpid (),transact++,mylocalhost (),
+	   uf&fFLAGGED ? "F" : "",uf&fANSWERED ? "R" : "",
+	   uf&fSEEN ? "S" : "",uf&fDELETED ? "T" : "");
+				/* build tmp file name */
+  sprintf (path1,"%s/../tmp/%s",maildir_file (tmp,mailbox),file);
+  
+  if ((fd = open (path1,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) {
+    sprintf (tmp,"Can't open append mailbox: %s",strerror (errno));
+    mm_log (tmp,ERROR);
+    return NIL;
+  }
+  i = SIZE (message);		/* get size of message */
+  s = (char *) fs_get (i + 1);	/* get space for the data */
+				/* copy the data w/o CR's */
+  while (i--) if ((c = SNX (message)) != '\015') s[size++] = c;
+  mm_critical (stream);		/* go critical */
+				/* write the data */
+  if ((write (fd,s,size) < 0) || fsync (fd)) {
+    unlink (path1);		/* delete message */
+    sprintf (tmp,"Message append failed: %s",strerror (errno));
+    mm_log (tmp,ERROR);
+    ret = NIL;
+  }
+				/* build final filename to use */
+  sprintf (path2,"%s/../new/%s",maildir_file (tmp,mailbox),file);
+  if (link (path1,path2) < 0) {
+    sprintf (tmp,"Message append failed: %s",strerror (errno));
+    mm_log (tmp,ERROR);
+    ret = NIL;
+  }
+  unlink (path1);
+  
+  close (fd);			/* close the file */
+  mm_nocritical (stream);	/* release critical */
+  fs_give ((void **) &s);	/* flush the buffer */
+  return ret;
+}
+
+
+/* Maildir garbage collect stream
+ * Accepts: mail stream
+ *	    garbage collection flags
+ */
+
+void maildir_gc (MAILSTREAM *stream,long gcflags)
+{
+  unsigned long i;
+  
+  if (gcflags & GC_TEXTS) {	/* garbage collect texts? */
+				/* flush texts from cache */
+    if (LOCAL->hdr) fs_give ((void **) &LOCAL->hdr);
+    if (stream->text) fs_give ((void **) &stream->text);
+    stream->msgno = 0;		/* invalidate stream text */
+  }
+}
+
+/* Internal routines */
+
+
+/* Maildir file name selection test
+ * Accepts: candidate directory entry
+ * Returns: T to use file name, NIL to skip it
+ */
+
+int maildir_select (struct direct *name)
+{
+  if (name->d_name[0] != '.')
+    return T;
+
+  return NIL;
+}
+
+
+/* Maildir file name comparision
+ * Accepts: first candidate directory entry
+ *	    second candidate directory entry
+ * Returns: negative if d1 < d2, 0 if d1 == d2, postive if d1 > d2
+ */
+
+int maildir_namesort (struct direct **d1,struct direct **d2)
+{
+  return strcmp ((*d1)->d_name,(*d2)->d_name);
+}
+
+
+/* Maildir mail generate file string
+ * Accepts: temporary buffer to write into (at least MAILTMPLEN long)
+ *	    mailbox name string
+ * Returns: local file string
+ */
+
+char *maildir_file (char *dst,char *name)
+{
+  char tmp[MAILTMPLEN];
+  
+  if (strlen (name) > 3 &&	/* safe do other comparisons */
+      (*name == '#') &&
+      (name[1] == 'm' || name[1] == 'M') &&
+      (name[2] == 'd' || name[2] == 'D') &&
+      (name[3] == '/'))
+    name += 4;
+  
+  if (*name == '/') {		/* if absolute path given, just append /cur */
+    strncpy (dst, name, MAILTMPLEN - 2);
+    strncat (dst, "/cur", MAILTMPLEN - 2);
+    dst[MAILTMPLEN - 1] = '\0';
+  }
+  else
+    sprintf (dst,"%s/%s/cur",myhomedir (),
+	    strcmp (ucase (strcpy (tmp, name)), "INBOX") ? name : MAILDIRPATH);
+  
+  return dst;
+}
+
+
+/* Parse flag list
+ * Accepts: MAIL stream
+ *	    flag list as a character string
+ * Returns: flag command list
+ */
+
+short maildir_getflags (MAILSTREAM *stream,char *flag)
+{
+  return bezerk_getflags (stream,flag);	/* nothing exciting, reuse old code */
+}
+
+/* Maildir clean out tmpdir
+ * Accepts: the INBOX mailbox
+ * Returns: nothing
+ */
+
+void maildir_clean (const char *mailbox)
+{
+  DIR *dir;
+  struct direct *d;
+  time_t t;
+  struct stat sbuf;
+  char tmpname[MAILTMPLEN],file[MAILTMPLEN];
+
+  t = time (0);
+
+  sprintf (tmpname,"%s/../tmp",mailbox);
+  if (!(dir = opendir (tmpname)))
+    return;
+
+  while (d = readdir (dir)) {
+    if (!strcmp (d->d_name,".")) continue;
+    if (!strcmp (d->d_name,"..")) continue;
+    sprintf (file,"%s/%s",tmpname,d->d_name);
+    if (stat (file,&sbuf) == 0)
+      if (t > sbuf.st_atime + 129600)
+	unlink (file);		/* delete the file */
+  }
+  closedir (dir);
+}
+
+
+/* Maildir copy in new mail
+ * Accepts: the INBOX mailbox
+ * Returns: nothing
+ */
+
+void maildir_copynew (const char *mailbox)
+{
+  char tmp[MAILTMPLEN],file[MAILTMPLEN],newfile[MAILTMPLEN];
+  DIR *dir;
+  struct dirent *d;
+  struct stat sbuf;
+  
+  sprintf (tmp,"%s/../new",mailbox);
+  if (!(dir = opendir (tmp)))
+    return;
+
+  while (d = readdir (dir)) {
+    if (d->d_name[0] == '.')
+      continue;			/* skip .files */
+
+    sprintf (file,"%s/%s",tmp,d->d_name);
+				/* make sure this is a normal file */
+    if (stat (file,&sbuf) == 0 && S_ISREG (sbuf.st_mode)) {
+      
+      if (strstr (d->d_name,":2,")) /* this message already has flags */
+	sprintf (newfile,"%s/%s",mailbox,d->d_name);
+      else
+	sprintf (newfile,"%s/%s:2,",mailbox,d->d_name);
+      
+				/* move the new mail to the cur dir */
+      if (link (file,newfile) == -1)
+	mm_log("Unable to read new mail!",WARN);
+      else
+	unlink (file);	
+    }
+  }
+  closedir (dir);
+}
+
+
+/* Maildir set flags on message
+ * Accepts: MAIL stream
+ *          message cache
+ *          bitvector of flags to set
+ * Returns: nothing
+ */
+
+void maildir_elt_setflag (MAILSTREAM *stream,MESSAGECACHE *elt,char flags)
+{
+  int changed = NIL;
+
+  if (!flags) return;		/* no-op if no flags to modify */
+
+				/* set all requested flags */
+  if (flags&fSEEN && !elt->seen) {
+    elt->seen = T;
+    changed = T;
+  }
+  if (flags&fDELETED && !elt->deleted) {
+    elt->deleted = T;
+    changed = T;
+  }
+  if (flags&fFLAGGED && !elt->flagged) {
+    elt->flagged = T;
+    changed = T;
+  }
+  if (flags&fANSWERED && !elt->answered) {
+    elt->answered = T;
+    changed = T;
+  }
+
+  if (changed)
+    maildir_write_flags (stream,elt);
+}
+
+
+/* Maildir write flags on message to disk
+ * Accepts: MAIL stream
+ *          message cache
+ * Returns: nothing
+ */
+
+void maildir_write_flags (MAILSTREAM *stream,MESSAGECACHE *elt)
+{
+  char oldfile[MAILTMPLEN],newfile[MAILTMPLEN],fn[MAILTMPLEN];
+  char *s;
+
+				/* build the new filename */
+  sprintf (oldfile,"%s/%s",LOCAL->dir,(char *) elt->data1);
+  if ((s = strchr ((char *) elt->data1,':'))) *s = '\0';
+  sprintf (fn,"%s:2,%s%s%s%s",(char *) elt->data1,elt->flagged ? "F" : "",
+	   elt->answered ? "R" : "",elt->seen ? "S" : "",
+	   elt->deleted ? "T" : "");
+  sprintf (newfile,"%s/%s",LOCAL->dir,fn);
+				/* rename the file with new flags */
+  if (rename (oldfile,newfile) < 0) {
+    sprintf(oldfile,"Unable to write flags to disk: %s",strerror (errno));
+    mm_log(oldfile,ERROR);
+    return;
+  }
+				/* update the file name in cache */
+  fs_give ((void **) &elt->data1);
+  elt->data1 = (long) cpystr (fn);
+}
+
+
+/* Search support routines
+ * Accepts: MAIL stream
+ *	    message number
+ *	    pointer to additional data
+ *	    pointer to temporary buffer
+ * Returns: T if search matches, else NIL
+ */
+
+char maildir_search_all (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return T;			/* ALL always succeeds */
+}
+
+
+char maildir_search_answered (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->answered ? T : NIL;
+}
+
+
+char maildir_search_deleted (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->deleted ? T : NIL;
+}
+
+
+char maildir_search_flagged (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->flagged ? T : NIL;
+}
+
+
+char maildir_search_keyword (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return NIL;			/* keywords not supported yet */
+}
+
+
+char maildir_search_new (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  MESSAGECACHE *elt = mail_elt (stream,msgno);
+  return (elt->recent && !elt->seen) ? T : NIL;
+}
+
+char maildir_search_old (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->recent ? NIL : T;
+}
+
+
+char maildir_search_recent (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->recent ? T : NIL;
+}
+
+
+char maildir_search_seen (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->seen ? T : NIL;
+}
+
+
+char maildir_search_unanswered (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->answered ? NIL : T;
+}
+
+
+char maildir_search_undeleted (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->deleted ? NIL : T;
+}
+
+
+char maildir_search_unflagged (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->flagged ? NIL : T;
+}
+
+
+char maildir_search_unkeyword (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return T;			/* keywords not supported yet */
+}
+
+
+char maildir_search_unseen (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mail_elt (stream,msgno)->seen ? NIL : T;
+}
+
+char maildir_search_before (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return (char) (maildir_msgdate (stream,msgno) < n);
+}
+
+
+char maildir_search_on (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return (char) (maildir_msgdate (stream,msgno) == n);
+}
+
+
+char maildir_search_since (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+				/* everybody interprets "since" as .GE. */
+  return (char) (maildir_msgdate (stream,msgno) >= n);
+}
+
+
+unsigned long maildir_msgdate (MAILSTREAM *stream,long msgno)
+{
+  struct stat sbuf;
+  struct tm *tm;
+  MESSAGECACHE *elt = mail_elt (stream,msgno);
+  if (!elt->day) {		/* get date if don't have it yet */
+				/* build message file name */
+    sprintf (LOCAL->buf,"%s/%s",LOCAL->dir,(char *) elt->data1);
+    stat (LOCAL->buf,&sbuf);	/* get message date */
+    tm = gmtime (&sbuf.st_mtime);
+    elt->day = tm->tm_mday; elt->month = tm->tm_mon + 1;
+    elt->year = tm->tm_year + 1900 - BASEYEAR;
+    elt->hours = tm->tm_hour; elt->minutes = tm->tm_min;
+    elt->seconds = tm->tm_sec;
+    elt->zhours = 0; elt->zminutes = 0;
+  }
+  return (long) (elt->year << 9) + (elt->month << 5) + elt->day;
+}
+
+char maildir_search_body (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  maildir_fetchheader (stream,msgno);
+  return stream->text ? search (stream->text,strlen (stream->text),d,n) : NIL;
+}
+
+
+char maildir_search_subject (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  char *t = maildir_fetchstructure (stream,msgno,NIL)->subject;
+  return t ? search (t,strlen (t),d,n) : NIL;
+}
+
+
+char maildir_search_text (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  char *t = maildir_fetchheader (stream,msgno);
+  return (t && search (t,strlen (t),d,n)) ||
+    maildir_search_body (stream,msgno,d,n);
+}
+
+char maildir_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  ADDRESS *a = maildir_fetchstructure (stream,msgno,NIL)->bcc;
+  LOCAL->buf[0] = '\0';		/* initially empty string */
+				/* get text for address */
+  rfc822_write_address (LOCAL->buf,a);
+  return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char maildir_search_cc (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  ADDRESS *a = maildir_fetchstructure (stream,msgno,NIL)->cc;
+  LOCAL->buf[0] = '\0';		/* initially empty string */
+				/* get text for address */
+  rfc822_write_address (LOCAL->buf,a);
+  return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char maildir_search_from (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  ADDRESS *a = maildir_fetchstructure (stream,msgno,NIL)->from;
+  LOCAL->buf[0] = '\0';		/* initially empty string */
+				/* get text for address */
+  rfc822_write_address (LOCAL->buf,a);
+  return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char maildir_search_to (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  ADDRESS *a = maildir_fetchstructure (stream,msgno,NIL)->to;
+  LOCAL->buf[0] = '\0';		/* initially empty string */
+				/* get text for address */
+  rfc822_write_address (LOCAL->buf,a);
+  return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+char maildir_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+    return maildir_search_to (stream,msgno,d,n)
+	    || maildir_search_cc (stream,msgno,d,n);
+}
+
+/* Search parsers */
+
+
+/* Parse a date
+ * Accepts: function to return
+ *	    pointer to date integer to return
+ * Returns: function to return
+ */
+
+search_t maildir_search_date (search_t f,long *n)
+{
+  long i;
+  char *s;
+  MESSAGECACHE elt;
+				/* parse the date and return fn if OK */
+  return (maildir_search_string (f,&s,&i) && mail_parse_date (&elt,s) &&
+	  (*n = (elt.year << 9) + (elt.month << 5) + elt.day)) ? f : NIL;
+}
+
+/* Parse a flag
+ * Accepts: function to return
+ *	    pointer to string to return
+ * Returns: function to return
+ */
+
+search_t maildir_search_flag (search_t f,char **d)
+{
+				/* get a keyword, return if OK */
+  return (*d = strtok (NIL," ")) ? f : NIL;
+}
+
+
+/* Parse a string
+ * Accepts: function to return
+ *	    pointer to string to return
+ *	    pointer to string length to return
+ * Returns: function to return
+ */
+
+search_t maildir_search_string (search_t f,char **d,long *n)
+{
+  char *end = " ";
+  char *c = strtok (NIL,"");	/* remainder of criteria */
+  if (!c) return NIL;		/* missing argument */
+  switch (*c) {			/* see what the argument is */
+  case '{':			/* literal string */
+    *n = strtol (c+1,d,10);	/* get its length */
+    if ((*(*d)++ == '}') && (*(*d)++ == '\015') && (*(*d)++ == '\012') &&
+	(!(*(c = *d + *n)) || (*c == ' '))) {
+      char e = *--c;
+      *c = DELIM;		/* make sure not a space */
+      strtok (c," ");		/* reset the strtok mechanism */
+      *c = e;			/* put character back */
+      break;
+    }
+  case '\0':			/* catch bogons */
+  case ' ':
+    return NIL;
+  case '"':			/* quoted string */
+    if (strchr (c+1,'"')) end = "\"";
+    else return NIL;
+  default:			/* atomic string */
+    if (*d = strtok (c,end)) *n = strlen (*d);
+    else return NIL;
+    break;
+  }
+  return f;
+}
diff -Nur pine3.96.dist/imap/ANSI/c-client/maildir.h pine3.96.local/imap/ANSI/c-client/maildir.h
--- pine3.96.dist/imap/ANSI/c-client/maildir.h	Wed Dec 31 16:00:00 1969
+++ pine3.96.local/imap/ANSI/c-client/maildir.h	Thu Jan 29 02:32:02 1998
@@ -0,0 +1,153 @@
+/*
+ * Program:	Maildir routines
+ *
+ * Author:      Eric Green
+ *              Bloodhounds International Inc.
+ *              thrytis@imaxx.net
+ *
+ * Additional contributions from:
+ *              Aidas Kasparas (kaspar@soften.ktu.lt)
+ *
+ * Date:        27 April 1997
+ * Last Edited: 13 June 1997
+ *
+ * Based (heavily) on mh.c and other c-client library files by Mark Crispin:
+ *
+ *      	Mark Crispin
+ *		Networks and Distributed Computing
+ *		Computing & Communications
+ *		University of Washington
+ *		Administration Building, AG-44
+ *		Seattle, WA  98195
+ *		Internet: MRC@CAC.Washington.EDU
+ *
+ * Copyright 1994 by the University of Washington
+ *
+ *  Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appears in all copies and that both the
+ * above copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the University of Washington not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  This software is made
+ * available "as is", and
+ * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+ * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
+ * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* Build parameters */
+
+#define MAILDIRPATH "Maildir"
+
+/* Command bits from maildir_getflags() */
+
+#define fSEEN 1
+#define fDELETED 2
+#define fFLAGGED 4
+#define fANSWERED 8
+
+/* Maildir I/O stream local data */
+
+typedef struct maildir_local {
+  unsigned int inbox : 1;	/* if it is an INBOX or not */
+  char *dir;			/* mail directory name */
+  char *buf;			/* temporary buffer */
+  char *hdr;			/* current header */
+  unsigned long buflen;		/* current size of temporary buffer */
+  time_t scantime;		/* last time directory scanned */
+} MAILDIRLOCAL;
+
+/* Convenient access to local data */
+
+#define LOCAL ((MAILDIRLOCAL *) stream->local)
+
+/* Function prototypes */
+
+DRIVER *maildir_valid (char *name);
+int maildir_isvalid (char *name,long justname);
+void *maildir_parameters (long function,void *value);
+void maildir_find (MAILSTREAM *stream,char *pat);
+void maildir_find_bboards (MAILSTREAM *stream,char *pat);
+void maildir_find_all (MAILSTREAM *stream,char *pat);
+void maildir_find_all_bboards (MAILSTREAM *stream,char *pat);
+long maildir_subscribe (MAILSTREAM *stream,char *mailbox);
+long maildir_unsubscribe (MAILSTREAM *stream,char *mailbox);
+long maildir_subscribe_bboard (MAILSTREAM *stream,char *mailbox);
+long maildir_unsubscribe_bboard (MAILSTREAM *stream,char *mailbox);
+long maildir_create (MAILSTREAM *stream,char *mailbox);
+long maildir_delete (MAILSTREAM *stream,char *mailbox);
+long maildir_rename (MAILSTREAM *stream,char *old,char *new);
+MAILSTREAM *maildir_open (MAILSTREAM *stream);
+void maildir_close (MAILSTREAM *stream);
+void maildir_fetchfast (MAILSTREAM *stream,char *sequence);
+void maildir_fetchflags (MAILSTREAM *stream,char *sequence);
+ENVELOPE *maildir_fetchstructure (MAILSTREAM *stream,long msgno,BODY **body);
+char *maildir_fetchheader (MAILSTREAM *stream,long msgno);
+char *maildir_fetchtext (MAILSTREAM *stream,long msgno);
+char *maildir_fetchbody (MAILSTREAM *stream,long m,char *sec,unsigned long *len);
+void maildir_setflag (MAILSTREAM *stream,char *sequence,char *flag);
+void maildir_clearflag (MAILSTREAM *stream,char *sequence,char *flag);
+void maildir_search (MAILSTREAM *stream,char *criteria);
+long maildir_ping (MAILSTREAM *stream);
+void maildir_check (MAILSTREAM *stream);
+void maildir_expunge (MAILSTREAM *stream);
+long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox);
+long maildir_move (MAILSTREAM *stream,char *sequence,char *mailbox);
+long maildir_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date,
+		   STRING *message);
+void maildir_gc (MAILSTREAM *stream,long gcflags);
+
+
+/* maildir utility functions */
+int maildir_select (struct direct *name);
+int maildir_namesort (struct direct **d1,struct direct **d2);
+char *maildir_file (char *dst,char *name);
+short maildir_getflags (MAILSTREAM *stream,char *flag);
+void maildir_clean (const char *mailbox);
+void maildir_copynew (const char *mailbox);
+void maildir_elt_setflag (MAILSTREAM *stream,MESSAGECACHE *elt,char flags);
+void maildir_write_flags (MAILSTREAM *stream,MESSAGECACHE *elt);
+
+
+/* maildir search functions */
+char maildir_search_all (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_answered (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_deleted (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_flagged (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_keyword (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_new (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_old (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_recent (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_seen (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_unanswered (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_undeleted (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_unflagged (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_unkeyword (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_unseen (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_before (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_on (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_since (MAILSTREAM *stream,long msgno,char *d,long n);
+unsigned long maildir_msgdate (MAILSTREAM *stream,long msgno);
+char maildir_search_body (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_subject (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_text (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
+char maildir_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
+typedef char (*search_t) (MAILSTREAM *stream,long msgno,char *d,long n);
+search_t maildir_search_date (search_t f,long *n);
+search_t maildir_search_flag (search_t f,char **d);
+search_t maildir_search_string (search_t f,char **d,long *n);
+
+
+/* extern functions */
+short bezerk_getflags (MAILSTREAM *stream,char *flag);
diff -Nur pine3.96.dist/imap/ANSI/c-client/mh.c pine3.96.local/imap/ANSI/c-client/mh.c
--- pine3.96.dist/imap/ANSI/c-client/mh.c	Wed May 15 11:49:54 1996
+++ pine3.96.local/imap/ANSI/c-client/mh.c	Thu Jan 29 01:01:32 1998
@@ -746,6 +746,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = mh_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = mh_search_string (mh_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = mh_search_seen;
@@ -1381,6 +1383,13 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char mh_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mh_search_to (stream,msgno,d,n) ||
+    mh_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/mh.h pine3.96.local/imap/ANSI/c-client/mh.h
--- pine3.96.dist/imap/ANSI/c-client/mh.h	Sun Aug 14 21:42:59 1994
+++ pine3.96.local/imap/ANSI/c-client/mh.h	Thu Jan 29 01:01:32 1998
@@ -127,6 +127,7 @@
 char mh_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
 char mh_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
 char mh_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char mh_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
 char mh_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
 typedef char (*search_t) (MAILSTREAM *stream,long msgno,char *d,long n);
 search_t mh_search_date (search_t f,long *n);
diff -Nur pine3.96.dist/imap/ANSI/c-client/mmdf.c pine3.96.local/imap/ANSI/c-client/mmdf.c
--- pine3.96.dist/imap/ANSI/c-client/mmdf.c	Tue Oct 15 15:20:50 1996
+++ pine3.96.local/imap/ANSI/c-client/mmdf.c	Thu Jan 29 01:01:32 1998
@@ -707,6 +707,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = mmdf_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = mmdf_search_string (mmdf_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = mmdf_search_seen;
@@ -1962,6 +1964,13 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char mmdf_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mmdf_search_to (stream,msgno,d,n) ||
+    mmdf_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/mmdf.h pine3.96.local/imap/ANSI/c-client/mmdf.h
--- pine3.96.dist/imap/ANSI/c-client/mmdf.h	Fri Jun 17 01:40:23 1994
+++ pine3.96.local/imap/ANSI/c-client/mmdf.h	Thu Jan 29 01:01:32 1998
@@ -157,6 +157,7 @@
 char mmdf_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
 char mmdf_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
 char mmdf_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char mmdf_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
 char mmdf_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
 
 search_t mmdf_search_date (search_t f,long *n);
diff -Nur pine3.96.dist/imap/ANSI/c-client/mtx.c pine3.96.local/imap/ANSI/c-client/mtx.c
--- pine3.96.dist/imap/ANSI/c-client/mtx.c	Tue Oct 15 15:21:30 1996
+++ pine3.96.local/imap/ANSI/c-client/mtx.c	Thu Jan 29 01:01:32 1998
@@ -771,6 +771,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = mtx_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = mtx_search_string (mtx_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = mtx_search_seen;
@@ -1740,6 +1742,13 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char mtx_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return mtx_search_to (stream,msgno,d,n) ||
+    mtx_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/mtx.h pine3.96.local/imap/ANSI/c-client/mtx.h
--- pine3.96.dist/imap/ANSI/c-client/mtx.h	Tue May 10 14:41:47 1994
+++ pine3.96.local/imap/ANSI/c-client/mtx.h	Thu Jan 29 01:01:32 1998
@@ -133,6 +133,7 @@
 char mtx_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
 char mtx_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
 char mtx_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char mtx_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
 char mtx_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
 
 typedef char (*search_t) (MAILSTREAM *stream,long msgno,char *d,long n);
diff -Nur pine3.96.dist/imap/ANSI/c-client/news.c pine3.96.local/imap/ANSI/c-client/news.c
--- pine3.96.dist/imap/ANSI/c-client/news.c	Wed May 15 11:50:02 1996
+++ pine3.96.local/imap/ANSI/c-client/news.c	Thu Jan 29 01:01:32 1998
@@ -676,6 +676,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = news_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = news_search_string (news_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = news_search_seen;
@@ -1054,6 +1056,13 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char news_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return news_search_to (stream,msgno,d,n) ||
+    news_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/news.h pine3.96.local/imap/ANSI/c-client/news.h
--- pine3.96.dist/imap/ANSI/c-client/news.h	Mon Sep 12 21:35:39 1994
+++ pine3.96.local/imap/ANSI/c-client/news.h	Thu Jan 29 01:01:32 1998
@@ -120,6 +120,7 @@
 char news_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
 char news_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
 char news_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char news_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
 char news_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
 typedef char (*search_t) (MAILSTREAM *stream,long msgno,char *d,long n);
 search_t news_search_date (search_t f,long *n);
diff -Nur pine3.96.dist/imap/ANSI/c-client/nntpcunx.c pine3.96.local/imap/ANSI/c-client/nntpcunx.c
--- pine3.96.dist/imap/ANSI/c-client/nntpcunx.c	Wed May 15 11:50:10 1996
+++ pine3.96.local/imap/ANSI/c-client/nntpcunx.c	Thu Jan 29 01:01:32 1998
@@ -734,6 +734,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = nntp_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = nntp_search_string (nntp_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = nntp_search_seen;
@@ -1103,6 +1105,13 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char nntp_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return nntp_search_to (stream,msgno,d,n) ||
+    nntp_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/nntpcunx.h pine3.96.local/imap/ANSI/c-client/nntpcunx.h
--- pine3.96.dist/imap/ANSI/c-client/nntpcunx.h	Mon Sep 12 21:37:18 1994
+++ pine3.96.local/imap/ANSI/c-client/nntpcunx.h	Thu Jan 29 01:01:32 1998
@@ -130,6 +130,7 @@
 char nntp_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
 char nntp_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
 char nntp_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char nntp_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
 char nntp_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
 typedef char (*search_t) (MAILSTREAM *stream,long msgno,char *d,long n);
 search_t nntp_search_date (search_t f,long *n);
diff -Nur pine3.96.dist/imap/ANSI/c-client/phile.c pine3.96.local/imap/ANSI/c-client/phile.c
--- pine3.96.dist/imap/ANSI/c-client/phile.c	Wed May 15 11:50:12 1996
+++ pine3.96.local/imap/ANSI/c-client/phile.c	Thu Jan 29 01:01:32 1998
@@ -625,6 +625,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = phile_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = phile_search_string (phile_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = phile_search_seen;
@@ -978,6 +980,13 @@
 				/* get text for address */
   rfc822_write_address (tmp,phile_fetchstructure (stream,m,NIL)->from);
   return search (tmp,strlen (tmp),d,n);
+}
+
+
+char phile_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return phile_search_to (stream,msgno,d,n) ||
+    phile_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/phile.h pine3.96.local/imap/ANSI/c-client/phile.h
--- pine3.96.dist/imap/ANSI/c-client/phile.h	Wed Mar  2 20:01:33 1994
+++ pine3.96.local/imap/ANSI/c-client/phile.h	Thu Jan 29 01:01:32 1998
@@ -130,6 +130,7 @@
 char phile_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
 char phile_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
 char phile_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char phile_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
 char phile_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
 
 typedef char (*search_t) (MAILSTREAM *stream,long msgno,char *d,long n);
diff -Nur pine3.96.dist/imap/ANSI/c-client/pop3.c pine3.96.local/imap/ANSI/c-client/pop3.c
--- pine3.96.dist/imap/ANSI/c-client/pop3.c	Tue Oct 22 13:04:29 1996
+++ pine3.96.local/imap/ANSI/c-client/pop3.c	Thu Jan 29 01:01:32 1998
@@ -699,6 +699,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = pop3_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = pop3_search_string (pop3_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = pop3_search_seen;
@@ -1149,6 +1151,13 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char pop3_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return pop3_search_to (stream,msgno,d,n) ||
+    pop3_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/pop3.h pine3.96.local/imap/ANSI/c-client/pop3.h
--- pine3.96.dist/imap/ANSI/c-client/pop3.h	Mon Jun  6 21:57:20 1994
+++ pine3.96.local/imap/ANSI/c-client/pop3.h	Thu Jan 29 01:01:32 1998
@@ -132,6 +132,7 @@
 char pop3_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
 char pop3_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
 char pop3_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char pop3_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
 char pop3_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
 typedef char (*search_t) (MAILSTREAM *stream,long msgno,char *d,long n);
 search_t pop3_search_date (search_t f,long *n);
diff -Nur pine3.96.dist/imap/ANSI/c-client/tenex2.c pine3.96.local/imap/ANSI/c-client/tenex2.c
--- pine3.96.dist/imap/ANSI/c-client/tenex2.c	Tue Oct 15 15:21:14 1996
+++ pine3.96.local/imap/ANSI/c-client/tenex2.c	Thu Jan 29 01:01:32 1998
@@ -789,6 +789,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = tenex_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = tenex_search_string (tenex_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = tenex_search_seen;
@@ -1767,6 +1769,13 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char tenex_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n)
+{
+  return tenex_search_to (stream,msgno,d,n) ||
+    tenex_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/ANSI/c-client/tenex2.h pine3.96.local/imap/ANSI/c-client/tenex2.h
--- pine3.96.dist/imap/ANSI/c-client/tenex2.h	Sun Oct  2 22:08:39 1994
+++ pine3.96.local/imap/ANSI/c-client/tenex2.h	Thu Jan 29 01:01:32 1998
@@ -140,6 +140,7 @@
 char tenex_search_bcc (MAILSTREAM *stream,long msgno,char *d,long n);
 char tenex_search_cc (MAILSTREAM *stream,long msgno,char *d,long n);
 char tenex_search_from (MAILSTREAM *stream,long msgno,char *d,long n);
+char tenex_search_recipient (MAILSTREAM *stream,long msgno,char *d,long n);
 char tenex_search_to (MAILSTREAM *stream,long msgno,char *d,long n);
 
 typedef char (*search_t) (MAILSTREAM *stream,long msgno,char *d,long n);
diff -Nur pine3.96.dist/imap/OSTYPE pine3.96.local/imap/OSTYPE
--- pine3.96.dist/imap/OSTYPE	Wed Dec 31 16:00:00 1969
+++ pine3.96.local/imap/OSTYPE	Sat Feb  7 20:03:16 1998
@@ -0,0 +1 @@
+lnx
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/bezerk.c pine3.96.local/imap/non-ANSI/c-client/bezerk.c
--- pine3.96.dist/imap/non-ANSI/c-client/bezerk.c	Tue Oct 15 15:20:17 1996
+++ pine3.96.local/imap/non-ANSI/c-client/bezerk.c	Thu Jan 29 01:01:32 1998
@@ -833,6 +833,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = bezerk_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = bezerk_search_string (bezerk_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = bezerk_search_seen;
@@ -2247,6 +2249,17 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char bezerk_search_recipient (stream,msgno,d,n)
+	MAILSTREAM *stream;
+	long msgno;
+	char *d;
+	long n;
+{
+  return bezerk_search_to (stream,msgno,d,n) ||
+    bezerk_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/bezerk.h pine3.96.local/imap/non-ANSI/c-client/bezerk.h
--- pine3.96.dist/imap/non-ANSI/c-client/bezerk.h	Wed Apr 12 23:03:14 1995
+++ pine3.96.local/imap/non-ANSI/c-client/bezerk.h	Thu Jan 29 01:01:32 1998
@@ -283,6 +283,7 @@
 char bezerk_search_bcc  ();
 char bezerk_search_cc  ();
 char bezerk_search_from  ();
+char bezerk_search_recipient  ();
 char bezerk_search_to  ();
 
 typedef char (*search_t)  ();
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/mh.c pine3.96.local/imap/non-ANSI/c-client/mh.c
--- pine3.96.dist/imap/non-ANSI/c-client/mh.c	Wed May 15 11:56:05 1996
+++ pine3.96.local/imap/non-ANSI/c-client/mh.c	Thu Jan 29 01:01:32 1998
@@ -801,6 +801,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = mh_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = mh_search_string (mh_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = mh_search_seen;
@@ -1556,6 +1558,16 @@
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
 }
 
+
+char mh_search_recipient (stream,msgno,d,n)
+	MAILSTREAM *stream;
+	long msgno;
+	char *d;
+	long n;
+{
+  return mh_search_to (stream,msgno,d,n) ||
+    mh_search_cc (stream,msgno,d,n);
+}
 
 char mh_search_to (stream,msgno,d,n)
 	MAILSTREAM *stream;
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/mh.h pine3.96.local/imap/non-ANSI/c-client/mh.h
--- pine3.96.dist/imap/non-ANSI/c-client/mh.h	Sun Aug 14 21:44:49 1994
+++ pine3.96.local/imap/non-ANSI/c-client/mh.h	Thu Jan 29 01:01:32 1998
@@ -127,6 +127,7 @@
 char mh_search_cc  ();
 char mh_search_from  ();
 char mh_search_to  ();
+char mh_search_recipient  ();
 typedef char (*search_t)  ();
 search_t mh_search_date  ();
 search_t mh_search_flag  ();
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/mmdf.c pine3.96.local/imap/non-ANSI/c-client/mmdf.c
--- pine3.96.dist/imap/non-ANSI/c-client/mmdf.c	Tue Oct 15 15:20:35 1996
+++ pine3.96.local/imap/non-ANSI/c-client/mmdf.c	Thu Jan 29 01:01:32 1998
@@ -761,6 +761,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = mmdf_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = mmdf_search_string (mmdf_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = mmdf_search_seen;
@@ -2153,6 +2155,17 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char mmdf_search_recipient (stream,msgno,d,n)
+	MAILSTREAM *stream;
+	long msgno;
+	char *d;
+	long n;
+{
+  return mmdf_search_to (stream,msgno,d,n) ||
+     mmdf_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/mmdf.h pine3.96.local/imap/non-ANSI/c-client/mmdf.h
--- pine3.96.dist/imap/non-ANSI/c-client/mmdf.h	Mon Sep 19 20:47:46 1994
+++ pine3.96.local/imap/non-ANSI/c-client/mmdf.h	Thu Jan 29 01:01:32 1998
@@ -157,6 +157,7 @@
 char mmdf_search_cc  ();
 char mmdf_search_from  ();
 char mmdf_search_to  ();
+char mmdf_search_recipient  ();
 
 search_t mmdf_search_date  ();
 search_t mmdf_search_flag  ();
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/mtx.c pine3.96.local/imap/non-ANSI/c-client/mtx.c
--- pine3.96.dist/imap/non-ANSI/c-client/mtx.c	Tue Oct 15 15:21:55 1996
+++ pine3.96.local/imap/non-ANSI/c-client/mtx.c	Thu Jan 29 01:01:32 1998
@@ -828,6 +828,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = mtx_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = mtx_search_string (mtx_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = mtx_search_seen;
@@ -1928,6 +1930,17 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char mtx_search_recipient (stream,msgno,d,n)
+	MAILSTREAM *stream;
+	long msgno;
+	char *d;
+	long n;
+{
+  return mtx_search_to (stream,msgno,d,n) ||
+    mtx_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/mtx.h pine3.96.local/imap/non-ANSI/c-client/mtx.h
--- pine3.96.dist/imap/non-ANSI/c-client/mtx.h	Tue May 10 14:58:40 1994
+++ pine3.96.local/imap/non-ANSI/c-client/mtx.h	Thu Jan 29 01:01:32 1998
@@ -133,6 +133,7 @@
 char mtx_search_cc  ();
 char mtx_search_from  ();
 char mtx_search_to  ();
+char mtx_search_recipient  ();
 
 typedef char (*search_t)  ();
 search_t mtx_search_date  ();
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/news.c pine3.96.local/imap/non-ANSI/c-client/news.c
--- pine3.96.dist/imap/non-ANSI/c-client/news.c	Wed May 15 11:56:11 1996
+++ pine3.96.local/imap/non-ANSI/c-client/news.c	Thu Jan 29 01:01:32 1998
@@ -731,6 +731,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = news_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = news_search_string (news_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = news_search_seen;
@@ -1222,6 +1224,17 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char news_search_recipient (stream,msgno,d,n)
+	MAILSTREAM *stream;
+	long msgno;
+	char *d;
+	long n;
+{
+  return news_search_to (stream,msgno,d,n) ||
+    news_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/news.h pine3.96.local/imap/non-ANSI/c-client/news.h
--- pine3.96.dist/imap/non-ANSI/c-client/news.h	Tue Sep 13 21:50:44 1994
+++ pine3.96.local/imap/non-ANSI/c-client/news.h	Thu Jan 29 01:01:33 1998
@@ -120,6 +120,7 @@
 char news_search_cc  ();
 char news_search_from  ();
 char news_search_to  ();
+char news_search_recipient  ();
 typedef char (*search_t)  ();
 search_t news_search_date  ();
 search_t news_search_flag  ();
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/nntpcunx.c pine3.96.local/imap/non-ANSI/c-client/nntpcunx.c
--- pine3.96.dist/imap/non-ANSI/c-client/nntpcunx.c	Wed May 15 11:56:13 1996
+++ pine3.96.local/imap/non-ANSI/c-client/nntpcunx.c	Thu Jan 29 01:01:33 1998
@@ -789,6 +789,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = nntp_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = nntp_search_string (nntp_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = nntp_search_seen;
@@ -1271,6 +1273,17 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char nntp_search_recipient (stream,msgno,d,n)
+	MAILSTREAM *stream;
+	long msgno;
+	char *d;
+	long n;
+{
+  return nntp_search_to (stream,msgno,d,n) ||
+    nntp_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/nntpcunx.h pine3.96.local/imap/non-ANSI/c-client/nntpcunx.h
--- pine3.96.dist/imap/non-ANSI/c-client/nntpcunx.h	Tue Sep 13 21:50:50 1994
+++ pine3.96.local/imap/non-ANSI/c-client/nntpcunx.h	Thu Jan 29 01:01:33 1998
@@ -130,6 +130,7 @@
 char nntp_search_cc  ();
 char nntp_search_from  ();
 char nntp_search_to  ();
+char nntp_search_recipient  ();
 typedef char (*search_t)  ();
 search_t nntp_search_date  ();
 search_t nntp_search_flag  ();
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/phile.c pine3.96.local/imap/non-ANSI/c-client/phile.c
--- pine3.96.dist/imap/non-ANSI/c-client/phile.c	Wed May 15 11:56:14 1996
+++ pine3.96.local/imap/non-ANSI/c-client/phile.c	Thu Jan 29 01:01:33 1998
@@ -682,6 +682,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = phile_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = phile_search_string (phile_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = phile_search_seen;
@@ -1146,6 +1148,17 @@
 				/* get text for address */
   rfc822_write_address (tmp,phile_fetchstructure (stream,m,NIL)->from);
   return search (tmp,strlen (tmp),d,n);
+}
+
+
+char phile_search_recipient (stream,msgno,d,n)
+	MAILSTREAM *stream;
+	long msgno;
+	char *d;
+	long n;
+{
+  return phile_search_to (stream,msgno,d,n) ||
+    phile_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/phile.h pine3.96.local/imap/non-ANSI/c-client/phile.h
--- pine3.96.dist/imap/non-ANSI/c-client/phile.h	Thu Mar  3 23:24:51 1994
+++ pine3.96.local/imap/non-ANSI/c-client/phile.h	Thu Jan 29 01:01:33 1998
@@ -130,6 +130,7 @@
 char phile_search_cc  ();
 char phile_search_from  ();
 char phile_search_to  ();
+char phile_search_recipient  ();
 
 typedef char (*search_t)  ();
 search_t phile_search_date  ();
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/pop3.c pine3.96.local/imap/non-ANSI/c-client/pop3.c
--- pine3.96.dist/imap/non-ANSI/c-client/pop3.c	Tue Oct 22 13:06:12 1996
+++ pine3.96.local/imap/non-ANSI/c-client/pop3.c	Thu Jan 29 01:01:33 1998
@@ -753,6 +753,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = pop3_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = pop3_search_string (pop3_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = pop3_search_seen;
@@ -1325,6 +1327,17 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char pop3_search_recipient (stream,msgno,d,n)
+	MAILSTREAM *stream;
+	long msgno;
+	char *d;
+	long n;
+{
+  return pop3_search_to (stream,msgno,d,n) ||
+    pop3_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/pop3.h pine3.96.local/imap/non-ANSI/c-client/pop3.h
--- pine3.96.dist/imap/non-ANSI/c-client/pop3.h	Mon Jun  6 22:28:51 1994
+++ pine3.96.local/imap/non-ANSI/c-client/pop3.h	Thu Jan 29 01:01:33 1998
@@ -132,6 +132,7 @@
 char pop3_search_cc  ();
 char pop3_search_from  ();
 char pop3_search_to  ();
+char pop3_search_recipient  ();
 typedef char (*search_t)  ();
 search_t pop3_search_date  ();
 search_t pop3_search_flag  ();
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/tenex2.c pine3.96.local/imap/non-ANSI/c-client/tenex2.c
--- pine3.96.dist/imap/non-ANSI/c-client/tenex2.c	Tue Oct 15 15:21:44 1996
+++ pine3.96.local/imap/non-ANSI/c-client/tenex2.c	Thu Jan 29 01:01:33 1998
@@ -852,6 +852,8 @@
 	break;
       case 'R':			/* possible RECENT */
 	if (!strcmp (criteria+1,"ECENT")) f = tenex_search_recent;
+	else if (!strcmp (criteria+1,"ECIPIENT"))
+	  f = tenex_search_string (tenex_search_recipient,&d,&n);
 	break;
       case 'S':			/* possible SEEN, SINCE, SUBJECT */
 	if (!strcmp (criteria+1,"EEN")) f = tenex_search_seen;
@@ -1963,6 +1965,17 @@
 				/* get text for address */
   rfc822_write_address (LOCAL->buf,a);
   return search (LOCAL->buf,(long) strlen (LOCAL->buf),d,n);
+}
+
+
+char tenex_search_recipient (stream,msgno,d,n)
+	MAILSTREAM *stream;
+	long msgno;
+	char *d;
+	long n;
+{
+  return tenex_search_to (stream,msgno,d,n) ||
+    tenex_search_cc (stream,msgno,d,n);
 }
 
 
diff -Nur pine3.96.dist/imap/non-ANSI/c-client/tenex2.h pine3.96.local/imap/non-ANSI/c-client/tenex2.h
--- pine3.96.dist/imap/non-ANSI/c-client/tenex2.h	Sun Oct  2 22:44:05 1994
+++ pine3.96.local/imap/non-ANSI/c-client/tenex2.h	Thu Jan 29 01:01:33 1998
@@ -140,6 +140,7 @@
 char tenex_search_cc  ();
 char tenex_search_from  ();
 char tenex_search_to  ();
+char tenex_search_recipient  ();
 
 typedef char (*search_t)  ();
 search_t tenex_search_date  ();
diff -Nur pine3.96.dist/pico/makefile.lnx pine3.96.local/pico/makefile.lnx
--- pine3.96.dist/pico/makefile.lnx	Fri Apr  5 10:07:54 1996
+++ pine3.96.local/pico/makefile.lnx	Thu Jan 29 01:01:33 1998
@@ -32,9 +32,9 @@
 #
 
 #includes symbol for debugging
-DASHO=		-g
+#DASHO=		-g
 #for normal build
-#DASHO=		-O2
+DASHO=		-O2
 
 STDCFLAGS=	-Dlnx -DPOSIX -DJOB_CONTROL -DMOUSE
 CFLAGS=	 	$(EXTRACFLAGS) $(DASHO) $(STDCFLAGS)
diff -Nur pine3.96.dist/pico/os_unix.c pine3.96.local/pico/os_unix.c
--- pine3.96.dist/pico/os_unix.c	Fri Jul 12 11:13:53 1996
+++ pine3.96.local/pico/os_unix.c	Sat Feb  7 20:01:12 1998
@@ -1653,6 +1653,18 @@
 tmpname(name)
 char *name;
 {
+    char *e, *e1;
+
+    e = getenv("TMPDIR");
+    if (!e) e = getenv("HOME");
+    if (!e || *e == '\0') {
+	e = "/tmp/";
+	e1 = "";
+    }
+    else {
+	e1 = e + strlen(e) - 1;
+	e1 = (*e1 == '/') ? "" : "/";
+    }
     sprintf(name, "/tmp/pico.%d", getpid());	/* tmp file name */
 }
 
diff -Nur pine3.96.dist/pine/date.c pine3.96.local/pine/date.c
--- pine3.96.dist/pine/date.c	Wed Dec 31 16:00:00 1969
+++ pine3.96.local/pine/date.c	Sat Feb  7 20:03:21 1998
@@ -0,0 +1,2 @@
+char datestamp[]="Sat Feb 7 20:03:21 PST 1998";
+char hoststamp[]="benchlark.transmeta.com";
diff -Nur pine3.96.dist/pine/init.c pine3.96.local/pine/init.c
--- pine3.96.dist/pine/init.c	Wed Jul 10 16:05:31 1996
+++ pine3.96.local/pine/init.c	Thu Jan 29 01:01:33 1998
@@ -1337,6 +1337,9 @@
 	{"disable-keymenu",			F_BLANK_KEYMENU},
 	{"disable-password-cmd",		F_DISABLE_PASSWORD_CMD},
 	{"disable-update-cmd",			F_DISABLE_UPDATE_CMD},
+#ifdef ALLOW_DISABLE_SENDER
+	{"disable-sender",			F_DISABLE_SENDER},
+#endif
 	{"disable-signature-edit-cmd",		F_DISABLE_SIGEDIT_CMD},
 	{"enable-8bit-esmtp-negotiation",	F_ENABLE_8BIT},
 	{"enable-8bit-nntp-posting",		F_ENABLE_8BIT_NNTP},
@@ -1381,6 +1384,9 @@
 	{"print-includes-from-line",		F_FROM_DELIM_IN_PRINT},
 	{"print-index-enabled",			F_PRINT_INDEX},
 	{"print-formfeed-between-messages",	F_AGG_PRINT_FF},
+#if defined( QMAIL_RETURN_PATH )
+	{"qmail-return-path",			F_QMAIL_RETURN_PATH},
+#endif
 	{"quell-dead-letter-on-cancel",		F_QUELL_DEAD_LETTER},
 	{"quell-lock-failure-warnings",		F_QUELL_LOCK_FAILURE_MSGS},
 	{"quell-status-message-beeping",	F_QUELL_BEEPS},
diff -Nur pine3.96.dist/pine/mailcmd.c pine3.96.local/pine/mailcmd.c
--- pine3.96.dist/pine/mailcmd.c	Mon Feb 24 13:57:22 1997
+++ pine3.96.local/pine/mailcmd.c	Thu Jan 29 01:01:33 1998
@@ -170,13 +170,14 @@
 
 
 static char *sel_text =
-    "Select based on To, From, Cc, or Subject fields or All message text ? ";
+    "Select based on To, From, Cc, Subject, Recpients, or All message text ? ";
 static ESCKEY_S sel_text_opt[] = {
     {'f', 'f', "F", "From"},
     {'s', 's', "S", "Subject"},
     {'t', 't', "T", "To"},
     {'a', 'a', "A", "All Text"},
     {'c', 'c', "C", "Cc"},
+    {'r', 'r', "R", "Recpients"},
     {-1, 0, NULL, NULL}
 };
 
@@ -5391,7 +5392,7 @@
 {
     int       r, type, we_cancel = 0;
     char     *sval = NULL, sstring[80], tmp[128];
-    ESCKEY_S  ekey[3];
+    ESCKEY_S  ekey[4];
     ENVELOPE *env = NULL;
     HelpType  help;
 
@@ -5402,6 +5403,7 @@
      */
     ekey[1].ch   = -1;
     ekey[2].ch   = -1;
+    ekey[3].ch   = -1;
     switch(type = radio_buttons(sel_text, -FOOTER_ROWS(ps_global),
 				sel_text_opt, 's', 'x', NO_HELP, RB_NORM)){
       case 't' :			/* address fields, offer To or From */
@@ -5426,6 +5428,22 @@
 	ekey[0].label = "Cur Subject";
 	break;
 
+      case 'r' :
+	sval = "RECIPIENT";
+	ekey[0].ch    = ctrl('T');
+	ekey[0].name  = "^T";
+	ekey[0].rval  = 10;
+	ekey[0].label = "Cur To";
+	ekey[1].ch    = ctrl('R');
+	ekey[1].name  = "^R";
+	ekey[1].rval  = 11;
+	ekey[1].label = "Cur From";
+	ekey[2].ch    = ctrl('Y');
+	ekey[2].name  = "^Y";
+	ekey[2].rval  = 12;
+	ekey[2].label = "Cur Cc";
+	break;
+
       case 'a' :
 	sval = "TEXT";			/* fall thru */
 	ekey[0].ch = -1;
@@ -5458,7 +5476,8 @@
 			       : (type == 'c') ? h_select_txt_cc
 				: (type == 's') ? h_select_txt_subj
 				 : (type == 'a') ? h_select_txt_all
-				  :              NO_HELP)
+				  : (type == 'r') ? h_select_txt_recipients
+				   :              NO_HELP)
 			    : NO_HELP;
 	      case 4 :
 		continue;
diff -Nur pine3.96.dist/pine/makefile.lnx pine3.96.local/pine/makefile.lnx
--- pine3.96.dist/pine/makefile.lnx	Fri Mar 15 12:29:39 1996
+++ pine3.96.local/pine/makefile.lnx	Thu Jan 29 01:01:33 1998
@@ -50,9 +50,9 @@
 RM=          rm -f
 LN=          ln -s
 MAKE=        make
-OPTIMIZE=    # -O2
+OPTIMIZE=    -O2
 PROFILE=     # -pg
-DEBUG=       -g -DDEBUG
+DEBUG=       #-g -DDEBUG
 
 IMAPDIR=     ../c-client
 PICODIR=     ../pico
diff -Nur pine3.96.dist/pine/osdep/os-lnx.h pine3.96.local/pine/osdep/os-lnx.h
--- pine3.96.dist/pine/osdep/os-lnx.h	Wed Jun  5 10:13:29 1996
+++ pine3.96.local/pine/osdep/os-lnx.h	Thu Jan 29 01:01:33 1998
@@ -52,6 +52,9 @@
 
  ----*/
 
+#define ALLOW_DISABLE_SENDER
+#define QMAIL_RETURN_PATH
+
 /*----------------------------------------------------------------------
    Define this if you want the disk quota to be checked on startup.
    Of course, this only makes sense if your system has quotas.  If it doesn't,
@@ -68,7 +71,7 @@
    either default-composer-hdrs or customized-hdrs to get at the From
    header, even if this is set.
  ----*/
-/* #define ALLOW_CHANGING_FROM  /* comment out to not allow changing From */
+#define ALLOW_CHANGING_FROM  /* comment out to not allow changing From */
 
 
 
diff -Nur pine3.96.dist/pine/other.c pine3.96.local/pine/other.c
--- pine3.96.dist/pine/other.c	Wed Jul 10 16:05:59 1996
+++ pine3.96.local/pine/other.c	Thu Jan 29 01:01:33 1998
@@ -2484,6 +2484,10 @@
 	    return(h_config_cruise_mode_delete);
 	  case F_ALLOW_GOTO :
 	    return(h_config_allow_goto);
+	  case F_DISABLE_SENDER :
+	    return(h_config_disable_sender);
+	  case F_QMAIL_RETURN_PATH :
+	    return(h_config_qmail_return_path);
 	  default :
 	    return(NO_HELP);
         }
diff -Nur pine3.96.dist/pine/pine.h pine3.96.local/pine/pine.h
--- pine3.96.dist/pine/pine.h	Wed Feb 26 14:45:44 1997
+++ pine3.96.local/pine/pine.h	Thu Jan 29 01:01:52 1998
@@ -63,7 +63,7 @@
 #ifndef _PINE_INCLUDED
 #define _PINE_INCLUDED
 
-#define PINE_VERSION		"3.96"
+#define PINE_VERSION		"3.96dg4"
 #define	PHONE_HOME_VERSION	"396"
 #define	PHONE_HOME_HOST		"docserver.cac.washington.edu"
 #define	UPDATE_FOLDER		"{pine.cac.washington.edu:144/anonymous}#news."
@@ -1153,7 +1153,9 @@
 #define	F_FROM_DELIM_IN_PRINT	   80
 #define	F_BACKGROUND_POST	   81
 #define	F_ALLOW_GOTO		   82
-#define F_LAST_FEATURE		   82		 /* RESET WITH NEW FEATURES */
+#define F_DISABLE_SENDER	   83
+#define F_QMAIL_RETURN_PATH	   84
+#define F_LAST_FEATURE		   84		 /* RESET WITH NEW FEATURES */
 
 #if (F_LAST_FEATURE > (LARGEST_BITMAP - 1))
    Whoa!  Too many features!
diff -Nur pine3.96.dist/pine/pine.hlp pine3.96.local/pine/pine.hlp
--- pine3.96.dist/pine/pine.hlp	Fri Feb 28 09:32:23 1997
+++ pine3.96.local/pine/pine.hlp	Thu Jan 29 01:01:33 1998
@@ -5561,6 +5561,27 @@
 two distant directories.
 
 <End of help on this topic>
+====== h_config_disable_sender =====
+        FEATURE: disable-sender
+
+Normally if the From: header does not match what pine thinks your email
+address is, it will generate a Sender: header (or X-Sender: depending on
+the use-sender-not-x-sender feature) with the address it thinks you
+are at.  This feature disables the generation of the Sender: header.
+
+<End of help on this topic>
+====== h_config_qmail_return_path =====
+        FEATURE: qmail-return-path
+
+The qmail mail transfer agent (see http://www.qmail.org/) will interpret a
+Return-Path: header as the envelope sender address.  This setting allows
+the Return-Path to be editted.  Additionally, if the Return-Path is not
+changed by the user then its value will default to whatever the From:
+header contains.  This is useful because qmail also allows a user to
+create addresses of the form userid-foobar@domain.edu.  It is also useful
+if the user uses different addresses for different functions.
+
+<End of help on this topic>
 ====== h_config_undo =====
 Yes, save changes and exit; No, exit without saving any changes made since
 entering this CONFIGURATION screen; ^C, cancel exit and stay in config screen.
@@ -5737,6 +5758,9 @@
 ========== h_select_txt_cc ==========
 Messages with From: headers containing the entered string will be selected.
 ^C to cancel. ^R enters current msg From: address.  ^T enters To: address.
+========== h_select_txt_recipients ==========
+Messages with To: or Cc: headers containing the entered string will be selected.
+^C to cancel. ^R uses From: address. ^T uses To: address. ^Y uses Cc: address.
 ========== h_select_txt_subj ==========
 Messages with Subject: headers containing the entered string will be selected.
 ^C to cancel.  ^X enters Subject: line of current message.
diff -Nur pine3.96.dist/pine/send.c pine3.96.local/pine/send.c
--- pine3.96.dist/pine/send.c	Mon Feb 24 13:57:38 1997
+++ pine3.96.local/pine/send.c	Thu Jan 29 01:01:33 1998
@@ -50,7 +50,6 @@
 #include "../c-client/smtp.h"
 #include "../c-client/nntp.h"
 
-
 #ifndef TCPSTREAM
 #define TCPSTREAM void
 #endif
@@ -1126,7 +1125,12 @@
 #if	!(defined(DOS) || defined(OS2)) || defined(NOAUTH)
   {"",            "Sender",      NO_HELP,               10, 0, NULL,
    NULL,          NULL, NULL, NULL,                 NULL,
-   0, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE}
+   0, 0, 0, 0, 0, 0, 0, 0, 0, KS_NONE},
+#endif
+#if defined( QMAIL_RETURN_PATH )
+  {"Return-P: ",  "Return-Path",        h_composer_from,       10, 0, NULL,
+   build_address, NULL, NULL, addr_book_compose,    "To AddrBk",
+   0, 1, 0, 1, 0, 1, 0, 0, 0, KS_TOADDRBOOK}
 #endif
 };
 
@@ -1159,6 +1163,7 @@
 #define N_NOBODY  14
 #define	N_POSTERR 15
 #define N_SENDER  16
+#define N_RETURNPATH 17
 
 /* this is used in pine_send and pine_simple_send */
 /* name::type::canedit::writehdr::localcopy::rcptto */
@@ -1182,6 +1187,9 @@
 #if	!(defined(DOS) || defined(OS2)) || defined(NOAUTH)
   {"X-Sender",    Address,	0, 1, 1, 0},
 #endif
+#if defined( QMAIL_RETURN_PATH )
+  {"Return-Path", Address,	1, 1, 1, 0},
+#endif
   {NULL,         FreeText}
 };
 
@@ -1371,6 +1379,12 @@
 		pf->addr		= &outgoing->sender;
                 break;
 #endif
+#if defined( QMAIL_RETURN_PATH )
+	      case N_RETURNPATH:
+		sending_order[NN+13]	= pf;
+		pf->addr		= &outgoing->return_path;
+		break;
+#endif
 
               case N_NOBODY: /* won't be used here */
 		sending_order[NN+5]	= pf;
@@ -1953,7 +1967,7 @@
 	else
 	  index = i;
 
-	if(i > 16)
+	if(i > 17)
 	  q_status_message1(SM_ORDER,3,7,
 	      "Internal error: i=%d in pine_send", (void *)i);
 
@@ -2125,6 +2139,12 @@
 		pf->addr		= &outgoing->sender;
                 break;
 #endif
+#if	defined( QMAIL_RETURN_PATH )
+	      case N_RETURNPATH:
+		sending_order[NN+13]	= pf;
+		pf->addr		= &outgoing->return_path;
+		break;
+#endif
 
 	      default:
 		q_status_message1(SM_ORDER,3,7,
@@ -2186,7 +2206,7 @@
 		if(index == N_FROM && !*pf->addr)
 		  *pf->addr = generate_from();
 
-	    }else if(index == N_FROM || index == N_REPLYTO){
+	    }else if(index == N_FROM || index == N_REPLYTO || index == N_RETURNPATH){
 		/* side effect of this may set canedit */
 		set_default_hdrval(pf);
 	    }else if(pf->addr && *pf->addr && !(*pf->addr)->mailbox){
@@ -2552,6 +2572,9 @@
 	  mail_free_address(&outgoing->reply_to);
 #endif /* OLDWAY */
 
+#ifdef ALLOW_DISABLE_SENDER
+	if(!F_ON(F_DISABLE_SENDER, ps_global)){
+#endif
 	/*
 	 * Don't ever believe the sender that is there.
 	 * If From doesn't look quite right, generate our own sender.
@@ -2577,6 +2600,24 @@
 	    outgoing->sender->mailbox = cpystr(ps_global->VAR_USER_ID);
 	    outgoing->sender->host    = cpystr(ps_global->hostname);
 	}
+#ifdef ALLOW_DISABLE_SENDER
+	}
+#endif
+
+#ifdef QMAIL_RETURN_PATH
+	if(F_ON(F_QMAIL_RETURN_PATH, ps_global)){
+	  /*
+	   * If the user hasn't edited the Return-Path header then inherit
+	   * it from the From: header
+	   */
+	  pf = &pfields[N_RETURNPATH];
+	  if( !pf->he->dirty ) {
+	    if(outgoing->return_path)
+	      mail_free_address(&outgoing->return_path);
+	    outgoing->return_path = rfc822_cpy_adr(outgoing->from);
+	  }
+	}
+#endif
 
         /*----- Message is edited, now decide what to do with it ----*/
 	if(editor_result & (COMP_SUSPEND | COMP_GOTHUP | COMP_CANCEL)){
