summaryrefslogblamecommitdiffstats
path: root/source/n/alpine/maildir.patch
blob: f745f8cacadfde5103fea66d7fd00cb224669280 (plain) (tree)
1
2
3
4
5
6
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920


                                                                           
               

                










                                                                        


                                                                                   
               

                  











                                                                           


                                                                                           
               
                  






                                                                     
                  







                                                                     

                  








                                                                              

                  












                                                                               


                                                                                           
               

                









                                     












                                                                                                














                                                                          
                




























                                                                              
                










                                                                       
                









                                                                                 
                











                                                                  
                                                                 














                                                                            
                






































                                                                                    
                















                                                                              


                                                                                                    

               
               
    
                                   
     

                                                         

















                                                  














































































































                                                                                          


































































































































































































































































































































































































































































































































                                                                                          





                                          
                              
      

                                           


                                                               


                                                                                     



                                           



                              
                                                                                































































































                                                                                          
                                  
























                                                                               
                                                                 













                                                                                     



                                                                 
































































































































































                                                                                   
  




















                                                                





                                                      



                                                                              





















































































                                                                                



                                                               
  
                                                                             
  
                                
  
                                   
  


                                                                                
  

                                                    



                                                                 








                                                                       
                                     
               
                                  
                             






                                                               
                                    
                      







                                                                           





                                                                                       




























































































                                                                                 
                                                                 
                          
                                                                 















                                          
                
                               
                                
                                                                           

                                                                                                                             


































































                                                                                    


                                                                                          
                                               



                                                                         















































                                                                                   





                                                                               




                                                                          



                                                                                    



















































































                                                                                       









                                                                      
















































































                                                                                             





                                                                                                     

























































                                                                                        
                                                         































                                                                                                

                                                                                                                              




                                                                 





                                                                                 



                                                             




                                                                 









                                                                            




                                                                




                                            
                                 
                                                               



                                                         
                                   




                                                                         






                                    




                                                                        









                                                                              




                                                                        










                                                                               




                                                                       






                                                                               




                                                                        










                                                                  
               



                                                         




                                                                       




                             


                                                                                            




                                                     


                                                                                             




                                                                             


                                                                                              





                                                                         






                                                                               








                                              




                                                                                      


                                                                         






                                                                                 





















































                                                                                  
            






















                                                                                        
                                





                                                           
                                                                                                             
                                      
                                      





                                                                          
                                                                                                                   
                                           
                                           







































































































































































































                                                                                                
                                                 








                                                                         
                                                                                                 


















                                                                           
                      

                                                         
       

                                                              











































































                                                                            
                    











                                                   

                             





                                                          

                                                                                                    






























                                                                       
                                                   







                                                   
                                           





                                

                             

                                         

                                                                                                     








                                             

                                                                                                    






                                           





                                                    






































































































































































































































                                                                                      
                                                                           




























































                                                                                        
                                         




































































































                                                                             
                                      





























                                                                                 
                                                    


























































                                                                                      


                                                                                                    

               
              

                                                                 
  
                                                    












                                                                             









                                                                             






























































































                                                                                                   


                                                                                                  





















                                                                                            
                                                                         


           
                


                                                                                  


                                                                     











                                                                 
                







                                                                 

                

                                                    
                                                                                                        



                                                    


                                                                                                  









                                                                    


                                                                           
               

                









                                                                                                                                                                                                                                                                                                                     

                










                                                                          

                  












                                                                             

                  










                                                                            
                  






                                                 
                  







                                                  

                  













                                                              

                  









                                          


                                                                           
               

                









                                                                                  


                                                                           












                                     

                








                                


                                                                           
               














                                                                           








                                                                 


                                                                           
               
              






                               
              












































































                                                                                 


                                                                           
               

                    






































































































                                                                                             

                    
















































                                                                                                              


                                                                           
               

              









                                                                 

                












                                                                     


                                                                           























































































































































                                                                               
diff -rc alpine-2.26/alpine/alpine.c alpine-2.26.maildir/alpine/alpine.c
*** alpine-2.26/alpine/alpine.c	2022-06-02 18:14:00.463274817 -0600
--- alpine-2.26.maildir/alpine/alpine.c	2022-06-02 18:14:52.219147911 -0600
***************
*** 593,598 ****
--- 593,603 ----
      if(F_ON(F_MAILDROPS_PRESERVE_STATE, ps_global))
        mail_parameters(NULL, SET_SNARFPRESERVE, (void *) TRUE);
  
+ #ifndef _WINDOWS
+     rv = F_ON(F_COURIER_FOLDER_LIST, ps_global) ? 1 : 0;
+     mail_parameters(NULL,SET_COURIERSTYLE, (void *) &rv);
+ #endif
+ 
      rvl = 0L;
      if(pine_state->VAR_NNTPRANGE){
  	if(!SVAR_NNTPRANGE(pine_state, rvl, tmp_20k_buf, SIZEOF_20KBUF))
diff -rc alpine-2.26/alpine/confscroll.c alpine-2.26.maildir/alpine/confscroll.c
*** alpine-2.26/alpine/confscroll.c	2022-06-02 18:14:00.463274817 -0600
--- alpine-2.26.maildir/alpine/confscroll.c	2022-06-02 18:14:52.223147900 -0600
***************
*** 5565,5570 ****
--- 5565,5576 ----
  			  (void *)var->current_val.p);
      }
  #endif
+ #ifndef _WINDOWS
+     else if(var == &ps->vars[V_MAILDIR_LOCATION]){
+       if(var->current_val.p && var->current_val.p[0])
+ 	mail_parameters(NULL, SET_MDINBOXPATH, (void *)var->current_val.p);
+     }
+ #endif
      else if(revert && standard_radio_var(ps, var)){
  
  	cur_rule_value(var, TRUE, FALSE);
diff -rc alpine-2.26/imap/src/c-client/mail.c alpine-2.26.maildir/imap/src/c-client/mail.c
*** alpine-2.26/imap/src/c-client/mail.c	2022-06-02 18:14:00.471274797 -0600
--- alpine-2.26.maildir/imap/src/c-client/mail.c	2022-06-02 18:14:52.223147900 -0600
***************
*** 1071,1077 ****
    MAILSTREAM *ts;
    char *s,*t,tmp[MAILTMPLEN];
    size_t i;
!   DRIVER *d;
  				/* never allow names with newlines */
    if ((s = strpbrk (mailbox,"\015\012")) != NULL) {
      MM_LOG ("Can't create mailbox with such a name",ERROR);
--- 1071,1077 ----
    MAILSTREAM *ts;
    char *s,*t,tmp[MAILTMPLEN];
    size_t i;
!   DRIVER *d, *md;
  				/* never allow names with newlines */
    if ((s = strpbrk (mailbox,"\015\012")) != NULL) {
      MM_LOG ("Can't create mailbox with such a name",ERROR);
***************
*** 1095,1100 ****
--- 1095,1102 ----
      return NIL;
    }
  
+   /* Hack, we should do this better, but it works */
+     for (md = maildrivers; md && strcmp (md->name, "md"); md = md->next);
  				/* see if special driver hack */
    if ((mailbox[0] == '#') && ((mailbox[1] == 'd') || (mailbox[1] == 'D')) &&
        ((mailbox[2] == 'r') || (mailbox[2] == 'R')) &&
***************
*** 1125,1130 ****
--- 1127,1139 ----
  	   (((*mailbox == '{') || (*mailbox == '#')) &&
  	    (stream = mail_open (NIL,mailbox,OP_PROTOTYPE | OP_SILENT))))
      d = stream->dtb;
+   else if(mailbox[0] == '#'
+ 	&& (mailbox[1] == 'm' || mailbox[1] == 'M')
+ 	&& (mailbox[2] == 'd' || mailbox[2] == 'D'
+ 	    || mailbox[2] == 'c' || mailbox[2] == 'C')
+ 	&& mailbox[3] == '/'
+ 	&& mailbox[4] != '\0')
+      return (*md->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 alpine-2.26/imap/src/c-client/mail.h alpine-2.26.maildir/imap/src/c-client/mail.h
*** alpine-2.26/imap/src/c-client/mail.h	2022-06-02 18:14:00.471274797 -0600
--- alpine-2.26.maildir/imap/src/c-client/mail.h	2022-06-02 18:14:52.239147861 -0600
***************
*** 389,394 ****
--- 389,398 ----
  #define SET_SCANCONTENTS (long) 573
  #define GET_MHALLOWINBOX (long) 574
  #define SET_MHALLOWINBOX (long) 575
+ #define GET_COURIERSTYLE (long) 576
+ #define SET_COURIERSTYLE (long) 577
+ #define SET_MDINBOXPATH  (long) 578
+ #define GET_MDINBOXPATH  (long) 579
  
  /* Driver flags */
  
diff -rc alpine-2.26/imap/src/osdep/unix/dummy.c alpine-2.26.maildir/imap/src/osdep/unix/dummy.c
*** alpine-2.26/imap/src/osdep/unix/dummy.c	2022-06-02 18:14:00.475274788 -0600
--- alpine-2.26.maildir/imap/src/osdep/unix/dummy.c	2022-06-02 18:14:52.243147852 -0600
***************
*** 33,38 ****
--- 33,39 ----
  #include <pwd.h>
  #include <sys/stat.h>
  #include "dummy.h"
+ #include "maildir.h"
  #include "misc.h"
  
  /* Function prototypes */
***************
*** 104,116 ****
   * Accepts: mailbox name
   * Returns: our driver if name is valid, NIL otherwise
   */
! 
  DRIVER *dummy_valid (char *name)
  {
!   char *s,tmp[MAILTMPLEN];
    struct stat sbuf;
  				/* must be valid local mailbox */
!   if (name && *name && (*name != '{') && (s = mailboxfile (tmp,name))) {
  				/* indeterminate clearbox INBOX */
      if (!*s) return &dummydriver;
      else if (!stat (s,&sbuf)) switch (sbuf.st_mode & S_IFMT) {
--- 105,123 ----
   * Accepts: mailbox name
   * Returns: our driver if name is valid, NIL otherwise
   */
! char * maildir_remove_root(char *);
  DRIVER *dummy_valid (char *name)
  {
!   char *s,tmp[MAILTMPLEN], *rname;
    struct stat sbuf;
+ 
+   if(strlen(name) > MAILTMPLEN)
+    name[MAILTMPLEN] = '\0';
+ 
+   strcpy(tmp, name);
+   rname = maildir_remove_root(tmp);
  				/* must be valid local mailbox */
!   if (rname && *rname && (*rname != '{') && (s = mailboxfile (tmp,rname))) {
  				/* indeterminate clearbox INBOX */
      if (!*s) return &dummydriver;
      else if (!stat (s,&sbuf)) switch (sbuf.st_mode & S_IFMT) {
***************
*** 119,126 ****
        return &dummydriver;
      }
  				/* blackbox INBOX does not exist yet */
!     else if (!compare_cstring (name,"INBOX")) return &dummydriver;
    }
    return NIL;
  }
  
--- 126,134 ----
        return &dummydriver;
      }
  				/* blackbox INBOX does not exist yet */
!     else if (!compare_cstring (rname,"INBOX")) return &dummydriver;
    }
+   if(rname) fs_give((void **)&rname);
    return NIL;
  }
  
***************
*** 453,458 ****
--- 461,468 ----
  {
    char *s,tmp[MAILTMPLEN];
    long ret = NIL;
+   if(!strncmp(mailbox,"#md/",4) || !strncmp(mailbox,"#mc/", 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);
***************
*** 518,523 ****
--- 528,541 ----
  {
    struct stat sbuf;
    char *s,tmp[MAILTMPLEN];
+   if (!strncmp(mailbox,"#md/",4) || !strncmp(mailbox,"#mc/", 4) 
+ 	|| is_valid_maildir(&mailbox)){
+     char tmp[MAILTMPLEN] = {'\0'};
+     strcpy(tmp, mailbox);
+     if(tmp[strlen(tmp) - 1] != '/')
+        tmp[strlen(tmp)] = '/';
+      return maildir_delete(stream, tmp);
+   }
    if (!(s = dummy_file (tmp,mailbox))) {
      sprintf (tmp,"Can't delete - invalid name: %.80s",mailbox);
      MM_LOG (tmp,ERROR);
***************
*** 543,554 ****
  long dummy_rename (MAILSTREAM *stream,char *old,char *newname)
  {
    struct stat sbuf;
!   char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN];
  				/* no trailing / allowed */
!   if (!dummy_file (oldname,old) || !(s = dummy_file (mbx,newname)) ||
        stat (oldname,&sbuf) || ((s = strrchr (s,'/')) && !s[1] &&
  			       ((sbuf.st_mode & S_IFMT) != S_IFDIR))) {
!     sprintf (mbx,"Can't rename %.80s to %.80s: invalid name",old,newname);
      MM_LOG (mbx,ERROR);
      return NIL;
    }
--- 561,583 ----
  long dummy_rename (MAILSTREAM *stream,char *old,char *newname)
  {
    struct stat sbuf;
!   char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN], *rold, *rnewname;
! 
!   if(strlen(old) > MAILTMPLEN)
!     old[MAILTMPLEN] = '\0';
! 
!   if(strlen(newname) > MAILTMPLEN)
!     newname[MAILTMPLEN] = '\0';
! 
!   strcpy(tmp, old);
!   rold = maildir_remove_root(tmp);
!   strcpy(tmp, newname);
!   rnewname = maildir_remove_root(tmp);
  				/* no trailing / allowed */
!   if (!dummy_file (oldname,rold) || !(s = dummy_file (mbx,rnewname)) ||
        stat (oldname,&sbuf) || ((s = strrchr (s,'/')) && !s[1] &&
  			       ((sbuf.st_mode & S_IFMT) != S_IFDIR))) {
!     sprintf (mbx,"Can't rename %.80s to %.80s: invalid name",rold,rnewname);
      MM_LOG (mbx,ERROR);
      return NIL;
    }
***************
*** 564,577 ****
      }
    }
  				/* rename of non-ex INBOX creates dest */
!   if (!compare_cstring (old,"INBOX") && stat (oldname,&sbuf))
      return dummy_create (NIL,mbx);
    if (rename (oldname,mbx)) {
!     sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",old,newname,
  	     strerror (errno));
      MM_LOG (tmp,ERROR);
      return NIL;
    }
    return T;			/* return success */
  }
  
--- 593,608 ----
      }
    }
  				/* rename of non-ex INBOX creates dest */
!   if (!compare_cstring (rold,"INBOX") && stat (oldname,&sbuf))
      return dummy_create (NIL,mbx);
    if (rename (oldname,mbx)) {
!     sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",rold,rnewname,
  	     strerror (errno));
      MM_LOG (tmp,ERROR);
      return NIL;
    }
+   if(rold) fs_give((void **)&rold);
+   if(rnewname) fs_give((void **)&rnewname);
    return T;			/* return success */
  }
  
