From lewiz@compsoc.man.ac.uk  Sat Jan 29 21:34:16 2005
Return-Path: <lewiz@compsoc.man.ac.uk>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id B021616A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 29 Jan 2005 21:34:16 +0000 (GMT)
Received: from serenity.mcc.ac.uk (serenity.mcc.ac.uk [130.88.200.93])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 999A143D2F
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 29 Jan 2005 21:34:15 +0000 (GMT)
	(envelope-from lewiz@compsoc.man.ac.uk)
Received: from kiki.compsoc.man.ac.uk ([192.84.78.5])
	by serenity.mcc.ac.uk with esmtp (Exim 4.20)
	id 1Cv0EQ-0007KX-0n
	for FreeBSD-gnats-submit@freebsd.org; Sat, 29 Jan 2005 21:34:14 +0000
Received: from xeon.compsoc.man.ac.uk (lewiz@xeon.compsoc.man.ac.uk [192.84.78.1])
	by kiki.compsoc.man.ac.uk (8.13.1/8.13.1) with ESMTP id j0TLZLQl016948
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 29 Jan 2005 21:35:21 GMT
	(envelope-from lewiz@xeon.compsoc.man.ac.uk)
Received: (from lewiz@localhost)
	by xeon.compsoc.man.ac.uk (8.13.1/8.13.1/Submit) id j0TLXSpq032602;
	Sat, 29 Jan 2005 21:33:28 GMT
	(envelope-from lewiz)
Message-Id: <200501292133.j0TLXSpq032602@xeon.compsoc.man.ac.uk>
Date: Sat, 29 Jan 2005 21:33:28 GMT
From: Lewis Thompson <lewiz@compsoc.man.ac.uk>
Reply-To: Lewis Thompson <lewiz@compsoc.man.ac.uk>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [ PORT UPDATE ] mail/pine4 -- add maildir patch support
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         76829
>Category:       ports
>Synopsis:       [ PORT UPDATE ] mail/pine4 -- add maildir patch support
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    dougb
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jan 29 21:40:17 GMT 2005
>Closed-Date:    Sun Mar 13 23:11:45 GMT 2005
>Last-Modified:  Sun Mar 13 23:11:45 GMT 2005
>Originator:     Lewis Thompson
>Release:        FreeBSD 5.3-RELEASE-p5 i386
>Organization:
The University of Manchester Computer Society
>Environment:
System: FreeBSD xeon.compsoc.man.ac.uk 5.3-RELEASE-p5 FreeBSD 5.3-RELEASE-p5 #2: Tue Jan 18 17:36:50 GMT 2005 lewiz@xeon.compsoc.man.ac.uk:/usr/src/sys/i386/compile/XEON i386


	
>Description:
A patch adding Maildir support to pine4.  The patch was fetched from
http://www.math.washington.edu/~chappa/pine/info/maildir.html

This is a follow-up to ports/76137 (now closed)
>How-To-Repeat:
>Fix:
diff -ruN pine4.orig/Makefile pine4/Makefile
--- pine4.orig/Makefile	Sun Jan 23 02:02:45 2005
+++ pine4/Makefile	Sat Jan 29 21:33:08 2005
@@ -75,6 +75,13 @@
 	${LN} -sf ${LDAP_PREFIX}/lib ${WRKSRC}/ldap/libraries
 .endif
 
+pre-build:
+# Define "WITH_MAILDIR" to include Maildir support.
+# patch from http://www.math.washington.edu/~chappa/pine/info/maildir.html
+.if defined(WITH_MAILDIR)
+	@${PATCH} ${PATCH_ARGS} -F 3 -p1 < ${PATCHDIR}/extra-patch-maildir
+.endif
+
 do-build:
 	@(cd ${WRKSRC}; ${SETENV} ${MAKE_ENV} ./build bsf ${EXTRA_OPTS})
 
