ports/76829: [ PORT UPDATE ] mail/pine4 -- add maildir patch support

Lewis Thompson lewiz at compsoc.man.ac.uk
Sat Jan 29 21:40:18 UTC 2005


>Number:         76829
>Category:       ports
>Synopsis:       [ PORT UPDATE ] mail/pine4 -- add maildir patch support
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jan 29 21:40:17 GMT 2005
>Closed-Date:
>Last-Modified:
>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 at 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 at 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 at 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 ----
+  <End of help on this topic>
+  </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>
++ <End of help on this topic>
++ </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 "#md/inbox" (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 "mail/" to 
++ "#md/mail". 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>
++ <End of help on this topic>
++ </BODY>
++ </HTML>
+  ====== h_config_literal_sig =====
+  <HTML>
+  <HEAD>
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list