diff -rc alpine-2.26/imap/src/osdep/unix/maildir.c alpine-2.26.maildir/imap/src/osdep/unix/maildir.c
*** alpine-2.26/imap/src/osdep/unix/maildir.c	2022-06-02 18:14:52.323147655 -0600
--- alpine-2.26.maildir/imap/src/osdep/unix/maildir.c	2022-06-02 18:14:52.251147832 -0600
***************
*** 0 ****
--- 1,2865 ----
+ /*
+  * Maildir driver for Alpine 2.25
+  * 
+  * Written by Eduardo Chappa <alpine.chappa@yandex.com>
+  * Last Update: October 16, 2021.
+  *
+  */
+ 
+ #include <stdio.h>
+ #include <ctype.h>
+ #include <errno.h>
+ extern int errno;		/* just in case */
+ #include "mail.h"
+ #include <pwd.h>
+ #include <sys/stat.h>
+ #include <sys/time.h>
+ #include "osdep.h"
+ #include "rfc822.h"
+ #include "fdstring.h"
+ #include "misc.h"
+ #include "dummy.h"
+ #include "maildir.h"
+ 
+ /* 
+  * 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 ','
+ 
+ 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! */
+ 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 */
+ char *mdstruct[] = {"cur", "tmp", "new", NULL};
+ #define MDNAME(i) mdstruct[(i)]
+ #define MDFLD(X, Y, i) do { snprintf((X), sizeof((X)), "%.*s/%.*s",	\
+ 				    (int) (sizeof((X)) - 6), (Y),	\
+ 				    3, mdstruct[(i)]);			\
+ 				(X)[sizeof((X)) - 1] = '\0';		\
+ 		       } while(0)
+ 				
+ #define MSGPATH(X, Y, Z,i) do { snprintf((X), sizeof((X)), "%.*s/%.*s/%.*s",		\
+ 				     (int) strlen((Y)), (Y),				\
+ 					3, mdstruct[(i)],				\
+ 				      (int)(sizeof((X)) - strlen((Y)) - 3 - 3), (Z));	\
+ 				(X)[sizeof((X)) - 1] = '\0';				\
+ 			   } while(0)
+ 
+ /* Files associated to a maildir directory */
+ 
+ #define MDUIDVALIDITY	".uidvalidity"	/* support for old maildirs    */
+ #define MDDIR		".mdir"		/* this folder is a directory  */
+ #define MDUIDLAST	".uidlast"	/* last assigned uid	       */
+ #define MDUIDTEMP	".uidtemp"	/* We assign uid's no one else */
+ 
+ /* Support of Courier Structure */
+ #define CCLIENT 0
+ #define COURIER 1
+ #define IS_CCLIENT(t) \
+ 		(((t) && (t)[0] == '#' && ((t)[1] == 'm' || (t)[1] == 'M')\
+ 		&& ((t)[2] == 'd' || (t)[2] == 'D')\
+ 		&& (t)[3] == '/'  && (t)[4] != '\0') ? 1 : 0)
+ 
+ #define IS_COURIER(t) \
+ 		(((t) && (t)[0] == '#' && ((t)[1] == 'm' || (t)[1] == 'M')\
+ 		&& ((t)[2] == 'c' || (t)[2] == 'C')\
+ 		&& (t)[3] == '/'  && (t)[4] != '\0') ? 1 : 0)
+ #define MDPREFIX(s) ((s) ? "#mc/" : "#md/")
+ #define MDSEPARATOR(s) ((s) ? '.' : '/')
+ 
+ /* UID Support */
+ 
+ #define MAXTEMPUID (unsigned long) 180L
+ const char mduid[] = {',','u','=','\0'};
+ #define MDUIDSEP mduid
+ 
+ /* Now we deal with messages filenames */
+ char mdlocaldomain[MAILTMPLEN+1] = {'\0'};
+ pid_t mypid = (pid_t) 0;
+ static char *mdfpath = NULL;
+ static char myMdInboxDir[50] = { '\0' };/* Location of the Maildir INBOX */
+ static long CourierStyle = CCLIENT;
+ 
+ #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 		*/
+   unsigned int courier : 1;	/* It is Courier style file system	*/
+   unsigned int link : 1;	/* There is a symbolic link		*/
+   int candouid;			/* we can assign uids and no one else	*/
+   char *uidtempfile;		/* path to uid temp file		*/
+   int fd;			/* fd of open message			*/
+   char *dir;			/* mail directory name			*/
+   char **path;			/* path to directories cur, new and tmp	*/
+   unsigned char *buf;		/* temporary buffer 			*/
+   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)
+ 
+ #define MDFILE(F) (((MAILDIRFILE *)((F)->private.spare.ptr))->name)
+ #define MDLOC(F)  (((MAILDIRFILE *)((F)->private.spare.ptr))->loc)
+ #define MDPOS(F)  (((MAILDIRFILE *)((F)->private.spare.ptr))->pos)
+ #define MDSIZE(F)  (((MAILDIRFILE *)((F)->private.spare.ptr))->size)
+ #define MDATIME(F)  (((MAILDIRFILE *)((F)->private.spare.ptr))->atime)
+ #define MDMTIME(F)  (((MAILDIRFILE *)((F)->private.spare.ptr))->mtime)
+ #define MDCTIME(F)  (((MAILDIRFILE *)((F)->private.spare.ptr))->ctime)
+ 
+ /* Driver dispatch used by MAIL */
+ DRIVER maildirdriver = {
+   "md",				/* driver name, yes it's md, not maildir */
+   DR_MAIL|DR_LOCAL|DR_NAMESPACE|DR_DIRFMT,		/* driver flags */
+   (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 			*/
+   maildir_fast,			/* 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 		*/
+ };
+ 
+ 
+ DRIVER courierdriver = {
+   "mc",	/* Why a separate driver? So that createproto will work		*/
+   DR_MAIL|DR_LOCAL|DR_NAMESPACE|DR_DIRFMT,		/* driver flags */
+   (DRIVER *) NIL,		/* next driver 				*/
+   maildir_valid,		/* mailbox is valid for us 		*/
+   maildir_parameters,		/* manipulate parameters		*/
+   NIL,				/* scan mailboxes 			*/
+   courier_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 			*/
+   maildir_fast,			/* 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 */
+ MAILSTREAM courierproto = {&courierdriver};	/* prototype stream */
+ 
+ long maildir_dirfmttest (char *name)
+ {
+   int i;
+   for (i = 0; mdstruct[i] && strcmp(name, mdstruct[i]); i++);
+   return (i < EndDir) || !strcmp(name, MDDIR) 
+ 	|| !strncmp(name, MDUIDLAST, strlen(MDUIDLAST))
+ 	|| !strncmp(name, MDUIDTEMP, strlen(MDUIDTEMP)) ? LONGT : NIL;
+ }
+ 
+ void 
+ md_domain_name(void)
+ {
+    int i, j;
+ 
+    strcpy(mdlocaldomain, mylocalhost ());
+    for (i = 0; mdlocaldomain[i] != '\0' ;)
+       if(mdlocaldomain[i] == '/' || mdlocaldomain[i] == ':'){
+ 	 for(j = strlen(mdlocaldomain); j >= i; j--)
+ 	    mdlocaldomain[j+4] = mdlocaldomain[j];
+ 	 mdlocaldomain[i++] = '\\';
+ 	 mdlocaldomain[i++] = '0';
+ 	 if(mdlocaldomain[i] == '/'){
+ 	    mdlocaldomain[i++] = '5';
+ 	    mdlocaldomain[i++] = '7';
+ 	 } else {
+ 	    mdlocaldomain[i++] = '7';
+ 	    mdlocaldomain[i++] = '2';
+ 	 }
+       }
+       else
+ 	i++;
+ }
+ 
+ char *
+ myrootdir(char *name)
+ {
+ return myhomedir();
+ }
+ 
+ char *
+ mdirpath(void)
+ {
+   char *path = maildir_parameters(GET_MDINBOXPATH, NIL);
+   return path ? (path[0] ? path : ".") : "Maildir";
+ }
+ 
+ /* remove the "#md/" or "#mc/" part from a folder name
+  * memory freed by caller
+  */
+ char *
+ maildir_remove_root (char *name)
+ {
+   int courier = IS_COURIER(name), offset;
+   char realname[MAILTMPLEN];
+ 
+   offset = maildir_valid_name(name) ? (name[3] == '/' ? 4 : 3) : 0;
+   if(courier)
+      courier_realname(name+offset, realname);
+   else
+      strcpy(realname, name+offset);
+   return cpystr(realname);
+ }
+ 
+ 
+ /* 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)
+ {
+   char tmpname[MAILTMPLEN] = {'\0'};
+ 
+    if (mdfpath)
+       fs_give((void **)&mdfpath);
+    if (name && (name[0] != '#'))
+ 	snprintf(tmpname, sizeof(tmpname), "%s%s",MDPREFIX(CCLIENT), name);
+    mdfpath = cpystr(tmpname[0] ? tmpname : name);
+ 
+   return IS_CCLIENT(name) || IS_COURIER(name);
+ }
+ 
+ /* 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];
+ 
+    if(name[strlen(name) - 1] == '/')
+       name[strlen(name) - 1] = '\0';
+    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;
+ }
+ 
+ void courier_realname(char *name, char *realname)
+ {
+   int i,j;
+ 
+   if(!name)
+     return;
+ 
+   for (i = 0, j = 0; i < MAILTMPLEN && j < strlen(name); j++, i++){
+       realname[i] = name[j];
+       if(name[j] == '/' && name[j+1] != '.' && name[j+1] != '%' 
+ 		&& name[j+1] != '*') 
+ 	realname[++i] = '.';
+   }
+   if(realname[i-1] == '.')
+     i--; 
+   realname[i] = '\0';
+ }
+ 
+ 
+ /* 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, size_t sizeoftmp)
+ {
+    char *maildirpath = mdirpath(), *rname;
+    int courier = IS_COURIER(name);
+ 
+    /* There are several ways in which the path can come, so we will handle 
+       them here. First we deal with #mc/ or #md/ prefix by removing the 
+       prefix, if any */
+ 
+     if(strlen(name) >= MAILTMPLEN)
+       name[MAILTMPLEN] = '\0';
+     strcpy(tmp, name);
+     rname = maildir_remove_root(tmp);
+     tmp[0] = '\0';	/* just in case something fails */
+ 
+     if (strlen(myrootdir(rname)) + 
+ 		max(strlen(rname), strlen(maildirpath)) > sizeoftmp){
+ 	errno = ENAMETOOLONG;
+ 	snprintf(tmp, sizeoftmp, "Error opening \"%s\": %s", rname, strerror (errno));
+ 	mm_log(tmp,ERROR);
+ 	if(rname) fs_give((void **)&rname);
+ 	return NIL;
+     }
+ 
+     /* There are two ways in which the name can come here, either as a 
+        full path or not. If it is not a full path it can come in two ways, 
+        either as a file system path (Maildir/.Drafts) or as a maildir path 
+        (INBOX.Drafts)
+      */
+ 
+      if(*rname == '/'){	/* full path */
+ 	strncpy(tmp, rname, sizeoftmp); /* do nothing */
+ 	tmp[sizeoftmp-1] = '\0';
+      }
+      else
+ 	snprintf (tmp, sizeoftmp, "%s/%s%s%s", myrootdir (rname),
+ 	    strncmp (ucase (strcpy (tmp, rname)), "INBOX", 5) 
+ 		? rname : maildirpath,
+ 	    strncmp (ucase (strcpy (tmp, rname)), "INBOX", 5) 
+ 		? "" : (courier ? "/" : ""),
+ 	    strncmp (ucase (strcpy (tmp, rname)), "INBOX", 5) 
+ 		? "" : (*(rname+5) == MDSEPARATOR(courier) ? rname+5 : ""));
+     if(rname) fs_give((void **)&rname);
+     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, myrootdir (*name), strlen(myrootdir(*name)))){
+      (*name) += strlen(myrootdir(*name));
+      if (**name == '/') (*name)++;
+   }
+   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];
+ 
+    maildir_file_path(name, tmpname, sizeof(tmpname));
+    
+    return maildir_valid_dir(tmpname) 
+ 		? (IS_COURIER(name) ? &courierdriver : &maildirdriver) : NIL;
+ }
+ 
+ void maildir_fast (MAILSTREAM *stream,char *sequence,long flags)
+ {
+   unsigned long i;
+   MESSAGECACHE *elt;
+                                 /* get sequence */
+   if (stream && LOCAL && ((flags & FT_UID) ?
+                           mail_uid_sequence (stream,sequence) :
+                           mail_sequence (stream,sequence)))
+     for (i = 1L; i <= stream->nmsgs; i++) {
+       if ((elt = mail_elt (stream,i))->sequence && (elt->valid = T) &&
+           !(elt->day && elt->rfc822_size)) {
+         ENVELOPE **env = NIL;
+         ENVELOPE *e = NIL;
+         if (!stream->scache) env = &elt->private.msg.env;
+         else if (stream->msgno == i) env = &stream->env;
+         else env = &e;
+         if (!*env || !elt->rfc822_size) {
+           STRING bs;
+           unsigned long hs;
+           char *ht = (*stream->dtb->header) (stream,i,&hs,NIL);
+ 
+           if (!*env) rfc822_parse_msg (env,NIL,ht,hs,NIL,BADHOST,
+                                        stream->dtb->flags);
+           if (!elt->rfc822_size) {
+             (*stream->dtb->text) (stream,i,&bs,FT_PEEK);
+             elt->rfc822_size = hs + SIZE (&bs) - GETPOS (&bs);
+           }
+         }
+ 
+         if (!elt->day && *env && (*env)->date)
+           mail_parse_date (elt,(*env)->date);
+ 
+         if (!elt->day) elt->day = elt->month = 1;
+         mail_free_envelope (&e);
+       }
+     }
+ }
+ 
+ int
+ maildir_eliminate_duplicate (char *name, struct direct ***flist, unsigned long *nfiles)
+ {
+    int i, j, k, error = 0, scanr;
+    char new[MAILTMPLEN], old[MAILTMPLEN], tmp[MAILTMPLEN], *str;
+    struct direct **names = NIL;
+ 
+    if((scanr = maildir_doscandir(name, &names, CCLIENT)) < 0)
+      return -1;
+ 
+    if(nfiles) *nfiles = scanr;
+    for(i = 0, j = 1, k = 0;  j < scanr; i++, j++){
+       if(k)
+ 	names[i] = names[i+k];
+       if(same_maildir_file(names[i]->d_name, names[j]->d_name)){
+ 	int d, f, r, s;
+ 	maildir_getflag(names[i]->d_name, &d, &f, &r, &s, NIL);
+ 	snprintf(old, sizeof(old), "%s/%s", name, names[i]->d_name);
+ 	snprintf(new, sizeof(new), "%s/.%s", name, names[i]->d_name);
+ 	if(rename(old, new) < 0 && errno != EEXIST)
+ 	  error++;
+ 	if(!error){
+ 	  for(; j < scanr
+ 		&& same_maildir_file(names[i]->d_name, names[j]->d_name)
+ 	      ; j++, k++){
+ 	      maildir_getflag(names[j]->d_name, (d ? NIL : &d), 
+ 			(f ? NIL : &f), (r ? NIL : &r), (s ? NIL : &s), NIL);
+ 	      snprintf(tmp, sizeof(tmp), "%s/%s", name, names[j]->d_name);
+ 	      if(unlink(tmp) < 0){	/* Hmmm... a problem, let's see */
+ 		struct stat sbuf;
+ 		if (stat(tmp, &sbuf) == 0 && (sbuf.st_mode & S_IFMT) == S_IFREG)
+ 		   error++;
+ 	      }
+ 	  }
+ 	  if((str = strrchr(names[i]->d_name,FLAGSEP)) != NULL) *str = '\0';
+ 	  snprintf (old, sizeof(old), "%s/%s%s%s%s%s%s", name, names[i]->d_name, MDSEP(2),
+ 		MDFLAG(Draft, d), MDFLAG(Flagged, f), MDFLAG(Replied, r), 
+ 		MDFLAG(Seen, s));
+ 	  if(rename(new, old) < 0)
+ 	     error++;
+ 	}
+       }
+ 
+    }
+    if(k > 0)
+      fs_give((void **)&names);
+    else
+      *flist = names;
+    return error ? -1 : k;
+ }
+ 
+ int
+ maildir_doscandir(char *name, struct direct ***flist, int flag)
+ {
+ return scandir(name, flist, 
+ 		flag == CCLIENT ? maildir_select : courier_dir_select, 
+ 		flag == CCLIENT ? maildir_namesort : courier_dir_sort);
+ }
+ 
+ /* 
+  * 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, int flag)
+ {
+   struct stat sbuf;
+   int rv = -2;	/* impossible value */
+ 
+   if (scand)
+      *scand = -1;	/* assume error for safety */
+   *nfiles = 0;
+   if((stat(name,&sbuf) < 0) 
+ 	|| (flag == CCLIENT
+ 	 && ((rv = maildir_eliminate_duplicate(name, flist, nfiles)) < 0)))
+      return 0L;
+ 
+   if (scand && (rv > 0 || rv == -2))
+      *nfiles = maildir_doscandir(name, flist, flag);
+ 
+   if(scand) *scand = *nfiles;
+ 
+   return (unsigned long) 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];
+   int gotit = NIL;
+   DIR *dir;
+   struct direct *d;
+   struct stat sbuf;
+ 
+   /* First check directly if it exists, if not there, look for it */
+   snprintf(tmp, sizeof(tmp), "%s/%s", LOCAL->path[Cur], name);
+   if ((stat(tmp, &sbuf) == 0) && ((sbuf.st_mode & S_IFMT) == S_IFREG))
+     return T;
+ 
+   if (!(dir = opendir (LOCAL->path[Cur])))
+      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];
+   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 */
+   if(mypid == (pid_t) 0)
+     mypid = getpid();
+   if (!stream->rdonly){
+      stream->perm_seen = stream->perm_deleted = stream->perm_flagged = 
+ 	stream->perm_answered = stream->perm_draft = T;
+   }
+   stream->local = (MAILDIRLOCAL *) fs_get (sizeof (MAILDIRLOCAL));
+   memset(LOCAL, 0, sizeof(MAILDIRLOCAL));
+   LOCAL->fd = -1;
+ 
+   LOCAL->courier = IS_COURIER(stream->mailbox);
+   strcpy(tmp, stream->mailbox);
+   if (maildir_file_path (stream->mailbox, tmp, sizeof(tmp)))
+      LOCAL->dir = cpystr (tmp);
+   LOCAL->candouid = maildir_can_assign_uid(stream);
+   maildir_read_uid(stream, &stream->uid_last, &stream->uid_validity);
+   if (LOCAL->dir){
+      LOCAL->path = (char **) fs_get(EndDir*sizeof(char *));
+      MDFLD(tmp, LOCAL->dir, Cur); LOCAL->path[Cur] = cpystr (tmp);
+      MDFLD(tmp, LOCAL->dir, New); LOCAL->path[New] = cpystr (tmp);
+      MDFLD(tmp, LOCAL->dir, Tmp); LOCAL->path[Tmp] = cpystr (tmp);
+      if (stat (LOCAL->path[Cur],&sbuf) < 0) {
+          snprintf (tmp, sizeof(tmp), "Can't open folder %s: %s",
+ 				stream->mailbox,strerror (errno));
+          mm_log (tmp,ERROR);
+ 	 maildir_close(stream, 0);
+         return NIL;
+      }
+   }
+ 
+   if(maildir_file_path (stream->mailbox, tmp, sizeof(tmp))){
+     fs_give ((void **) &stream->mailbox);
+     stream->mailbox = cpystr(tmp);
+   }
+ 
+   LOCAL->buf = (char *) fs_get (CHUNKSIZE);
+   LOCAL->buflen = CHUNKSIZE - 1;
+   stream->sequence++;
+   stream->nmsgs = stream->recent = 0L;
+ 
+   maildir_parse_folder(stream, 1);
+ 
+   return stream;
+ }
+ 
+ /* Maildir initial parsing of the folder */
+ void
+ maildir_parse_folder (MAILSTREAM *stream, int full)
+ {
+    char tmp[MAILTMPLEN];
+    struct direct **namescur = NIL, **namesnew = NIL;
+    unsigned long i, nfilescur = 0L, nfilesnew = 0L, oldpos, newpos, total;
+    int scan_err, rescan, loop = 0;
+ 
+    if (!stream)		/* what??? */
+       return;
+ 
+    MM_CRITICAL(stream);
+ 
+    maildir_scandir (LOCAL->path[New], &namesnew, &nfilesnew, &scan_err, CCLIENT);
+    if (scan_err < 0){
+       if(namesnew){
+ 	for(i = 0L; i < nfilesnew; i++)
+ 	   fs_give((void **)&namesnew[i]);
+ 	fs_give((void **) &namesnew);
+       }
+       maildir_abort(stream);
+    }
+ 
+    /* Scan old messages first, escoba! */
+    if(stream->rdonly
+ 	|| (LOCAL && ((maildir_initial_check(stream, Cur) == 0)
+ 	    || nfilesnew > 0L))){
+       LOCAL->scantime =  maildir_scandir (LOCAL->path[Cur], &namescur, &nfilescur, 
+ 					&scan_err, CCLIENT);
+       if (scan_err < 0){
+ 	if(namescur){
+ 	  for(i = 0L; i < nfilescur; i++)
+ 	    fs_give((void **)&namescur[i]);
+ 	  fs_give((void **) &namescur);
+ 	}
+ 	maildir_abort(stream);
+       }
+    }
+    if(LOCAL && (maildir_initial_check(stream, New) == 0) && (nfilescur > 0L)){
+       while(LOCAL && loop < 10){
+ 	 if(nfilesnew == 0L)
+ 	   maildir_scandir (LOCAL->path[New], &namesnew, &nfilesnew, &scan_err, CCLIENT);
+          if (scan_err < 0){
+ 	    if(namesnew){
+ 	      for(i = 0L; i < nfilesnew; i++)
+ 		fs_give((void **)&namesnew[i]);
+ 	      fs_give((void **) &namesnew);
+ 	    }
+ 	    maildir_abort(stream);
+ 	    break;
+ 	 }
+ 	 for(i = 0L, rescan = 0, newpos = oldpos = 0L; 
+ 		newpos < nfilescur && i < nfilesnew; i++){
+ 	    if(maildir_message_in_list(namesnew[i]->d_name, namescur, oldpos, 
+ 						nfilescur - 1L, &newpos)){
+ 	       oldpos = newpos;
+ 	       snprintf(tmp, sizeof(tmp), "%s/%s", LOCAL->path[New], namesnew[i]->d_name);
+ 	       if(unlink(tmp) < 0)
+ 		 scan_err = -1;
+ 	       rescan++;
+ 	    }
+ 	    else
+ 	      newpos = oldpos;
+ 	 }
+ 	 if(scan_err < 0)
+ 	    maildir_abort(stream);
+ 	 if(rescan == 0)
+ 	   break;
+ 	 else{ /* restart */
+ 	   if(namesnew){
+ 	     for(i = 0L; i < nfilesnew; i++)
+ 		fs_give((void **)&namesnew[i]);
+ 	     fs_give((void **) &namesnew);
+ 	   }
+ 	   nfilesnew = 0L;
+ 	   loop++;
+ 	 }
+       }
+    }
+    if(loop == 10)
+      maildir_abort(stream);
+    if(LOCAL){
+      if(stream->rdonly)
+ 	stream->recent = 0L;
+      total = namescur || stream->rdonly 
+ 		? maildir_parse_dir(stream, 0L, Cur, namescur, 
+ 					      nfilescur, full) : stream->nmsgs;
+      stream->nmsgs = maildir_parse_dir(stream, total, New, namesnew, 
+ 						nfilesnew, full);
+    }
+    if(namesnew){
+      for(i = 0L; i < nfilesnew; i++)
+ 	fs_give((void **)&namesnew[i]);
+      fs_give((void **) &namesnew);
+    }
+    if(namescur){
+      for(i = 0L; i < nfilescur; i++)
+ 	fs_give((void **)&namescur[i]);
+      fs_give((void **) &namescur);
+    }
+    MM_NOCRITICAL(stream);
+ }
+ 
+ int
+ maildir_initial_check (MAILSTREAM *stream, DirNamesType dirtype)
+ {
+    char *tmp;
+    struct stat sbuf;
+ 
+    if (access (LOCAL->path[dirtype], R_OK|W_OK|X_OK) != 0){
+       maildir_abort(stream);
+       return -1;
+    }
+ 
+    if (dirtype != New && 
+ 	(stat(LOCAL->path[Cur], &sbuf) < 0 || sbuf.st_ctime == LOCAL->scantime))
+       return -1;
+    return 0;
+ }
+ 
+ 
+ /* 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, struct direct **names, 
+ 		  unsigned long nfiles, int full)
+ {
+    char tmp[MAILTMPLEN], file[MAILTMPLEN], newfile[MAILTMPLEN], *mdstr;
+    struct stat sbuf;
+    unsigned long i, new = 0L, l, uid_last;
+    unsigned long recent = stream ? stream->recent : 0L;
+    int d = 0, f = 0, r = 0, s = 0, t = 0;
+    int we_compute, in_list, len;
+    int silent = stream ? stream->silent : NIL;
+    MESSAGECACHE *elt;
+ 
+    if (dirtype == Cur && !stream->rdonly)
+       for (i = 1L; i <= stream->nmsgs;){
+ 	elt = mail_elt(stream,  i);
+ 	in_list = elt && elt->private.spare.ptr && 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->private.spare.ptr)
+ 	      maildir_free_file ((void **) &elt->private.spare.ptr);
+ 
+ 	   if (elt->recent) --recent;
+ 	   mail_expunged(stream,i);
+ 	}
+ 	else i++;
+       }
+ 
+    stream->silent = T;
+    uid_last = 0L;
+    len = LOCAL->path[Cur] ? (int) strlen(LOCAL->path[Cur]) : 0;
+    for (we_compute = 0, i = l = 1L; l <= nfiles; l++){
+       unsigned long pos, uid;
+       if (dirtype == New && !stream->rdonly){ /* move new messages to cur */
+ 	pos = l - 1L;
+ 	snprintf (file, sizeof(file), "%s/%s", LOCAL->path[New], names[pos]->d_name);
+ 	if(lstat(file,&sbuf) == 0)
+ 	   switch(sbuf.st_mode & S_IFMT){
+ 	    case S_IFREG:
+ 		strcpy(tmp, names[pos]->d_name);
+ 		if((mdstr = strstr(tmp,MDSEP(3))) 
+ 		   || (mdstr = strstr(tmp,MDSEP(2))))
+ 		   *(mdstr+1) = '2';
+ 		else
+ 		   strcat(tmp, MDSEP(2));
+ 		snprintf(newfile, sizeof(newfile), "%.*s/%.*s", 
+ 		   len, LOCAL->path[Cur] ? LOCAL->path[Cur] : "",
+ 		   (int) sizeof(newfile) - len, tmp);
+ 		newfile[sizeof(newfile)-1] = '\0';
+ 		if(rename (file, newfile) != 0){
+ 		   mm_log("Unable to read new mail!", WARN);
+ 		   continue;
+ 		}
+ 		unlink (file);
+ 		new++;
+ 	        break;
+ 	    case S_IFLNK:  /* clean up, clean up, everybody, everywhere */
+ 		if(unlink(file) < 0){
+ 		   if(LOCAL->link == NIL){ 
+ 		      mm_log("Unable to remove symbolic link", WARN);
+ 		      LOCAL->link = T;
+ 		   }
+ 		}
+ 		continue;
+ 		break;
+ 	    default: 
+ 		if(LOCAL && LOCAL->link == NIL){
+ 		  mm_log("Unrecognized file or link in folder", WARN);
+ 		  LOCAL->link = T;
+ 		}
+ 		continue;
+ 		break;
+ 	   }
+       }
+       mail_exists(stream, i + nmsgs);
+       elt = mail_elt(stream, i + nmsgs);
+       pos = (elt && elt->private.spare.ptr) ? MDPOS(elt) : l - 1L;
+       if (dirtype == New) elt->recent = T;
+       maildir_getflag(names[pos]->d_name, &d, &f, &r ,&s, &t);
+       if (elt->private.spare.ptr)
+ 	 maildir_free_file_only ((void **)&elt->private.spare.ptr);
+       else{
+ 	 maildir_get_file((MAILDIRFILE **)&elt->private.spare.ptr);
+ 	 we_compute++;
+       }
+       MDFILE(elt) = cpystr(names[pos]->d_name);
+       MDPOS(elt)  = pos;
+       MDLOC(elt)  = dirtype;
+       if (dirtype == Cur){	/* deal with UIDs */
+ 	if(elt->private.uid == 0L)
+ 	  elt->private.uid = maildir_get_uid(MDFILE(elt));
+ 	if(elt->private.uid <= uid_last){
+ 	  uid = (we_compute ? uid_last : stream->uid_last) + 1L;
+ 	  if(LOCAL->candouid)
+ 	    maildir_assign_uid(stream, i + nmsgs, uid);
+ 	  else
+ 	    elt->private.uid = uid;
+ 	}
+ 	else
+ 	  uid = elt->private.uid;
+ 	uid_last = uid;
+ 	if(uid_last > stream->uid_last)
+ 	  stream->uid_last = uid_last;
+       }
+       if(dirtype == New && !stream->rdonly){
+ 	maildir_free_file_only((void **)&elt->private.spare.ptr);
+ 	MDFILE(elt)  = cpystr(tmp);
+ 	MDSIZE(elt)  = sbuf.st_size;
+ 	MDMTIME(elt) = sbuf.st_mtime;
+ 	MDLOC(elt)   = Cur;
+       }
+       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;
+ 	   if (!we_compute && !stream->rdonly)
+ 	      MM_FLAGS(stream, i+nmsgs);
+       }
+       maildir_get_date(stream, i+nmsgs);
+       elt->valid = T;
+       i++;
+    }
+    stream->silent = silent;
+    if(LOCAL->candouid && dirtype == Cur)
+       maildir_read_uid(stream, NULL, &stream->uid_validity);
+    if (dirtype == New && stream->rdonly)
+       new = nfiles;
+    mail_exists(stream, nmsgs  + ((dirtype == New) ? new : nfiles));
+    mail_recent(stream, recent + ((dirtype == New) ? new : 0L));
+ 
+    return (nmsgs  + (dirtype == New ? new : nfiles));
+ }
+ 
+ long maildir_ping (MAILSTREAM *stream)
+ {
+   maildir_parse_folder(stream, 0);
+   if(stream && LOCAL){
+      if(LOCAL->candouid < 0)
+ 	LOCAL->candouid++;
+      else if(LOCAL->candouid)
+         maildir_uid_renew_tempfile(stream);
+      else	 /* try again to get uids */
+ 	LOCAL->candouid = maildir_can_assign_uid(stream);
+   }
+   return stream && LOCAL ? LONGT : NIL;
+ }
+ 
+ int maildir_select (const struct direct *name)
+ {
+  return (name->d_name[0] != '.');
+ }
+ 
+ /*
+  * 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 struct direct **d1, const struct direct **d2)
+ {
+   const struct direct *e1 = *(const struct direct **) d1;
+   const struct direct *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 = 1L; i <= stream->nmsgs; i++)
+     if((elt = (MESSAGECACHE *) (*mc)(stream,i,CH_ELT)) && elt->private.spare.ptr)
+       maildir_free_file ((void **) &elt->private.spare.ptr);
+   stream->silent = T;
+   if (options & CL_EXPUNGE) maildir_expunge (stream, NIL, NIL);
+   maildir_abort(stream);
+   if (mdfpath) fs_give((void **)&mdfpath);
+   if (mypid) mypid = (pid_t) 0;
+   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];
+   unsigned long i;
+   MESSAGECACHE *elt;
+   char *s;
+                                 /* UID call "impossible" */
+   if (flags & FT_UID || !LOCAL) return NIL;
+   elt = mail_elt (stream, msgno);
+ 
+   if (!(flags & FT_PEEK) && !elt->seen){
+     elt->seen = T;
+     maildir_flagmsg (stream, elt);
+     MM_FLAGS(stream, elt->msgno);
+   }
+ 
+   MSGPATH(tmp, LOCAL->dir, MDFILE(elt), MDLOC(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;
+   }
+ 
+   s = maildir_text_work(stream, elt, &i, flags);
+   INIT (bs, mail_string, s, i);
+   return LONGT;
+ }
+ 
+ char *maildir_text_work (MAILSTREAM *stream,MESSAGECACHE *elt,
+                       unsigned long *length,long flags)
+ {
+   FDDATA d;
+   STRING bs;
+   char *s,tmp[CHUNK];
+   unsigned long msgno = elt->msgno;
+ 
+   if (length)
+      *length = 0L;
+   LOCAL->buf[0] = '\0';
+ 
+   MSGPATH(tmp, LOCAL->dir, MDFILE(elt), MDLOC(elt));
+   if (LOCAL->fd < 0 && ((LOCAL->fd = open (tmp,O_RDONLY,NIL)) < 0))
+      return maildir_update_elt_maildirp(stream, msgno) > 0
+ 	    ? maildir_text_work(stream, mail_elt(stream, msgno),length, flags)
+ 	    : 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, *t, c;
+   char tmp[MAILTMPLEN];
+   struct stat sbuf;
+   unsigned long i, len;
+   int 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);
+   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';
+ 	t = s + strlen(s);	/* make t point to the end of s */
+ 	for (i = 0L, b = s; b < t && !(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 = 0L, b = s, c = *b; b &&
+ 	    ((c < '\016' && ((c == '\012' && ++i) 
+ 			 ||(c == '\015' && *(b+1) == '\012' && ++b && (i +=2))))
+ 	    || b < t); 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)
+ {
+    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;
+ 
+    maildir_scandir (LOCAL->path[Cur], &names, &nfiles, &scan_err, CCLIENT);
+ 
+    if(scan_err < 0) return -1;
+ 
+    elt = mail_elt (stream,msgno);
+ 
+    in_list = nfiles > 0L
+ 	    ? maildir_message_in_list(MDFILE(elt), names, 0L, nfiles - 1L, &pos)
+ 	    : 0;
+ 
+    if (in_list && pos >= 0L && pos < nfiles
+ 	&& strcmp(MDFILE(elt), names[pos]->d_name)){
+ 	maildir_free_file_only((void **)&elt->private.spare.ptr);
+ 	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);
+ 	}
+    }
+    else in_list = 0;	/* we did not update the file name */
+ 
+    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], *s = NULL;
+   MESSAGECACHE *elt;
+ 
+   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, MDLOC(elt));
+ 
+   MSGPATH(tmp, LOCAL->dir, MDFILE(elt), MDLOC(elt));
+   if (LOCAL->fd < 0 && ((LOCAL->fd = open (tmp,O_RDONLY,NIL)) < 0)){
+      if(errno == EACCES)
+         mm_log ("Message exists but can not be read. Envelope and body lost!",ERROR);
+      return maildir_update_elt_maildirp(stream, msgno) > 0
+ 	    ? maildir_header(stream, msgno, length, flags)
+ 	    : NULL;
+   }
+ 
+   if (flags & FT_INTERNAL){
+      if(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);
+      }
+      read (LOCAL->fd, (void *)LOCAL->buf, elt->private.msg.header.text.size);
+      LOCAL->buf[*length = elt->private.msg.header.text.size] = '\0';
+   }
+   else{
+       s = (char *) fs_get(elt->private.msg.header.text.size+1);
+       read (LOCAL->fd, (void *)s, elt->private.msg.header.text.size);
+       s[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;
+   close(LOCAL->fd); LOCAL->fd = -1;
+   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],file[MAILTMPLEN];
+   long i = 0L;
+ 
+   if((!pat || !*pat) && maildir_canonicalize (test,ref,"*")
+ 	&& maildir_valid_name(test)){	/* there is a #md/ leading here */
+     for (i = 3L; test[i] && test[i] != '/'; i++);
+     if ((s = strchr (test+i+1,'/')) != NULL) *++s = '\0';
+     else test[0] = '\0';
+     mm_list (stream,'/',test, LATT_NOSELECT);
+   }
+   else if (maildir_canonicalize (test,ref,pat)) {
+     if (test[3] == '/') {       /* looking down levels? */
+                                 /* yes, found any wildcards? */
+       if ((s = strpbrk (test,"%*")) != NULL){
+                                 /* 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, '/')) != NULL){
+         *s = '\0';              /* found, tie off at that point */
+         s = file;
+       }
+                                 /* do the work */
+       if(IS_COURIER(test))
+ 	courier_list_work (stream,s,test,0);
+       else
+ 	maildir_list_work (stream,s,test,0);
+     }
+                                 /* always an INBOX */
+     if (!compare_cstring (test,"#MD/INBOX"))
+       mm_list (stream,NIL,"#MD/INBOX",LATT_NOINFERIORS);
+     if (!compare_cstring (test,"#MC/INBOX"))
+       mm_list (stream,NIL,"#MC/INBOX",LATT_NOINFERIORS);
+   }
+ }
+ 
+ void courier_list (MAILSTREAM *stream,char *ref, char *pat)
+ {
+ /* I am too lazy to do anything. Do you care to ask maildir list, please?
+    The real reason why this is a dummy function is because we do not want to
+    see the same folder listed twice. 
+ */
+ }
+ 
+ /* 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_MDINBOXPATH:
+     if(strlen((char *) value ) > 49)
+        strcpy(myMdInboxDir, "Maildir");
+     else
+        strcpy(myMdInboxDir, (char *) value);
+   case GET_MDINBOXPATH:
+     if (myMdInboxDir[0] == '\0') strcpy(myMdInboxDir,"Maildir");
+     ret = (void *) myMdInboxDir;
+     break;
+   case SET_COURIERSTYLE:
+     CourierStyle = * (long *) value;	/* fix by Chris Caputo */
+   case GET_COURIERSTYLE:
+     ret = (void *) &CourierStyle;	/* fix by Chris Caputo */
+     break;
+   case GET_DIRFMTTEST:
+     ret = (void *) maildir_dirfmttest;
+     break;
+   default:
+     break;
+   }
+   return ret;
+ }
+ 
+ int maildir_create_folder(char *mailbox)
+ {
+   char tmp[MAILTMPLEN], err[MAILTMPLEN];
+   DirNamesType i;
+ 
+   for (i = Cur; i != EndDir; i++){
+ 	int len;
+ 	MDFLD(tmp, mailbox, i);
+ 	len = (int) strlen(tmp);
+ 	if (mkdir(tmp, 0700) && errno != EEXIST){ /* try to make new dir */
+ 	    snprintf (err, sizeof(err), "Can't create %.*s: %.*s", len, tmp, (int)(sizeof(err) - len - 16), strerror(errno));
+ 	    err[sizeof(err) - 1] = '\0';
+ 	    mm_log (err,ERROR);
+ 	    return NIL;
+ 	}
+   }
+   return T;
+ }
+ 
+ int maildir_create_work(char *mailbox, int loop)
+ {
+   char *s, c, err[MAILTMPLEN], tmp[MAILTMPLEN], tmp2[MAILTMPLEN], mbx[MAILTMPLEN];
+   int fnlen, create_dir = 0, courier, mv;
+   struct stat sbuf;
+   long style = *(long *) maildir_parameters(GET_COURIERSTYLE, NIL);
+ 
+   courier = IS_COURIER(mailbox);
+   strcpy(mbx, mailbox);
+   mv = maildir_valid(mbx) ? 1 : 0;
+   maildir_file_path(mailbox, tmp, sizeof(tmp));
+   if (mailbox[strlen(mailbox) - 1] == MDSEPARATOR(courier)){
+       create_dir++;
+       mailbox[strlen(mailbox) - 1] = '\0';
+   }
+ 
+   if(!loop && courier){
+     if(mv){
+        if(create_dir){
+ 	  if(style == CCLIENT)
+ 	   strcpy (err,"Can not create directory: folder exists. Create subfolder");
+ 	  else
+ 	   strcpy(err,"Folder and Directory already exist");
+        }
+        else
+           strcpy (err, "Can't create mailbox: mailbox already exists");
+     }
+     else{
+ 	if(create_dir)
+ 	   strcpy(err, "Can not create directory. Cread folder instead");
+ 	else
+ 	  err[0] = '\0';
+     }
+     if(err[0]){
+        mm_log (err,ERROR);
+        return NIL;
+     }
+   }
+ 
+   fnlen = strlen(tmp);
+   if ((s = strrchr(mailbox,MDSEPARATOR(courier))) != NULL){
+      c = *++s;
+     *s = '\0';
+     if ((stat(tmp,&sbuf) || ((sbuf.st_mode & S_IFMT) != S_IFDIR)) &&
+         !maildir_create_work (mailbox, ++loop))
+       return NIL;
+     *s = c;
+   }
+   tmp[fnlen] = '\0';
+ 
+   if (mkdir(tmp,0700) && errno != EEXIST)
+      return NIL;
+ 
+   if (create_dir)
+      mailbox[fnlen] = '/';
+ 
+   if (create_dir){
+      if(style == CCLIENT){
+ 	if(!courier){
+ 	   FILE *fp = NULL;
+ 	   int len = (int) (sizeof(tmp2) - strlen(MDDIR)) - 1;
+ 	   snprintf(tmp2, sizeof(tmp2), "%.*s%.*s", len, tmp, (int) strlen(MDDIR), MDDIR);
+ 	   tmp2[sizeof(tmp2) - 1] = '\0';
+ 	   if ((fp = fopen(tmp2,"w")) == NULL){
+ 	      snprintf (err, sizeof(err), "Problem creating %.*s: %.*s", 
+ 			len, tmp2, 
+ 			(int) sizeof(err) - len - 19, strerror(errno));
+ 	      err[sizeof(err) - 1] = '\0';
+               mm_log (err,ERROR);
+               return NIL;
+ 	   }
+ 	   fclose(fp);
+ 	}
+      }
+      return T;
+   }
+   else
+      return maildir_create_folder(tmp);
+ }
+ 
+ long maildir_create (MAILSTREAM *stream,char *mailbox)
+ {
+   char tmp[MAILTMPLEN], err[MAILTMPLEN];
+   int rv, create_dir;
+ 
+   create_dir = mailbox ? 
+ 		(mailbox[strlen(mailbox) - 1] == 
+ 					MDSEPARATOR(IS_COURIER(mailbox))) : 0;
+   maildir_file_path(mailbox, tmp, sizeof(tmp));
+   strcpy(tmp, mailbox);
+   rv = maildir_create_work(mailbox, 0);
+   strcpy(mailbox, tmp);
+   if (rv == 0){
+      snprintf (err, sizeof(err), "Can't create %s %s",
+ 		   (create_dir ? "directory" : "mailbox"), mailbox);
+      mm_log (err,ERROR);
+   }
+   return rv ? LONGT : NIL;
+ }
+ 
+ #define MAXTRY 10000
+ void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt)
+ {
+   char oldfile[MAILTMPLEN],newfile[MAILTMPLEN],fn[MAILTMPLEN];
+   char *s;
+   int ren, try = 0;
+ 
+   if (elt->valid){
+      for (try = 1; try > 0 && try < MAXTRY; try++){
+                                 /* build the new filename */
+ 	snprintf (oldfile, sizeof(oldfile), "%s/%s",LOCAL->path[Cur], MDFILE(elt));
+ 	fn[0] = '\0';
+ 	if ((ren = maildir_message_exists(stream, MDFILE(elt), fn)) == 0){
+ 	    errno = ENOENT;
+ 	    try = MAXTRY;
+ 	}
+ 	if (*fn){	/* new oldfile! */
+ 	   snprintf (oldfile,sizeof(oldfile),"%.*s/%.*s", 
+ 			(int) strlen(LOCAL->path[Cur]), LOCAL->path[Cur],
+ 			(int) (sizeof(oldfile) - strlen(LOCAL->path[Cur])),fn);
+ 	   oldfile[sizeof(oldfile) - 1] = '\0';
+ 	}
+         if ((s = strrchr (MDFILE(elt), FLAGSEP))) *s = '\0';
+ 	snprintf (fn, sizeof(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));
+ 	snprintf (newfile, sizeof(newfile), "%.*s/%.*s",
+ 			(int) strlen(LOCAL->path[Cur]), LOCAL->path[Cur],
+ 			(int) (sizeof(newfile) - strlen(LOCAL->path[Cur]) - 4), fn);
+ 	newfile[sizeof(newfile) - 1] = '\0';
+         if (ren != 0 && rename (oldfile,newfile) >= 0)
+ 	    try = -1;
+      }
+ 
+      if (try > 0){
+        snprintf(oldfile, sizeof(oldfile), "Unable to write flags to disk: %s",
+ 		(errno == ENOENT) ? "message is gone!" : strerror (errno));
+        mm_log(oldfile,ERROR);
+        return;
+      }
+ #ifdef __CYGWIN__
+      utime(LOCAL->path[Cur], NIL);	/* make sure next scan will catch the change */
+ #endif
+      maildir_free_file_only ((void **) &elt->private.spare.ptr);
+      MDFILE(elt) = cpystr (fn);
+   }
+ }
+ 
+ long maildir_expunge (MAILSTREAM *stream, char *sequence, long options)
+ {
+   long ret;
+   MESSAGECACHE *elt;
+   unsigned long i, n = 0L;
+   unsigned long recent = stream->recent;
+   char tmp[MAILTMPLEN];
+ 
+   mm_critical (stream);               /* go critical */
+   ret = sequence ? ((options & EX_UID) ?
+                          mail_uid_sequence (stream,sequence) :
+                          mail_sequence (stream,sequence)) : LONGT;
+   if(ret == 0L)
+      return 0L;
+   for (i = 1L; i <= stream->nmsgs;){
+     elt = mail_elt (stream,i);
+     if (elt->deleted && (sequence ? elt->sequence : T)){
+       snprintf (tmp, sizeof(tmp), "%s/%s", LOCAL->path[Cur], MDFILE(elt));
+       if (unlink (tmp) < 0) {/* try to delete the message */
+       snprintf (tmp, sizeof(tmp), "Expunge of message %ld failed, aborted: %s",i,
+               strerror (errno));
+       if (!stream->silent)
+          mm_log (tmp,WARN);
+       break;
+       }
+       if (elt->private.spare.ptr)
+        maildir_free_file ((void **) &elt->private.spare.ptr);
+       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 */
+     snprintf (tmp, sizeof(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);
+   return ret;
+ }
+ 
+ long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options)
+ {
+   STRING st;
+   MESSAGECACHE *elt;
+   unsigned long len;
+   int fd;
+   unsigned long i;
+   struct stat sbuf;
+   char tmp[MAILTMPLEN], flags[MAILTMPLEN], path[MAILTMPLEN], *s;
+ 				/* copy the messages */
+   if ((options & CP_UID) ? mail_uid_sequence (stream, sequence) : 
+   	mail_sequence (stream,sequence)) 
+   for (i = 1L; i <= stream->nmsgs; i++)
+     if ((elt = mail_elt (stream,i))->sequence){
+       MSGPATH(path, LOCAL->dir, MDFILE(elt), MDLOC(elt));
+       if (((fd = open (path,O_RDONLY,NIL)) < 0)	 
+ 	  ||((!elt->rfc822_size && 
+ 		((stat(path, &sbuf) < 0) || !S_ISREG (sbuf.st_mode)))))
+ 	 return NIL;
+       if(!elt->rfc822_size)  MDSIZE(elt) = sbuf.st_size;
+       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);
+       elt->rfc822_size = 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 LONGT;			/* return success */
+ }
+ 
+ long maildir_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data)
+ {
+   int fd, k, done, fail;
+   STRING *message;
+   char c,*s, *flags, *date;
+   char tmp[MAILTMPLEN],file[MAILTMPLEN],path1[MAILTMPLEN],path2[MAILTMPLEN];
+   MESSAGECACHE elt;
+   long i, size = 0L, ret = LONGT, f;
+   unsigned long uf, ti;
+   static unsigned int transact = 0;
+   struct stat sbuf;
+ 
+   if (!maildir_valid(mailbox)) {
+     snprintf (tmp, sizeof(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 (mypid == (pid_t) 0)
+     mypid = getpid();
+ 
+  if (!stream){
+     stream = &maildirproto;
+   
+     for (k = 0; k < NUSERFLAGS && stream->user_flags[k]; ++k)
+        fs_give ((void **) &stream->user_flags[k]);
+  }
+ 
+   if (!(*af)(stream, data, &flags, &date, &message)) return NIL;
+ 
+   mm_critical (stream);		/* go critical */
+   do {
+     fail = done = 0;			/* we have not determined name of message file yet */
+     if (!SIZE (message)) {      /* guard against zero-length */
+       mm_log ("Append of zero-length message", ERROR);
+       ret = NIL;
+       break;
+     }
+ 
+     if (date && !mail_parse_date(&elt,date)){
+        snprintf (tmp, sizeof(tmp), "Bad date in append: %.80s", date);
+        mm_log (tmp, ERROR);
+        ret = NIL;
+        break;
+     }
+ 
+     if(date){
+       struct tm tm;
+ 
+       tm.tm_sec  = elt.seconds;
+       tm.tm_min  = elt.minutes;
+       tm.tm_hour = elt.hours;
+       tm.tm_mday = elt.day;
+       tm.tm_mon  = elt.month - 1;
+       tm.tm_year = BASEYEAR + elt.year - 1900;
+ 
+       ti = mktime(&tm);
+     } else ti = time(0);
+ 
+     f = mail_parse_flags (stream,flags,&uf);
+     do {
+ 			/* build file name we will use, fix by Chris Caputo */
+ 	snprintf (file, sizeof(file), "%lu.%d_%09u.%.*s%.*s%.*s%.*s%.*s%.*s",
+ 		ti, mypid, transact++,
+ 		(int)(sizeof(file) - 50), mdlocaldomain, (int) strlen(MDSEP(2)), (f ? MDSEP(2) : ""),
+ 		1, MDFLAG(Draft, f&fDRAFT), 1, MDFLAG(Flagged, f&fFLAGGED),
+ 		1, MDFLAG(Replied, f&fANSWERED), 1, MDFLAG(Seen, f&fSEEN));
+ 				/* build tmp file name */
+ 	if (maildir_file_path(mailbox, tmp, sizeof(tmp)))	/* copy in TMP */
+ 	   MSGPATH(path1, tmp, file, Tmp);
+ 				/* build final filename to use */
+         if (maildir_file_path(mailbox, tmp, sizeof(tmp)))
+ 	   MSGPATH(path2, tmp, file, New);			/* copy in NEW */
+         if(stat(path1, &sbuf) < 0 && errno == ENOENT 
+ 	   &&  stat(path2, &sbuf) < 0 && errno == ENOENT)
+ 	  done++;
+ 	else
+ 	  fail++;
+ 	if(fail == 1000){
+ 	   snprintf (tmp, sizeof(tmp), "Failure to create append message name");
+ 	   mm_log (tmp, ERROR);
+ 	   return NIL;
+ 	}
+     } while (done == 0);
+ 
+     if ((fd = open (path1,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) {
+        snprintf (tmp, sizeof(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 */
+ 	snprintf (tmp, sizeof(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 */
+ 
+     if (rename (path1,path2) < 0) {
+        snprintf (tmp, sizeof(tmp), "Message append failed: %s", strerror (errno));
+        mm_log (tmp, ERROR);
+        ret = NIL;
+     }
+     unlink (path1);
+     if(date){
+ 	time_t tp[2];
+         tp[0] = tp[1] = ti;
+         utime (path2,tp);
+     }
+ 
+     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, error = 0, len;
+   char tmp[MAILTMPLEN],tmp2[MAILTMPLEN], realname[MAILTMPLEN];
+   struct stat sbuf;
+   int courier = IS_COURIER(mailbox);
+ 
+   if (mailbox[strlen(mailbox) - 1] == MDSEPARATOR(courier)){
+       remove_dir++;
+       mailbox[strlen(mailbox) -1] = '\0';
+   }
+ 
+   if (!maildir_valid(mailbox)){
+       maildir_file_path(mailbox, tmp, sizeof(tmp));
+       if (stat(tmp, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode)){
+         snprintf(tmp, sizeof(tmp), "Can not remove %s", mailbox);
+ 	error++;
+       }
+   }
+ 
+   if (!error && remove_dir && !maildir_dir_is_empty(mailbox)){
+      snprintf(tmp, sizeof(tmp), "Can not remove directory %s/: directory not empty", mailbox);
+      error++;
+   }
+ 
+   if(error){
+      mm_log (tmp,ERROR);
+      return NIL;
+   }
+ 
+   maildir_close(stream,0);	/* even if stream was NULL */
+ 
+   maildir_file_path(mailbox, realname, sizeof(realname));
+ 
+   if (remove_dir){
+      snprintf(tmp, sizeof(tmp), "%.*s/%.*s", (int) (sizeof(tmp) - strlen(MDDIR) - 2), realname, (int) strlen(MDDIR), MDDIR);
+      tmp[sizeof(tmp) - 1] = '\0';
+      if ((rv = stat (tmp,&sbuf)) == 0 && S_ISREG(sbuf.st_mode))
+ 	rv = unlink(tmp);
+      else if (errno == ENOENT)
+ 	rv = 0;
+      if (rv != 0){
+ 	len = (int) strlen(tmp2);
+ 	snprintf(tmp, sizeof(tmp), "Can not remove %.*s/%.*s: %.*s", 
+ 		len, tmp2, 
+ 		(int) strlen(MDDIR), MDDIR, 
+ 		(int) (sizeof(tmp) - strlen(MDDIR)) - len - 19, strerror(errno));
+ 	tmp[sizeof(tmp) - 1] = '\0';
+ 	mm_log (tmp,ERROR);
+ 	return NIL;
+      }
+      if (!maildir_valid(realname) && rmdir(realname) != 0){
+ 	len = (int) strlen(mailbox);
+ 	snprintf(tmp, sizeof(tmp), "Can not remove %.*s/: %.*s", 
+ 		len, mailbox, 
+ 		(int)(sizeof(tmp) - len - 19), strerror(errno));
+ 	tmp[sizeof(tmp)-1] = '\0';
+ 	mm_log (tmp, ERROR);
+ 	return NIL;
+      }
+      return LONGT;
+   }
+   /* else remove just the folder. Remove all hidden files, except MDDIR */
+   for (i = Cur; i != EndDir; i++){
+       MDFLD(tmp, realname, i);
+ 
+       if (!(dirp = opendir (tmp))){
+ 	  len = (int) strlen(mailbox);
+ 	  snprintf(tmp, sizeof(tmp), "Can not read %.*s/: %.*s",
+ 		len, mailbox, 
+ 		(int)(sizeof(tmp) - len - 19), strerror(errno));
+ 	  tmp[sizeof(tmp)-1] = '\0';
+ 	  mm_log (tmp, ERROR);
+ 	  return NIL;
+       }
+ 
+       while ((d = readdir(dirp)) != NULL){
+ 	 len = (int) strlen(tmp);
+ 	 if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")){
+ 	    snprintf(tmp2, sizeof(tmp2), "%.*s/%.*s", 
+ 		len, tmp, 
+ 		(int) (sizeof(tmp) - len) -1, d->d_name);
+ 	    tmp2[sizeof(tmp2) - 1] = '\0';
+ 	    if (unlink(tmp2) != 0){
+ 	       len = (int) strlen(mailbox);
+ 	       snprintf(tmp2, sizeof(tmp2), "Can not remove %.*s: %.*s",
+ 			len, mailbox, 
+ 			(int)(sizeof(tmp2) - len - 18), strerror(errno));
+ 	       tmp2[sizeof(tmp2)-1] = '\0';
+ 	       mm_log (tmp2, ERROR);
+ 	       return NIL;
+ 	    }
+ 	 }
+       }
+       closedir(dirp);
+       if (rmdir(tmp) != 0){
+ 	 len = (int) strlen(mailbox);
+ 	 snprintf(tmp, sizeof(tmp), "Can not remove %.*s: %.*s",
+ 			len, mailbox, 
+ 			(int)(sizeof(tmp) - len - 18), strerror(errno));
+ 	 tmp[sizeof(tmp)-1] = '\0';
+ 	 mm_log (tmp, ERROR);
+ 	 return NIL;
+       }
+   }
+   /* 
+    * ok we have removed all subdirectories of the folder mailbox, Remove the
+    * hidden files.
+    */
+ 
+   if(!(dirp = opendir (realname))){
+     len = (int) strlen(realname);
+     snprintf(tmp, sizeof(tmp), "Can not read %.*s/: %.*s",
+ 			len, realname,
+ 			(int)(sizeof(tmp) - len - 16), strerror(errno));
+     tmp[sizeof(tmp)-1] = '\0';
+     mm_log (tmp, ERROR);
+     return NIL;
+   }
+ 
+   while ((d = readdir(dirp)) != NULL){
+ 	if (strcmp(d->d_name, ".") && strcmp(d->d_name,"..")
+ 		&& (!strcmp(d->d_name, MDDIR)
+ 			|| !strncmp(d->d_name, MDUIDLAST, strlen(MDUIDLAST))
+ 			|| !strncmp(d->d_name, MDUIDTEMP, strlen(MDUIDTEMP)))){
+ 	   if(strcmp(d->d_name, MDDIR) == 0)
+ 	      mddir++;
+ 	   len = (int) strlen(realname);
+ 	   snprintf(tmp, sizeof(tmp), "%.*s/%.*s",
+ 			len, realname,
+ 			(int)(sizeof(tmp) - len - 2), strerror(errno));
+ 	   tmp[sizeof(tmp)-1] = '\0';
+ 	   if (unlink(tmp) != 0)
+ 	      error++;
+ 	}
+   }
+   closedir(dirp);
+   if (error || 
+ 	 (maildir_dir_is_empty(mailbox) && mddir == 0 && rmdir(realname) < 0)){
+ 	len = (int) strlen(mailbox);
+         snprintf(tmp, sizeof(tmp), "Can not remove folder %.*s: %.*s",
+ 			len, mailbox,
+ 			(int)(sizeof(tmp) - len - 16), strerror(errno));
+ 	tmp[sizeof(tmp)-1] = '\0';
+         mm_log (tmp, ERROR);
+         return NIL;
+   }
+   return LONGT;
+ }
+ 
+ long maildir_rename (MAILSTREAM *stream, char *old, char *new)
+ {
+   char tmp[MAILTMPLEN], tmpnew[MAILTMPLEN], realold[MAILTMPLEN];
+   char realnew[MAILTMPLEN];
+   int courier = IS_COURIER(old) && IS_COURIER(new);
+   int i, len;
+   long rv = LONGT;
+   COURIER_S *cdir;
+ 
+   if((IS_COURIER(old) || IS_COURIER(new)) && !courier){
+     len = (int) strlen(old);
+     snprintf (tmp, sizeof(tmp), "Can't rename mailbox %.*s to %.*s", 
+ 	len, old, 
+ 	(int) sizeof(tmp) - len - 26, new);
+     tmp[sizeof(tmp) - 1] = '\0';
+     mm_log (tmp, ERROR);
+     return NIL;
+   }
+ 
+   if (!maildir_valid(old)){
+     snprintf (tmp, sizeof(tmp), "Can't rename mailbox %.*s: folder not in maildir format",
+ 	(int) sizeof(tmp) - 52, old);
+     tmp[sizeof(tmp) - 1] = '\0';
+     mm_log (tmp, ERROR);
+     return NIL;
+   }
+   maildir_file_path(old, realold, sizeof(realold));
+   if (!maildir_valid_name(new) && new[0] == '#'){
+     snprintf (tmp, sizeof(tmp), "Cannot rename mailbox %.*s: folder not in maildir format",
+ 		(int) sizeof(tmp) - 53, new);
+     tmp[sizeof(tmp) - 1] = '\0';
+     mm_log (tmp, ERROR);
+     return NIL;
+   }
+   maildir_file_path(new, realnew, sizeof(realnew));
+   if (access(tmpnew,F_OK) == 0){ 	/* new mailbox name must not exist */
+     snprintf (tmp, sizeof(tmp), "Cannot rename to mailbox %.*s: destination already exists",
+ 		(int)(sizeof(tmp) - 54), new);
+     tmp[sizeof(tmp) - 1]  = '\0';
+     mm_log (tmp, ERROR);
+     return NIL;
+   }
+ 
+   if(!courier){
+     if (rename(realold, realnew)){	/* try to rename the directory */
+ 	int len2 = (int) strlen(new);
+ 	len = (int) strlen(old);
+        snprintf(tmp, sizeof(tmp), "Can't rename mailbox %.*s to %.*s: %.*s", 
+ 		len, old, 
+ 	        len2, new,
+ 		(int) sizeof(tmp) - len - len2 - 28, strerror(errno));
+        tmp[sizeof(tmp) - 1] = '\0';
+        mm_log(tmp,ERROR);
+        return NIL;
+     }
+     return LONGT;	/* return success */
+   }
+ 
+   cdir = courier_list_dir(old);
+   for (i = 0; cdir && i < cdir->total; i++){
+       if(strstr(cdir->data[i]->name, old)){
+ 	len = (int) strlen(new);
+ 	snprintf(tmp, sizeof(tmp), "%.*s%.*s", 
+ 			len, new, 
+ 			(int) sizeof(tmp) - len - 1, cdir->data[i]->name+strlen(old));
+ 	tmp[sizeof(tmp) - 1] = '\0';
+ 	maildir_file_path(cdir->data[i]->name, realold, sizeof(realold));
+ 	maildir_file_path(tmp, realnew, sizeof(realnew));
+ 	if (rename(realold, realnew)){
+ 	   int len2 = (int) strlen(new);
+ 	   len = (int) strlen(old);
+ 	   snprintf (tmp, sizeof(tmp), "Can't rename mailbox %.*s to %.*s: %.*s",
+ 			len, old,
+ 			len2, new,
+ 			(int) sizeof(tmp) - len - len2 - 28, strerror(errno));
+ 	   tmp[sizeof(tmp) - 1] = '\0';
+ 	   mm_log(tmp,ERROR);
+ 	   rv = NIL;
+ 	}
+     }
+   }
+   courier_free_cdir(&cdir);
+   return rv;
+ }
+ 
+ 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], tmp[MAILTMPLEN];
+                                 /* get canonical form of name */
+   if (maildir_canonicalize (test, ref, pat) && (s = sm_read (tmp, &sdb))) {
+     do if (pmatch_full (s, test, '/')) mm_lsub (stream, '/', s, NIL);
+     while ((s = sm_read (tmp, &sdb)) != NULL); /* 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) ? LONGT : NIL;
+ }
+ 
+ void maildir_list_work (MAILSTREAM *stream,char *dir,char *pat,long level)
+ {
+   DIR *dp;
+   struct direct *d;
+   struct stat sbuf;
+   char curdir[MAILTMPLEN],name[MAILTMPLEN], tmp[MAILTMPLEN];
+   char realpat[MAILTMPLEN];
+   long i;
+   int len;
+   char *maildirpath = mdirpath();
+ 
+   snprintf(curdir, sizeof(curdir), "%s/%s/", myrootdir(pat), dir ? dir : maildirpath);
+   if ((dp = opendir (curdir)) != NULL){ 
+      if (dir) snprintf (name, sizeof(name), "%s%s/",MDPREFIX(CCLIENT),dir);
+      else strcpy (name, pat);
+ 
+      if (level == 0 && !strpbrk(pat,"%*")){
+ 	if(maildir_valid(pat)){
+ 	  i =  maildir_contains_folder(pat, NULL)
+ 		? LATT_HASCHILDREN
+ 		: (maildir_is_dir(pat, NULL)
+ 			     ? LATT_HASNOCHILDREN : LATT_NOINFERIORS);
+ 	  maildir_file_path(pat, realpat, sizeof(realpat));
+ 	  i +=  maildir_any_new_msgs(realpat) 
+ 			? LATT_MARKED : LATT_UNMARKED;
+ 	  mm_list (stream,'/', pat, i);
+ 	}
+ 	else
+ 	   if(pat[strlen(pat) - 1] == '/')
+ 	     mm_list (stream,'/', pat, LATT_NOSELECT);
+      }
+ 
+      len = (int) strlen(name);
+      while ((d = readdir (dp)) != NULL)
+ 	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) snprintf (tmp, sizeof(tmp), "%.*s%.*s", len, name,(int) sizeof(tmp) - len - 1, d->d_name);
+ 	  else strcpy(tmp, d->d_name);
+ 	  tmp[sizeof(tmp) - 1] = '\0';
+ 
+ 	  if(pmatch_full (tmp, pat,'/')){
+ 	     snprintf(tmp, sizeof(tmp), "%s/%s/%s", myrootdir(d->d_name), 
+ 				(dir ? dir : maildirpath), d->d_name);
+ 	     if(stat (tmp,&sbuf) == 0 
+ 		   && ((sbuf.st_mode & S_IFMT) == S_IFDIR)){
+ 	       if (dir) snprintf (tmp, sizeof(tmp), "%.*s%.*s", len, name, (int) sizeof(tmp) - len - 1, d->d_name);
+ 	       else strcpy(tmp, d->d_name);
+ 	       tmp[sizeof(tmp) - 1] = '\0';
+                i = maildir_valid(tmp)
+ 			? (maildir_contains_folder(dir, d->d_name)
+ 			  ? LATT_HASCHILDREN
+ 			  : (maildir_is_dir(dir, d->d_name)
+ 			     ? LATT_HASNOCHILDREN : LATT_NOINFERIORS))
+ 			: LATT_NOSELECT;
+ 	       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))){
+ 		   snprintf(tmp, sizeof(tmp), "%s/%s",dir,d->d_name);
+  		   maildir_list_work (stream,tmp,pat,level+1);
+ 	       }
+ 	     }
+ 	  }
+        }
+      closedir (dp);
+   }
+ }
+ 
+ void courier_list_work (MAILSTREAM *stream, char *dir, char *pat, long level)
+ {
+   char c, curdir[MAILTMPLEN], tmp[MAILTMPLEN];
+   char realname[MAILTMPLEN], realpat[MAILTMPLEN] = {'\0'};
+   int i, found;
+   long style = *(long *) maildir_parameters(GET_COURIERSTYLE, NIL), j;
+   char *maildirpath = mdirpath();
+   COURIER_S *cdir;
+ 
+   if(!strpbrk(pat,"%*")){	/* a mailbox */
+      maildir_file_path(pat, curdir, sizeof(curdir));
+      i = strlen(curdir) - 1;
+      if(curdir[i] == '/')
+        curdir[i] = '\0';
+      cdir = courier_list_dir(curdir);
+      if(cdir){
+ 	found = 0; j = 0L;
+ 	if(maildir_valid_name(pat)){
+ 	  for(i = 0; !found && i < cdir->total; i++)
+ 	     if(strstr(curdir, cdir->data[i]->name)){
+ 		if(strlen(curdir) < strlen(cdir->data[i]->name))
+ 		  found += 2;
+ 		else if(strlen(curdir) == strlen(cdir->data[i]->name))
+ 		  found -= 1;
+ 	     }
+ 	  if(found > 0)
+             j = LATT_HASCHILDREN;
+           else if(found == 0)
+ 	    j = (style == COURIER) ? LATT_HASNOCHILDREN : LATT_NOINFERIORS;
+ 	}
+ 	else
+ 	   j = LATT_NOSELECT;
+         j += maildir_any_new_msgs(curdir) ? LATT_MARKED : LATT_UNMARKED;
+ 	if (found)
+ 	   mm_list (stream, '.', pat, j);
+         courier_free_cdir(&cdir);
+      }
+      return;
+   }
+ 
+   strcpy(tmp,pat + 4);	/* a directory */
+   j = strlen(pat) - 1;
+   maildir_file_path(pat, realpat, sizeof(realpat));
+   c = pat[j];
+   pat[j] = '\0';
+   realname[0] = '\0';
+   if(dir)
+     maildir_file_path(dir, realname, sizeof(realname));
+   snprintf(curdir, sizeof(curdir), "%s%s%s/%s", (dir ? "" : myrootdir(pat)), (dir ? "" : "/"),
+ 		(dir ? realname : maildirpath),	(dir ? "" : "."));
+   snprintf(tmp, sizeof(tmp), "%s%s/.", MDPREFIX(COURIER), dir ? dir : maildirpath);
+   if (level == 0 && tmp && pmatch_full (tmp, realpat, '.'))
+      mm_list (stream,'.', tmp, LATT_NOSELECT);
+ 
+   cdir = courier_list_dir(pat);
+   pat[j] = c;
+   for (i = 0; cdir && i < cdir->total; i++)
+    if(pmatch_full (cdir->data[i]->name, pat, '.')){
+       snprintf(tmp, sizeof(tmp), "%s.", cdir->data[i]->name);
+       courier_list_info(&cdir, tmp, i);
+       mm_list (stream,'.',cdir->data[i]->name, cdir->data[i]->attribute);
+    }
+   courier_free_cdir(&cdir);
+ }
+ 
+ int 
+ same_maildir_file(char *name1, char *name2)
+ {
+  char tmp1[MAILTMPLEN], tmp2[MAILTMPLEN];
+  char *s;
+ 
+  strcpy(tmp1, name1 ? name1 : "");
+  strcpy(tmp2, name2 ? name2 : "");
+  if ((s = strrchr(tmp1, FLAGSEP)) != NULL)
+    *s = '\0';
+  if (((s = strrchr(tmp1, SIZESEP)) != NULL) && (strchr(s,'.') == NULL))
+    *s = '\0';
+  if ((s = strrchr(tmp2, FLAGSEP)) != NULL)
+    *s = '\0';
+  if (((s = strrchr(tmp2, SIZESEP)) != NULL) && (strchr(s,'.') == NULL))
+    *s = '\0';
+ 
+  return !strcmp(tmp1, tmp2);
+ }
+ 
+ unsigned long antoul(char *seed)
+ {
+   int i, error = 0;
+   unsigned long val = 0L, rv1 = 0L, t;
+   char c, *p;
+  if(!seed)
+    return 0L;
+  t = strtoul(seed, &p, 10);
+  if(p && (*p == '.' || *p == '_'))
+    return t;
+  /* else */
+  if((p = strchr(seed,'.')) != NULL)
+    *p = '\0';
+  error = (strlen(seed) > 6); /* too long */
+  for(i= strlen(seed)-1; error == 0 && i >= 0; i--){
+     c = seed[i];
+     if (c >= 'A' && c <= 'Z') val = c - 'A';
+     else if (c >= 'a' && c <= 'z') val = c - 'a' + 26;
+     else if (c >= '0' && c <= '9') val = c - '0' + 26 + 26; 
+     else if (c == '-') val = c - '-' + 26 + 26 + 10;
+     else if (c == '_') val = c - '_' + 26 + 26 + 10 + 1;
+     else error++;
+     rv1 = val + (rv1 << 6);
+  }
+  if(p)
+    *p = '.';
+   return error ? 0L : rv1;
+ }
+ 
+ unsigned long mdfntoul (char *name)
+ {
+   unsigned long t;
+   char *r, last;
+ 
+   if((*name == '_') && ((r = strpbrk(name,".,%+")) != NULL)){ /* Grrr!!! */
+     last = *r;
+     *r = '\0';
+      t = antoul(r+1);
+     *r = last;
+   }
+   else
+     t = antoul(name);
+   return t;
+ }
+ 
+ int comp_maildir_file(char *name1, char *name2)
+ {
+   int uset1 = 1, uset2 = 1, i, j, cmp;
+   unsigned long t1, t2;
+   char *s1, *s2;
+ 
+   if (!(name1 && *name1))
+      return (name2 && *name2) ? (*name2 == FLAGSEP ? 0 : -1) : 0;
+ 
+   if (!(name2 && *name2))
+      return (name1 && *name1) ? (*name1 == FLAGSEP ? 0 : 1) : 0;
+ 
+    if((cmp = strcmp(name1,name2)) == 0)
+       return 0;
+ 
+   t1 = strtoul(name1, &s1, 10);
+   t2 = strtoul(name2, &s2, 10);
+ 
+   if(!s1 || *s1 != '.')
+     uset1 = 0;
+ 
+   if(!s2 || *s2 != '.')
+     uset2 = 0;
+ 
+   if(uset1 && uset2)	/* normal sort order */
+     return (t1 < t2) ? -1 : (t1 > t2 ? 1 : (cmp < 0 ? -1 : 1));
+ 
+   /* If we make it here we say Grrrr.... first, then we try to figure out
+    * how to sort this mess.
+    * These are the rules.
+    * If there is a number at the beginning it is bigger than anything else.
+    * If there are digits, then the number of digits decides which one is bigger.
+    */
+ 
+   for(i = 0; isdigit(name1[i]); i++);
+   for(j = 0; isdigit(name2[j]); j++);
+ 
+   return(uset1 ? 1 
+ 	       : (uset2 ? -1 
+ 			: (i < j ? -1 : (i > j ? 1 : (cmp < 0 ? -1 : 1)))));
+ }
+ 
+ void
+ maildir_getflag(char *name, int *d, int *f, int *r ,int *s, int *t)
+ {
+   char tmp[MAILTMPLEN], *b;
+   int offset = 0;
+   int tmpd, tmpf, tmpr, tmps, tmpt;
+   int done = 0; 	/* fix by Chris Caputo */
+ 
+   if(d) *d = 0;
+   if(f) *f = 0;
+   if(r) *r = 0;
+   if(s) *s = 0;
+   if(t) *t = 0;
+ 
+   tmpd = tmpf = tmpr = tmps = tmpt = NIL; /* no flags set by default */
+   strcpy(tmp,name);
+   while (!done && (b = strrchr(tmp+offset, FLAGSEP)) != NULL){ 	/* fix by Chris Caputo */
+     char flag,last;
+     int  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'){
+ 		     tmpd = strchr (b, MDFLAGC(Draft))   ? T : NIL;
+ 		     tmpf = strchr (b, MDFLAGC(Flagged)) ? T : NIL;
+ 		     tmpr = strchr (b, MDFLAGC(Replied)) ? T : NIL;
+ 		     tmps = strchr (b, MDFLAGC(Seen))    ? T : NIL;
+ 		     tmpt = strchr (b, MDFLAGC(Trashed)) ? T : NIL;
+ 		  }
+ 		  b[k] = last;
+ 		  b += k;
+ 		break;
+ 	default: done++; 	/* fix by Chris Caputo */
+ 		break;
+     }
+     offset++;
+     for (; tmp[offset] && tmp[offset] != FLAGSEP; offset++);
+   }
+   if(d) *d = tmpd;
+   if(f) *f = tmpf;
+   if(r) *r = tmpr;
+   if(s) *s = tmps;
+   if(t) *t = tmpt;
+ }
+ 
+ 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){
+     DirNamesType i;
+ 
+     if(LOCAL->candouid)
+       maildir_read_uid(stream, NULL, &stream->uid_validity);
+     if (LOCAL->dir) fs_give ((void **) &LOCAL->dir);
+     for (i = Cur; i < EndDir; i++)
+       if(LOCAL->path[i]) fs_give ((void **) &LOCAL->path[i]);
+     fs_give ((void **) &LOCAL->path);
+     if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
+     if(LOCAL->uidtempfile){
+       unlink(LOCAL->uidtempfile);
+       fs_give ((void **) &LOCAL->uidtempfile);
+     }
+     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], tmp2[MAILTMPLEN];
+   int rv = 0, len;
+   DIR *dir;
+   struct direct *d;
+ 
+   maildir_file_path(dirname, tmp2, sizeof(tmp2));
+   if(name){
+     strcat(tmp2,"/");
+     strcat(tmp2, name);
+   }
+ 
+   if (!(dir = opendir (tmp2)))
+      return NIL;
+ 
+   len = (int) strlen(tmp2);
+ 
+   while ((d = readdir(dir)) != NULL){
+     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))){
+ 
+        snprintf(tmp, sizeof(tmp), "%.*s/%.*s", len, tmp2, (int) sizeof(tmp) - len - 2, d->d_name);
+        tmp[sizeof(tmp) - 1] = '\0';
+        if(maildir_valid(tmp)){
+ 	  rv++;
+ 	  break;
+        }
+     }
+   }
+   closedir(dir);
+   return rv;
+ }
+ 
+ int
+ maildir_is_dir(char *dirname, char *name)
+ {
+   char tmp[MAILTMPLEN];
+   struct stat sbuf;
+ 
+   maildir_file_path(dirname, tmp, sizeof(tmp));
+   if(name){
+     strcat(tmp, "/");
+     strcat(tmp, name);
+   }
+   strcat(tmp, "/");
+   strcat(tmp, MDDIR);
+ 
+   return ((stat(tmp, &sbuf) == 0) && S_ISREG (sbuf.st_mode)) ? 1 : 0;
+ }
+ 
+ int
+ maildir_dir_is_empty(char *mailbox)
+ {
+   char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], tmp3[MAILTMPLEN],*s;
+   int rv = 1, courier = IS_COURIER(mailbox), len;
+   DIR *dir;
+   struct direct *d;
+   struct stat sbuf;
+ 
+   maildir_file_path(mailbox, tmp2, sizeof(tmp2));
+ 
+   if(courier){
+      strcpy(tmp3, tmp2);
+      if((s = strrchr(tmp2, '/')) != NULL)
+ 	*s = '\0';
+   }
+ 
+   if (!(dir = opendir (tmp2)))
+      return rv;
+ 
+   len = (int) strlen(tmp2);
+ 
+   if(courier){
+      while((d = readdir(dir)) != NULL){
+         snprintf(tmp, sizeof(tmp), "%.*s/%.*s", len, tmp2, (int)(sizeof(tmp) - len - 2),d->d_name);
+ 	tmp[sizeof(tmp) - 1] = '\0';
+ 	if(!strncmp(tmp, tmp3, strlen(tmp3)) 
+ 	   && tmp[strlen(tmp3)] == '.'){
+ 	   rv = 0;
+ 	   break;
+ 	}
+      }
+   }
+   else
+     while ((d = readdir(dir)) != NULL){
+       snprintf(tmp, sizeof(tmp), "%.*s/%.*s", len, tmp2, (int)(sizeof(tmp) - len - 2), d->d_name);
+       tmp[sizeof(tmp) - 1] = '\0';
+       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)
+ 	&& strncmp(d->d_name, MDUIDTEMP, 8)
+ 	&& strcmp(d->d_name, ".mbsyncstate")
+ 	&& strcmp(d->d_name, ".mbsyncstate")
+ 	&& strcmp(d->d_name, ".mbsyncstate.new")
+ 	&& strcmp(d->d_name, ".mbsyncstate.journal")
+ 	&& strcmp(d->d_name, ".mbsyncstate.lock")
+ 	&& !(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];
+   int rv = NIL;
+   DIR *dir;
+   struct direct *d;
+ 
+   MDFLD(tmp, mailbox, New);
+ 
+   if (!(dir = opendir (tmp)))
+      return rv;
+ 
+   while ((d = readdir(dir)) != NULL){
+     if (d->d_name[0] == '.')
+ 	continue;
+     rv = T;
+     break;
+   }
+   closedir(dir);
+   return rv;
+ }
+ 
+ 
+ void
+ maildir_get_date(MAILSTREAM *stream, unsigned long msgno)
+ {
+   MESSAGECACHE *elt;
+   struct tm *t;
+   time_t ti;
+   int i,k;
+ 
+   elt = mail_elt (stream,msgno);
+   if(elt && elt->year != 0)
+     return;
+   if ((ti = mdfntoul(MDFILE(elt))) > 0L && (t = gmtime(&ti))){
+      i = t->tm_hour * 60 + t->tm_min;
+      k = t->tm_yday;
+      t = localtime(&ti);
+      i = t->tm_hour * 60 + t->tm_min - i;
+      if((k = t->tm_yday - k) != 0) 
+ 	i += ((k < 0) == (abs (k) == 1)) ? -24*60 : 24*60;
+      k = abs (i);
+      elt->hours = t->tm_hour; 
+      elt->minutes = t->tm_min; 
+      elt->seconds = t->tm_sec;
+      elt->day = t->tm_mday; elt->month = t->tm_mon + 1;
+      elt->year = t->tm_year - (BASEYEAR - 1900);
+      elt->zoccident = (k == i) ? 0 : 1;
+      elt->zhours = k/60;
+      elt->zminutes = k % 60;
+   }
+ }
+ 
+ /* Support for Courier Style directories 
+    When this code is complete there will be two types of support, which 
+    will be configurable. The problem is the following: In Courier style 
+    folder structure, a "folder" may have a subfolder called 
+    "folder.subfolder", which is not natural in the file system in the 
+    sense that I can not stat for "folder.subfolder" wihtout knowing what 
+    "subfolder" is. It needs to be guessed. Because of this I need to look 
+    in the list of folders if there is a folder with a name 
+    "folder.subfolder", before I can say if the folder is dual or not. One 
+    can avoid this annoyance if one ignores the problem by declaring that 
+    every folder is dual. I will however code as the default the more 
+    complicated idea of scaning the containing directory each time it is 
+    modified and search for subfolders, and list the entries it found.
+  */
+ 
+ int courier_dir_select (const struct direct *name)
+ {
+  return name->d_name[0] == '.' && (strlen(name->d_name) > 2
+ 	|| (strlen(name->d_name) == 2 &&  name->d_name[1] != '.'));
+ }
+ 
+ int courier_dir_sort (const struct direct **d1, const struct direct **d2)
+ {
+   const struct direct *e1 = *(const struct direct **) d1;
+   const struct direct *e2 = *(const struct direct **) d2;
+ 
+   return strcmp((char *) e1->d_name, (char *) e2->d_name);
+ }
+ 
+ void courier_free_cdir (COURIER_S **cdir)
+ {
+   int i;
+ 
+   if (!*cdir)
+      return;
+ 
+   if ((*cdir)->path) fs_give((void **)&((*cdir)->path));
+   for (i = 0; i < (*cdir)->total; i++)
+     if((*cdir)->data[i]->name) fs_give((void **)&((*cdir)->data[i]->name));
+   fs_give((void **)&((*cdir)->data));
+   fs_give((void **)&(*cdir));
+ }
+ 
+ COURIER_S *courier_get_cdir (int total)
+ {
+  COURIER_S *cdir;
+ 
+  cdir = (COURIER_S *)fs_get(sizeof(COURIER_S));
+  memset(cdir, 0, sizeof(COURIER_S));
+  cdir->data = (COURIERLOCAL **) fs_get(total*sizeof(COURIERLOCAL *));
+  memset(cdir->data, 0, sizeof(COURIERLOCAL *));
+  cdir->total = total;
+  return cdir;
+ }
+ 
+ int courier_search_list(COURIERLOCAL **data, char *name, int first, int last)
+ {
+   int try = (first + last)/2;
+ 
+   if(!strstr(data[try]->name, name)){
+      if(first == try) /* first == last || first + 1 == last */
+ 	return strstr(data[last]->name, name) ? 1 : 0;
+      if(strcmp(data[try]->name, name) < 0) /*data[try] < name < data[end] */
+ 	return courier_search_list(data, name, try, last);
+      else	/* data[begin] < name < data[try] */
+ 	return courier_search_list(data, name, first, try);
+   }
+   return 1;
+ }
+ 
+ /* Lists all directories that are subdirectories of a given directory */
+ 
+ COURIER_S *courier_list_dir(char *curdir)
+ {
+   struct direct **names = NIL;
+   struct stat sbuf;
+   unsigned long ndir;
+   COURIER_S *cdir = NULL;
+   char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], pathname[MAILTMPLEN], 
+ 	realname[MAILTMPLEN];
+   int i, j, scand, td;
+ 
+   /* There are two cases, either curdir is 
+  	 #mc/INBOX.	 #mc/INBOX.foo
+ 	or
+ 	 #mc/Maildir/. 	 #mc/Maildir/.foo
+    */
+   strcpy(tmp,curdir + 4);
+   if(!strncmp(ucase(tmp), "INBOX", 5))
+     strcpy(tmp, "#mc/INBOX.");
+   else{
+    strcpy(tmp, curdir);
+    for (i = strlen(tmp) - 1; tmp[i] && tmp[i] != '/'; i--);
+    tmp[i+2] = '\0'; 	/* keep the last "." intact */
+   }
+   maildir_file_path(tmp, realname, sizeof(realname));
+   maildir_scandir (realname, &names, &ndir, &scand, COURIER);
+ 
+   if (scand > 0){
+      cdir = courier_get_cdir(ndir);
+      cdir->path = cpystr(realname);
+      for(i = 0, j = 0; i < ndir; i++){
+         td = realname[strlen(realname) - 1] == '.'
+ 		&& *names[i]->d_name == '.';
+ 	snprintf(tmp2, sizeof(tmp2), "%s%s", tmp, names[i]->d_name+1);
+ 	snprintf(pathname, sizeof(pathname), "%s%s", realname, names[i]->d_name + td);
+ 	if(stat(pathname, &sbuf) == 0 && S_ISDIR(sbuf.st_mode)){
+ 	   cdir->data[j] = (COURIERLOCAL *) fs_get(sizeof(COURIERLOCAL));
+ 	   cdir->data[j++]->name = cpystr(tmp2);
+ 	}
+ 	fs_give((void **)&names[i]);
+      }
+      cdir->total = j;
+      if(cdir->total == 0)
+         courier_free_cdir(&cdir);
+   }
+   if(names)
+     fs_give((void **) &names);
+   return cdir;
+ }
+ 
+ void
+ courier_list_info(COURIER_S **cdirp, char *data, int i)
+ {
+    long style = *(long *) maildir_parameters(GET_COURIERSTYLE, NIL);
+    COURIER_S *cdir = *cdirp;
+ 
+    if(maildir_valid(cdir->data[i]->name)){
+       if(courier_search_list(cdir->data, data, 0, cdir->total - 1))
+ 	 cdir->data[i]->attribute = LATT_HASCHILDREN;
+       else
+ 	 cdir->data[i]->attribute = (style == COURIER)
+ 				? LATT_HASNOCHILDREN : LATT_NOINFERIORS;
+    }
+    else
+       cdir->data[i]->attribute = LATT_NOSELECT;
+    cdir->data[i]->attribute += maildir_any_new_msgs(cdir->data[i]->name) 
+ 					? LATT_MARKED : LATT_UNMARKED;
+ }
+ 
+ /* UID Support */
+ /* Yes, I know I procastinated a lot about this, but here it is finally */
+ 
+ /* return code:
+    bigger than zero: this session can assign uids
+    zero: this session will not assign uid
+    smaller than zero: this session temporarily suspends assigning uids 
+  */
+ int
+ maildir_can_assign_uid (MAILSTREAM *stream)
+ {
+   unsigned int rv = 0;
+   int ownuid, existuid;
+   unsigned long t;
+   char tmp[MAILTMPLEN], tmp2[MAILTMPLEN], *p, *s;
+   DIR *dir;
+   struct direct *d;
+ 
+   if(!stream || stream->rdonly 
+ 	|| !LOCAL || !LOCAL->dir || !(dir = opendir(LOCAL->dir)))
+     return 0;
+ 
+   if(mypid == (pid_t) 0)
+     mypid = getpid();
+ 
+   snprintf(tmp, sizeof(tmp), "%s.%d", MDUIDTEMP, mypid);
+ 
+   ownuid = existuid = 0;
+   s = NULL;
+   while ((d = readdir(dir)) != NULL){
+     if(strncmp(d->d_name, tmp, strlen(tmp)) == 0){
+ 	existuid++; ownuid++;
+ 	if(ownuid > 1){
+ 	  snprintf(tmp2, sizeof(tmp), "%s/%s", LOCAL->dir, d->d_name);
+ 	  unlink(tmp2);
+ 	  if(s){
+ 	     snprintf(tmp2, sizeof(tmp2), "%s/%s", LOCAL->dir, s);
+ 	     unlink(tmp2);
+ 	     fs_give((void **)&s);
+ 	  }
+ 	}
+ 	else
+ 	  s = cpystr(d->d_name);
+     }
+     else if(strncmp(d->d_name, MDUIDTEMP, strlen(MDUIDTEMP)) == 0)
+         existuid++;
+   }
+ 
+   closedir(dir);
+   if(s)
+     fs_give((void **)&s);
+ 
+   if(ownuid == 1 && existuid == 1)
+      rv = 1;
+ 
+   if(ownuid == 0 && existuid == 0){ /* nobody owns the uid? */
+     FILE *fp;
+     snprintf(tmp, sizeof(tmp), "%s/%s.%d.%lu", LOCAL->dir, MDUIDTEMP, mypid, time(0));
+     if((fp = fopen(tmp, "w")) != NULL){
+       fclose(fp);
+       if(LOCAL->uidtempfile)
+ 	 fs_give((void **)&LOCAL->uidtempfile);
+       LOCAL->uidtempfile = cpystr(tmp);
+     }
+     rv = 1;
+   }
+ 
+   if(ownuid == 0 && existuid > 0) /* someone else owns uid assignment */
+     return 0;
+ 
+   /* if we own the uid, check that we do not own it more than once
+    * or that we share ownership. If any of these situations happens,
+    * give up the ownership until we can recover it
+    */
+ 
+   if(ownuid > 0){
+     if(ownuid > 1)	/* impossible, two lock files for the same session */
+        return (-1)*ownuid;
+ 
+     if(ownuid != existuid){	/* lock files for different sessions */
+       if(LOCAL->uidtempfile){
+ 	 unlink(LOCAL->uidtempfile);
+ 	 fs_give((void **)&LOCAL->uidtempfile);
+       }
+       return (-1)*ownuid;
+     }
+   }
+ 
+   return rv;
+ }
+ 
+ void
+ maildir_read_uid(MAILSTREAM *stream, unsigned long *uid_last, 
+ 			unsigned long *uid_validity)
+ {
+   int createuid, deleteuid = 0;
+   char tmp[MAILTMPLEN], *s = NULL;
+   DIR *dir;
+   struct direct *d;
+ 
+   if(uid_last) *uid_last = 0L;
+   if(uid_last && uid_validity) *uid_validity = time(0);
+   if(!stream || !LOCAL || !LOCAL->dir || !(dir = opendir(LOCAL->dir)))
+     return;
+ 
+   while ((d = readdir(dir)) != NULL){
+       if(!strncmp(d->d_name, MDUIDLAST, strlen(MDUIDLAST)))
+        break;
+   }
+   createuid = d == NULL ? 1 : 0;
+   if(uid_last == NULL)
+     deleteuid++;
+   if(d){
+      if(uid_last){
+ 	s = d->d_name + strlen(MDUIDLAST) + 1;
+ 	*uid_last = strtoul(s, &s, 10);
+ 	if(!s || *s != '.'){
+ 	  deleteuid++;
+ 	  createuid++;
+ 	  *uid_last = 0L;
+ 	}
+      }
+      if(s && *s == '.'){
+         if(uid_validity){
+ 	  s++;
+ 	  *uid_validity = strtoul(s, &s, 10);
+ 	  if(s && *s != '\0'){
+ 	    *uid_validity = time(0);
+ 	    deleteuid++;
+ 	    createuid++;
+ 	  }
+ 	}
+      }
+      else{
+ 	deleteuid++;
+ 	createuid++;
+      }
+   }
+   if(deleteuid){
+      snprintf(tmp, sizeof(tmp), "%s/%s", LOCAL->dir, d->d_name);
+      unlink(tmp);
+   }
+   if(createuid)
+      maildir_write_uid(stream, (uid_last ? *uid_last : stream->uid_last), 
+ 		uid_validity ? *uid_validity : time(0));
+   closedir(dir);
+ }
+ 
+ void
+ maildir_write_uid(MAILSTREAM *stream, unsigned long uid_last, 
+ 			unsigned long uid_validity)
+ {
+   char tmp[MAILTMPLEN];
+   FILE *fp;
+ 
+   if(!stream || stream->rdonly || !LOCAL || !LOCAL->dir)
+     return;
+ 
+   snprintf(tmp, sizeof(tmp), "%s/%s.%010lu.%010lu", LOCAL->dir, MDUIDLAST, 
+ 			uid_last, uid_validity);
+   if((fp = fopen(tmp, "w")) != NULL)
+      fclose(fp);
+ }
+ 
+ unsigned long 
+ maildir_get_uid(char *name)
+ {
+   char *s;
+   unsigned long rv = 0L;
+ 
+   if(!name || (s = strstr(name,MDUIDSEP)) == NULL)
+     return rv;
+ 
+   s += strlen(MDUIDSEP);
+   rv = strtoul(s, NULL, 10);
+   return rv;
+ }
+ 
+ 
+ void
+ maildir_delete_uid(MAILSTREAM *stream, unsigned long msgno)
+ {
+   char old[MAILTMPLEN], new[MAILTMPLEN], *s, *t;
+   MESSAGECACHE *elt;
+ 
+   elt = mail_elt(stream, msgno);
+   if(!stream || !elt || !elt->private.spare.ptr || !LOCAL || !LOCAL->dir)
+     return;
+ 
+   snprintf(old, sizeof(old), "%s/%s/%s", LOCAL->dir, MDNAME(Cur), MDFILE(elt));
+   t = MDFILE(elt);
+   if((s = strstr(MDFILE(elt), MDUIDSEP)) != NULL){
+      *s = '\0';
+      s += strlen(MDUIDSEP);
+      strtoul(s, &s, 10);
+      snprintf(new, sizeof(new), "%s/%s/%s%s", LOCAL->dir, MDNAME(Cur), t, s);
+      if(rename(old, new) == 0){
+ 	maildir_free_file_only ((void **)&elt->private.spare.ptr);
+ 	s = strrchr(new, '/');
+ 	MDFILE(elt) = cpystr(s+1);
+      }
+      elt->private.uid = 0L;
+   }
+ }
+ 
+ void
+ maildir_assign_uid(MAILSTREAM *stream, unsigned long msgno, unsigned long uid)
+ {
+   int createuid, deleteuid = 0;
+   char old[MAILTMPLEN], new[MAILTMPLEN], *s, *t;
+   MESSAGECACHE *elt;
+ 
+   elt = mail_elt(stream, msgno);
+   if(!stream || !elt || !elt->private.spare.ptr || !LOCAL || !LOCAL->dir)
+     return;
+ 
+   maildir_delete_uid(stream, msgno);
+   snprintf(old, sizeof(old), "%s/%s/%s", LOCAL->dir, MDNAME(Cur), MDFILE(elt));
+   t = MDFILE(elt);
+   if((s = strrchr(MDFILE(elt),FLAGSEP)) != NULL){
+      *s++ = '\0';
+      snprintf(new, sizeof(new), "%s/%s/%s%s%lu%c%s", 
+ 		LOCAL->dir, MDNAME(Cur), t, MDUIDSEP, uid, FLAGSEP, s);
+      if(rename(old, new) == 0){
+ 	maildir_free_file_only ((void **)&elt->private.spare.ptr);
+ 	s = strrchr(new, '/');
+ 	MDFILE(elt) = cpystr(s+1);
+ 	stream->uid_validity = time(0);
+      }
+      elt->private.uid = uid;
+   }
+ }
+ 
+ void
+ maildir_uid_renew_tempfile(MAILSTREAM *stream)
+ {
+   char tmp[MAILTMPLEN];
+ 
+   if(!stream || stream->rdonly 
+ 	|| !LOCAL || !LOCAL->candouid || !LOCAL->dir || !LOCAL->uidtempfile)
+     return;
+ 
+   if(mypid == (pid_t) 0)
+     mypid = getpid();
+ 
+   snprintf(tmp, sizeof(tmp), "%s/%s.%d.%lu", LOCAL->dir, MDUIDTEMP, mypid, time(0));
+   if(rename(LOCAL->uidtempfile, tmp) == 0){
+       fs_give((void **)&LOCAL->uidtempfile);
+       LOCAL->uidtempfile = cpystr(tmp);
+   }
+ }
diff -rc alpine-2.26/imap/src/osdep/unix/maildir.h alpine-2.26.maildir/imap/src/osdep/unix/maildir.h
*** alpine-2.26/imap/src/osdep/unix/maildir.h	2022-06-02 18:14:52.323147655 -0600
--- alpine-2.26.maildir/imap/src/osdep/unix/maildir.h	2022-06-02 18:14:52.251147832 -0600
***************
*** 0 ****
--- 1,122 ----
+ typedef enum  {Draft, Flagged, Passed, Replied, Seen, Trashed, 
+ 	       EmptyFlag, EndFlags} MdFlagNamesType;
+ 
+ typedef enum {Cur, Tmp, New, EndDir} DirNamesType;
+ 
+ typedef struct courier_local {
+   char *name;		/* name of directory/folder */
+   int attribute;	/* attributes (children/marked/etc) */
+ } COURIERLOCAL;
+ 
+ typedef struct courier {
+   char *path;			/* Path to collection */
+   time_t scantime;		/* time at which information was generated */
+   int total;			/* total number of elements in data */
+   COURIERLOCAL **data;
+ } COURIER_S;
+ 
+ typedef struct maildir_file_info {
+    char *name;		/* name of the file			   */
+    DirNamesType loc;	/* location of this 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;
+ 
+ /* 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);
+ int maildir_create_folder (char *mailbox);
+ long maildir_create (MAILSTREAM *stream,char *mailbox);
+ void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt); /*check */
+ long maildir_expunge (MAILSTREAM *stream, char *sequence, long options);
+ 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);
+ void courier_list (MAILSTREAM *stream,char *ref, char *pat);
+ 
+ /* utility functions */
+ void courier_realname (char *name, char *realname);
+ long maildir_dirfmttest (char *name);
+ char *maildir_file (char *dst,char *name);
+ int maildir_select (const struct direct *name);
+ int maildir_namesort (const struct direct **d1, const struct direct **d2);
+ unsigned long antoul (char *seed);
+ unsigned long mdfntoul (char *name);
+ int courier_dir_select (const struct direct *name);
+ int courier_dir_sort (const struct direct **d1, const struct direct **d2);
+ long maildir_canonicalize (char *pattern,char *ref,char *pat);
+ void maildir_list_work (MAILSTREAM *stream,char *subdir,char *pat,long level);
+ void courier_list_work (MAILSTREAM *stream,char *subdir,char *pat,long level);
+ int maildir_file_path(char *name, char *tmp, size_t sizeoftmp);
+ 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);
+ char *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);
+ int maildir_eliminate_duplicate (char *name, struct direct ***flist, 
+ 					unsigned long *nfiles);
+ int maildir_doscandir (char *name, struct direct ***flist, int flag);
+ unsigned long maildir_scandir (char *name, struct direct ***flist,
+ 			unsigned long *nfiles, int *scand, int flag);
+ void maildir_parse_folder (MAILSTREAM *stream, int full);
+ void  md_domain_name (void);
+ char  *myrootdir (char *name);
+ char  *mdirpath (void);
+ int   maildir_initial_check (MAILSTREAM *stream, DirNamesType dirtype);
+ unsigned long  maildir_parse_dir(MAILSTREAM *stream, unsigned long nmsgs, 
+    DirNamesType dirtype, struct direct **names, unsigned long nfiles, 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_is_dir(char *dirname, char *name);
+ int maildir_dir_is_empty(char *mailbox);
+ int maildir_create_work (char *mailbox, int loop);
+ 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);
+ void maildir_fast (MAILSTREAM *stream,char *sequence,long flags);
+ 
+ /* Courier server support */
+ void courier_free_cdir (COURIER_S **cdir);
+ COURIER_S *courier_get_cdir (int total);
+ int courier_search_list(COURIERLOCAL **data, char *name, int first, int last);
+ COURIER_S *courier_list_dir(char *curdir);
+ void courier_list_info(COURIER_S **cdirp, char *data, int i);
+ 
+ /* UID Support */
+ int maildir_can_assign_uid (MAILSTREAM *stream);
+ void maildir_read_uid(MAILSTREAM *stream, unsigned long *uid_last, 
+      			                   unsigned long *uid_validity);
+ void maildir_write_uid(MAILSTREAM *stream, unsigned long uid_last, 
+      			                   unsigned long uid_validity);
+ unsigned long maildir_get_uid(char *name);
+ void maildir_delete_uid(MAILSTREAM *stream, unsigned long msgno);
+ void maildir_assign_uid(MAILSTREAM *stream, unsigned long msgno, unsigned long uid);
+ void maildir_uid_renew_tempfile(MAILSTREAM *stream);
+ 
diff -rc alpine-2.26/imap/src/osdep/unix/Makefile alpine-2.26.maildir/imap/src/osdep/unix/Makefile
*** alpine-2.26/imap/src/osdep/unix/Makefile	2022-06-02 18:14:00.475274788 -0600
--- alpine-2.26.maildir/imap/src/osdep/unix/Makefile	2022-06-02 18:14:52.255147822 -0600
***************
*** 146,152 ****
  # However, mh needs to be before any sysinbox formats (such as mmdf or unix)
  # since otherwise INBOX won't work correctly when mh_allow_inbox is set.
  #