diff -ruN pine4.orig/files/extra-patch-maildir pine4/files/extra-patch-maildir
--- pine4.orig/files/extra-patch-maildir	Thu Jan  1 01:00:00 1970
+++ pine4/files/extra-patch-maildir	Fri Jan 28 18:09:19 2005
@@ -0,0 +1,2256 @@
+diff -rc pine4.62/README.maildir pine4.62.maildir/README.maildir
+*** pine4.62/README.maildir	Fri Jan 28 10:08:42 2005
+--- pine4.62.maildir/README.maildir	Wed Jan 19 15:00:52 2005
+***************
+*** 0 ****
+--- 1,76 ----
++ Maildir Driver for Pine4.62
++ ---------------------------
++ 
++ This is a maildir driver for the c-client library and Pine. This code
++ started from code in old maildir patches but it was completely rewritten,
++ so the old way to configure it does not apply anymore.
++ 
++ This patch takes the approach that you should not patch Pine to make the 
++ maildir driver do its work correctly, by this I mean things like appending 
++ messages to a folder, or so. You could of course patch Pine if you want to 
++ pass parameters to the driver, but not to fix the driver. This patch 
++ modifies Pine so that it will be possible to pass a parameter to the 
++ driver (e.g. the location of the INBOX). Although this patch was based in 
++ an old version of a maildir patch it has been almost completely rewritten 
++ and it can be considered independent work (look at the flow of functions, 
++ checks, etc). The patch is based on the code for the unix driver plus some 
++ combinations of the mh driver and the mbx driver for the c-client library. 
++ Those drivers were designed by Mark Crispin, and bugs in this code are not 
++ his bugs, but my own.
++ 
++  One of my goals with this patch is that the associated imap server must
++ work well with this patch and any client!. Trying to do this I've cleaned
++ a lot of bugs in older work and restructured the flow. I am sure that
++ doing this is a never ending job, since improvements to the code can
++ always be made, and I am looking forward to doing them sometime in the
++ future.
++ 
++  This patch does not keep UIDs between sessions, but hopefully it does
++ keep consistent UIDs during one session. This is not a bug of the driver,
++ instead it is a shortcoming of the maildir specification. The main point
++ of the maildir configuration is that you should never (read my lips) ever
++ edit the message, but edit the filename associated to the message. Well, I
++ could not find any single place in the web where it was told how to save
++ the UID of a message, if there is one please let me know and I will add
++ UID support for this driver.
++ 
++   I got all the specification for this patch from 
++ http://cr.yp.to/proto/maildir.html. If you know of a place with a better 
++ specification for maildir format please let me know. The method this patch 
++ uses to create a unique filename for a message is one of the "old 
++ fashioned" methods. I realize that this is old fashioned, but it is 
++ portable, and portability is the main reason why I decided to use an old 
++ fashioned method (most methods are not portable. See the word 
++ "Unfortunately" in that document).
++ 
++   I am interested in improving speed in the driver, please send me reports
++ of slowness or any other comments you can think are appropriate.
++ 
++ Once this approach was chosen, it implied the following:
++ 
++     * This patch assumes that your INBOX is located at "$HOME/Maildir".  
++       This is a directory which should have three subdirectories "cur", 
++       "tmp" and "new". Mail is delivered to 'new' and read from 'cur'. I 
++       have added a configuration option "maildir-location" which can be 
++       used to tell Pine where your Maildir inbox is, in case your system 
++       do not use the above directory (e.g. your system may use 
++       "~/.maildir"). In this case define that variable to be the name of 
++       the directory where your e-mail is being delivered (e.g. 
++       ".maildir").
++ 
++     * If you want to use the above configuration as your inbox, you must
++       define your inbox-path as "#md/inbox" (no quotes).  You can define
++       the inbox-path like above even if you have changed the
++       maildir-location variable. That's the whole point of that variable.
++ 
++     * You can create a collection of folders which are in maildir format.
++       In order to do that press M S L and add the following data:
++        
++       Nickname: Anything
++       Server  :
++       Path    : #md/relative/path/to/home
++       View    :
++ 
++ Written by Eduardo Chappa <chappa@math.washington.edu>
++ 
++ Last Updated June 04, 2004
+diff -rc pine4.62/imap/src/c-client/mail.c pine4.62.maildir/imap/src/c-client/mail.c
+*** pine4.62/imap/src/c-client/mail.c	Tue Jan 18 18:16:41 2005
+--- pine4.62.maildir/imap/src/c-client/mail.c	Wed Jan 19 15:00:52 2005
+***************
+*** 976,981 ****
+--- 976,982 ----
+  	   (((*mailbox == '{') || (*mailbox == '#')) &&
+  	    (stream = mail_open (NIL,mailbox,OP_PROTOTYPE | OP_SILENT))))
+      d = stream->dtb;
++   else if (maildir_valid_name(mailbox)) return maildir_create(stream, mailbox);
+    else if ((*mailbox != '{') && (ts = default_proto (NIL))) d = ts->dtb;
+    else {			/* failed utterly */
+      sprintf (tmp,"Can't create mailbox %.80s: indeterminate format",mailbox);
+diff -rc pine4.62/imap/src/c-client/mail.h pine4.62.maildir/imap/src/c-client/mail.h
+*** pine4.62/imap/src/c-client/mail.h	Mon Dec  6 23:40:10 2004
+--- pine4.62.maildir/imap/src/c-client/mail.h	Wed Jan 19 15:00:52 2005
+***************
+*** 789,794 ****
+--- 789,795 ----
+    unsigned int spare7 : 1;	/* seventh spare bit */
+    unsigned int spare8 : 1;	/* eighth spare bit */
+    void *sparep;			/* spare pointer */
++   void *maildirp;		/* for the Maildir driver, can't use sparep */
+    unsigned long user_flags;	/* user-assignable flags */
+  } MESSAGECACHE;
+  
+diff -rc pine4.62/imap/src/osdep/unix/Makefile pine4.62.maildir/imap/src/osdep/unix/Makefile
+*** pine4.62/imap/src/osdep/unix/Makefile	Fri Nov  5 14:33:53 2004
+--- pine4.62.maildir/imap/src/osdep/unix/Makefile	Wed Jan 19 15:00:52 2005
+***************
+*** 107,113 ****
+  # Standard distribution build parameters
+  
+  DEFAULTAUTHENTICATORS=md5 pla log
+! DEFAULTDRIVERS=imap nntp pop3 mh mx mbx tenex mtx mmdf unix news phile
+  
+  
+  # Normally no need to change any of these
+--- 107,113 ----
+  # Standard distribution build parameters
+  
+  DEFAULTAUTHENTICATORS=md5 pla log
+! DEFAULTDRIVERS=maildir imap nntp pop3 mh mx mbx tenex mtx mmdf unix news phile
+  
+  
+  # Normally no need to change any of these
+***************
+*** 116,122 ****
+  BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o siglocal.o \
+   dummy.o pseudo.o netmsg.o flstring.o fdstring.o \
+   rfc822.o nntp.o smtp.o imap4r1.o pop3.o \
+!  unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o
+  CFLAGS=-g
+  
+  CAT=cat
+--- 116,122 ----
+  BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o siglocal.o \
+   dummy.o pseudo.o netmsg.o flstring.o fdstring.o \
+   rfc822.o nntp.o smtp.o imap4r1.o pop3.o \
+!  unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o maildir.o
+  CFLAGS=-g
+  
+  CAT=cat
+***************
+*** 245,251 ****
+  
+  cyg:	# Cygwin - note that most local file drivers don't work!!
+  	$(BUILD) `$(CAT) SPECIALS` OS=$@ \
+! 	DEFAULTDRIVERS="imap nntp pop3 mbx unix phile" \
+  	SIGTYPE=psx CHECKPW=cyg LOGINPW=cyg CRXTYPE=std \
+  	SPOOLDIR=/var \
+  	ACTIVEFILE=/usr/local/news/lib/active \
+--- 245,251 ----
+  
+  cyg:	# Cygwin - note that most local file drivers don't work!!
+  	$(BUILD) `$(CAT) SPECIALS` OS=$@ \
+! 	DEFAULTDRIVERS="imap nntp pop3 mbx unix maildir phile" \
+  	SIGTYPE=psx CHECKPW=cyg LOGINPW=cyg CRXTYPE=std \
+  	SPOOLDIR=/var \
+  	ACTIVEFILE=/usr/local/news/lib/active \
+***************
+*** 834,840 ****
+  tenex.o: mail.h misc.h osdep.h dummy.h
+  unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h
+  utf8.o: mail.h misc.h osdep.h utf8.h
+! 
+  
+  # OS-dependent
+  
+--- 834,840 ----
+  tenex.o: mail.h misc.h osdep.h dummy.h
+  unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h
+  utf8.o: mail.h misc.h osdep.h utf8.h
+! maildir.o: mail.h misc.h osdep.h maildir.h dummy.h
+  
+  # OS-dependent
+  
+diff -rc pine4.62/imap/src/osdep/unix/dummy.c pine4.62.maildir/imap/src/osdep/unix/dummy.c
+*** pine4.62/imap/src/osdep/unix/dummy.c	Wed Nov 10 16:32:35 2004
+--- pine4.62.maildir/imap/src/osdep/unix/dummy.c	Wed Jan 19 15:00:52 2005
+***************
+*** 364,370 ****
+    char *s,tmp[MAILTMPLEN];
+  				/* don't \NoSelect dir if it has a driver */
+    if ((attributes & LATT_NOSELECT) && (d = mail_valid (NIL,name,NIL)) &&
+!       (d != &dummydriver)) attributes &= ~LATT_NOSELECT;
+    if (!contents ||		/* notify main program */
+        (!(attributes & LATT_NOSELECT) && (csiz = strlen (contents)) &&
+         (s = mailboxfile (tmp,name)) &&
+--- 364,373 ----
+    char *s,tmp[MAILTMPLEN];
+  				/* don't \NoSelect dir if it has a driver */
+    if ((attributes & LATT_NOSELECT) && (d = mail_valid (NIL,name,NIL)) &&
+!       (d != &dummydriver)){
+! 	 attributes &= ~LATT_NOSELECT;
+! 	 attributes |= LATT_NOINFERIORS;
+!   }
+    if (!contents ||		/* notify main program */
+        (!(attributes & LATT_NOSELECT) && (csiz = strlen (contents)) &&
+         (s = mailboxfile (tmp,name)) &&
+***************
+*** 385,390 ****
+--- 388,395 ----
+  {
+    char *s,tmp[MAILTMPLEN];
+    long ret = NIL;
++   if(!strncmp(mailbox,"#md/",4))
++     return maildir_create(stream, mailbox);
+  				/* validate name */
+    if (!(compare_cstring (mailbox,"INBOX") && (s = dummy_file (tmp,mailbox)))) {
+      sprintf (tmp,"Can't create %.80s: invalid name",mailbox);
+***************
+*** 450,455 ****
+--- 455,462 ----
+  {
+    struct stat sbuf;
+    char *s,tmp[MAILTMPLEN];
++   if (!strncmp(mailbox,"#md/",4) || is_valid_maildir(&mailbox))
++      return maildir_delete(stream, mailbox);
+    if (!(s = dummy_file (tmp,mailbox))) {
+      sprintf (tmp,"Can't delete - invalid name: %.80s",s);
+      MM_LOG (tmp,ERROR);
+***************
+*** 476,481 ****
+--- 483,491 ----
+  {
+    struct stat sbuf;
+    char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN];
++ 
++   maildir_remove_root(&old);
++   maildir_remove_root(&newname);
+  				/* no trailing / allowed */
+    if (!dummy_file (oldname,old) || !(s = dummy_file (mbx,newname)) ||
+        ((s = strrchr (s,'/')) && !s[1])) {
+diff -rc pine4.62/imap/src/osdep/unix/maildir.c pine4.62.maildir/imap/src/osdep/unix/maildir.c
+*** pine4.62/imap/src/osdep/unix/maildir.c	Fri Jan 28 10:08:42 2005
+--- pine4.62.maildir/imap/src/osdep/unix/maildir.c	Thu Jan 20 17:01:23 2005
+***************
+*** 0 ****
+--- 1,1640 ----
++ /*
++  * Maildir driver for Pine4.62
++  * 
++  * Written by Eduardo Chappa <chappa@math.washington.edu>
++  * Last Update: January 18, 2005
++  *
++  * The IMAP toolkit provided in this Distribution is
++  * Copyright 2004 University of Washington.
++  * The full text of our legal notices is contained in the file called
++  * CPYRIGHT, included with this Distribution.
++  */
++ 
++ #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 "maildir.h"
++ #include "fdstring.h"
++ #include "misc.h"
++ #include "dummy.h"
++ 
++ /* Driver dispatch used by MAIL */
++ 
++ DRIVER maildirdriver = {
++   "md",				/* driver name, yes it's md, not maildir */
++ 				/* driver flags */
++   DR_MAIL|DR_LOCAL|DR_NOFAST|DR_NAMESPACE|DR_NOSTICKY,
++   (DRIVER *) NIL,		/* next driver 				*/
++   maildir_valid,		/* mailbox is valid for us 		*/
++   maildir_parameters,		/* manipulate parameters		*/
++   NIL,				/* scan mailboxes 			*/
++   maildir_list,			/* find mailboxes 			*/
++   maildir_lsub,			/* find subscribed mailboxes 		*/
++   maildir_sub,			/* subscribe to mailbox 		*/
++   maildir_unsub,		/* unsubscribe from mailbox 		*/
++   maildir_create,		/* create mailbox 			*/
++   maildir_delete,		/* delete mailbox 			*/
++   maildir_rename,		/* rename mailbox 			*/
++   mail_status_default,		/* status of mailbox 			*/
++   maildir_open,			/* open mailbox				*/
++   maildir_close,		/* close mailbox 			*/
++   NIL,				/* fetch message "fast" attributes	*/
++   NIL,				/* fetch message flags 			*/
++   NIL,				/* fetch overview 			*/
++   NIL,				/* fetch message structure 		*/
++   maildir_header,		/* fetch message header 		*/
++   maildir_text,			/* fetch message body 			*/
++   NIL,				/* fetch partial message text 		*/
++   NIL,				/* unique identifier 			*/
++   NIL,				/* message number 			*/
++   NIL,				/* modify flags 			*/
++   maildir_flagmsg,		/* per-message modify flags 		*/
++   NIL,				/* search for message based on criteria */
++   NIL,				/* sort messages 			*/
++   NIL,				/* thread messages 			*/
++   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_append,		/* append string message to mailbox 	*/
++   NIL				/* garbage collect stream 		*/
++ };
++ 
++ MAILSTREAM maildirproto = {&maildirdriver};	/* prototype stream */
++ 
++ void 
++ md_domain_name(void)
++ {
++    int i;
++ 
++    strcpy(mdlocaldomain,mylocalhost ());
++    for (i = 0; mdlocaldomain[i] ; i++)
++       if(mdlocaldomain[i] == '/')
++ 	 mdlocaldomain[i] = '\057';
++       else if (mdlocaldomain[i] == ':')
++ 	 mdlocaldomain[i] =  '\072';
++ }
++ 
++ /* remove the "#md/" part from a folder name */
++ void maildir_remove_root (char **name)
++ {
++   if (maildir_valid_name(*name)){
++      (*name) += 3;
++      if (**name == '/')
++ 	(*name)++;
++   }
++ }
++ 
++ 
++ /* Check validity of the name, we accept:
++  *	a) #md/directory/folder
++  *	b) #md/inbox
++  * A few considerations: We can only accept as valid
++  *  a) names that start with #md/ and the directory exists or
++  *  b) names that do not start with #md/ but are maildir directories (have
++  *     the /cur, /tmp and /new structure)
++  */
++ int maildir_valid_name (char *name)
++ {
++   int ret = NIL;
++   char tmpname[MAILTMPLEN+1] = {'\0'};
++ 
++    if (mdfpath)
++       fs_give((void **)&mdfpath);
++    if (name && (name[0] != '#'))
++ 	sprintf(tmpname,"#md/%s",name);
++    mdfpath = cpystr(tmpname[0] ? tmpname : name);
++ 
++   if (name && (name[0] == '#') 
++ 	&& ((name[1] == 'm') || (name[1] == 'M'))
++ 	&& ((name[2] == 'd') || (name[2] == 'D')) 
++ 	&& ((name[3] == '/') && name[4])) ret = T;
++ 
++   return ret;
++ }
++ 
++ /* Check if the directory whose path is given by name is a valid maildir
++  *  directory (contains /cur, /tmp and /new)
++  */
++ int maildir_valid_dir (char *name)
++ {
++  int len;
++  DirNamesType i;
++  struct stat sbuf;
++  char tmp[MAILTMPLEN+1];
++ 
++    len = strlen(name);
++    for (i = Cur; i != EndDir; i++){
++       MDFLD(tmp, name, i);
++       if (stat(tmp, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
++ 	  break;
++    }
++    name[len] = '\0';
++    return i == EndDir ? T : NIL;
++ }
++ 
++ /* given a maildir folder, return its path. Memory freed by caller. Directory
++  * does not contain the trailing slash "/". On error NULL is returned.
++  */
++ int maildir_file_path (char *name, char *tmp)
++ {
++    char *maildirpath = maildir_parameters(GET_INBOXPATH,NIL);
++ 
++     maildir_remove_root(&name);
++     tmp[0] = '\0';	/* just in case something fails */
++     if (strlen(myhomedir()) + 
++ 		max(strlen(name), strlen(maildirpath 
++ 				 ? maildirpath : "Maildir")) > MAILTMPLEN){
++ 	errno = ENAMETOOLONG;
++ 	sprintf(tmp,"Error opening \"%s\": %s", name, strerror (errno));
++ 	mm_log(tmp,ERROR);
++     }
++     else
++ 	sprintf (tmp,"%s/%s%s",myhomedir (),
++ 	    strncmp (ucase (strcpy (tmp, name)), "INBOX", 5) 
++ 		? name : (maildirpath ? maildirpath : "Maildir") ,
++ 	    strncmp (ucase (strcpy (tmp, name)), "INBOX", 5) 
++ 		? "" : *(name+5) == '/' ? name+5 : "");
++ 
++     return tmp[0] ? T : NIL;
++ }
++ 
++ /* This function is given a full path for a mailbox and returns
++  * if it is a valid maildir transformed to canonical notation
++  */
++ int
++ is_valid_maildir (char **name)
++ {
++   if (!strncmp(*name, myhomedir (), strlen(myhomedir()))){
++      (*name) += strlen(myhomedir());
++   }
++   return maildir_valid(*name) ? T :  NIL;
++ }
++ 
++ /* Check validity of mailbox. This routine does not send errors to log, other
++  *  routines calling this one may do so, though
++  */ 
++ 
++ DRIVER *maildir_valid (char *name)
++ {
++   char tmpname[MAILTMPLEN+1];
++   struct stat sbuf;
++   int  rv, mdv, mdvd;
++ 
++    maildir_file_path(name, tmpname);
++    mdv = maildir_valid_name(name);
++    mdvd = maildir_valid_dir(tmpname);
++    rv = stat(tmpname, &sbuf);
++ 
++    return (mdv == 1 && rv == 0 && S_ISDIR(sbuf.st_mode) && mdvd == 1)
++ 	   || (mdv == 0 && mdvd == 1) ? &maildirdriver : NIL;
++ }
++ 
++ /* 
++  * return all files in a given directory. This is a separate call
++  * so that if there are warnings during compilation this only appears once.
++  */
++ unsigned long
++ maildir_scandir (char *name, struct direct ***flist, 
++ 			unsigned long *nfiles, int *scand)
++ {
++   struct stat sbuf;
++ 
++   if (scand)
++      *scand = -1;	/* assume error for safety */
++   stat(name,&sbuf);	/* stat the containing directory */
++   if (scand)
++      *scand = scandir(name, flist, maildir_select, maildir_namesort);
++  *nfiles = (scand && (*scand > 0)) ? (unsigned long) *scand : 0L;
++ 
++   return sbuf.st_ctime;
++ }
++ 
++ /* Does a message with given name exists (or was it removed)?
++  * Returns: 1 - yes, such message exist,
++  *	    0 - No, that message does not exist anymore
++  *
++  * Parameters: stream, name of mailbox, new name if his message does not
++  *		exist.
++  */
++ 
++ int maildir_message_exists(MAILSTREAM *stream, char *name, char *newfile)
++ {
++   char tmp[MAILTMPLEN+1];
++   int gotit = NIL;
++   DIR *dir;
++   struct direct *d;
++   struct stat sbuf;
++ 
++   /* First check directly if it exists, if not there, look for it */
++   sprintf(tmp,"%s/%s", LOCAL->curdir, name);
++   if ((stat(tmp, &sbuf) == 0) && ((sbuf.st_mode & S_IFMT) == S_IFREG))
++     return T;
++ 
++   if (!(dir = opendir (LOCAL->curdir)))
++      return NIL;
++ 
++   while ((d = readdir(dir)) && gotit == NIL){
++     if (d->d_name[0] == '.')
++       continue;
++     if (same_maildir_file(d->d_name, name)){
++ 	  gotit = T;
++ 	  strcpy(newfile, d->d_name);
++     }
++   }
++   closedir(dir);
++   return gotit;
++ }
++ 
++ /* Maildir open */
++  
++ MAILSTREAM *maildir_open (MAILSTREAM *stream)
++ {
++   char tmp[MAILTMPLEN+1];
++   struct stat sbuf;
++ 
++   if (!stream) return &maildirproto;
++   if (stream->local) fatal ("maildir recycle stream");
++   md_domain_name();    /* get domain name for maildir files in mdlocaldomain */
++   stream->uid_last  = stream->uid_validity = 0;
++   if (!stream->rdonly){
++      stream->perm_seen = stream->perm_deleted = stream->perm_flagged = 
++ 	stream->perm_answered = stream->perm_draft = T;
++   }
++   stream->uid_validity = time(0);
++   stream->local = (MAILDIRLOCAL *)fs_get (sizeof (MAILDIRLOCAL));
++   memset(LOCAL, 0, sizeof(MAILDIRLOCAL));
++   LOCAL->fd = -1;
++ 
++   strcpy(tmp, stream->mailbox);
++   if (maildir_file_path (stream->mailbox, tmp))
++      LOCAL->dir = cpystr (tmp);
++   if (LOCAL->dir){
++      MDFLD(tmp, LOCAL->dir, Cur);
++      LOCAL->curdir = cpystr (tmp);
++      if (stat (LOCAL->curdir,&sbuf) < 0) {
++          sprintf (tmp,"Can't open folder %s: %s",
++ 				stream->mailbox,strerror (errno));
++          mm_log (tmp,ERROR);
++ 	 maildir_close(stream, 0);
++         return NIL;
++      }
++   }
++   sprintf(tmp,"%s/%s", *stream->mailbox == '/' ? "" : myhomedir(),
++ 			*stream->mailbox == '#' ? stream->mailbox+4 :
++ 			stream->mailbox);
++   fs_give ((void **) &stream->mailbox);
++   stream->mailbox = cpystr(tmp);
++ 
++   LOCAL->buf = (char *) fs_get ((LOCAL->buflen = MAXMESSAGESIZE) + 1);
++   stream->sequence++;
++   stream->nmsgs = stream->recent = 0;
++ 
++   maildir_parse_folder(stream, 1);
++ 
++   return stream;
++ }
++ 
++ /* Maildir initial parsing of the folder */
++ void
++ maildir_parse_folder (MAILSTREAM *stream, int full)
++ {
++    unsigned long total;
++ 
++    if (!stream)		/* what??? */
++       return;
++ 
++    MM_CRITICAL(stream);
++ 
++    /* Scan old messages first, escoba! */
++    total = LOCAL ? maildir_parse_dir(stream, 0L, Cur, full) 
++ 		 : stream->nmsgs;
++    stream->nmsgs = LOCAL ? maildir_parse_dir(stream, total, New, full) 
++ 			 : stream->nmsgs;
++ 
++    MM_NOCRITICAL(stream);
++ }
++ 
++ /* Return the number of messages in the directory, while filling the
++  * elt structure.
++  */
++ 
++ unsigned long
++ maildir_parse_dir(MAILSTREAM *stream, unsigned long nmsgs,
++ 		  DirNamesType dirtype, int full)
++ {
++    char tmp[MAILTMPLEN+1], tmp2[MAILTMPLEN+1], file[MAILTMPLEN+1], 
++ 	newfile[MAILTMPLEN+1], *mdstr;
++    struct direct **names = NIL;
++    struct stat sbuf;
++    unsigned long i, j = 0L, nfiles, last_scan;
++    unsigned long recent = stream ? stream->recent : 0L;
++    int d = 0, f = 0, r = 0, s = 0, t = 0;
++    int k, we_compute, in_list, scan_err;
++    int silent = stream ? stream->silent : NIL;
++    MESSAGECACHE *elt;
++ 
++    MDFLD(tmp, LOCAL->dir, dirtype);
++    if (access (tmp, R_OK|W_OK|X_OK) != 0){
++       maildir_abort(stream);
++       return stream->nmsgs;
++    }
++ 
++    MDFLD(tmp, LOCAL->dir, Cur);
++    if (dirtype != New && 
++ 	(stat(tmp, &sbuf) < 0 || sbuf.st_ctime == LOCAL->scantime))
++       return stream->nmsgs;
++ 
++    MDFLD(tmp, LOCAL->dir, dirtype);
++    last_scan =  maildir_scandir (tmp, &names, &nfiles, &scan_err);
++    if (dirtype == Cur)
++       LOCAL->scantime = last_scan;
++ 
++    if (scan_err < 0){
++ 	maildir_abort(stream);
++ 	return nmsgs;
++    }
++ 
++    if (dirtype == Cur)
++       for (i = 1L; i <= stream->nmsgs;){
++ 	elt = mail_elt(stream,  i);
++ 	in_list = elt && elt->maildirp && nfiles > 0L
++ 		  ? (MDPOS(elt) < nfiles 
++ 		    ? same_maildir_file(MDFILE(elt), names[MDPOS(elt)]->d_name)
++ 		    : NIL)
++ 		    || maildir_message_in_list(MDFILE(elt), names, 0L, 
++ 						nfiles - 1L, &MDPOS(elt))
++ 		  : NIL;
++ 	if (!in_list){
++ 	   if (elt->maildirp)
++ 	      maildir_free_file ((void **) &elt->maildirp);
++ 
++ 	   if (elt->recent) --recent;
++ 	   mail_expunged(stream,i);
++ 	}
++ 	else i++;
++       }
++ 
++    stream->silent = T;
++    for (we_compute = 0, i = 1L; i <= nfiles; i++){
++       unsigned long pos, n;
++       mail_exists(stream, i + nmsgs);
++       elt = mail_elt(stream, i + nmsgs);
++       if (elt && elt->maildirp)
++          pos = MDPOS(elt);	/* use data we found above */
++       else{
++         if (full)
++            pos = i - 1;		/* first time, use sequence number */
++         else{
++            for (n = 0L ; (n < nfiles) && !names[n] ; n++);
++            pos = n;		/* nfiles > stream->nmsgs!!, assign one */
++         }
++       }
++       if (dirtype == New) elt->recent = T;
++       if (!elt->private.uid){
++ 	 elt->private.uid = stream->uid_last + 1;
++ 	 stream->uid_validity = time(0);
++       }
++       if (stream->uid_last < elt->private.uid) 
++ 	  stream->uid_last = elt->private.uid;
++       if (elt->maildirp || stream->rdonly){
++ 	we_compute++; /* get old flags */
++ 	maildir_getflag(names[pos]->d_name, &d, &f, &r ,&s, &t);
++ 	maildir_free_file_only ((void **)&elt->maildirp);
++       }
++       if(!elt->maildirp)
++ 	 maildir_get_file((MAILDIRFILE **)&elt->maildirp);
++       MDFILE(elt) = cpystr(names[pos]->d_name);
++       MDPOS(elt)  = pos;
++       if (full && !stream->rdonly)
++ 	  maildir_parse_message(stream, i+nmsgs, dirtype);
++ 
++       if (we_compute && (elt->draft != d || elt->flagged != f || 
++ 	elt->answered != r || elt->seen != s || elt->deleted != t)){
++ 	   elt->draft = d; elt->flagged = f; elt->answered = r;
++ 	   elt->seen  = s; elt->deleted = t;
++ 	   if (!stream->rdonly)
++ 	      MM_FLAGS(stream, i+nmsgs);
++       }
++       if (dirtype == New && !stream->rdonly){ /* move new messages to cur */
++ 	 sprintf (file,"%s/%s", tmp, names[pos]->d_name);
++ 	 if (stat (file,&sbuf) == 0 && S_ISREG (sbuf.st_mode)){
++ 	    strcpy(tmp2,names[pos]->d_name);
++ 	    if ((mdstr = strstr (names[pos]->d_name,MDSEP(3)))
++ 		|| (mdstr = strstr (names[pos]->d_name,MDSEP(2)))){ /* Grrr */
++ 	       *(mdstr+1) = '2';
++ 	       sprintf (newfile,"%s/%s",LOCAL->curdir,names[pos]->d_name);
++ 	    }
++ 	    else{
++ 	       sprintf (newfile,"%s/%s%s",LOCAL->curdir,names[pos]->d_name,MDSEP(2));
++ 	       strcat(tmp2, MDSEP(2));
++ 	    }
++ 	    if (link (file,newfile) < 0){
++ 	       mm_log("Unable to read new mail!",WARN);
++ 	    }
++ 	    else{
++ 	      unlink (file);
++ 	      j++;	/* success!, count it! */
++ 	    }
++ 	    maildir_free_file_only((void **)&elt->maildirp);
++ 	    MDFILE(elt) = cpystr(tmp2);
++ 	    MDSIZE(elt) = sbuf.st_size;
++ 	    MDMTIME(elt) = sbuf.st_mtime;
++ 	    maildir_get_date(stream, i + nmsgs, New);
++ 	 }
++       }
++       fs_give((void **)&names[pos]);
++    }
++    if(names)
++       fs_give((void **) &names);
++    stream->silent = silent;
++    if (dirtype == New && stream->rdonly)
++       j = nfiles;
++    mail_exists(stream, nmsgs  + (dirtype == New ? j : nfiles));
++    mail_recent(stream, recent + (dirtype == New ? j : 0));
++ 
++    return (nmsgs  + (dirtype == New ? j : nfiles));
++ }
++ 
++ long maildir_ping (MAILSTREAM *stream)
++ {
++   maildir_parse_folder(stream, 0);
++   return stream && LOCAL ? T : NIL;
++ }
++ 
++ int maildir_select (struct direct *name)
++ {
++  int rv = NIL, val;
++  val = name->d_name[0] - '0';
++  switch(val){
++      case 1: case 2: case 3: case 4: case 5:
++      case 6: case 7: case 8: case 9:
++         rv = T;
++      default: break;
++  }
++  return rv;
++ }
++ 
++ /*
++  * Unfortunately, there is no way to sort by arrival in this driver, this
++  * means that opening a folder in this driver using the scandir function
++  * will always make this driver slower than any driver that has a natural
++  * way of sorting by arrival (like a flat file format, "mbox", "mbx", etc).
++  */
++ 
++ int maildir_namesort (const void *d1,const  void *d2)
++ {
++   const struct direct **e1, **e2;
++ 
++   e1 = (const struct direct **)d1;
++   e2 = (const struct direct **)d2;
++ 
++   return comp_maildir_file((char*)(*e1)->d_name, (char *)(*e2)->d_name);
++ }
++ 
++ /* Maildir close */
++ 
++ void maildir_close (MAILSTREAM *stream, long options)
++ {
++   MESSAGECACHE *elt;
++   unsigned long i;
++   int silent = stream ? stream->silent : 0;
++   mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL);
++ 
++   if (!stream) return;
++ 
++   for (i = 1; i <= stream->nmsgs; i++)
++     if ((elt = (MESSAGECACHE *) (*mc) (stream,i,CH_ELT)) && elt->maildirp)
++       maildir_free_file ((void **) &(elt->maildirp));
++   stream->silent = T;
++   if (options & CL_EXPUNGE) maildir_expunge (stream);
++   maildir_abort(stream);
++   stream->silent = silent;
++ }
++ 
++ void maildir_check (MAILSTREAM *stream)
++ {
++   if (maildir_ping (stream)) mm_log ("Check completed",(long) NIL);   
++ }
++ 
++ long maildir_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs, long flags)
++ {
++   char tmp[MAILTMPLEN+1];
++   unsigned long i;
++   MESSAGECACHE *elt;
++   char *s;
++                                 /* UID call "impossible" */
++   if (flags & FT_UID || !LOCAL) return NIL;
++   elt = mail_elt (stream,msgno);
++   sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt));
++   if (LOCAL->fd < 0)	/* if file closed ? */
++      LOCAL->fd = open(tmp,O_RDONLY,NIL);
++ 
++   if (LOCAL->fd < 0 && (errno == EACCES || errno == ENOENT)){
++      INIT (bs, mail_string, "", 0);
++      elt->rfc822_size = 0L;
++      return NIL;
++   }
++ 
++   if (!(flags & FT_PEEK) && !elt->seen) {     /* mark as seen */
++     elt->seen = T;
++     maildir_flagmsg (stream,elt); /* Change flags physically */
++     if (LOCAL->dirty == 0)
++ 	MM_FLAGS(stream, elt->msgno); 
++   }
++   s = maildir_text_work(stream, elt, &i, flags);
++   INIT (bs, mail_string, s, i);
++   return T;
++ }
++ 
++ char *maildir_text_work (MAILSTREAM *stream,MESSAGECACHE *elt,
++                       unsigned long *length,long flags)
++ {
++   FDDATA d;
++   STRING bs;
++   char *s,*t,*tl,tmp[CHUNK];
++   unsigned long msgno = elt->msgno;
++   static int try = 0;
++ 
++   if (length)
++      *length = 0L;
++   LOCAL->buf[0] = '\0';
++ 
++   sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt));
++   if (LOCAL->fd < 0)	/* if file closed ? */
++      LOCAL->fd = open(tmp,O_RDONLY,NIL);
++ 
++   if (LOCAL->fd < 0){		/* flag change? */
++       if (try < 5){
++ 	try++;
++ 	if (maildir_update_elt_maildirp(stream, msgno) > 0)
++ 	  try = 0;
++ 	return maildir_text_work(stream, mail_elt(stream, msgno),length, flags);
++       }
++       try = 0;
++       return NULL;
++   }
++ 
++   lseek (LOCAL->fd, elt->private.msg.text.offset,L_SET);
++ 
++   if (flags & FT_INTERNAL) {    /* initial data OK? */
++     if (elt->private.msg.text.text.size > LOCAL->buflen) {
++       fs_give ((void **) &LOCAL->buf);
++       LOCAL->buf = (char *) fs_get ((LOCAL->buflen =
++                                      elt->private.msg.text.text.size) + 1);
++     }
++     read (LOCAL->fd,LOCAL->buf,elt->private.msg.text.text.size);
++     LOCAL->buf[*length = elt->private.msg.text.text.size] = '\0';
++   }
++   else {
++     if (elt->rfc822_size > LOCAL->buflen) {
++       fs_give ((void **) &LOCAL->buf);
++       LOCAL->buf = (char *) fs_get ((LOCAL->buflen = elt->rfc822_size) + 1);
++     }
++     d.fd = LOCAL->fd;           /* yes, set up file descriptor */
++     d.pos = elt->private.msg.text.offset;
++     d.chunk = tmp;              /* initial buffer chunk */
++     d.chunksize = CHUNK;
++     INIT (&bs,fd_string,&d,elt->private.msg.text.text.size);
++     for (s = LOCAL->buf; SIZE (&bs);) switch (CHR (&bs)) {
++     case '\r':                  /* carriage return seen */
++       *s++ = SNX (&bs);         /* copy it and any succeeding LF */
++       if (SIZE (&bs) && (CHR (&bs) == '\n')) *s++ = SNX (&bs);
++       break;
++     case '\n':
++       *s++ = '\r';              /* insert a CR */
++     default:
++       *s++ = SNX (&bs);         /* copy characters */
++     }
++     *s = '\0';                  /* tie off buffer */
++     *length = s - (char *) LOCAL->buf;   /* calculate length */
++   }
++   close(LOCAL->fd); LOCAL->fd = -1;
++   return LOCAL->buf;
++ }
++ 
++ /* maildir parse, fill the elt structure... well not all of it... */
++ unsigned long maildir_parse_message(MAILSTREAM *stream, unsigned long msgno,
++ 				    DirNamesType dirtype)
++ {
++   char *b, *s, c;
++   char tmp[MAILTMPLEN+1];
++   struct stat sbuf;
++   unsigned long i, len;
++   int offset = 0, d, f, r, se, dt;
++   MESSAGECACHE *elt;
++ 
++   elt = mail_elt (stream,msgno);
++   MSGPATH(tmp, LOCAL->dir, MDFILE(elt), dirtype);
++   if(stat(tmp, &sbuf) == 0)
++      MDSIZE(elt) = sbuf.st_size;
++ 
++   maildir_get_date(stream, msgno, dirtype);
++   maildir_getflag(MDFILE(elt), &d, &f, &r ,&se, &dt);
++   elt->draft = d; elt->flagged = f; elt->answered = r; elt->seen = se;
++   elt->deleted = dt; elt->valid  = T;
++   if (LOCAL->fd < 0)	/* if file closed ? */
++      LOCAL->fd = open(tmp,O_RDONLY,NIL);
++ 
++   if (LOCAL->fd >= 0){
++ 	s = (char *) fs_get (MDSIZE(elt) + 1);
++ 	read (LOCAL->fd,s,MDSIZE(elt));
++ 	s[MDSIZE(elt)] = '\0';
++ 	for (i = 0, b = s; *b && !(i && (*b == '\n')); i = (*b++ == '\n'));
++ 	len = (*b ? ++b : b) - s;
++ 	elt->private.msg.header.text.size = 
++ 		elt->private.msg.text.offset = len;
++ 	elt->private.msg.text.text.size = MDSIZE(elt) - len;
++ 	for (i = 0, b = s, c = *b; b && c &&
++ 	    ((c < '\016') && (((c == '\012') && ++i) ||
++ 		((c == '\015') && (*++b == '\012') && (i +=2)))
++ 	    || c); i++, c= *++b);
++ 	elt->rfc822_size = i;
++ 	fs_give ((void **) &s);
++ 	close(LOCAL->fd); LOCAL->fd = -1;
++   }
++   return elt->rfc822_size;
++ }
++ 
++ int
++ maildir_update_elt_maildirp(MAILSTREAM *stream, unsigned long msgno)
++ {
++      char tmp[MAILTMPLEN+1];
++      struct direct **names = NIL;
++      unsigned long i, nfiles, pos;
++      int d = 0, f = 0 , r = 0, s = 0, t = 0, in_list, scan_err;
++      MESSAGECACHE *elt;
++ 
++      MDFLD(tmp, LOCAL->dir, Cur);
++ 
++      maildir_scandir (tmp, &names, &nfiles, &scan_err);
++ 
++      elt = mail_elt (stream,msgno);
++ 
++      in_list = nfiles > 0L
++ 		? maildir_message_in_list(MDFILE(elt), names, 0L, 
++ 					nfiles - 1L, &pos)
++ 		: NIL;
++ 
++      if (in_list && pos >= 0L && pos < nfiles
++ 	 && !strcmp(MDFILE(elt), names[pos]->d_name)){
++ 	in_list = NIL;
++ 	maildir_abort(stream);
++      }
++ 
++      if (in_list && pos >= 0L && pos < nfiles){
++ 	maildir_free_file_only((void **)&elt->maildirp);
++ 	MDFILE(elt) = cpystr(names[pos]->d_name);
++ 	maildir_getflag(MDFILE(elt), &d, &f, &r ,&s, &t);
++ 	if (elt->draft != d || elt->flagged != f || 
++ 	   elt->answered != r || elt->seen != s || elt->deleted != t){
++ 	   elt->draft = d; elt->flagged = f; elt->answered = r;
++ 	   elt->seen  = s; elt->deleted = t;
++ 	   MM_FLAGS(stream, msgno);
++         }
++      }
++      for (i = 0L; i < nfiles; i++)
++ 	fs_give((void **) &names[i]);
++      if (names)
++ 	fs_give((void **) &names);
++      return in_list ? 1 : -1;
++ }
++ 
++ /* Maildir fetch message header */
++ 
++ char *maildir_header (MAILSTREAM *stream,unsigned long msgno,
++ 		unsigned long *length, long flags)
++ {
++   char tmp[MAILTMPLEN+1], *s;
++   MESSAGECACHE *elt;
++   static int try = 0;
++   unsigned long hdrlen;
++ 
++   if (length)
++      *length = 0;
++   if (flags & FT_UID || !LOCAL) return "";	/* UID call "impossible" */
++   elt = mail_elt (stream,msgno);
++   if(elt->private.msg.header.text.size == 0)
++      maildir_parse_message(stream, msgno, Cur);
++ 
++ 
++   sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt));
++   if (LOCAL->fd < 0)
++      LOCAL->fd = open (tmp,O_RDONLY,NIL);
++ 
++   if (LOCAL->fd < 0 && errno == EACCES){
++      mm_log ("Message exists but can not be read. Envelope and body lost!",ERROR);
++      return NULL;
++   }
++ 
++   if (LOCAL->fd < 0){			/* flag change? */
++       if (try < 5){
++ 	try++;
++ 	if (maildir_update_elt_maildirp(stream, msgno) > 0)
++ 	  try = 0;
++ 	return maildir_header(stream, msgno, length, flags);
++       }
++       try = 0;
++       return NULL;
++   }
++ 
++   if ((flags & FT_INTERNAL) &&
++         (elt->private.msg.header.text.size > LOCAL->buflen)){
++          fs_give ((void **) &LOCAL->buf);
++          LOCAL->buf = (char *) fs_get ((LOCAL->buflen =
++                                  elt->private.msg.header.text.size) + 1);
++   }
++   else
++       s = (char *) fs_get(elt->private.msg.header.text.size+1);
++   if (LOCAL->fd >= 0){
++      read (LOCAL->fd, flags & FT_INTERNAL ? (void *)LOCAL->buf : (void *)s,
++                                       elt->private.msg.header.text.size);
++      if (flags & FT_INTERNAL)
++         LOCAL->buf[*length = elt->private.msg.header.text.size] = '\0';
++      else{
++         s[*length = elt->private.msg.header.text.size] = '\0';
++         *length = strcrlfcpy (&LOCAL->buf,&LOCAL->buflen,s,
++                           elt->private.msg.header.text.size);
++         fs_give ((void **) &s);
++      }
++   }
++   elt->private.msg.text.offset = elt->private.msg.header.text.size;
++   elt->private.msg.text.text.size = MDSIZE(elt) - elt->private.msg.text.offset;
++   if(s)
++     fs_give((void **)&s);
++   close(LOCAL->fd); LOCAL->fd = -1;
++   return LOCAL->buf;
++ 
++ 
++ 
++   return LOCAL->buf;
++ }
++ 
++ /* Maildir find list of subscribed mailboxes
++  * Accepts: mail stream
++  *	    pattern to search
++  */
++ 
++ void maildir_list (MAILSTREAM *stream,char *ref, char *pat)
++ {
++   char *s,test[MAILTMPLEN+1],file[MAILTMPLEN+1];
++   long i = 0;
++ 
++   if (!pat || !*pat) {
++     if (maildir_canonicalize (test,ref,"*")) {
++       if (maildir_valid_name(test)){	/* there is a #md/ leading here */
++ 	for (i = 3; test[i] && test[i] != '/'; i++);
++ 	if (s = strchr (test+i+1,'/')) *++s = '\0';
++ 	else test[0] = '\0';
++ 	mm_list (stream,'/',test, LATT_NOSELECT);
++       }
++     }
++   }
++                                 /* get canonical form of name */
++   else if (maildir_canonicalize (test,ref,pat)) {
++     if (test[3] == '/') {       /* looking down levels? */
++                                 /* yes, found any wildcards? */
++       if (s = strpbrk (test,"%*")) {
++                                 /* yes, copy name up to that point */
++         strncpy (file,test+4,i = s - (test+4));
++         file[i] = '\0';         /* tie off */
++       }
++       else strcpy (file,test+4);/* use just that name then */
++                                 /* find directory name */
++       if (s = strrchr (file,'/')) {
++         *s = '\0';              /* found, tie off at that point */
++         s = file;
++       }
++                                 /* do the work */
++       maildir_list_work (stream,s,test,0);
++     }
++                                 /* always an INBOX */
++     if (!compare_cstring (test,"#MD/INBOX"))
++       mm_list (stream,NIL,"#MD/INBOX",LATT_NOINFERIORS);
++   }
++ }
++ 
++ /* For those that want to hide things, we give them a chance to do so */
++ void *maildir_parameters (long function, void *value)
++ {
++   void *ret = NIL;
++   switch ((int) function) {
++   case SET_INBOXPATH:
++     if (myMdInboxDir) fs_give ((void **) &myMdInboxDir);
++     myMdInboxDir = cpystr ((char *) value);
++   case GET_INBOXPATH:
++     if (!myMdInboxDir) myMdInboxDir = cpystr("Maildir");
++     ret = (void *) myMdInboxDir;
++     break;
++   default:
++     break;
++   }
++   return ret;
++ }
++ 
++ long maildir_create_work(char *mailbox)
++ {
++   char *s, c, err[MAILTMPLEN+1], tmp[MAILTMPLEN+1];
++   int fnlen, i, create_dir = 0;
++   struct stat sbuf;
++ 
++   if (mailbox[strlen(mailbox) - 1] == '/'){
++       create_dir++;
++       mailbox[strlen(mailbox) - 1] = '\0';
++   }
++ 
++   fnlen = strlen(mailbox);
++ 
++   if (s = strrchr(mailbox,'/')){
++      c = *++s;
++     *s = '\0';
++ 
++     if ((stat(mailbox,&sbuf) || ((sbuf.st_mode & S_IFMT) != S_IFDIR)) &&
++         !maildir_create_work (mailbox))
++       return NIL;
++     *s = c;
++   }
++   mailbox[fnlen] = '\0';
++ 
++   if (mkdir (mailbox,0700) && errno != EEXIST)
++      return NIL;
++ 
++   if (create_dir)
++      mailbox[fnlen] = '/';
++ 
++   if (!create_dir){
++      for (i = Cur; i != EndDir; i++){
++ 	MDFLD(tmp, mailbox, i);
++ 
++ 	if (mkdir(tmp, 0700)){	/* try to make new dir */
++ 	    sprintf (err, "Can't create %s: %s", tmp, strerror(errno));
++ 	    mm_log (err,ERROR);
++ 	    return NIL;
++ 	}
++      }
++   }
++   else{
++      FILE *fp = NULL;
++      sprintf(tmp,"%s%s", mailbox, MDDIR);
++      if ((fp = fopen(tmp,"w")) == NULL){
++ 	sprintf (err,"Problem creating %s: %s", tmp, strerror(errno));
++ 	    mm_log (err,ERROR);
++ 	    return NIL;
++      }
++      fclose(fp);
++   }
++   return T;			/* return success */
++ }
++ 
++ long maildir_create (MAILSTREAM *stream,char *mailbox)
++ {
++   char tmp[MAILTMPLEN+1], err[MAILTMPLEN+1];
++   long rv;
++   int create_dir;
++ 
++   create_dir = mailbox ? (mailbox[strlen(mailbox) - 1] == '/') : 0;
++   maildir_file_path(mailbox, tmp);
++   rv = maildir_create_work(tmp);
++   if (rv == 0L){
++      sprintf (err,"Can't create %s %s: %s %s",
++ 		   create_dir ? "directory" : "mailbox", 
++ 		   mailbox, tmp, strerror (errno));
++      mm_log (err,ERROR);
++   }
++   return rv;
++ }
++ 
++ #define MAXTRY 10000
++ void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt)
++ {
++   char oldfile[MAILTMPLEN+1],newfile[MAILTMPLEN+1],fn[MAILTMPLEN+1];
++   char tmp[MAILTMPLEN+1];
++   char *s;
++   int ren, try = 0;
++ 
++   LOCAL->dirty = 0;
++   if (elt->valid){
++      for (try = 1; try > 0 && try < MAXTRY; try++){
++                                 /* build the new filename */
++ 	sprintf (oldfile,"%s/%s",LOCAL->curdir, MDFILE(elt));
++ 	fn[0] = '\0';
++ 	if ((ren = maildir_message_exists(stream, MDFILE(elt), fn)) == 0){
++ 	    errno = ENOENT;
++ 	    try = MAXTRY;
++ 	}
++ 	if (*fn)	/* new oldfile! */
++ 	   sprintf (oldfile,"%s/%s",LOCAL->curdir,fn);
++         if ((s = strchr (MDFILE(elt), FLAGSEP))) *s = '\0';
++ 	sprintf (fn,"%s%s%s%s%s%s%s", MDFILE(elt), MDSEP(2),
++ 		MDFLAG(Draft, elt->draft), MDFLAG(Flagged, elt->flagged),
++ 		MDFLAG(Replied, elt->answered), MDFLAG(Seen, elt->seen),
++ 		MDFLAG(Trashed, elt->deleted));
++ 	sprintf (newfile,"%s/%s",LOCAL->curdir,fn);
++         if (ren != 0 && rename (oldfile,newfile) >= 0){
++ 	   char tmp[MAILTMPLEN+1];
++          try = -1;
++ 	}
++      }
++ 
++      if (try > 0){
++        sprintf(oldfile,"Unable to write flags to disk: %s",strerror (errno));
++        mm_log(oldfile,ERROR);
++        LOCAL->dirty = 1;
++        return;
++      }
++      maildir_free_file_only ((void **) &elt->maildirp);
++      MDFILE(elt) = cpystr (fn);
++   }
++ }
++ 
++ void maildir_expunge (MAILSTREAM *stream)
++ {
++   MESSAGECACHE *elt;
++   unsigned long i;
++   unsigned long n = 0;
++   unsigned long nmsgs = stream->nmsgs;
++   unsigned long recent = stream->recent;
++   char tmp[MAILTMPLEN+1];
++   
++   mm_critical (stream);		/* go critical */
++   for (i = 1; i <= stream->nmsgs;)
++     if ((elt = mail_elt (stream,i))->deleted){
++       sprintf (tmp,"%s/%s",LOCAL->curdir, MDFILE(elt));
++       if (unlink (tmp)) {/* try to delete the message */
++ 	sprintf (tmp,"Expunge of message %ld failed, aborted: %s",i,
++ 		 strerror (errno));
++ 	if (!stream->silent)
++ 	   mm_log (tmp,WARN);
++ 	break;
++       }
++ 				/* free the cached filename */
++       if (elt->maildirp)
++ 	 maildir_free_file ((void **) &elt->maildirp);
++ 
++       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++;
++   if (n) {			/* output the news if any expunged */
++     sprintf (tmp,"Expunged %ld messages",n);
++     if (!stream->silent)
++        mm_log (tmp,(long) NIL);
++   }
++   else 
++     if (!stream->silent)
++ 	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);
++ }
++ 
++ long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options)
++ {
++   STRING st;
++   MESSAGECACHE *elt;
++   unsigned long len;
++   int fd;
++   long i, length;
++   char tmp[MAILTMPLEN+1], flags[MAILTMPLEN+1], path[MAILTMPLEN+1], *s, *b;
++ 				/* copy the messages */
++   if ((options & CP_UID) ? mail_uid_sequence (stream, sequence) : 
++   	mail_sequence (stream,sequence)) 
++   for (i = 1; i <= stream->nmsgs; i++)
++     if ((elt = mail_elt (stream,i))->sequence){
++       sprintf (path,"%s/%s",LOCAL->curdir, MDFILE(elt));
++       if ((fd = open (path,O_RDONLY,NIL)) < 0) return NIL;
++         s = (char *) fs_get(MDSIZE(elt) + 1);
++         read (fd,s,MDSIZE(elt));
++         s[MDSIZE(elt)] = '\0';
++         close (fd);
++ 	len = strcrlfcpy (&LOCAL->buf,&LOCAL->buflen, s, MDSIZE(elt));
++         INIT (&st,mail_string, LOCAL->buf, len);
++ 	fs_give ((void **)&s);
++ 
++       flags[0] = flags[1] = '\0';
++       if (elt->seen) strcat (flags," \\Seen");
++       if (elt->draft) strcat (flags," \\Draft");
++       if (elt->deleted) strcat (flags," \\Deleted");
++       if (elt->flagged) strcat (flags," \\Flagged");
++       if (elt->answered) strcat (flags," \\Answered");
++       flags[0] = '(';         /* open list */
++       strcat (flags,")");     /* close list */
++       mail_date (tmp,elt);	/* generate internal date */
++       if (!mail_append_full (NIL,mailbox,flags,tmp,&st))
++         return NIL;
++       if (options & CP_MOVE) elt->deleted = T;
++     }
++   return T;			/* return success */
++ }
++ 
++ long maildir_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data)
++ {
++   int fd;
++   STRING *message;
++   char c,*s, *flags, *date;
++   char tmp[MAILTMPLEN+1],file[MAILTMPLEN+1],path1[MAILTMPLEN+1],path2[MAILTMPLEN+1];
++   MESSAGECACHE elt;
++   long i;
++   long size = 0;
++   long ret = LONGT;
++   unsigned long uf;
++   long f;
++   static unsigned int transact = 0;
++ 
++   if (!maildir_valid(mailbox)) {
++     sprintf (tmp,"Not a valid Maildir mailbox: %s",mailbox);
++     mm_log (tmp,ERROR);
++     return NIL;
++   }
++ 
++  if (!*mdlocaldomain)
++      md_domain_name();    /* get domain name for maildir files in mdlocaldomain now! */
++ 
++   if (!(*af) (stream,data,&flags,&date,&message)) return NIL;
++ 
++   mm_critical (stream);		/* go critical */
++   do {
++     if (!SIZE (message)) {      /* guard against zero-length */
++       mm_log ("Append of zero-length message",ERROR);
++       ret = NIL;
++       break;
++     }
++     if (date) {                 /* want to preserve date? */
++                                 /* yes, parse date into an elt */
++       if (!mail_parse_date (&elt,date)) {
++         sprintf (tmp,"Bad date in append: %.80s",date);
++         mm_log (tmp,ERROR);
++         ret = NIL;
++         break;
++       }
++     }
++     f = mail_parse_flags (stream,flags,&uf);
++ 				/* build file name we will use */
++     sprintf (file,"%u.%d_%09u.%s%s%s%s%s%s",
++ 	   time (0),getpid (),transact++,mdlocaldomain, f ? MDSEP(2) : "",
++ 		MDFLAG(Draft, f&fDRAFT), MDFLAG(Flagged, f&fFLAGGED),
++ 		MDFLAG(Replied, f&fANSWERED), MDFLAG(Seen, f&fSEEN));
++ 				/* build tmp file name */
++     if (maildir_file_path(mailbox, tmp))
++        MSGPATH(path1, tmp, file, Tmp);
++ 
++     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;
++     }
++     for (size = 0,i = SIZE (message),s = (char *) fs_get (i + 1); i; --i)
++       if ((c = SNX (message)) != '\015') s[size++] = c;
++     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;
++     }
++     fs_give ((void **) &s);	/* flush the buffer */
++     close (fd);			/* close the file */
++ 				/* build final filename to use */
++     if (maildir_file_path(mailbox, tmp))
++ 	MSGPATH(path2, tmp, file, New);
++     if (link (path1,path2) < 0) {
++        sprintf (tmp,"Message append failed: %s",strerror (errno));
++        mm_log (tmp,ERROR);
++        ret = NIL;
++     }
++     unlink (path1);
++ 
++     if (ret)
++      if (!(*af) (stream,data,&flags,&date,&message)) ret = NIL;
++ 
++   } while (ret && message);	/* write the data */
++   
++   mm_nocritical (stream);	/* release critical */
++   return ret;
++ }
++ 
++ long maildir_delete (MAILSTREAM *stream,char *mailbox)
++ {
++   DIR *dirp;
++   struct direct *d;
++   int i, remove_dir = 0, mddir = 0, rv;
++   char tmp[MAILTMPLEN+1],tmp2[MAILTMPLEN+1];
++   struct stat sbuf;
++   char *mdpath = maildir_parameters(GET_INBOXPATH,NIL);
++ 
++   if (mailbox[strlen(mailbox) - 1] == '/'){
++       remove_dir++;
++       mailbox[strlen(mailbox) -1] = '\0';
++   }
++ 
++   if (!maildir_valid(mailbox)){
++       sprintf(tmp,"%s/%s/", myhomedir(), *(mdfpath+4) ? mdfpath+4 
++ 					: (mdpath ? mdpath : "Maildir"));
++       if (stat(tmp, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
++      return NIL;
++   }
++ 
++   maildir_close(stream,0);	/* even if stream was NULL */
++ 
++   if (remove_dir && !maildir_dir_is_empty(mailbox)){
++      sprintf(tmp,"Can not remove directory %s/: directory not empty", mailbox);
++      mm_log (tmp,ERROR);
++      return NIL;
++   }
++   maildir_file_path(mailbox, tmp2);
++ 
++   if (remove_dir){
++      sprintf(tmp,"%s/%s", tmp2, MDDIR);
++      if ((rv = stat (tmp,&sbuf)) == 0 && S_ISREG(sbuf.st_mode))
++ 	rv = unlink(tmp);
++      else if (errno == ENOENT)
++ 	rv = 0;
++      if (rv != 0){
++ 	sprintf(tmp,"Can not remove %s/%s: %s", tmp2, MDDIR, strerror(errno));
++ 	mm_log (tmp,ERROR);
++ 	return NIL;
++      }
++      if (!maildir_valid(mailbox) && rmdir(tmp2) != 0){
++ 	sprintf(tmp,"Can not remove %s/: %s", tmp2, strerror(errno));
++ 	mm_log (tmp,ERROR);
++ 	return NIL;
++      }
++      return T;
++   }
++   /* else remove just the folder. Remove all hidden files, except MDDIR */
++   for (i = Cur; i != EndDir; i++){
++       maildir_file_path(mailbox, tmp);
++       MDFLD(tmp2, tmp, i);
++ 
++       if (!(dirp = opendir (tmp2))){
++ 	  sprintf(tmp,"Can not read %s/: %s", tmp2, strerror(errno));
++ 	  mm_log (tmp,ERROR);
++ 	  return NIL;
++       }
++ 
++       while (d = readdir(dirp)){
++ 	 if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")){
++ 	    sprintf(tmp,"%s/%s", tmp2, d->d_name);
++ 	    if (unlink(tmp) != 0){
++ 	       sprintf(tmp,"Can not remove %s: %s", tmp2, strerror(errno));
++ 	       mm_log (tmp,ERROR);
++ 	       return NIL;
++ 	    }
++ 	 }
++       }
++       closedir(dirp);
++       if (rmdir(tmp2) != 0){
++ 	 sprintf(tmp,"Can not remove %s: %s", tmp2, strerror(errno));
++ 	 mm_log (tmp,ERROR);
++ 	 return NIL;
++       }
++   }
++   /* 
++    * ok we have removed all subdirectories of the folder mailbox, Remove the
++    * hidden files.
++    */
++ 
++      maildir_file_path(mailbox, tmp2);
++      if (!(dirp = opendir (tmp2))){
++ 	sprintf(tmp,"Can not read %s/: %s", tmp2, strerror(errno));
++ 	mm_log (tmp,ERROR);
++ 	return NIL;
++      }
++ 
++      while (d = readdir(dirp)){
++ 	if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")
++ 		&& strcmp(d->d_name, MDDIR)){
++ 	   sprintf(tmp,"%s/%s", tmp2, d->d_name);
++ 	   if (unlink(tmp) != 0){
++ 	      sprintf(tmp,"Can not remove %s: %s", tmp2, strerror(errno));
++ 	      mm_log (tmp,ERROR);
++ 	      return NIL;
++ 	   }
++ 	}
++ 	else if (!strcmp(d->d_name, MDDIR)) mddir++;
++      }
++      closedir(dirp);
++      if (maildir_dir_is_empty(mailbox) && mddir == 0 && rmdir(tmp2) < 0){
++         sprintf(tmp,"Can not remove folder %s: %s", mailbox, strerror(errno));
++         mm_log (tmp,ERROR);
++         return NIL;
++      }
++    return T;
++ }
++ 
++ long maildir_rename (MAILSTREAM *stream,char *old,char *new)
++ {
++   char tmp[MAILTMPLEN+1],tmpnew[MAILTMPLEN+1];
++   char *maildirpath = maildir_parameters(GET_INBOXPATH, NIL);
++ 
++   if (!maildir_valid(old)){
++     sprintf (tmp,"Can't rename mailbox %s: folder not in maildir format",old);
++     mm_log (tmp,ERROR);
++     return NIL;
++   }
++   sprintf(tmp,"%s/%s/", myhomedir(), *(mdfpath+4) ? mdfpath+4 : 
++ 					maildirpath ? maildirpath : "Maildir");
++ 
++   if (!maildir_valid_name(new) && new[0] == '#'){
++     sprintf (tmp,"Can't rename mailbox %s: folder not in maildir format",new);
++     mm_log (tmp,ERROR);
++     return NIL;
++   }
++   sprintf(tmpnew,"%s/%s/", myhomedir(), *(mdfpath+4) ? mdfpath+4 : 
++ 					maildirpath ? maildirpath : "Maildir");
++ 
++ 				/* new mailbox name must not exist */
++   if (access(tmpnew,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 (tmp,tmpnew)) {
++     sprintf (tmp,"Can't rename mailbox %s to %s: %s",old,new,strerror (errno));
++     mm_log (tmp,ERROR);
++     return NIL;
++   }
++   return T;			/* return success */
++ }
++ 
++ long maildir_sub (MAILSTREAM *stream,char *mailbox)
++ {
++   return sm_subscribe (mailbox);
++ }
++ 
++ long maildir_unsub (MAILSTREAM *stream,char *mailbox)
++ {
++   return sm_unsubscribe (mailbox);
++ }
++ 
++ void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat)
++ {
++   void *sdb = NIL;
++   char *s, 	test[MAILTMPLEN+1];
++                                 /* get canonical form of name */
++   if (maildir_canonicalize (test,ref,pat) && (s = sm_read (&sdb))) {
++     do if (pmatch_full (s,test,'/')) mm_lsub (stream,'/',s,NIL);
++     while (s = sm_read (&sdb)); /* until no more subscriptions */
++   }
++ }
++ 
++ long maildir_canonicalize (char *pattern,char *ref,char *pat)
++ {
++   if (ref && *ref) {            /* have a reference */
++     strcpy (pattern,ref);       /* copy reference to pattern */
++                                 /* # overrides mailbox field in reference */
++     if (*pat == '#') strcpy (pattern,pat);
++                                 /* pattern starts, reference ends, with / */
++     else if ((*pat == '/') && (pattern[strlen (pattern) - 1] == '/'))
++       strcat (pattern,pat + 1); /* append, omitting one of the period */
++                                                                                 
++     else strcat (pattern,pat);  /* anything else is just appended */
++   }
++   else strcpy (pattern,pat);    /* just have basic name */
++   return (maildir_valid_name(pattern));
++ }
++ 
++ void maildir_list_work (MAILSTREAM *stream,char *dir,char *pat,long level)
++ {
++   DIR *dp;
++   struct direct *d;
++   struct stat sbuf;
++   char *cp,*np, curdir[MAILTMPLEN+1],name[MAILTMPLEN+1], tmp[MAILTMPLEN+1];
++   int i;
++   char *maildirpath = maildir_parameters(GET_INBOXPATH, NIL);
++ 
++   sprintf(curdir,"%s/%s/", myhomedir(), dir ? dir : 
++ 				(maildirpath ? maildirpath : "Maildir"));
++   if (dp = opendir (curdir)){ 
++      if (dir) sprintf (name,"#md/%s/",dir);
++      else strcpy (name,"#md/");
++ 
++      if (level == 0 && name && pmatch_full (name, pat, '/'))
++ 	mm_list (stream,'/', name, LATT_NOSELECT);
++ 
++      while (d = readdir (dp))
++        if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")
++ 		&& strcmp(d->d_name, MDNAME(Cur)) 
++ 		&& strcmp(d->d_name, MDNAME(Tmp)) 
++ 		&& strcmp(d->d_name, MDNAME(New))){
++ 
++ 	  if (dir) sprintf (tmp,"%s%s", name,d->d_name);
++ 	  else strcpy(tmp, d->d_name);
++ 
++ 	  if (pmatch_full (tmp,pat,'/')){
++ 	       sprintf(tmp,"%s/%s/%s", myhomedir(), dir ? dir : 
++ 			 (maildirpath ? maildirpath : "Maildir"), d->d_name);
++                if (stat (tmp,&sbuf) == 0 
++ 		   && ((sbuf.st_mode & S_IFMT) == S_IFDIR)){
++ 		    if (dir) sprintf (tmp,"%s%s", name,d->d_name);
++ 		    else strcpy(tmp, d->d_name);
++ 		     i = maildir_valid(tmp) ? LATT_NOINFERIORS : LATT_NOSELECT;
++ 		     if (i == LATT_NOINFERIORS && 
++ 				maildir_contains_folder(dir, d->d_name))
++ 			i = LATT_HASCHILDREN;
++ 		     i += maildir_any_new_msgs(tmp) ? LATT_MARKED : LATT_UNMARKED;
++ 	             mm_list (stream,'/',tmp, i);
++ 		     strcat (tmp, "/");
++ 	             if (dmatch (tmp,pat,'/') &&
++                        (level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL))){
++ 		       sprintf(tmp,"%s/%s",dir,d->d_name);
++  		       maildir_list_work (stream,tmp,pat,level+1);
++ 		     }
++ 	       }
++ 	  }
++        }
++   }
++   closedir (dp);
++ }
++ 
++ int 
++ same_maildir_file(char *name1, char *name2)
++ {
++  char tmp1[MAILTMPLEN+1], tmp2[MAILTMPLEN+1];
++  char *s;
++ 
++  strcpy(tmp1, name1 ? name1 : "");
++  strcpy(tmp2, name2 ? name2 : "");
++  if (s = strchr(tmp1, FLAGSEP))
++    *s = '\0';
++  if (s = strchr(tmp1, SIZESEP))
++    *s = '\0';
++  if (s = strchr(tmp2, FLAGSEP))
++    *s = '\0';
++  if (s = strchr(tmp2, SIZESEP))
++    *s = '\0';
++ 
++  return !strcmp(tmp1, tmp2);
++ }
++ 
++ 
++ int comp_maildir_file(char *name1, char *name2)
++ {
++   unsigned long t1, t2;
++   int i;
++ 
++   if (!(name1 && *name1))
++      return name2 && *name2 ? (*name2 == FLAGSEP ? 0 : -1) : 0;
++                                                                                 
++   if (!(name2 && *name2))
++      return name1 && *name1 ? (*name1 == FLAGSEP ? 0 : 1) : 0;
++                                                                                 
++    if(!strcmp(name1,name2))
++       return 0;
++ 
++   t1 = strtoul(name1, NULL, 10);
++   t2 = strtoul(name2, NULL, 10);
++ 
++   if (t1 < t2)
++      return -1;
++ 
++   if (t1 > t2)
++     return 1;
++ 
++   i = strchr(name1,'.') - name1 + 1;
++   return (strcmp (name1 + i, name2 + i));
++ }
++ 
++ void
++ maildir_getflag(char *name, int *d, int *f, int *r ,int *s, int *t)
++ {
++   char tmp[MAILTMPLEN+1], *b;
++   int offset = 0;
++ 
++   if(d && f && r && s && t) 
++     *d = *f = *r = *s = *t = 0;
++   else
++     return; 		/* can not call this function with null arguments */
++ 
++   strcpy(tmp,name);
++   while (b = strchr(tmp+offset, FLAGSEP)){
++     char flag,last;
++     int  i,k;
++     if (!++b) break;
++     switch (*b){
++ 	case '1':
++ 	case '2':
++ 	case '3': flag = *b; b += 2;
++ 		  for (k = 0; b[k] && b[k] != FLAGSEP && b[k] != ','; k++);
++ 		  last = b[k];
++ 		  b[k] = '\0';
++ 		  if (flag == '2' || flag == '3'){
++ 		     *d = strchr (b, MDFLAGC(Draft))   ? T : NIL;
++ 		     *f = strchr (b, MDFLAGC(Flagged)) ? T : NIL;
++ 		     *r = strchr (b, MDFLAGC(Replied)) ? T : NIL;
++ 		     *s = strchr (b, MDFLAGC(Seen))    ? T : NIL;
++ 		     *t = strchr (b, MDFLAGC(Trashed)) ? T : NIL;
++ 		  }
++ 		  b[k] = last;
++ 		  b += k;
++ 		  for (; tmp[offset] && tmp[offset] != FLAGSEP; offset++);
++ 		  offset++;
++ 		break;
++ 	default: break;	/* Should we crash?... Nahhh */
++     }
++   }
++ }
++ 
++ int
++ maildir_message_in_list(char *msgname, struct direct **names, 
++ 		unsigned long bottom, unsigned long top, unsigned long *pos)
++ {
++   unsigned long middle = (bottom + top)/2;
++   int test;
++ 
++   if (!msgname)
++      return NIL;
++ 
++   if (pos) *pos = middle;
++ 
++   if (same_maildir_file(msgname, names[middle]->d_name))
++      return T;
++ 
++   if (middle == bottom){	 /* 0 <= 0 < 1 */
++      int rv = NIL;
++      if (same_maildir_file(msgname, names[middle]->d_name)){
++ 	rv = T;
++ 	if (pos) *pos = middle;
++      } 
++      else
++        if (same_maildir_file(msgname, names[top]->d_name)){
++ 	  rv = T;
++ 	  if (pos) *pos = top;
++        }
++      return rv;
++   }
++ 
++   test = comp_maildir_file(msgname, names[middle]->d_name);
++ 
++   if (top <= bottom)
++       return test ? NIL : T;
++ 
++   if (test < 0 ) /* bottom <  msgname < middle */
++      return maildir_message_in_list(msgname, names, bottom, middle, pos);
++   else if (test > 0)  /* middle < msgname < top */
++      return maildir_message_in_list(msgname, names, middle, top, pos);
++   else return T;
++ }
++ 
++ void
++ maildir_abort(MAILSTREAM *stream)
++ {
++   if (LOCAL){
++     if (LOCAL->dir) fs_give ((void **) &LOCAL->dir);
++     if (LOCAL->curdir) fs_give ((void **) &LOCAL->curdir);
++     if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
++     fs_give ((void **) &stream->local);
++   }
++   if (mdfpath) fs_give((void **)&mdfpath);
++   stream->dtb = NIL;
++ }
++ 
++ int
++ maildir_contains_folder(char *dirname, char *name)
++ {
++   char tmp[MAILTMPLEN+1], tmp2[MAILTMPLEN+1];
++   int rv = 0;
++   DIR *dir;
++   struct direct *d;
++   struct stat sbuf;
++   char *maildirpath = maildir_parameters(GET_INBOXPATH, NIL);
++ 
++   sprintf(tmp2,"%s/%s/%s", myhomedir(), dirname ? dirname 
++ 			: (maildirpath ? maildirpath : "Maildir"), name);
++ 
++   if (!(dir = opendir (tmp2)))
++      return NIL;
++ 
++   while (d = readdir(dir)){
++     if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")
++ 	&& strcmp(d->d_name, MDNAME(Cur)) 
++ 	&& strcmp(d->d_name, MDNAME(Tmp)) 
++ 	&& strcmp(d->d_name, MDNAME(New))){
++ 
++        sprintf(tmp,"%s/%s", tmp2, d->d_name);
++        if (stat (tmp,&sbuf) == 0 
++ 	   && ((sbuf.st_mode & S_IFMT) == S_IFDIR || 
++ 		(S_ISREG(sbuf.st_mode) && !strcmp(d->d_name, MDDIR)))){
++ 	   rv++;
++ 	   break;
++        }
++     }
++   }
++   closedir(dir);
++   return rv;
++ }
++ 
++ int
++ maildir_dir_is_empty(char *mailbox)
++ {
++   char tmp[MAILTMPLEN+1], tmp2[MAILTMPLEN+1];
++   int rv = 1;
++   DIR *dir;
++   struct direct *d;
++   struct stat sbuf;
++ 
++   maildir_file_path(mailbox, tmp2);
++ 
++   if (!(dir = opendir (tmp2)))
++      return rv;
++ 
++   while (d = readdir(dir)){
++     sprintf(tmp,"%s/%s", tmp2, d->d_name);
++     if (strcmp(d->d_name, ".") 
++ 	&& strcmp(d->d_name,"..")
++ 	&& strcmp(d->d_name, MDNAME(Cur)) 
++ 	&& strcmp(d->d_name, MDNAME(Tmp)) 
++ 	&& strcmp(d->d_name, MDNAME(New))
++ 	&& strcmp(d->d_name, MDDIR)
++ 	&& strcmp(d->d_name, MDUIDVALIDITY)
++ 	&& !(d->d_name[0] == '.' 
++ 		&& stat (tmp,&sbuf) == 0 
++ 		&& S_ISREG(sbuf.st_mode))){
++ 	   rv = 0;
++ 	   break;
++        }
++   }
++   closedir(dir);
++   return rv;
++ }
++ 
++ void
++ maildir_get_file (MAILDIRFILE **mdfile)
++ {
++   MAILDIRFILE *md;
++ 
++   md = (MAILDIRFILE *) fs_get(sizeof(MAILDIRFILE));
++   memset(md, 0, sizeof(MAILDIRFILE));
++   *mdfile = md;
++ }
++ 
++ void
++ maildir_free_file (void **mdfile)
++ {
++   MAILDIRFILE *md = (mdfile && *mdfile) ? (MAILDIRFILE *) *mdfile : NULL;
++ 
++   if (md){
++      if (md->name) fs_give((void **)&md->name);
++      fs_give((void **)&md);
++   }
++ }
++ 
++ void
++ maildir_free_file_only (void **mdfile)
++ {
++   MAILDIRFILE *md = (mdfile && *mdfile) ? (MAILDIRFILE *) *mdfile : NULL;
++ 
++   if (md && md->name) 
++      fs_give((void **)&md->name);
++ }
++ 
++ int
++ maildir_any_new_msgs(char *mailbox)
++ {
++   char tmp[MAILTMPLEN+1];
++   int rv = NIL;
++   DIR *dir;
++   struct direct *d;
++   struct stat sbuf;
++ 
++   MDFLD(tmp, mailbox, New);
++ 
++   if (!(dir = opendir (tmp)))
++      return rv;
++ 
++   while (d = readdir(dir)){
++     if (d->d_name[0] == '.')
++ 	continue;
++     rv = T;
++     break;
++   }
++   closedir(dir);
++   return rv;
++ }
++ 
++ 
++ void
++ maildir_get_date(MAILSTREAM *stream, unsigned long msgno, DirNamesType dirtype)
++ {
++   MESSAGECACHE *elt;
++   struct tm *tm;
++   unsigned long t1;
++ 
++   elt = mail_elt (stream,msgno);
++   if ((t1 = strtoul(MDFILE(elt), NULL, 10)) > 0){
++      tm = gmtime (&t1);
++      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;
++   }
++ }
+diff -rc pine4.62/imap/src/osdep/unix/maildir.h pine4.62.maildir/imap/src/osdep/unix/maildir.h
+*** pine4.62/imap/src/osdep/unix/maildir.h	Fri Jan 28 10:08:42 2005
+--- pine4.62.maildir/imap/src/osdep/unix/maildir.h	Wed Jan 19 15:00:52 2005
+***************
+*** 0 ****
+--- 1,143 ----
++ /* 
++  * A few definitions that try to make this module portable to other
++  * platforms (e.g. Cygwin). This module is based on the information from
++  * http://cr.yp.to/proto/maildir.html
++  */
++ 
++ /* First we deal with the separator character */
++ #ifndef FLAGSEP
++ #define FLAGSEP ':'
++ #endif
++ #define SIZESEP ','
++ 
++ #define MDUIDVALIDITY	".uidvalidity"	/* support for old maildirs   */
++ #define MDDIR		".mdir"		/* this folder is a directory */
++ 
++ const char sep1[] = {FLAGSEP, '1', ',', '\0'}; /* experimental semantics*/
++ const char sep2[] = {FLAGSEP, '2', ',', '\0'}; /* Flags Information	*/
++ const char sep3[] = {FLAGSEP, '3', ',', '\0'}; /* Grrrr....		*/
++ 
++ const char *sep[] = { sep1, sep2, sep3, NULL};
++ 
++ #define MDSEP(i)  sep[((i) - 1)]
++ 
++ /* Now we deal with flags. Woohoo! */
++ typedef enum  {Draft, Flagged, Passed, Replied, Seen, Trashed, 
++ 	       EmptyFlag, EndFlags} MdFlagNamesType;
++ const int mdimapflags[] = {Draft, Flagged, Replied, Seen, Trashed, EmptyFlag, EndFlags};
++ const int mdkwdflags[]  = {Passed, EmptyFlag, EndFlags};
++ 
++ /* this array lists the codes for mdflgnms (maildir flag names) above */
++ const char *mdflags[] = { "D", "F", "P", "R", "S", "T", "", NULL};
++ /* and as characters too */
++ const char cmdflags[] = { 'D', 'F', 'P', 'R', 'S', 'T', '0', '\0'};
++ 
++ /* MDFLAG(Seen, elt->seen) */
++ #define MDFLAG(i,j) mdflags[j ? (i) : EmptyFlag]
++ /* MDFLAGC(Seen) */
++ #define MDFLAGC(i) cmdflags[(i)]
++ 
++ /* Now we deal with the directory structure */
++ typedef enum {Cur, Tmp, New, EndDir} DirNamesType;
++ char *mdstruct[] = {"cur", "tmp", "new", NULL};
++ #define MDNAME(i) mdstruct[(i)]
++ #define MDFLD(tmp, dir, i) sprintf((tmp),"%s/%s", (dir), mdstruct[(i)])
++ #define MSGPATH(tmp, dir, msg,i) sprintf((tmp),"%s/%s/%s", (dir), mdstruct[(i)],(msg))
++ 
++ /* Now we deal with messages filenames */
++ char mdlocaldomain[MAILTMPLEN+1] = {'\0'};
++ static char *mdfpath = NULL;
++ static char *myMdInboxDir = NIL;/* Location of the Maildir INBOX */
++ 
++ #define CHUNK	16384	/* from unix.h */
++ /* In gdb this is the  *(struct maildir_local *)stream->local structure */
++ 	
++ typedef struct maildir_local {
++   unsigned int dirty : 1;	/* diskcopy needs updating */
++   int fd;			/* fd of open message */
++   char *dir;			/* mail directory name */
++   char *curdir;			/* mail directory name/cur */
++   unsigned 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)
++ 
++ typedef struct maildir_file_info {
++    char *name;		/* name of the file			   */
++    unsigned long pos;	/* place in list where this file is listed */
++    off_t size;		/* size in bytes, on disk */
++    time_t atime;	/* last access time */
++    time_t mtime;	/* last modified time */
++    time_t ctime;	/* last changed time */
++ } MAILDIRFILE;
++ 
++ #define MDFILE(F) (((MAILDIRFILE *)((F)->maildirp))->name)
++ #define MDPOS(F)  (((MAILDIRFILE *)((F)->maildirp))->pos)
++ #define MDSIZE(F)  (((MAILDIRFILE *)((F)->maildirp))->size)
++ #define MDATIME(F)  (((MAILDIRFILE *)((F)->maildirp))->atime)
++ #define MDMTIME(F)  (((MAILDIRFILE *)((F)->maildirp))->mtime)
++ #define MDCTIME(F)  (((MAILDIRFILE *)((F)->maildirp))->ctime)
++ 
++ /* Function prototypes */
++ 
++ DRIVER *maildir_valid (char *name);
++ MAILSTREAM *maildir_open (MAILSTREAM *stream);
++ void maildir_close (MAILSTREAM *stream, long options);
++ long maildir_ping (MAILSTREAM *stream);
++ void maildir_check (MAILSTREAM *stream);
++ long maildir_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);
++ char *maildir_header (MAILSTREAM *stream,unsigned long msgno,
++ 		unsigned long *length, long flags);
++ void maildir_list (MAILSTREAM *stream,char *ref,char *pat);
++ void *maildir_parameters (long function,void *value);
++ long maildir_create (MAILSTREAM *stream,char *mailbox);
++ void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt); /*check */
++ void maildir_expunge (MAILSTREAM *stream);
++ long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);
++ long maildir_append (MAILSTREAM *stream,char *mailbox, append_t af, void *data);
++ long maildir_delete (MAILSTREAM *stream,char *mailbox);
++ long maildir_rename (MAILSTREAM *stream,char *old,char *new);
++ long maildir_sub (MAILSTREAM *stream,char *mailbox);
++ long maildir_unsub (MAILSTREAM *stream,char *mailbox);
++ void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat);
++ 
++ /* utility functions */
++ char *maildir_file (char *dst,char *name);
++ int maildir_select (struct direct *name);
++ int maildir_namesort (const void *d1, const void *d2);
++ long maildir_canonicalize (char *pattern,char *ref,char *pat);
++ void maildir_list_work (MAILSTREAM *stream,char *subdir,char *pat,long level);
++ int maildir_file_path(char *name, char *tmp);
++ int maildir_valid_name (char *name);
++ int maildir_valid_dir (char *name);
++ int is_valid_maildir (char **name);
++ int maildir_message_exists(MAILSTREAM *stream,char *name, char *tmp);
++ void maildir_remove_root(char **name);
++ char *maildir_text_work (MAILSTREAM *stream,MESSAGECACHE *elt, unsigned long *length,long flags);
++ unsigned long  maildir_parse_message(MAILSTREAM *stream, unsigned long msgno, 
++ 						DirNamesType dirtype);
++ unsigned long maildir_scandir (char *name, struct direct ***flist, 
++ 					unsigned long *nfiles, int *scand);
++ void maildir_parse_folder (MAILSTREAM *stream, int full);
++ void  md_domain_name (void);
++ unsigned long  maildir_parse_dir(MAILSTREAM *stream, unsigned long nmsgs, 
++ 						DirNamesType dirtype, int full);
++ int same_maildir_file(char *name1, char *name2);
++ int comp_maildir_file(char *name1, char *name2);
++ int maildir_message_in_list(char *msgname, struct direct **names,
++ 		unsigned long bottom, unsigned long top, unsigned long *pos);
++ void maildir_getflag(char *name, int *d, int *f, int *r ,int *s, int *t);
++ int maildir_update_elt_maildirp(MAILSTREAM *stream, unsigned long msgno);
++ void maildir_abort (MAILSTREAM *stream);
++ int maildir_contains_folder(char *dirname, char *name);
++ int maildir_dir_is_empty(char *mailbox);
++ long maildir_create_work (char *mailbox);
++ void maildir_get_file (MAILDIRFILE **mdfile);
++ void maildir_free_file (void **mdfile);
++ void maildir_free_file_only (void **mdfile);
++ int maildir_any_new_msgs(char *mailbox);
++ void maildir_get_date(MAILSTREAM *stream, unsigned long msgno, DirNamesType dirtype);
+diff -rc pine4.62/imap/src/osdep/unix/os_cyg.h pine4.62.maildir/imap/src/osdep/unix/os_cyg.h
+*** pine4.62/imap/src/osdep/unix/os_cyg.h	Mon Apr 19 08:23:48 2004
+--- pine4.62.maildir/imap/src/osdep/unix/os_cyg.h	Wed Jan 19 15:00:52 2005
+***************
+*** 39,44 ****
+--- 39,45 ----
+  #define setpgrp setpgid
+  
+  #define SYSTEMUID 18		/* Cygwin returns this for SYSTEM */
++ #define FLAGSEP ';'
+  #define geteuid Geteuid
+  uid_t Geteuid (void);
+  
+diff -rc pine4.62/pine/init.c pine4.62.maildir/pine/init.c
+*** pine4.62/pine/init.c	Fri Dec 10 16:17:13 2004
+--- pine4.62.maildir/pine/init.c	Wed Jan 19 15:00:52 2005
+***************
+*** 416,421 ****
+--- 416,424 ----
+  
+  CONF_TXT_T cf_text_newsrc_path[] =		"Full path and name of NEWSRC file";
+  
++ CONF_TXT_T cf_text_maildir_location[] =		"Location relative to your HOME directory of the directory where your INBOX\n# for the maildir format is located. Default value is \"Maildir\". If your\n# inbox is located at \"~/Maildir\" you do not need to change this value.\n# A common value is also \".maildir\"";
++ 
++ 
+  /* these are used to report folder directory creation problems */
+  CONF_TXT_T init_md_exists[] =	"The \"%s\" subdirectory already exists, but it is not writable by Pine so Pine cannot run.  Please correct the permissions and restart Pine.";
+  
+***************
+*** 601,606 ****
+--- 604,611 ----
+  				cf_text_news_active},
+  {"news-spool-directory",		0, 1, 0, 1, 1, 0, 0, 0, 0, 1,
+  				cf_text_news_spooldir},
++ {"maildir-location",			0, 1, 0, 1, 1, 0, 0, 0, 0, 1,
++ 				cf_text_maildir_location},
+  {"upload-command",			0, 1, 0, 1, 1, 0, 0, 0, 0, 1,
+  				cf_text_upload_cmd},
+  {"upload-command-prefix",		0, 1, 0, 1, 1, 0, 0, 0, 0, 1,
+***************
+*** 2083,2088 ****
+--- 2088,2097 ----
+        mail_parameters(NULL, SET_NEWSSPOOL,
+  		      (void *)VAR_NEWS_SPOOL_DIR);
+  
++     set_current_val(&vars[V_MAILDIR_LOCATION], TRUE, TRUE);
++     if(VAR_MAILDIR_LOCATION && VAR_MAILDIR_LOCATION[0])
++       maildir_parameters(SET_INBOXPATH, (void *)VAR_MAILDIR_LOCATION);
++ 
+      /* guarantee a save default */
+      set_current_val(&vars[V_DEFAULT_SAVE_FOLDER], TRUE, TRUE);
+      if(!VAR_DEFAULT_SAVE_FOLDER || !VAR_DEFAULT_SAVE_FOLDER[0])
+diff -rc pine4.62/pine/other.c pine4.62.maildir/pine/other.c
+*** pine4.62/pine/other.c	Thu Jan 13 14:13:03 2005
+--- pine4.62.maildir/pine/other.c	Wed Jan 19 15:00:53 2005
+***************
+*** 7590,7595 ****
+--- 7590,7597 ----
+  	return(h_config_newmailwidth);
+        case V_NEWSRC_PATH :
+  	return(h_config_newsrc_path);
++       case V_MAILDIR_LOCATION :
++ 	return(h_config_maildir_location);
+        case V_BROWSER :
+  	return(h_config_browser);
+  #if defined(DOS) || defined(OS2)
+***************
+*** 12915,12920 ****
+--- 12917,12926 ----
+  			  (void *)var->current_val.p);
+      }
+  #endif
++     else if(var == &ps->vars[V_MAILDIR_LOCATION]){
++ 	if(var->current_val.p && var->current_val.p[0])
++ 	  maildir_parameters(SET_INBOXPATH, (void *)var->current_val.p);
++     }
+      else if(revert && standard_radio_var(ps, var)){
+  
+  	cur_rule_value(var, TRUE, FALSE);
+diff -rc pine4.62/pine/pine.c pine4.62.maildir/pine/pine.c
+*** pine4.62/pine/pine.c	Tue Jan 18 18:43:33 2005
+--- pine4.62.maildir/pine/pine.c	Wed Jan 19 15:00:53 2005
+***************
+*** 561,567 ****
+      rv = 0;
+      if(pine_state->VAR_TCPWRITEWARNTIMEO){
+  	if(!SVAR_TCP_WRITEWARN(pine_state, rv, tmp_20k_buf))
+! 	  if(rv == 0 || rv > 4)				/* making sure */
+  	    mail_parameters(NULL, SET_WRITETIMEOUT, (void *)(long)rv);
+      }
+  
+--- 561,567 ----
+      rv = 0;
+      if(pine_state->VAR_TCPWRITEWARNTIMEO){
+  	if(!SVAR_TCP_WRITEWARN(pine_state, rv, tmp_20k_buf))
+! 	  if(rv == 0 || rv > 4) 			/* making sure */
+  	    mail_parameters(NULL, SET_WRITETIMEOUT, (void *)(long)rv);
+      }
+  
+diff -rc pine4.62/pine/pine.h pine4.62.maildir/pine/pine.h
+*** pine4.62/pine/pine.h	Tue Jan 18 13:48:43 2005
+--- pine4.62.maildir/pine/pine.h	Wed Jan 19 15:00:53 2005
+***************
+*** 687,692 ****
+--- 687,693 ----
+  		, V_NEWSRC_PATH
+  		, V_NEWS_ACTIVE_PATH
+  		, V_NEWS_SPOOL_DIR
++ 		, V_MAILDIR_LOCATION
+  		, V_UPLOAD_CMD
+  		, V_UPLOAD_CMD_PREFIX
+  		, V_DOWNLOAD_CMD
+***************
+*** 985,990 ****
+--- 986,993 ----
+  #define GLO_NEWS_ACTIVE_PATH	     vars[V_NEWS_ACTIVE_PATH].global_val.p
+  #define VAR_NEWS_SPOOL_DIR	     vars[V_NEWS_SPOOL_DIR].current_val.p
+  #define GLO_NEWS_SPOOL_DIR	     vars[V_NEWS_SPOOL_DIR].global_val.p
++ #define VAR_MAILDIR_LOCATION	     vars[V_MAILDIR_LOCATION].current_val.p
++ #define GLO_MAILDIR_LOCATION	     vars[V_MAILDIR_LOCATION].global_val.p
+  #define VAR_DISABLE_DRIVERS	     vars[V_DISABLE_DRIVERS].current_val.l
+  #define VAR_DISABLE_AUTHS	     vars[V_DISABLE_AUTHS].current_val.l
+  #define VAR_REMOTE_ABOOK_METADATA    vars[V_REMOTE_ABOOK_METADATA].current_val.p
+diff -rc pine4.62/pine/pine.hlp pine4.62.maildir/pine/pine.hlp
+*** pine4.62/pine/pine.hlp	Tue Jan 18 18:16:49 2005
+--- pine4.62.maildir/pine/pine.hlp	Wed Jan 19 15:00:53 2005
+***************
+*** 19552,19557 ****
+--- 19552,19647 ----
+  &lt;End of help on this topic&gt;
+  </BODY>
+  </HTML>
++ ====== h_config_maildir_location ======
++ <HTML>
++ <HEAD>
++ <TITLE>OPTION: maildir-location</TITLE>
++ </HEAD>
++ <BODY>
++ <H1>OPTION: maildir-location</H1>
++ 
++ <P>
++ This option should be used only if you have a Maildir folder which you
++ want to use as your INBOX. If this is not your case (or don't know what
++ this is), you can safely ignore this option.
++ 
++ <P>
++ This option overrides the default directory Pine uses to find the location of
++ your INBOX, in case this is in Maildir format. The default value of this
++ option is "Maildir", but in some systems, this directory could have been
++ renamed (e.g. to ".maildir"). If this is your case use this option to change
++ the default.
++ 
++ <P>
++ The value of this option is prefixed with the "~/" string to determine the
++ full path to your INBOX.
++ 
++ <P>
++ You should probably <A HREF="h_config_maildir">read</A> a few tips that 
++ teach you how to configure your maildir for optimal performance.
++ 
++ <P><UL>
++ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
++ </UL>
++ <P>
++ &lt;End of help on this topic&gt;
++ </BODY>
++ </HTML>
++ ====== h_config_maildir =====
++ <HTML>
++ <HEAD>
++ <TITLE>Maildir Support</TITLE>
++ </HEAD>
++ <BODY>
++ <H1>Maildir Support</H1>
++ 
++ This version of Pine has been enhanced with Maildir support. This text is 
++ intended to be a reference on its support.
++ <P>
++ 
++ A Maildir folder is a directory that contains three directories called 
++ cur, tmp and new. A program that delivers mail (e.g. postfix) will put new 
++ mail in the new directory. A program that reads mail will look for for old 
++ messages in the cur directory, while it will look for new mail in the new 
++ directory.
++ <P>
++ 
++ In order to use maildir support it is better to set your inbox-path to the 
++ value &quot;#md/inbox&quot; (without quotes). This assumes that your mail 
++ delivery agent is delivering new mail to ~/Maildir/new. If the directory 
++ where new mail is being delivered is not called "Maildir", you can set the 
++ name of the subdirectory of home where it is being delivered in the <A 
++ HREF="h_config_maildir_location">maildir-location</A> configuration 
++ variable. Most of the time you will not have to worry about the 
++ maildir-location variable, because it will probably be set by your 
++ administrator in the pine.conf configuration file.
++ <P>
++ 
++ One of the advantages of the Maildir support of this version of Pine is 
++ that you do not have to stop using folders in another styles (mbox, mbx, 
++ etc.). This is desirable since the usage of a specific mail storage system 
++ is a personal decision. Folders in the maildir format that are part of the 
++ Mail collection will be recognized without any extra configuration of your 
++ part. If your mail/ collection is located under the mail/ directory, then 
++ creating a new maildir folder in this collection is done by pressing "A" 
++ and entering the string "#driver.md/mail/newfolder". Observe that adding a 
++ new folder as "newfolder" may not create such folder in maildir format.
++ <P>
++ 
++ If you would like to have all folders created in the maildir format by 
++ default, you do so by adding a Maildir Collection. In order to convert 
++ your current mail/ collection into a maildir collection, edit the 
++ collection and change the pah variable from &quot;mail/&quot; to 
++ &quot;#md/mail&quot;. In a maildir collection folders of any other format 
++ are ignored.
++ 
++ <P>
++ <UL>   
++ <LI><A HREF="h_finding_help">Finding more information and requesting help</A>
++ </UL><P>
++ &lt;End of help on this topic&gt;
++ </BODY>
++ </HTML>
+  ====== h_config_literal_sig =====
+  <HTML>
+  <HEAD>
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-ports-bugs->dougb 
Responsible-Changed-By: pav 
Responsible-Changed-When: Sun Jan 30 13:55:34 GMT 2005 
Responsible-Changed-Why:  
Over to pine maintainer. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=76829 
State-Changed-From-To: open->feedback 
State-Changed-By: dougb 
State-Changed-When: Sun Mar 13 11:23:04 GMT 2005 
State-Changed-Why:  

First off, it really wasn't necessary to include the whole 
big patch in your PR. The reference to it would have been 
enough for future reference. 

Second, there is no indication in your PR that you have 
actually tested this patch and can affirm that it works 
properly. I do not have access to a maildir server, so 
I have no way to test it, but I'm happy to include the 
patch if there is proof that it works. 

Thanks, 

Doug 

http://www.freebsd.org/cgi/query-pr.cgi?pr=76829 
State-Changed-From-To: feedback->closed 
State-Changed-By: dougb 
State-Changed-When: Sun Mar 13 23:10:50 GMT 2005 
State-Changed-Why:  

Thanks for your prompt response. I commiteed a work-alike 
update to the port that will allow those that need the patch 
to download it on the fly. 

Enjoy, 

Doug 

http://www.freebsd.org/cgi/query-pr.cgi?pr=76829 
>Unformatted:
