Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 18893 Details for
Bug 28877
pine-maildir update request
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Update of line numbers in pine-maildir-4.56
pine-maildir-4.58 (text/plain), 45.29 KB, created by
Anders Hellgren
on 2003-10-07 01:52:54 UTC
(
hide
)
Description:
Update of line numbers in pine-maildir-4.56
Filename:
MIME Type:
Creator:
Anders Hellgren
Created:
2003-10-07 01:52:54 UTC
Size:
45.29 KB
patch
obsolete
>diff -Nur pine4.50/README.maildir pine4.50-maildir/README.maildir >--- pine4.50/README.maildir Thu Jan 1 01:00:00 1970 >+++ pine4.50-maildir/README.maildir Tue Dec 3 11:28:13 2002 >@@ -0,0 +1,93 @@ >+Pine 4.0x Maildir c-client module >+--------------------------------- >+ >+Written by Mattias Larsson <ml@techno.org> <mta@freeit.com> >+ >+This is the second release of my Maildir driver for Pine 4. It is based >+on Eric Greens IMAP2bis Maildir driver. >+ >+PLEASE NOTE that this driver has only been tested in the IMAP4rev1 daemon >+before. It was just put into Pine 4.00, and it looks like it works, but it >+has not been extensively tested. It has been running for 8 months in >+production in our IMAP4 daemon though. >+ >+PLEASE NOTE: >+ >+This driver needs to store the UID's of the message in the file somehow. In >+the earlier versions of this driver this was done by adding a new maildir >+flag (the ,3 flag), however, this solution was not very good since most >+other clients could not handle it. Thus I had to find another solution. In >+this driver I use a pretty radical method. Any file in the maildir with the >+execute bit set has its UID set in the mtime of the file. So you should not >+edit the files in here, or in any otherway update the mtime, because then >+the UID gets changed. Most clients should not do this, so I think this >+solution is compatible with most other clients (if you find one that isn't, >+let me know). If you for some reason have to edit a file in the Maildir, >+delete the ".uidvalidity" file in the root of the Maildir (ie, the dir where >+you find cur/ new/ and tmp/). Alternatively, edit maildir.c and define the >+NO_UID_VALIDITY option, which will cause the Maildir to get set new UID's on >+every start up. Note that if you are running IMAP and Netscape as a client, >+you can't change the UID's, because Netscape do not support the UID validity >+flag in the IMAP protocol. So use this with care. >+ >+Please edit the maildir.c file in any case. There are 3 options you can >+set yourself. The default configuration is not suitable for ISPs. If you are >+an ISP, or system with many users, you might want to consider setting some >+of the options different. >+ >+Ohh, if there are problems compiling it, let me know, and please let me know >+what you did to fix it. This thing was developed on Solaris (using both GCC >+and SunCC, should work with both), but I haven't tried it on any other >+platform. It is also known to compile cleanly on Linux RH5.1 >+ >+CONFIGURATION >+------------- >+ >+There are a few configurable options. You find these at the top of the >+maildir.c file (and it can be found in imap/src/osdep/unix if I'm not all >+mistaken). Right now, two options are configurable. By default it is >+configured for ISP use, something that you might want to change if you use >+it at home. >+ >+HOW TO USE >+---------- >+ >+Use it as any other c-client driver. There is some option you want to change >+if you want all folders to be created as Maildirs (and I can't remember what >+the option is from the top of my head). Read the pine documentation. >+ >+CHANGES >+------- >+ >+Rel 4. Coredump problem fixed. In release 3 I decided to user the sparep >+ in the message cache so no patching of mail.h would be necessary, >+ however, PINE uses this pointer internally for other things, causing >+ coredumps when used with the Rel 3. patch. >+ >+Rel 3. New way of storing UID's (compatible with ,2 clients). >+ Multiple inbox patches applied >+ >+Rel 2. Pine 4 changes. >+ >+Rel 1. Imap4rev 1 driver >+ >+FINAL NOTES >+----------- >+ >+I'll try to maintain and release new versions as soon as I have time over, >+which unfortunately does not happen very often in this business ;) >+ >+You can (might) find newer versions of this driver at: >+ >+http://www.freeit.com/mta/ >+ >+ >+Regards, >+Daniel Mattias Larsson >+ >+e-mail: ml@techno.org >+ph: +46-707-268785 >+snail-mail: >+Industrivagen 4 >+SE-194 77 Upplands Vasby >+SWEDEN >diff -Nur pine4.53/imap/src/c-client/mail.h pine4.50-maildir/imap/src/c-client/mail.h >--- pine4.53/imap/src/c-client/mail.h Tue Oct 29 02:10:29 2002 >+++ pine4.50-maildir/imap/src/c-client/mail.h Tue Dec 3 11:28:13 2002 >@@ -755,6 +755,7 @@ > unsigned int spare7 : 1; /* seventh spare bit */ > unsigned int spare8 : 1; /* eighth spare bit */ > void *sparep; /* spare pointer */ >+ void *maildirp; /* for the Maildir driver */ > unsigned long user_flags; /* user-assignable flags */ > } MESSAGECACHE; > >diff -Nur pine4.53/imap/src/osdep/unix/Makefile pine4.50-maildir/imap/src/osdep/unix/Makefile >--- pine4.53/imap/src/osdep/unix/Makefile Tue Oct 15 02:44:49 2002 >+++ pine4.50-maildir/imap/src/osdep/unix/Makefile Tue Dec 3 11:28:13 2002 >@@ -21,7 +21,7 @@ > # Command line build parameters > > EXTRAAUTHENTICATORS= >-EXTRADRIVERS=mbox >+EXTRADRIVERS=maildir mbox > PASSWDTYPE=std > SSLTYPE=nopwd > >@@ -106,7 +106,7 @@ > # Standard distribution build parameters > > DEFAULTAUTHENTICATORS=md5 pla log >-DEFAULTDRIVERS=imap nntp pop3 mh mx mbx tenex mtx mmdf unix news phile >+DEFAULTDRIVERS=maildir imap nntp pop3 mh mx mbx tenex mtx mmdf unix news phile > > > # Normally no need to change any of these >@@ -115,7 +115,7 @@ > BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o siglocal.o \ > dummy.o pseudo.o netmsg.o flstring.o fdstring.o \ > rfc822.o nntp.o smtp.o imap4r1.o pop3.o \ >- unix.o mbox.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o >+ unix.o mbox.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o maildir.o > CFLAGS=-g > > CAT=cat >@@ -809,7 +809,7 @@ > tenex.o: mail.h misc.h osdep.h tenex.h dummy.h > unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h > utf8.o: mail.h misc.h osdep.h utf8.h >- >+maildir.o: mail.h misc.h osdep.h maildir.h dummy.h > > # OS-dependent > >diff -Nur pine4.53/imap/src/osdep/unix/dummy.c pine4.50-maildir/imap/src/osdep/unix/dummy.c >--- pine4.53/imap/src/osdep/unix/dummy.c Fri May 10 23:17:42 2002 >+++ pine4.50-maildir/imap/src/osdep/unix/dummy.c Tue Dec 3 11:28:13 2002 >@@ -345,13 +345,17 @@ > char tmp[MAILTMPLEN]; > /* don't \NoSelect dir if it has a driver */ > if ((attributes & LATT_NOSELECT) && (d = mail_valid (NIL,name,NIL)) && >- (d != &dummydriver)) attributes &= ~LATT_NOSELECT; >+ (d != &dummydriver)) { >+ attributes &= ~LATT_NOSELECT; >+ attributes |= LATT_NOINFERIORS; >+ } > if (!contents || /* notify main program */ > (!(attributes & LATT_NOSELECT) && (csiz = strlen (contents)) && > !stat (dummy_file (tmp,name),&sbuf) && (csiz <= sbuf.st_size) && > SAFE_SCAN_CONTENTS (d,tmp,contents,csiz,sbuf.st_size))) > mm_list (stream,delimiter,name,attributes); >- return T; >+ if (attributes & LATT_NOINFERIORS) return NIL; >+ else return T; > } > > /* Dummy create mailbox >diff -Nur pine4.53/imap/src/osdep/unix/maildir.c pine4.50-maildir/imap/src/osdep/unix/maildir.c >--- pine4.53/imap/src/osdep/unix/maildir.c Thu Jan 1 01:00:00 1970 >+++ pine4.50-maildir/imap/src/osdep/unix/maildir.c Tue Dec 3 11:28:13 2002 >@@ -0,0 +1,1143 @@ >+/* >+ * Maildir Module for PINE 4.0x - fourth release, use with CARE! >+ * >+ * Author: Mattias Larsson <ml@techno.org> >+ * >+ * Version: 21.07.98 >+ * >+ * Please read the README.maildir file before using this module! >+ * >+ * If you have any questions, please e-mail ml@techno.org >+ * >+ * Multiple inboxes patch by Dean Gaudet <dgaudet@arctic.org> >+ * >+ * ================================================= >+ * >+ * Based on the IMAP2 maildir routines by: >+ * >+ * Author: Eric Green >+ * Bloodhounds International Inc. >+ * thrytis@imaxx.net >+ * >+ * Additional contributions from: >+ * Aidas Kasparas (kaspar@soften.ktu.lt) >+ * >+ * Date: 27 April 1997 >+ * Last Edited: 13 June 1997 >+ * >+ * Based (heavily) on mh.c and other c-client library files by Mark Crispin: >+ * >+ * Mark Crispin >+ * Networks and Distributed Computing >+ * Computing & Communications >+ * University of Washington >+ * Administration Building, AG-44 >+ * Seattle, WA 98195 >+ * Internet: MRC@CAC.Washington.EDU >+ * >+ * Copyright 1995 by the University of Washington >+ * >+ * Permission to use, copy, modify, and distribute this software and its >+ * documentation for any purpose and without fee is hereby granted, provided >+ * that the above copyright notice appears in all copies and that both the >+ * above copyright notice and this permission notice appear in supporting >+ * documentation, and that the name of the University of Washington not be >+ * used in advertising or publicity pertaining to distribution of the software >+ * without specific, written prior permission. This software is made >+ * available "as is", and >+ * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, >+ * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN >+ * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL, >+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM >+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT >+ * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION >+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. >+ * >+ */ >+ >+/* CONFIGURABLE OPTIONS - PLEASE CHECK THESE OUT */ >+ >+#define NO_MAILDIR_FIDDLE /* disallow Maildir with Maildir in the >+ name. This is useful in an ISP setup >+ using the IMAP daemon. #undef it if you >+ are running a normal pine and know what >+ you are doing */ >+ >+#define NO_ABSOLUTE_PATHS /* if you define this, all paths >+ use your HOMEDIR is the root instead >+ of the actual root of the machine. This >+ is also useful in an ISP setup with >+ IMAP */ >+ >+#undef NO_UID_VALIDITIY /* define this if you want the UID's not >+ to be persistent over sessions. Use this >+ if you use another client to read the >+ maildir that screws up the special way >+ in which we store UIDs. Do not enable >+ unless you are sure you need it. */ >+ >+/* END CONFIGURATION */ >+ >+#define MTA_DEBUG /* debugging sent to stdout */ >+#undef MTA_DEBUG >+ >+#include <stdio.h> >+#include <ctype.h> >+#include <errno.h> >+extern int errno; /* just in case */ >+#include "mail.h" >+#include "osdep.h" >+#include <pwd.h> >+#include <sys/stat.h> >+#include <sys/time.h> >+#include <sys/types.h> >+#include <utime.h> >+#include "maildir.h" >+#include "misc.h" >+#include "dummy.h" >+ >+/* Driver dispatch used by MAIL */ >+ >+DRIVER maildirdriver = { >+ "maildir", /* driver name */ >+ /* driver flags */ >+ DR_MAIL|DR_LOCAL|DR_NOFAST|DR_NAMESPACE, >+ (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 */ >+ NIL, /* 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 envelopes */ >+ maildir_fetchheader, /* fetch message header */ >+ maildir_fetchtext, /* 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 */ >+ maildir_gc /* garbage collect stream */ >+}; >+ >+ /* prototype stream */ >+MAILSTREAM maildirproto = {&maildirdriver}; >+ >+/* Check validity of mailbox >+ */ >+ >+DRIVER *maildir_valid (char *name) >+{ >+ return maildir_isvalid(name,T) ? &maildirdriver : NIL; >+} >+ >+int maildir_isvalid (char *name,long justname) >+{ >+ char tmp[MAILTMPLEN]; >+ struct stat sbuf; >+ >+ if (!name || (!*name) || >+ ((*name == '#') && >+ (*(name+1) == 0 || >+ (*(name+1) != 'm' && *(name+1) != 'M') || >+ (*(name+2) != 'd' && *(name+1) != 'D') || >+ *(name+3) != '/')) || (*name == '.')) >+ return NIL; >+ >+ /* okay, anything containing the name Maildir will be ignored >+ this is to prevent anyone from fiddling with their incoming Maildir >+ directly, it should be accessed via the INBOX alias */ >+ >+ #ifdef NO_MAILDIR_FIDDLE >+ if (strstr(name, ".maildir")) { >+ return NIL; >+ } >+ #endif >+ /* If we are requested only to check >+ if the name is appropriate then we >+ have done! */ >+ if (justname && *name == '#') return T; >+ >+ >+ /* must be valid local mailbox */ >+ if ((*name != '*') && (*name != '{') && >+ maildir_file (tmp,name) && >+ /* assume its maildir if its a dir */ >+ stat (tmp,&sbuf) == 0 && S_ISDIR (sbuf.st_mode)) >+ return T; >+ >+ /* INBOX is for default Maildir */ >+ if (!strcmp (ucase (strcpy (tmp,name)), "INBOX") && >+ (stat (maildir_file (tmp,name),&sbuf) == 0) && >+ S_ISDIR (sbuf.st_mode)) >+ return T; >+ >+ return NIL; >+} >+ >+/* Maildir mail generate file string >+ */ >+ >+char *maildir_file (char *dst,char *name) >+{ >+ char tmp[MAILTMPLEN]; >+ >+ if (strlen (name) > 3 && /* safe do other comparisons */ >+ (*name == '#') && >+ (name[1] == 'm' || name[1] == 'M') && >+ (name[2] == 'd' || name[2] == 'D') && >+ (name[3] == '/')) >+ name += 4; >+ >+#ifdef NO_ABSOLUTE_PATHS >+ if (*name == '/') { >+ /* we do not want to accept / absolute paths, so lets strip the first >+ / ... */ >+ sprintf(dst,"%s/%s/cur", myhomedir(), name+1); >+ >+/* strncpy (dst, name, MAILTMPLEN - 2); >+ strncat (dst, "/cur", MAILTMPLEN - 2); >+ dst[MAILTMPLEN - 1] = '\0'; */ >+ } >+ else >+ sprintf (dst,"%s/%s/cur",myhomedir (), >+ strcmp (ucase (strcpy (tmp, name)), "INBOX") ? name : MAILDIRPATH); >+#else >+ if (*name == '/') { >+ strncpy (dst, name, MAILTMPLEN - 2); >+ strncat (dst, "/cur", MAILTMPLEN - 2); >+ dst[MAILTMPLEN - 1] = '\0'; >+ } >+ else >+ sprintf (dst,"%s/%s/cur",myhomedir (), >+ strcmp (ucase (strcpy (tmp, name)), "INBOX") ? name : MAILDIRPATH); >+ >+#endif >+ >+ #ifdef MTA_DEBUG >+ printf("maildir_file '%s'\n", dst); >+ #endif >+ return dst; >+} >+ >+/* Maildir open >+ */ >+ >+MAILSTREAM *maildir_open (MAILSTREAM *stream) >+{ >+ char tmp[MAILTMPLEN],tmp2[MAILTMPLEN]; >+ >+ if (!stream) return &maildirproto; >+ if (LOCAL) { /* recycle stream */ >+ maildir_close (stream, 0); >+ stream->dtb = &maildirdriver; >+ mail_free_cache (stream); >+ stream->uid_last = 0; /* default UID validity */ >+ stream->uid_validity = time (0); >+ } >+ >+ stream->uid_validity = 0; /* was time(0) */ >+ >+ if (stream->uid_last < time(0)) >+ stream->uid_last = time (0); >+ >+ stream->local = fs_get (sizeof (MAILDIRLOCAL)); >+ LOCAL->inbox = !strcmp (ucase (strcpy (tmp,stream->mailbox)),"INBOX") || >+ !strcmp (stream->mailbox,maildir_file (tmp2,"INBOX")); >+ LOCAL->dir = cpystr (maildir_file (tmp,stream->mailbox)); /* copy dir name */ >+ /* make temporary buffer */ >+ LOCAL->buf = (char *) fs_get ((LOCAL->buflen = MAXMESSAGESIZE) + 1); >+ LOCAL->scantime = 0; /* not scanned yet */ >+ stream->sequence++; >+ stream->nmsgs = stream->recent = 0; >+ >+ maildir_ping_core (stream); >+ maildir_ping (stream); >+/* if (maildir_ping (stream) && !(stream->nmsgs || stream->silent)) >+ printf("Mailbox is empty\n"); >+*/ >+ return stream; >+ >+} >+ >+/* Maildir ping mailbox >+ */ >+ >+long maildir_ping_core (MAILSTREAM *stream) >+{ >+ char tmp[MAILTMPLEN]; >+ MESSAGECACHE *elt; >+ struct stat sbuf, sbuf2; >+ DIR *dir; >+ struct direct *d; >+ int reloadall = NIL; >+ int uidinvalid = NIL; >+ unsigned long old; >+ long i; >+ long nmsgs = stream->nmsgs; >+ long recent = stream->recent; >+ long nfiles = stream->nmsgs; >+ int silent = stream->silent; >+ char *s, *s2; >+ mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL); >+ >+/* maildir_copynew (LOCAL->dir); >+ */ >+ >+ if (stat (LOCAL->dir,&sbuf) < 0) { >+ sprintf (tmp,"Unable to open maildir: %s",strerror (errno)); >+ mm_log (tmp,ERROR); >+ return NIL; >+ } >+ >+ /* okay, lets try to figure out the Maildir UID validity. This is done >+ by checking the last modification time of the file .uidvalidity >+ in the rootdir of the Maildir. Any program reordering the files >+ in the directory have to touch this file */ >+ >+ sprintf(tmp, "%s/../.uidvalidity", LOCAL->dir); >+ >+ if (stat (tmp,&sbuf2) < 0) { >+ /* no uid validity file found, if uid_validity == 0, we have >+ to set it to something other than 0, and then create the >+ .uidvalidity file for future accesses */ >+ >+ if (stream->uid_validity == 0) { >+ FILE *fl; >+ struct utimbuf tbuf; >+ >+ stream->uid_validity = time(0); >+ tbuf.actime = stream->uid_validity; >+ tbuf.modtime = stream->uid_validity; >+ >+ if ((fl = fopen(tmp, "w"))) { >+ fclose(fl); >+ chmod (tmp, S_IRUSR|S_IWUSR); >+ utime(tmp, &tbuf); >+ } >+ } >+ uidinvalid = T; /* UID's are invalid, update them */ >+ } else { >+ /* valid file, lets set UID if uid_validity = 0 */ >+ if (stream->uid_validity == 0) { >+ stream->uid_validity = sbuf2.st_mtime; >+ } >+ } >+ >+ #ifdef NO_UID_VALIDITY >+ uidinvalid = T; /* force the UIDs to be invalid and reset every time, >+ useful in an environment without imap servers and >+ clients that screw up the UIDs.. i'd leave it to >+ OFF until I really need it though... */ >+ #endif >+ >+ stream->silent = T; >+ if (sbuf.st_ctime != LOCAL->scantime) { >+ /* update the message list */ >+ struct direct **names = NIL; >+ nfiles = scandir (LOCAL->dir,&names,maildir_select,maildir_namesort); >+ >+ for (i = 0; i < nfiles; i++) { >+ >+ /* check if file has executable bit set */ >+ sprintf(tmp, "%s/%s", LOCAL->dir, names[i]->d_name); >+ stat (tmp,&sbuf2); >+ if (sbuf2.st_mode & S_IXUSR) { >+ /* executable bit set, modtime is uid */ >+ if (sbuf2.st_mtime > stream->uid_last) >+ stream->uid_last = sbuf2.st_mtime+1; >+ } >+ /* this is kept for backwards compatibility */ >+ if ((s = strstr (names[i]->d_name,":3,"))) >+ s += 3; >+ if (s && (s2 = strstr (s, ",U"))) { >+ s2 += 2; >+ sscanf(s2, "%d", &old); >+ if (old > stream->uid_last) { >+ stream->uid_last = old+1; >+ } >+ } >+ >+ } >+ >+ mm_critical (stream); /* go critical */ >+ old = stream->uid_last; >+ LOCAL->scantime = sbuf.st_ctime; >+ >+ /* check if old files same */ >+ for (i = 0; i < stream->nmsgs; i++) { >+ >+ if (strcmp ((char *) mail_elt (stream, i + 1)->maildirp, >+ names[i]->d_name)) { >+ reloadall = T; >+ break; >+ } >+ } >+ >+ if (reloadall) { /* files are out of order, rebuild cache */ >+ >+ i = 1; >+ while (i <= stream->nmsgs) >+ /* clean out cache */ >+ if ((elt = (MESSAGECACHE *) (*mc) (stream,i,CH_ELT))) { >+ fs_give ((void **) &elt->maildirp); >+ mail_expunged (stream,i); >+ } >+ else >+ i++; >+ >+ mm_log ("Warning: Mailbox has changed in an unexpected way. Reloading.", >+ WARN); >+ stream->nmsgs = 0; >+ } >+ nmsgs = stream->nmsgs; >+ >+ stream->nmsgs = nfiles; /* hm? */ >+ >+ for (i = nmsgs; i < nfiles; i++) { >+ >+ mail_exists(stream, i+1); >+ /* if newly seen, add to list */ >+ (elt = mail_elt (stream, i + 1))->maildirp = (long) cpystr (names[i]->d_name); >+ elt->valid = T; >+ >+ /* grab the flags */ >+ if ((s = strstr (names[i]->d_name,":3,"))) { >+ s += 3; >+ if (strchr (s,'F')) >+ elt->flagged = T; >+ if (strchr (s,'R')) >+ elt->answered = T; >+ if (strchr (s,'S')) >+ elt->seen = T; >+ if (strchr (s,'T')) >+ elt->deleted = T; >+ } else if ((s = strstr (names[i]->d_name,":2,"))) { >+ /* this is the :2, id where all files go nowadays */ >+ s += 3; >+ if (strchr (s,'F')) >+ elt->flagged = T; >+ if (strchr (s,'R')) >+ elt->answered = T; >+ if (strchr (s,'S')) >+ elt->seen = T; >+ if (strchr (s,'T')) >+ elt->deleted = T; >+ sprintf(tmp, "%s/%s", LOCAL->dir, names[i]->d_name); >+ stat (tmp,&sbuf2); >+ if (sbuf2.st_mode & S_IXUSR) { >+ /* executable bit set, modtime is uid */ >+ elt->private.uid = sbuf2.st_mtime; >+ } >+ /* and if we could not retrieve UID from modtime, or if >+ UIDs are invalid, go here */ >+ if (elt->private.uid == 0 || uidinvalid) { >+ stream->uid_last = (elt = mail_elt (stream,i+1))->private.uid = stream->uid_last+1; >+ maildir_flagmsg(stream, elt); >+ } >+ s = 0; /* make sure next if statement does not trigger */ >+ } >+ >+ if (s) >+ if ((s2 = strstr (s, ",U"))) { >+ s2 += 2; >+ sscanf(s2, "%d", &elt->private.uid); >+ if (elt->private.uid == 0 || uidinvalid) { >+ stream->uid_last = (elt = mail_elt (stream,i+1))->private.uid = stream->uid_last+1; >+ maildir_flagmsg(stream, elt); >+ } >+ >+ } else { /* assign new UID */ >+ stream->uid_last = (elt = mail_elt (stream,i+1))->private.uid = stream->uid_last+1; >+ elt->recent = T; >+ recent++; >+ maildir_flagmsg(stream, elt); /* store the UID that we assigned to it */ >+ } >+ >+ >+ >+ } >+ >+ mm_nocritical (stream); /* release critical */ >+ /* free the names stuff */ >+ for (i = 0; i < nfiles; i++) >+ fs_give ((void **) &names[i]); >+ if (names) >+ fs_give ((void **) &names); >+ } >+ stream->silent = silent; >+ mail_exists(stream,nfiles); >+/* if (!reloadall) */ >+ mail_recent (stream,recent); >+ >+ return T; /* return that we are alive */ >+} >+ >+long maildir_ping (MAILSTREAM *stream) >+{ >+ maildir_copynew (LOCAL->dir); >+ return maildir_ping_core (stream); >+} >+ >+void maildir_copynew (const char *mailbox) >+{ >+ char tmp[MAILTMPLEN],file[MAILTMPLEN],newfile[MAILTMPLEN]; >+ DIR *dir; >+ struct dirent *d; >+ struct stat sbuf; >+ >+ sprintf (tmp,"%s/../new",mailbox); >+ if (!(dir = opendir (tmp))) >+ return; >+ >+ while (d = readdir (dir)) { >+ if (d->d_name[0] == '.') >+ continue; /* skip .files */ >+ >+ sprintf (file,"%s/%s",tmp,d->d_name); >+ /* make sure this is a normal file */ >+ if (stat (file,&sbuf) == 0 && S_ISREG (sbuf.st_mode)) { >+ >+ if (strstr (d->d_name,":3,")) /* this message already has flags */ >+ sprintf (newfile,"%s/%s",mailbox,d->d_name); >+ else >+ sprintf (newfile,"%s/%s:3,",mailbox,d->d_name); >+ >+ /* move the new mail to the cur dir */ >+ if (link (file,newfile) == -1) >+ mm_log("Unable to read new mail!",WARN); >+ else >+ unlink (file); >+ } >+ } >+ closedir (dir); >+} >+ >+int maildir_select (struct direct *name) >+{ >+ if (name->d_name[0] != '.') >+ return T; >+ >+ return NIL; >+} >+ >+int maildir_namesort (struct direct **d1,struct direct **d2) >+{ >+/* this maildir module is kind of lame and expects files it just moved >+ * from new/ to cur/ to show up at the end of the sorting... this mostly >+ * works fine when the timestamp is less than 1000000000 -- you can just >+ * strcmp. but when the timestamp went past that point we need to do >+ * this convoluted sort. >+ */ >+ unsigned long t1, t2; >+ >+ t1 = strtoul((*d1)->d_name, NULL, 10); >+ t2 = strtoul((*d2)->d_name, NULL, 10); >+ if (t1 == t2) { >+ return strcmp ((*d1)->d_name,(*d2)->d_name); >+ } >+ else if (t1 > t2) { >+ return 1; >+ } >+ return -1; >+} >+ >+ >+/* Maildir garbage collect stream >+ */ >+ >+void maildir_gc (MAILSTREAM *stream,long gcflags) >+{ >+ unsigned long i; >+ >+ if (gcflags & GC_TEXTS) { /* garbage collect texts? */ >+ /* flush texts from cache */ >+/* if (LOCAL->hdr) fs_give ((void **) &LOCAL->hdr); >+// if (stream->text) fs_give ((void **) &stream->text); >+// stream->msgno = 0; invalidate stream text >+*/ >+ } >+} >+ >+/* Maildir close >+ */ >+ >+void maildir_close (MAILSTREAM *stream, long options) >+{ >+ MESSAGECACHE *elt; >+ int i; >+ mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL); >+ >+/* CL_EXPUNGE OPTION SUPPORT HERE SOMEWHERE! */ >+ /* clean out the cached paths */ >+ for (i = 1; i <= stream->nmsgs; i++) >+ if ((elt = (MESSAGECACHE *) (*mc) (stream,i,CH_ELT)) && elt->maildirp) { >+ fs_give ((void **) &elt->maildirp); >+ elt->maildirp = 0; /* otherwise pine coredumps */ >+ } >+ >+ if (LOCAL) { /* only if a stream is open */ >+ if (LOCAL->dir) fs_give ((void **) &LOCAL->dir); >+ maildir_gc (stream,GC_TEXTS); /* free local cache */ >+ /* free local scratch buffer */ >+ if (LOCAL->buf) fs_give ((void **) &LOCAL->buf); >+ /* nuke the local data */ >+ fs_give ((void **) &stream->local); >+ stream->dtb = NIL; /* log out the DTB */ >+ } >+} >+ >+void maildir_check (MAILSTREAM *stream) >+{ >+ /* Perhaps in the future this will preserve flags */ >+ if (maildir_ping (stream)) mm_log ("Check completed",(long) NIL); >+} >+ >+long maildir_fetchtext (MAILSTREAM *stream,unsigned long msgno,STRING *bs, long flags) >+{ >+ unsigned long i; >+ MESSAGECACHE *elt; >+ /* UID call "impossible" */ >+ if (flags & FT_UID) return NIL; >+ elt = mail_elt (stream,msgno);/* get elt */ >+ /* snarf message if don't have it yet */ >+ if (!elt->private.msg.text.text.data) { >+ maildir_fetchheader (stream,msgno,&i,flags); >+ if (!elt->private.msg.text.text.data) return NIL; >+ } >+ if (!(flags & FT_PEEK)) { /* mark as seen */ >+ mail_elt (stream,msgno)->seen = T; >+ maildir_flagmsg (stream, mail_elt(stream,msgno)); >+ mm_flags (stream,msgno); >+ } >+ if (!elt->private.msg.text.text.data) return NIL; >+ INIT (bs,mail_string,elt->private.msg.text.text.data, >+ elt->private.msg.text.text.size); >+ return T; >+} >+ >+ >+/* Maildir fetch message header >+ */ >+ >+char *maildir_fetchheader (MAILSTREAM *stream,unsigned long msgno, >+ unsigned long *length, long flags) >+{ >+ unsigned long i,hdrsize; >+ int fd; >+ char *t; >+ char tmp[MAILTMPLEN]; >+ char *s,*b; >+ struct stat sbuf; >+ struct tm *tm; >+ MESSAGECACHE *elt; >+ *length = 0; /* default to empty */ >+ if (flags & FT_UID) return "";/* UID call "impossible" */ >+ elt = mail_elt (stream,msgno);/* get elt */ >+ if (!elt->private.msg.header.text.data) { >+ >+/* maildir_gc (stream,GC_TEXTS); invalidate current cache */ >+ /* build message file name */ >+ sprintf (tmp,"%s/%s",LOCAL->dir,(char *) elt->maildirp); >+ if ((fd = open (tmp,O_RDONLY,NIL)) >= 0) { >+ fstat (fd,&sbuf); /* get size of message */ >+ /* make plausible IMAPish date string */ >+ tm = gmtime (&sbuf.st_mtime); >+ elt->day = tm->tm_mday; elt->month = tm->tm_mon + 1; >+ elt->year = tm->tm_year + 1900 - BASEYEAR; >+ elt->hours = tm->tm_hour; elt->minutes = tm->tm_min; >+ elt->seconds = tm->tm_sec; >+ elt->zhours = 0; elt->zminutes = 0; >+ /* slurp message */ >+ read (fd,s = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size); >+ s[sbuf.st_size] = '\0'; /* tie off file */ >+ close (fd); /* close file */ >+ >+ for (i = 0,b = s; *b && !(i && (*b == '\n')); i = (*b++ == '\n')); >+ hdrsize = (*b ? ++b:b)-s; /* number of header bytes */ >+ >+ elt->rfc822_size = /* size of entire message in CRLF form */ >+ (elt->private.msg.header.text.size = >+ strcrlfcpy ((char **) &elt->private.msg.header.text.data,&i,s, >+ hdrsize)) + >+ (elt->private.msg.text.text.size = >+ strcrlfcpy ((char **) &elt->private.msg.text.text.data,&i,b, >+ sbuf.st_size - hdrsize)); >+ fs_give ((void **) &s); >+ } else return ""; >+ >+ } >+ >+ *length = elt->private.msg.header.text.size; >+ return (char *) elt->private.msg.header.text.data; >+} >+ >+void maildir_fast (MAILSTREAM *stream,char *sequence,long flags) >+{ >+ unsigned long i,j; >+ /* ugly and slow */ >+ if (stream && LOCAL && ((flags & FT_UID) ? >+ mail_uid_sequence (stream,sequence) : >+ mail_sequence (stream,sequence))) >+ for (i = 1; i <= stream->nmsgs; i++) >+ if (mail_elt (stream,i)->sequence) maildir_fetchheader (stream,i,&j,NIL); >+} >+ >+/* Maildir find list of subscribed mailboxes >+ * Accepts: mail stream >+ * pattern to search >+ */ >+ >+void maildir_list (MAILSTREAM *stream,char *ref, char *pat) >+{ >+ return; >+} >+ >+void *maildir_parameters (long function,void *value) >+{ >+ return NIL; >+} >+ >+long maildir_create (MAILSTREAM *stream,char *mailbox) >+{ >+ char tmp[MAILTMPLEN]; >+ char err[MAILTMPLEN]; >+ char *s, *s2; >+ int fnlen, i; >+ char *subdir_names[] = {"/cur","/new","/tmp",NULL}; >+ >+ /* must not already exist */ >+ if (access (maildir_file (tmp,mailbox),F_OK) == 0) { >+ sprintf (err,"Can't create mailbox %s: mailbox already exists",mailbox); >+ mm_log (err,ERROR); >+ return NIL; >+ } >+ >+ maildir_file (tmp,mailbox); /* get file name */ >+ fnlen = strlen (tmp); >+ /*syslog(LOG_INFO, "fname: '%s'", tmp);*/ >+ tmp[fnlen - 4] = '\0'; /* making main directory's name */ >+ fnlen -= 4; >+ >+ /* okay, try to add support for adding hiearchys of directories, this >+ is done by scanning for /'s.... */ >+ >+ /*syslog(LOG_INFO, "tmp '%s'", tmp);*/ >+ s = tmp; >+ >+ while ((s = strstr(s, "/")) != 0) { >+ /*syslog(LOG_INFO, "Before make: '%s'", s);*/ >+ *s = '\0'; >+ /*syslog(LOG_INFO, "Trying to make: '%s'", tmp);*/ >+ if (mkdir (tmp,0700) && *s != '\0') /* trying to make the dir */ >+ if (errno != EEXIST) { >+ sprintf (err,"Can't create mailbox %s: %s %s", >+ mailbox,tmp,strerror (errno)); >+ mm_log (err,ERROR); >+ return NIL; >+ } >+ *s = '/'; >+ s++; >+ } >+ >+ if (mkdir (tmp,0700)) { /* try to make new dir */ >+ sprintf (err,"Can't create mailbox %s: %s %s", >+ mailbox,tmp,strerror (errno)); >+ mm_log (err,ERROR); >+ return NIL; >+ } >+ >+ /*syslog(LOG_INFO, "create maildir");*/ >+ for (i = 0; subdir_names[i]; i++) { >+ strcpy (tmp + fnlen,subdir_names[i]); >+ >+ if (mkdir (tmp,0700)) { /* try to make new dir */ >+ sprintf (err,"Can't create mailbox %s: %s %s", >+ mailbox,tmp,strerror (errno)); >+ mm_log (err,ERROR); >+ return NIL; >+ } >+ } >+ >+ return T; /* return success */ >+} >+ >+void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt) >+{ >+ char oldfile[MAILTMPLEN],newfile[MAILTMPLEN],fn[MAILTMPLEN]; >+ struct utimbuf tbuf; >+ char *s; >+ >+ /* build the new filename */ >+ sprintf (oldfile,"%s/%s",LOCAL->dir,(char *) elt->maildirp); >+ if ((s = strchr ((char *) elt->maildirp,':'))) *s = '\0'; >+ sprintf (fn,"%s:2,%s%s%s%s",(char *) elt->maildirp,elt->flagged ? "F" : "", >+ elt->answered ? "R" : "",elt->seen ? "S" : "", >+ elt->deleted ? "T" : ""); >+ sprintf (newfile,"%s/%s",LOCAL->dir,fn); >+ /* rename the file with new flags */ >+ if (rename (oldfile,newfile) < 0) { >+ sprintf(oldfile,"Unable to write flags to disk: %s",strerror (errno)); >+ mm_log(oldfile,ERROR); >+ return; >+ } >+ /* update the file name in cache */ >+ fs_give ((void **) &elt->maildirp); >+ elt->maildirp = (long) cpystr (fn); >+ >+ /* fix the UID on the file */ >+ tbuf.actime = elt->private.uid; >+ tbuf.modtime = elt->private.uid; >+ chmod (newfile, S_IRUSR|S_IWUSR|S_IXUSR); >+ utime (newfile, &tbuf); >+ >+} >+ >+void maildir_expunge (MAILSTREAM *stream) >+{ >+ MESSAGECACHE *elt; >+ unsigned long i = 1; >+ unsigned long n = 0; >+ unsigned long recent = stream->recent; >+ >+ maildir_gc (stream,GC_TEXTS); /* invalidate texts */ >+ mm_critical (stream); /* go critical */ >+ while (i <= stream->nmsgs) { /* for each message */ >+ /* if deleted, need to trash it */ >+ if ((elt = mail_elt (stream,i))->deleted) { >+ sprintf (LOCAL->buf,"%s/%s",LOCAL->dir,(char *) elt->maildirp); >+ if (unlink (LOCAL->buf)) {/* try to delete the message */ >+ sprintf (LOCAL->buf,"Expunge of message %ld failed, aborted: %s",i, >+ strerror (errno)); >+ mm_log (LOCAL->buf,WARN); >+ break; >+ } >+ /* free the cached filename */ >+ if (elt->maildirp) { >+ fs_give ((void **) &elt->maildirp); >+ elt->maildirp = 0; /* otherwise pine coredumps */ >+ } >+ if (elt->recent) --recent;/* if recent, note one less recent message */ >+ mail_expunged (stream,i); /* notify upper levels */ >+ n++; /* count up one more expunged message */ >+ } >+ else i++; /* otherwise try next message */ >+ } >+ if (n) { /* output the news if any expunged */ >+ sprintf (LOCAL->buf,"Expunged %ld messages",n); >+ mm_log (LOCAL->buf,(long) NIL); >+ } >+ else mm_log ("No messages deleted, so no update needed",(long) NIL); >+ mm_nocritical (stream); /* release critical */ >+ /* notify upper level of new mailbox size */ >+ mail_exists (stream,stream->nmsgs); >+ mail_recent (stream,recent); >+} >+ >+/* dont forget to process options in here */ >+long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options) >+{ >+ STRING st; >+ MESSAGECACHE *elt; >+ struct stat sbuf; >+ int fd; >+ long i; >+ char *s,tmp[MAILTMPLEN]; >+ /* copy the messages */ >+ if ((options & CP_UID) ? mail_uid_sequence (stream, sequence) : >+ mail_sequence (stream,sequence)) >+ for (i = 1; i <= stream->nmsgs; i++) >+ if ((elt = mail_elt (stream,i))->sequence) { >+ sprintf (LOCAL->buf,"%s/%s",LOCAL->dir,(char *) elt->maildirp); >+ if ((fd = open (LOCAL->buf,O_RDONLY,NIL)) < 0) return NIL; >+ fstat (fd,&sbuf); /* get size of message */ >+ /* slurp message */ >+ read (fd,s = (char *) fs_get (sbuf.st_size +1),sbuf.st_size); >+ s[sbuf.st_size] = '\0'; /* tie off file */ >+ close (fd); /* flush message file */ >+ INIT (&st,mail_string,(void *) s,sbuf.st_size); >+ sprintf (LOCAL->buf,"%s%s%s%s%s)", >+ elt->seen ? " \\Seen" : "", >+ elt->deleted ? " \\Deleted" : "", >+ elt->flagged ? " \\Flagged" : "", >+ elt->answered ? " \\Answered" : "", >+ (elt->seen || elt->deleted || elt->flagged || elt->answered) ? >+ "" : " "); >+ LOCAL->buf[0] = '('; /* open list */ >+ mail_date (tmp,elt); /* generate internal date */ >+ if (!maildir_append (stream,mailbox,LOCAL->buf,tmp,&st)) { >+ fs_give ((void **) &s); /* give back temporary space */ >+ return NIL; >+ } >+ fs_give ((void **) &s); /* give back temporary space */ >+ } >+ return T; /* return success */ >+} >+ >+long maildir_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date, >+ STRING *message) >+{ >+ int fd; >+ char c,*s; >+ char tmp[MAILTMPLEN],file[MAILTMPLEN],path1[MAILTMPLEN],path2[MAILTMPLEN]; >+ MESSAGECACHE elt; >+ long i; >+ long size = 0; >+ long ret = LONGT; >+ short uf = 0; >+ >+ /* >+ This is intentionaly made static. Users can ask to save a LOT of messages >+ at once and this program can do that within one second. Dan's assumption >+ that time+pid+hostname always will be unique stops being true in this >+ case. So we will add yet another number to host part of message file's >+ name. Hostname is used only to make filename unique and Dan explicitly >+ says that "<...> Other than this [skipping filenames starting at dot] , >+ readers should not attempt to parse filenames. <...>". Therefore this >+ addition should be no problem. Am I right, Dan? --AK >+ */ >+ >+ static unsigned int transact = 0; >+ >+ if (flags) /* get flags if given */ >+ uf = maildir_getflags (user_flags (&maildirproto),flags); >+ >+/* if (date) { want to preserve date? >+ //syslog(LOG_INFO, "date: '%s'", date); >+ // yes, parse date into an elt >+ if (!mail_parse_date (&elt,date)) { >+ sprintf (tmp,"Bad date in append: %s",date); >+ mm_log (tmp,ERROR); >+ return NIL; >+ } >+ } */ >+ /* N.B.: can't use LOCAL->buf for tmp */ >+ /* make sure valid mailbox */ >+ if (!maildir_isvalid (mailbox, NIL)) { >+ sprintf (tmp,"Not a valid Maildir mailbox: %s",mailbox); >+ mm_log (tmp,ERROR); >+ return NIL; >+ } >+ /* build file name we will use */ >+ sprintf (file,"%u.%d.%09u.%s:3,%s%s%s%s", >+ time (0),getpid (),transact++,mylocalhost (), >+ uf&fFLAGGED ? "F" : "",uf&fANSWERED ? "R" : "", >+ uf&fSEEN ? "S" : "",uf&fDELETED ? "T" : ""); >+ /* build tmp file name */ >+ sprintf (path1,"%s/../tmp/%s",maildir_file (tmp,mailbox),file); >+ >+ if ((fd = open (path1,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) { >+ sprintf (tmp,"Can't open append mailbox: %s",strerror (errno)); >+ mm_log (tmp,ERROR); >+ return NIL; >+ } >+ i = SIZE (message); /* get size of message */ >+ s = (char *) fs_get (i + 1); /* get space for the data */ >+ /* copy the data w/o CR's */ >+ while (i--) if ((c = SNX (message)) != '\015') s[size++] = c; >+ mm_critical (stream); /* go critical */ >+ /* write the data */ >+ if ((write (fd,s,size) < 0) || fsync (fd)) { >+ unlink (path1); /* delete message */ >+ sprintf (tmp,"Message append failed: %s",strerror (errno)); >+ mm_log (tmp,ERROR); >+ ret = NIL; >+ } >+ /* build final filename to use */ >+ sprintf (path2,"%s/../new/%s",maildir_file (tmp,mailbox),file); >+ if (link (path1,path2) < 0) { >+ sprintf (tmp,"Message append failed: %s",strerror (errno)); >+ mm_log (tmp,ERROR); >+ ret = NIL; >+ } >+ unlink (path1); >+ >+ close (fd); /* close the file */ >+ mm_nocritical (stream); /* release critical */ >+ fs_give ((void **) &s); /* flush the buffer */ >+ return ret; >+} >+ >+short bezerk_getflags (MAILSTREAM *stream,char *flag) >+{ >+ char *t,tmp[MAILTMPLEN],err[MAILTMPLEN]; >+ short f = 0; >+ short i,j; >+ if (flag && *flag) { /* no-op if no flag string */ >+ /* check if a list and make sure valid */ >+ if ((i = (*flag == '(')) ^ (flag[strlen (flag)-1] == ')')) { >+ mm_log ("Bad flag list",ERROR); >+ return NIL; >+ } >+ /* copy the flag string w/o list construct */ >+ strncpy (tmp,flag+i,(j = strlen (flag) - (2*i))); >+ tmp[j] = '\0'; >+ t = ucase (tmp); /* uppercase only from now on */ >+ >+ while (t && *t) { /* parse the flags */ >+ if (*t == '\\') { /* system flag? */ >+ switch (*++t) { /* dispatch based on first character */ >+ case 'S': /* possible \Seen flag */ >+ if (t[1] == 'E' && t[2] == 'E' && t[3] == 'N') i = fSEEN; >+ t += 4; /* skip past flag name */ >+ break; >+ case 'D': /* possible \Deleted flag */ >+ if (t[1] == 'E' && t[2] == 'L' && t[3] == 'E' && t[4] == 'T' && >+ t[5] == 'E' && t[6] == 'D') i = fDELETED; >+ t += 7; /* skip past flag name */ >+ break; >+ case 'F': /* possible \Flagged flag */ >+ if (t[1] == 'L' && t[2] == 'A' && t[3] == 'G' && t[4] == 'G' && >+ t[5] == 'E' && t[6] == 'D') i = fFLAGGED; >+ t += 7; /* skip past flag name */ >+ break; >+ case 'A': /* possible \Answered flag */ >+ if (t[1] == 'N' && t[2] == 'S' && t[3] == 'W' && t[4] == 'E' && >+ t[5] == 'R' && t[6] == 'E' && t[7] == 'D') i = fANSWERED; >+ t += 8; /* skip past flag name */ >+ break; >+ default: /* unknown */ >+ i = 0; >+ break; >+ } >+ /* add flag to flags list */ >+ if (i && ((*t == '\0') || (*t++ == ' '))) f |= i; >+ } >+ else { /* no user flags yet */ >+ t = strtok (t," "); /* isolate flag name */ >+ sprintf (err,"Unknown flag: %.80s",t); >+ t = strtok (NIL," "); /* get next flag */ >+ mm_log (err,ERROR); >+ } >+ } >+ } >+ return f; >+} >+ >+short maildir_getflags (MAILSTREAM *stream,char *flag) >+{ >+ return bezerk_getflags (stream,flag); /* nothing exciting, reuse old code */ >+} >+ >+long maildir_delete (MAILSTREAM *stream,char *mailbox) >+{ >+ DIR *dirp; >+ struct direct *d; >+ int i,j; >+ char tmp[MAILTMPLEN],err[MAILTMPLEN]; >+ char *subdir_names[] = {"cur/","new/","tmp/",NULL}; >+ >+ /* check if mailbox even exists */ >+ if (!maildir_isvalid (mailbox,NIL)) { >+/* sprintf (tmp,"Can't delete mailbox %s: no such mailbox",mailbox); >+ mm_log (tmp,ERROR); >+ return NIL; */ >+ /*syslog(LOG_INFO, "Invalid maildir in delete()"); */ >+ return T; /* well.. a stupid hack to get by a problem in netscape .. >+ it remembers folders locally, and if a folder is deleted on >+ another machine, you have no way removing it on any other >+ netscapes... */ >+ } >+ >+ /* get name of directory */ >+ i = strlen (maildir_file (tmp,mailbox)) + 1; >+ for (j = 0; subdir_names[j]; j++) { >+ strcpy (tmp + i - 4,subdir_names[j]); >+ if (dirp = opendir (tmp)) { /* open directory */ >+ while (d = readdir (dirp)) /* empty the directory */ >+ if (strcmp (d->d_name,".") && strcmp (d->d_name,"..")) { >+ strcpy (tmp + i,d->d_name); >+ /*syslog(LOG_INFO, "unlink1: '%s'");*/ >+ unlink (tmp); >+ } >+ closedir (dirp); /* flush directory */ >+ } >+ /* remove the subdir */ >+ tmp[i + 3] = '\0'; >+ /*syslog(LOG_INFO, "tmp: '%s'", tmp);*/ >+ if (rmdir (tmp)) { >+ /* sprintf (err,"Can't delete directory %s: %s",tmp,strerror (errno)); >+ mm_log (err,ERROR);*/ >+ } >+ } >+ >+ /* try to remove the directory */ >+ *(tmp + i - 5) = '\0'; >+ /*syslog(LOG_INFO, "tmp2: '%s'", tmp);*/ >+ if (rmdir (tmp)) { >+/* sprintf (err,"Can't delete mailbox %s: %s",mailbox,strerror (errno)); >+ mm_log (err,ERROR); >+ return NIL; */ >+ } >+ return T; /* return success */ >+} >+ >+long maildir_rename (MAILSTREAM *stream,char *old,char *new) >+{ >+ char tmp[MAILTMPLEN],tmpnew[MAILTMPLEN]; >+ >+ /* old mailbox name must be valid */ >+ if (!maildir_isvalid (old,NIL)) { >+ sprintf (tmp,"Can't rename mailbox %s: no such mailbox",old); >+ mm_log (tmp,ERROR); >+ return NIL; >+ } >+ >+ /* new mailbox name must not exist */ >+ if (access (maildir_file (tmp,new),F_OK) == 0) { >+ sprintf (tmp,"Can't rename to mailbox %s: destination already exists",new); >+ mm_log (tmp,ERROR); >+ return NIL; >+ } >+ >+ /* try to rename the directory */ >+ if (rename (maildir_file (tmp,old),maildir_file (tmpnew,new))) { >+ sprintf (tmp,"Can't rename mailbox %s to %s: %s",old,new,strerror (errno)); >+ mm_log (tmp,ERROR); >+ return NIL; >+ } >+ return T; /* return success */ >+} >+ >+long maildir_sub (MAILSTREAM *stream,char *mailbox) >+{ >+ char tmp[MAILTMPLEN]; >+ return sm_subscribe (mailbox); >+} >+ >+long maildir_unsub (MAILSTREAM *stream,char *mailbox) >+{ >+ char tmp[MAILTMPLEN]; >+ return sm_unsubscribe (mailbox); >+} >+ >+void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat) >+{ >+ void *sdb = NIL; >+ char *s; >+ /* get canonical form of name */ >+ if ((s = sm_read (&sdb))) { >+ do if (pmatch_full (s,pat,'/')) mm_lsub (stream,'/',s,NIL); >+ while (s = sm_read (&sdb)); /* until no more subscriptions */ >+ } >+ >+} >diff -Nur pine4.50/imap/src/osdep/unix/maildir.h pine4.50-maildir/imap/src/osdep/unix/maildir.h >--- pine4.50/imap/src/osdep/unix/maildir.h Thu Jan 1 01:00:00 1970 >+++ pine4.50-maildir/imap/src/osdep/unix/maildir.h Tue Dec 3 11:28:13 2002 >@@ -0,0 +1,56 @@ >+/* >+ * Please read maildir.c for license and information >+ * >+ */ >+ >+#define MAILDIRPATH ".maildir" >+ >+typedef struct maildir_local { >+ unsigned int inbox : 1; /* if it is an INBOX or not */ >+ unsigned int dirty : 1; /* diskcopy needs updating */ >+ char *dir; /* mail directory name */ >+ char *buf; /* temporary buffer */ >+ char *hdr; /* current header */ >+ unsigned long buflen; /* current size of temporary buffer */ >+ time_t scantime; /* last time directory scanned */ >+} MAILDIRLOCAL; >+ >+/* Convenient access to local data */ >+ >+#define LOCAL ((MAILDIRLOCAL *) stream->local) >+ >+/* Function prototypes */ >+ >+DRIVER *maildir_valid (char *name); >+int maildir_isvalid (char *name,long justname); >+MAILSTREAM *maildir_open (MAILSTREAM *stream); >+void maildir_gc (MAILSTREAM *stream,long gcflags); >+void maildir_close (MAILSTREAM *stream, long options); >+long maildir_ping (MAILSTREAM *stream); >+long maildir_ping_core (MAILSTREAM *stream); >+void maildir_check (MAILSTREAM *stream); >+long maildir_fetchtext (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags); >+char *maildir_fetchheader (MAILSTREAM *stream,unsigned long msgno, >+ unsigned long *length, long flags); >+void maildir_fast (MAILSTREAM *stream,char *sequence,long flags); >+void maildir_list (MAILSTREAM *stream,char *ref,char *pat); >+void *maildir_parameters (long function,void *value); >+long maildir_create (MAILSTREAM *stream,char *mailbox); >+void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt); >+void maildir_expunge (MAILSTREAM *stream); >+long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options); >+long maildir_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date, >+ STRING *message); >+short maildir_getflags (MAILSTREAM *stream,char *flag); >+long maildir_delete (MAILSTREAM *stream,char *mailbox); >+long maildir_rename (MAILSTREAM *stream,char *old,char *new); >+long maildir_sub (MAILSTREAM *stream,char *mailbox); >+long maildir_unsub (MAILSTREAM *stream,char *mailbox); >+void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat); >+ >+/* utility functions */ >+char *maildir_file (char *dst,char *name); >+void maildir_copynew (const char *mailbox); >+int maildir_select (struct direct *name); >+int maildir_namesort (struct direct **d1,struct direct **d2); >+void maildir_listwork(char *name, MAILSTREAM *stream, char *s2, char *subdir, int flag); >diff -Nur pine4.53/pine/mailcmd.c pine4.50-maildir/pine/mailcmd.c >--- pine4.53/pine/mailcmd.c Wed Nov 20 01:17:17 2002 >+++ pine4.50-maildir/pine/mailcmd.c Tue Dec 3 11:28:14 2002 >@@ -3372,8 +3372,7 @@ > * the destination folder will need... > */ > context_apply(tmp, context, save_folder, sizeof(tmp)); >- save_stream = (stream->dtb->flags & DR_LOCAL) && !IS_REMOTE(tmp) ? >- stream : context_same_stream(context, save_folder, stream); >+ save_stream = context_same_stream(context, save_folder, stream); > } > > /* if needed, this'll get set in mm_notify */ >diff -Nur pine4.53/pine/pine.h pine4.50-maildir/pine/pine.h >--- pine4.53/pine/pine.h Wed Nov 20 19:19:44 2002 >+++ pine4.50-maildir/pine/pine.h Tue Dec 3 11:32:34 2002 >@@ -63,7 +63,7 @@ > #ifndef _PINE_INCLUDED > #define _PINE_INCLUDED > >-#define PINE_VERSION "4.58" >+#define PINE_VERSION "4.58L0" > #define PHONE_HOME_VERSION "-count" > #define PHONE_HOME_HOST "docserver.cac.washington.edu" >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 28877
: 18893 |
30545
|
30751