! DEFAULTDRIVERS=imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile
  CHUNKSIZE=65536
  
  # Normally no need to change any of these
--- 146,152 ----
  # However, mh needs to be before any sysinbox formats (such as mmdf or unix)
  # since otherwise INBOX won't work correctly when mh_allow_inbox is set.
  #
! DEFAULTDRIVERS=maildir courier imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile
  CHUNKSIZE=65536
  
  # Normally no need to change any of these
***************
*** 155,161 ****
  BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o utf8aux.o siglocal.o \
   dummy.o pseudo.o netmsg.o flstring.o fdstring.o \
   rfc822.o nntp.o smtp.o imap4r1.o http.o json.o pop3.o \
!  unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o mix.o sha.o
  CFLAGS=-g
  
  CAT=cat
--- 155,163 ----
  BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o utf8aux.o siglocal.o \
   dummy.o pseudo.o netmsg.o flstring.o fdstring.o \
   rfc822.o nntp.o smtp.o imap4r1.o http.o json.o pop3.o \
!  unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o mix.o \
!  maildir.o sha.o
! 
  CFLAGS=-g
  
  CAT=cat
***************
*** 292,298 ****
  
  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 \
--- 294,300 ----
  
  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 \
***************
*** 922,927 ****
--- 924,930 ----
  json.o: mail.h misc.h osdep.h utf8.h json.h
  http.o: mail.h misc.h osdep.h utf8.h http.h json.h
  sha.o: mail.h misc.h osdep.h sha.h sha-private.h hash.h hmac.c sha1.c sha224-256.c sha384-512.c usha.c
+ maildir.o: mail.h misc.h osdep.h maildir.h dummy.h
  
  # OS-dependent
  
diff -rc alpine-2.26/imap/src/osdep/unix/os_cyg.h alpine-2.26.maildir/imap/src/osdep/unix/os_cyg.h
*** alpine-2.26/imap/src/osdep/unix/os_cyg.h	2022-06-02 18:14:00.475274788 -0600
--- alpine-2.26.maildir/imap/src/osdep/unix/os_cyg.h	2022-06-02 18:14:52.255147822 -0600
***************
*** 47,52 ****
--- 47,53 ----
  #define setpgrp setpgid
  
  #define SYSTEMUID 18		/* Cygwin returns this for SYSTEM */
+ #define FLAGSEP ';'
  #define geteuid Geteuid
  uid_t Geteuid (void);
  
diff -rc alpine-2.26/pith/conf.c alpine-2.26.maildir/pith/conf.c
*** alpine-2.26/pith/conf.c	2022-06-02 18:14:00.491274749 -0600
--- alpine-2.26.maildir/pith/conf.c	2022-06-02 18:14:52.259147813 -0600
***************
*** 451,456 ****
--- 451,459 ----
  
  CONF_TXT_T cf_text_newsrc_path[] =		"Full path and name of NEWSRC file";
  
+ #ifndef _WINDOWS
+ 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\"";
+ #endif
  
  /*----------------------------------------------------------------------
  These are the variables that control a number of pine functions.  They
***************
*** 655,660 ****
--- 658,667 ----
  	NULL,			cf_text_news_active},
  {"news-spool-directory",		0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
  	NULL,			cf_text_news_spooldir},
+ #ifndef _WINDOWS
+ {"maildir-location",			0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
+ 	"Maildir Location",			cf_text_maildir_location},
+ #endif
  {"upload-command",			0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
  	NULL,			cf_text_upload_cmd},
  {"upload-command-prefix",		0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
***************
*** 2396,2401 ****
--- 2403,2414 ----
        mail_parameters(NULL, SET_NEWSSPOOL,
  		      (void *)VAR_NEWS_SPOOL_DIR);
  
+ #ifndef _WINDOWS
+     set_current_val(&vars[V_MAILDIR_LOCATION], TRUE, TRUE);
+     if(VAR_MAILDIR_LOCATION && VAR_MAILDIR_LOCATION[0])
+       mail_parameters(NULL, SET_MDINBOXPATH, (void *)VAR_MAILDIR_LOCATION);
+ #endif
+ 
      /* guarantee a save default */
      set_current_val(&vars[V_DEFAULT_SAVE_FOLDER], TRUE, TRUE);
      if(!VAR_DEFAULT_SAVE_FOLDER || !VAR_DEFAULT_SAVE_FOLDER[0])
***************
*** 3037,3042 ****
--- 3050,3059 ----
  	 F_SORT_DEFAULT_SAVE_ALPHA, h_config_sort_save_alpha, PREF_FLDR, 0},
  	{"vertical-folder-list", "Use Vertical Folder List",
  	 F_VERTICAL_FOLDER_LIST, h_config_vertical_list, PREF_FLDR, 0},
+ #ifndef _WINDOWS
+ 	{"use-courier-folder-list", "Courier Style Folder List",
+ 	 F_COURIER_FOLDER_LIST, h_config_courier_list, PREF_FLDR, 0},
+ #endif
  
  /* Addr book */
  	{"combined-addrbook-display", "Combined Address Book Display",
***************
*** 7217,7223 ****
  	       int just_flip_value, EditWhich ew)
  {
      char      **vp, *p, **lval, ***alval;
!     int		og, on_before, was_set;
      char       *err;
      long	l;
  
--- 7234,7240 ----
  	       int just_flip_value, EditWhich ew)
  {
      char      **vp, *p, **lval, ***alval;
!     int		og, on_before, was_set, i;
      char       *err;
      long	l;
  
***************
*** 7270,7275 ****
--- 7287,7299 ----
  
  	break;
  
+ #ifndef _WINDOWS
+       case F_COURIER_FOLDER_LIST:
+       i = F_ON(f->id ,ps) ? 1 : 0;
+       mail_parameters(NULL,SET_COURIERSTYLE, (void *) &i);
+       break; /* COURIER == 1, CCLIENT == 0, see maildir.h */
+ #endif
+ 
        case F_COLOR_LINE_IMPORTANT :
        case F_DATES_TO_LOCAL :
  	clear_index_cache(ps->mail_stream, 0);
***************
*** 8074,8079 ****
--- 8098,8107 ----
  	return(h_config_newmailwidth);
        case V_NEWSRC_PATH :
  	return(h_config_newsrc_path);
+ #ifndef _WINDOWS
+       case V_MAILDIR_LOCATION :
+ 	return(h_config_maildir_location);
+ #endif
        case V_BROWSER :
  	return(h_config_browser);
        case V_HISTORY :
diff -rc alpine-2.26/pith/conf.h alpine-2.26.maildir/pith/conf.h
*** alpine-2.26/pith/conf.h	2022-06-02 18:14:00.491274749 -0600
--- alpine-2.26.maildir/pith/conf.h	2022-06-02 18:14:52.263147802 -0600
***************
*** 265,270 ****
--- 265,274 ----
  #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
+ #ifndef _WINDOWS
+ #define VAR_MAILDIR_LOCATION	     vars[V_MAILDIR_LOCATION].current_val.p
+ #define GLO_MAILDIR_LOCATION	     vars[V_MAILDIR_LOCATION].global_val.p
+ #endif
  #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 alpine-2.26/pith/conftype.h alpine-2.26.maildir/pith/conftype.h
*** alpine-2.26/pith/conftype.h	2022-06-02 18:14:00.491274749 -0600
--- alpine-2.26.maildir/pith/conftype.h	2022-06-02 18:14:52.275147774 -0600
***************
*** 118,123 ****
--- 118,126 ----
  		, V_NEWSRC_PATH
  		, V_NEWS_ACTIVE_PATH
  		, V_NEWS_SPOOL_DIR
+ #ifndef _WINDOWS
+ 		, V_MAILDIR_LOCATION
+ #endif
  		, V_UPLOAD_CMD
  		, V_UPLOAD_CMD_PREFIX
  		, V_DOWNLOAD_CMD
***************
*** 410,415 ****
--- 413,421 ----
  	F_PASS_C1_CONTROL_CHARS,
  	F_SINGLE_FOLDER_LIST,
  	F_VERTICAL_FOLDER_LIST,
+ #ifndef _WINDOWS
+ 	F_COURIER_FOLDER_LIST,
+ #endif
  	F_TAB_CHK_RECENT,
  	F_AUTO_REPLY_TO,
  	F_VERBOSE_POST,
diff -rc alpine-2.26/pith/headers.h alpine-2.26.maildir/pith/headers.h
*** alpine-2.26/pith/headers.h	2022-06-02 18:14:00.495274738 -0600
--- alpine-2.26.maildir/pith/headers.h	2022-06-02 18:14:52.275147774 -0600
***************
*** 32,37 ****
--- 32,38 ----
  #include "../c-client/utf8.h"	/* for CHARSET and such*/
  #include "../c-client/imap4r1.h"
  #include "../c-client/http.h"	/* for http support */
+ #include "../c-client/maildir.h"
  
  /* include osdep protos and def'ns */
  #include "osdep/bldpath.h"
diff -rc alpine-2.26/pith/init.c alpine-2.26.maildir/pith/init.c
*** alpine-2.26/pith/init.c	2022-06-02 18:14:00.491274749 -0600
--- alpine-2.26.maildir/pith/init.c	2022-06-02 18:14:52.283147754 -0600
***************
*** 404,409 ****
--- 404,412 ----
             && stricmp(filename, folder_base)){
  #else
          if(strncmp(filename, folder_base, folder_base_len) == 0
+ #ifndef _WINDOWS
+ 	   && filename[folder_base_len] != list_cntxt->dir->delim
+ #endif
             && strcmp(filename, folder_base)){
  #endif
  #endif
diff -rc alpine-2.26/pith/pattern.c alpine-2.26.maildir/pith/pattern.c
*** alpine-2.26/pith/pattern.c	2022-06-02 18:14:00.491274749 -0600
--- alpine-2.26.maildir/pith/pattern.c	2022-06-02 18:14:52.291147734 -0600
***************
*** 46,52 ****
  #include "../pith/icache.h"
  #include "../pith/ablookup.h"
  #include "../pith/keyword.h"
! 
  
  /*
   * Internal prototypes
--- 46,54 ----
  #include "../pith/icache.h"
  #include "../pith/ablookup.h"
  #include "../pith/keyword.h"
! #ifndef _WINDOWS
! int maildir_file_path(char *name, char *tmp, size_t sizeoftmp);
! #endif /* _WINDOWS */
  
  /*
   * Internal prototypes
***************
*** 5485,5490 ****
--- 5487,5501 ----
  		break;
  	      
  	      case '#':
+ #ifndef _WINDOWS
+ 		if(!struncmp(patfolder, "#md/", 4)
+ 		       || !struncmp(patfolder, "#mc/", 4)){
+ 		  maildir_file_path(patfolder, tmp1, sizeof(tmp1));
+ 		  if(!strcmp(tmp1, stream->mailbox))
+ 		     match++;
+ 		  break;
+ 		}
+ #endif
  	        if(!strcmp(patfolder, stream->mailbox))
  		  match++;
  
***************
*** 7905,7911 ****
      int           we_cancel = 0, width;
      CONTEXT_S	 *save_context = NULL;
      char	  buf[MAX_SCREEN_COLS+1], sbuf[MAX_SCREEN_COLS+1];
!     char         *save_ref = NULL;
  #define	FILTMSG_MAX	30
  
      if(!stream)
--- 7916,7922 ----
      int           we_cancel = 0, width;
      CONTEXT_S	 *save_context = NULL;
      char	  buf[MAX_SCREEN_COLS+1], sbuf[MAX_SCREEN_COLS+1];
!     char         *save_ref = NULL, *save_dstfldr = NULL, *save_dstfldr2 = NULL;
  #define	FILTMSG_MAX	30
  
      if(!stream)
***************
*** 7939,7944 ****
--- 7950,7965 ----
      if(F_OFF(F_QUELL_FILTER_MSGS, ps_global))
        we_cancel = busy_cue(buf, NULL, 0);
  
+ #ifndef _WINDOWS
+     if(!struncmp(dstfldr, "#md/", 4) || !struncmp(dstfldr, "#mc/", 4)){  
+ 	char tmp1[MAILTMPLEN];
+ 	maildir_file_path(dstfldr, tmp1, sizeof(tmp1));
+ 	save_dstfldr2 = dstfldr;
+ 	save_dstfldr = cpystr(tmp1);
+ 	dstfldr = save_dstfldr;
+    }
+ #endif
+ 
      if(!is_absolute_path(dstfldr)
         && !(save_context = default_save_context(ps_global->context_list)))
        save_context = ps_global->context_list;
***************
*** 8002,8007 ****
--- 8023,8033 ----
      if(we_cancel)
        cancel_busy_cue(buf[0] ? 0 : -1);
  
+     if(save_dstfldr){
+ 	fs_give((void **)&save_dstfldr);
+ 	dstfldr = save_dstfldr2;
+     }
+ 
      return(buf[0] != '\0');
  }
  
diff -rc alpine-2.26/pith/pine.hlp alpine-2.26.maildir/pith/pine.hlp
*** alpine-2.26/pith/pine.hlp	2022-06-02 18:14:00.491274749 -0600
--- alpine-2.26.maildir/pith/pine.hlp	2022-06-02 18:14:52.299147715 -0600
***************
*** 23793,23798 ****
--- 23793,23894 ----
  &lt;End of help on this topic&gt;
  </BODY>
  </HTML>
+ ====== h_config_maildir_location ======
+ <HTML>
+ <HEAD>
+ <TITLE>OPTION: <!--#echo var="VAR_maildir-location"--></TITLE>
+ </HEAD>
+ <BODY>
+ <H1>OPTION: <!--#echo var="VAR_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. This
+ version also has <A HREF="h_config_courier_list">support</A> for the 
+ Courier style file system when a maildir collection is accessed locally.
+ 
+ <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 Alpine 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"><!--#echo var="VAR_maildir-location"--></A> configuration 
+ variable. Most of the time you will not have to worry about the 
+ <!--#echo var="VAR_maildirlocation"--> 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 Alpine 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 path variable from &quot;mail/&quot; to 
+ &quot;#md/mail&quot;. In a maildir collection folders of any other format 
+ are ignored.
+ 
+ <P> Finally, This version also has 
+ <A HREF="h_config_courier_list">support</A> for the Courier style file system 
+ when a maildir collection is accessed locally.
+ 
+ <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>
***************
*** 31999,32004 ****
--- 32095,32143 ----
  <P>
  &lt;End of help on this topic&gt;
  </BODY>
+ </HTML>
+ ====== h_config_courier_list =====
+ <HTML>
+ <HEAD>
+ <TITLE>FEATURE: <!--#echo var="FEAT_courier-folder-list"--></TITLE>
+ </HEAD>
+ <BODY>
+ <H1>FEATURE: <!--#echo var="FEAT_courier-folder-list"--></H1>
+ 
+ In a maildir collection, a folder could be used as a directory to store 
+ folders. In the Courier server if you create a folder, then a directory 
+ with the same name is created. If you use this patch to access a 
+ collection created by the Courier server, then the display of such 
+ collection will look confusing. The best way to access a maildir 
+ collection created by the Courier server is by using the &quot;#mc/&quot; 
+ prefix instead of the &quot;#md/&quot; prefix. If you use this alternate 
+ prefix, then this feature applies to you, otherwise you can safely ignore 
+ the text that follows.
+ <P>
+ Depending on if you have enabled the option 
+ <a href="h_config_separate_fold_dir_view"><!--#echo var="FEAT_separate-folder-and-directory-entries"--></a> 
+ a folder may be listed as &quot;folder[.]&quot;, or as two entries in the 
+ list by &quot;folder&quot; and &quot;folder.&quot;.
+ <P>
+ If this option is disabled, Pine will list local folders that are in Courier
+ style format, as &quot;folder&quot;, and those that are also directories as
+ &quot;folder[.]&quot;. This makes the default display cleaner.
+ <P>
+ If this feature is enabled then creating folders in a maildir collection
+ will create a directory with the same name. If this feature is disabled, then 
+ a folder is considered a directory only if it contains subfolders, so you can
+ not create a directory with the same name as an exisiting folder unless 
+ you create a subfolder of that folder first (e.g. if you have a folder
+ called &quot;foo&quot; simply add &quot;foo.bar&quot; directly. This will
+ create the directory &quot;foo&quot; and the subfolder &quot;bar&quot; of it).
+ <P>
+ Observe that this feature works only for maildir collections that are accessed
+ locally. If a collection is accessed remotely then this feature has no value,
+ as the report is created in a server, and Pine only reports what received
+ from the server in this case.
+ <P>
+ &lt;End of help on this topic&gt;
+ </BODY>
  </HTML>
  ====== h_config_verbose_post =====
  <HTML>
diff -rc alpine-2.26/pith/send.c alpine-2.26.maildir/pith/send.c
*** alpine-2.26/pith/send.c	2022-06-02 18:14:00.491274749 -0600
--- alpine-2.26.maildir/pith/send.c	2022-06-02 18:14:52.303147704 -0600
***************
*** 43,48 ****
--- 43,51 ----
  
  #include "../c-client/smtp.h"
  #include "../c-client/nntp.h"
+ #ifndef _WINDOWS
+ int maildir_file_path(char *name, char *tmp, size_t sizeoftmp);
+ #endif /* _WINDOWS */
  
  
  /* this is used in pine_send and pine_simple_send */
***************
*** 246,251 ****
--- 249,261 ----
  
      if(exists & FEX_ISFILE){
  	context_apply(tmp, p_cntxt, mbox, sizeof(tmp));
+ #ifndef _WINDOWS
+         if (!struncmp(tmp, "#md/",4) || !struncmp(tmp, "#mc/", 4)){
+ 	    char tmp2[MAILTMPLEN];
+ 	    maildir_file_path(tmp, tmp2, sizeof(tmp2));
+ 	    strcpy(tmp, tmp2);
+ 	}
+ #endif
  	if(!(IS_REMOTE(tmp) || is_absolute_path(tmp))){
  	    /*
  	     * The mbox is relative to the home directory.
diff -rc alpine-2.26/README.maildir alpine-2.26.maildir/README.maildir
*** alpine-2.26/README.maildir	2022-06-02 18:14:52.327147646 -0600
--- alpine-2.26.maildir/README.maildir	2022-06-02 18:14:52.303147704 -0600
***************
*** 0 ****
--- 1,149 ----
+ ---------------------------------------
+ 
+ Maildir Driver for Alpine 2.0
+ By Eduardo Chappa 
+ <alpine.chappa@gmx.com>
+ 
+ ---------------------------------------
+ 1. General Information About This Patch
+ ---------------------------------------
+ 
+ This patch adds support for the maildir format to Alpine. We take the 
+ approach that this patch is one more driver among the number of formats 
+ supported by Alpine (more generally c-client). This approach differs from 
+ older versions of similar patches, in that once a maildir patch was 
+ applied, it was assumed that all your folders would be created in the 
+ maildir format. 
+ 
+ This patch does not assume that maildir is a preferred format, instead 
+ puts maildir in equal footing with other formats (mbox, mbx, mix, etc), 
+ and so a maildir folder in the mail/ collection is treated in the same way 
+ as any other folder in any other format. In other words, just by reading 
+ the name of a folder, or opening it, or doing any operation with it, you 
+ can not know in which format the folder is.
+ 
+ This implies that if you want to add a folder in the maildir format to the 
+ mail/ collection, then you must add by pressing "A" in the folder list 
+ collection and enter "#driver.md/mail/name_maildir_folder".
+ 
+ If you only want to use maildir, however, you can do so too. In this case, 
+ you must create a maildir collection. In that collection, only maildir 
+ folders will be listed. If there is any folder in any other format, that 
+ folder will be ignored. In another words, any folder listed there is in 
+ maildir format and can be accessed through that collection, conversely, 
+ any folder not listed there is not in maildir format and there is no way 
+ to access it using this collection.
+ 
+ In order to create a maildir collection, you could press M S L, and "A" to 
+ add a collection. Fill in the required fields as follows:
+ 
+ Nickname  : Anything
+ Server    :
+ Path      : #md/relative/path/to/maildir/collection/
+ View      :
+ 
+ For example, if "path" is set to "#md/mail/", then Alpine will look for your 
+ maildir folders that are in ~/mail/.
+ 
+ The code in this patch is mostly based in code for the unix driver plus 
+ some combinations of the mh, mbx and nntp drivers for the c-client 
+ library. Those drivers were designed by Mark Crispin, and bugs in this 
+ code are not his bugs, but my own.
+ 
+   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).
+ 
+ --------------
+ 2. Other Goals
+ --------------
+ 
+   It is intended that this code will work well with any application 
+ written using the c-client library. Of paramount importance is to make the 
+ associated imap server work well when the server accesses a folder in 
+ Maildir format. The program mailutil should also work flawlessly with this 
+ implemetation of the driver.
+ 
+   It is intended that this driver be fast and stable. We intend not to 
+ patch Alpine to make this driver do its work, unless such patching is for 
+ fixing bugs in Alpine or to pass parameters to the driver.
+ 
+ ------------------------------------------------------------------------ 
+ 3. What are the known bugs of this implementation of the Maildir driver? 
+ ------------------------------------------------------------------------
+ 
+   I don't know any at this time. There have been bugs before, though, but 
+ I try to fix bugs as soon as they are reported. 
+ 
+ ----------
+ 4. On UIDs
+ ----------
+ 
+  This patch keeps uids in the name of the file that contains the message, 
+ by adding a ",u=" string to the file name to save the uid of a message. A 
+ file is kept between sessions to save information on the last uid assigned 
+ and its time of validity. Only one session with writing access can write 
+ uids, all others must wait for the other session to assign them. The 
+ session assigning uids creates a ".uidtemp" file which other sessions must 
+ not disturb.
+ 
+   Uid support appeared in Alpine 1.00 (snapshot 925), and is experimental,
+ please report any problems.
+ 
+ ----------------------------------------------
+ 5. Configuring Alpine and Setting up a Maildir 
+ ----------------------------------------------
+ 
+ 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 Alpine where your Maildir inbox is, in case your system 
+       does 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.
+ 
+ -------------------------------------------
+ 6. What about Courier/Dovecot file systems?
+ -------------------------------------------
+ 
+ In a courier file system all folders are subfolders of a root folder 
+ called INBOX. Normally INBOX is located at ~/Maildir and subfolders are 
+ "dot" directories in ~/Maildir. For example ~/Maildir/.Trash is a 
+ subfolder of INBOX and is accessed with the nickname "INBOX.Trash".
+ 
+ You can not access folders in this way unless you preceed them with the 
+ string "#mc/". The purpose of the string "#mc/" is to warn Alpine that a 
+ collection in the Courier format is going to be accessed. Therefore, you 
+ can SELECT a folder like "#mc/INBOX.Trash", but not "INBOX.Trash"
+ 
+ You can access a collection through a server, but if you want to access a 
+ collection of folders created using the Courier server, you MUST edit your
+ ".pinerc" file and enter the definition of the collection as follows:
+ 
+ folder-collections="Anything you want" #mc/INBOX.[]
+ 
+ You can replace the string "#mc/INBOX." by something different, for example
+ "#mc/Courier/." will make Alpine search for your collection in ~/Courier.
+ 
+ You can not add this setting directly into Alpine because Alpine fails to 
+ accept this value from its input, but it takes it correctly when it is 
+ added through the ".pinerc" file.
+ 
+ You can access your inbox as "#mc/INBOX" or "#md/INBOX". Both definitions 
+ point to the same place.
+ 
+ Last Updated May 28, 2011