Revision: 7153
http://svn.sourceforge.net/mahogany/?rev=7153&view=rev
Author: vadz
Date: 2006-11-06 16:18:21 -0800 (Mon, 06 Nov 2006)
Log Message:
-----------
merged in IMAP 2006c1
Modified Paths:
--------------
trunk/M/lib/imap/docs/RELNOTES
trunk/M/lib/imap/src/c-client/utf8.c
trunk/M/lib/imap/src/dmail/dmail.c
trunk/M/lib/imap/src/imapd/imapd.c
trunk/M/lib/imap/src/ipopd/ipop2d.c
trunk/M/lib/imap/src/ipopd/ipop3d.c
trunk/M/lib/imap/src/mailutil/mailutil.c
trunk/M/lib/imap/src/osdep/amiga/dummy.c
trunk/M/lib/imap/src/osdep/amiga/mh.c
trunk/M/lib/imap/src/osdep/amiga/mix.c
trunk/M/lib/imap/src/osdep/amiga/mmdf.c
trunk/M/lib/imap/src/osdep/amiga/mx.c
trunk/M/lib/imap/src/osdep/amiga/unix.c
trunk/M/lib/imap/src/osdep/nt/unixnt.c
trunk/M/lib/imap/src/osdep/os2/unixnt.c
trunk/M/lib/imap/src/osdep/unix/Makefile
trunk/M/lib/imap/src/osdep/unix/dummy.c
trunk/M/lib/imap/src/osdep/unix/flocksim.c
trunk/M/lib/imap/src/osdep/unix/mh.c
trunk/M/lib/imap/src/osdep/unix/mix.c
trunk/M/lib/imap/src/osdep/unix/mmdf.c
trunk/M/lib/imap/src/osdep/unix/mx.c
trunk/M/lib/imap/src/osdep/unix/os_soln.h
trunk/M/lib/imap/src/osdep/unix/os_solo.h
trunk/M/lib/imap/src/osdep/unix/unix.c
trunk/M/lib/imap/src/tmail/tmail.c
Removed Paths:
-------------
trunk/M/lib/imap/src/c-client/.smtp.c.swp
trunk/M/lib/imap/src/osdep/unix/nfstnew.c
trunk/M/lib/imap/src/osdep/unix/nfstold.c
Modified: trunk/M/lib/imap/docs/RELNOTES
===================================================================
--- trunk/M/lib/imap/docs/RELNOTES 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/docs/RELNOTES 2006-11-07 00:18:21 UTC (rev 7153)
@@ -11,6 +11,16 @@
* ========================================================================
*/
+Updated: 23 October 2006
+
+imap-2006c is a maintenance release, consisting primarily of bugfixes to
+problems discovered in the release that affected a small number of users.
+
+By popular request, if a user has a mix (or other dual-use) format INBOX,
+it will no longer be listed as \NoInferiors. It's a bad idea to depend
+upon this due to the case ambiguity issue, but it's there.
+
+
Updated: 26 September 2006
imap-2006b is a maintenance release, consisting entirely of bugfixes to
Deleted: trunk/M/lib/imap/src/c-client/.smtp.c.swp
===================================================================
(Binary files differ)
Modified: trunk/M/lib/imap/src/c-client/utf8.c
===================================================================
--- trunk/M/lib/imap/src/c-client/utf8.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/c-client/utf8.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 11 June 1997
- * Last Edited: 27 September 2006
+ * Last Edited: 12 October 2006
*/
@@ -873,7 +873,8 @@
/* Return UCS-4 character from UTF-8 string
* Accepts: pointer to string
* remaining octets in string
- * Returns: UCS-4 character with pointer and count updated, negative if error
+ * Returns: UCS-4 character with pointer and count updated
+ * or error code with pointer and count unchanged
*/
unsigned long utf8_get (unsigned char **s,unsigned long *i)
@@ -881,55 +882,45 @@
unsigned char c;
unsigned char *t = *s;
unsigned long j = *i;
- unsigned long ret = 0;
+ unsigned long ret = U8G_NOTUTF8;
int more = 0;
- while (j) { /* until run out of input */
- j--; /* count this character */
+ do { /* make sure have soure octets available */
+ if (!j--) return more ? U8G_ENDSTRI : U8G_ENDSTRG;
/* UTF-8 continuation? */
- if (((c = *t++) > 0x7f) && (c < 0xc0)) {
- if (more) {
- ret <<= 6; /* shift current value by 6 bits */
- ret |= c & 0x3f;
- if (!--more) { /* last octet */
- *s = t; /* update pointer and counter */
- *i = j;
- return ret;
- }
- }
- else return U8G_BADCONT; /* continuation when not in progress */
+ else if (((c = *t++) > 0x7f) && (c < 0xc0)) {
+ /* continuation when not in progress */
+ if (!more) return U8G_BADCONT;
+ --more; /* found a continuation octet */
+ ret <<= 6; /* shift current value by 6 bits */
+ ret |= c & 0x3f; /* merge continuation octet */
}
/* incomplete UTF-8 character */
else if (more) return U8G_INCMPLT;
- else if (c < 0x80) { /* U+0000 - U+007f */
- *s = t; /* update pointer and counter */
- *i = j;
- return (unsigned long) c;
+ else { /* start of sequence */
+ if (c < 0x80) ret = c; /* U+0000 - U+007f */
+ else if (c < 0xe0) { /* U+0080 - U+07ff */
+ if (c &= 0x1f) more = 1;/* first 5 bits of 12 */
+ }
+ else if (c < 0xf0) { /* U+1000 - U+ffff */
+ if (c &= 0x0f) more = 2;/* first 4 bits of 16 */
+ }
+ else if (c < 0xf8) { /* U+10000 - U+10ffff (and 110000 - 1fffff) */
+ if (c &= 0x07) more = 3;/* first 3 bits of 20.5 (21) */
+ }
+ else if (c < 0xfc) { /* ISO 10646 200000 - 3fffffff */
+ if (c &= 0x03) more = 4;/* first 2 bits of 26 */
+ }
+ else if (c < 0xfe) { /* ISO 10646 4000000 - 7fffffff*/
+ if (c &= 0x01) more = 5;/* first bit of 31 */
+ }
+ if (more) ret = c; /* continuation needed, save start bits */
}
- else if (c < 0xe0) { /* U+0080 - U+07ff */
- ret = c & 0x1f; /* first 5 bits of 12 */
- more = 1;
- }
- else if (c < 0xf0) { /* U+1000 - U+ffff */
- ret = c & 0x0f; /* first 4 bits of 16 */
- more = 2;
- }
- /* non-BMP Unicode */
- else if (c < 0xf8) { /* U+10000 - U+10ffff (and 110000 - 1fffff) */
- ret = c & 0x07; /* first 3 bits of 20.5 (21) */
- more = 3;
- }
- else if (c < 0xfc) { /* ISO 10646 200000 - 3fffffff */
- ret = c & 0x03; /* first 2 bits of 26 */
- more = 4;
- }
- else if (c < 0xfe) { /* ISO 10646 4000000-7fffffff*/
- ret = c & 0x01; /* first bit of 31 */
- more = 5;
- }
- else return U8G_NOTUTF8; /* not in ISO 10646 */
+ } while (more);
+ if (!(ret & U8G_ERROR)) { /* success return? */
+ *s = t; /* yes, update pointer */
+ *i = j; /* and counter */
}
- /* end of string */
- return more ? U8G_ENDSTRI : U8G_ENDSTRG;
+ return ret; /* return value */
}
/* Return UCS-4 character from named charset string
Modified: trunk/M/lib/imap/src/dmail/dmail.c
===================================================================
--- trunk/M/lib/imap/src/dmail/dmail.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/dmail/dmail.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 5 April 1993
- * Last Edited: 30 August 2006
+ * Last Edited: 12 October 2006
*/
#include <stdio.h>
@@ -41,7 +41,7 @@
/* Globals */
-char *version = "2006(12)"; /* dmail release version */
+char *version = "2006c.12"; /* dmail release version */
int debug = NIL; /* debugging (don't fork) */
int flagseen = NIL; /* flag message as seen */
int trycreate = NIL; /* flag saying gotta create before appending */
Modified: trunk/M/lib/imap/src/imapd/imapd.c
===================================================================
--- trunk/M/lib/imap/src/imapd/imapd.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/imapd/imapd.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 5 November 1990
- * Last Edited: 29 September 2006
+ * Last Edited: 17 October 2006
*/
/* Parameter files */
@@ -202,7 +202,7 @@
/* Global storage */
-char *version = "2006b.373"; /* version number of this server */
+char *version = "2006c.374"; /* version number of this server */
char *logout = "Logout"; /* syslogreason for logout */
char *goodbye = NIL; /* bye reason */
time_t alerttime = 0; /* time of last alert */
@@ -1118,7 +1118,12 @@
else if (!(anonymous || strcmp (cmd,"DELETE"))) {
if (!(s = snarf (&arg))) response = misarg;
else if (arg) response = badarg;
- else mail_delete (NIL,s);
+ else { /* make sure not selected */
+ if (lastsel && (!strcmp (s,lastsel) ||
+ (stream && !strcmp (s,stream->mailbox))))
+ mm_log ("Can not DELETE the selected mailbox",ERROR);
+ else mail_delete (NIL,s);
+ }
if (stream) /* allow untagged EXPUNGE */
mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);
}
@@ -1126,7 +1131,14 @@
else if (!(anonymous || strcmp (cmd,"RENAME"))) {
if (!((s = snarf (&arg)) && (t = snarf (&arg)))) response = misarg;
else if (arg) response = badarg;
- else mail_rename (NIL,s,t);
+ else { /* make sure not selected */
+ if (!compare_cstring (s,"INBOX")) s = "INBOX";
+ else if (!compare_cstring (s,"#MHINBOX")) s = "#MHINBOX";
+ if (lastsel && (!strcmp (s,lastsel) ||
+ (stream && !strcmp (s,stream->mailbox))))
+ mm_log ("Can not RENAME the selected mailbox",ERROR);
+ else mail_rename (NIL,s,t);
+ }
if (stream) /* allow untagged EXPUNGE */
mail_parameters (stream,SET_ONETIMEEXPUNGEATPING,(void *) stream);
}
Modified: trunk/M/lib/imap/src/ipopd/ipop2d.c
===================================================================
--- trunk/M/lib/imap/src/ipopd/ipop2d.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/ipopd/ipop2d.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 28 October 1990
- * Last Edited: 15 September 2006
+ * Last Edited: 12 October 2006
*/
@@ -59,7 +59,7 @@
/* Global storage */
-char *version = "2006a.72"; /* server version */
+char *version = "2006c.72"; /* server version */
short state = LISN; /* server state */
short critical = NIL; /* non-zero if in critical code */
MAILSTREAM *stream = NIL; /* mailbox stream */
Modified: trunk/M/lib/imap/src/ipopd/ipop3d.c
===================================================================
--- trunk/M/lib/imap/src/ipopd/ipop3d.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/ipopd/ipop3d.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 1 November 1990
- * Last Edited: 15 September 2006
+ * Last Edited: 6 October 2006
*/
/* Parameter files */
@@ -65,7 +65,7 @@
/* Global storage */
-char *version = "2006a.94"; /* server version */
+char *version = "2006c.94"; /* server version */
short state = AUTHORIZATION; /* server state */
short critical = NIL; /* non-zero if in critical code */
MAILSTREAM *stream = NIL; /* mailbox stream */
Modified: trunk/M/lib/imap/src/mailutil/mailutil.c
===================================================================
--- trunk/M/lib/imap/src/mailutil/mailutil.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/mailutil/mailutil.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 2 February 1994
- * Last Edited: 13 September 2006
+ * Last Edited: 12 October 2006
*/
@@ -37,7 +37,7 @@
/* Globals */
-char *version = "2006.3"; /* program version */
+char *version = "2006c.5"; /* program version */
int debugp = NIL; /* flag saying debug */
int verbosep = NIL; /* flag saying verbose */
int rwcopyp = NIL; /* flag saying readwrite copy (for POP) */
@@ -48,6 +48,19 @@
int ddelim = -1; /* destination delimiter */
FILE *f = NIL;
+/* Usage strings */
+
+char *usage2 = "usage: %s %s\n";
+char *usage3 = "usage: %s %s %s\n";
+char *usgchk = "check [-d[ebug]] [-v[erbose]] [mailbox]";
+char *usgcre = "create [-d[ebug]] [-v[erbose]] mailbox";
+char *usgdel = "delete [-d[ebug]] [-v[erbose]] mailbox";
+char *usgren = "rename [-d[ebug]] [-v[erbose]] src dst";
+char *usgcpymov = "[-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] src dst";
+char *usgappdel = "[-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] src dst";
+char *usgprn = "prune [-d[ebug]] [-v[erbose]] mailbox search_criteria";
+char *usgxfr = "transfer [-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] [-m[erge] m] src dst";
+
/* Merge modes */
#define mPROMPT 1
@@ -160,7 +173,7 @@
unsigned long m,len,curlen,start,last;
int i;
int merge = NIL;
- int ret = 1;
+ int retcode = 1;
int moreswitchp = T;
char *cmd = NIL;
char *src = NIL;
@@ -184,7 +197,7 @@
}
else {
printf ("unknown merge option: %s\n",s);
- exit (ret);
+ exit (retcode);
}
}
/* -- means no more switches, so mailbox
@@ -192,7 +205,7 @@
else if ((s[1] == '-') && !s[2]) moreswitchp = NIL;
else {
printf ("unknown switch: %s\n",s);
- exit (ret);
+ exit (retcode);
}
}
else if (!cmd) cmd = s; /* first non-switch is command */
@@ -200,76 +213,68 @@
else if (!dst) dst = s; /* third non-switch is destination */
else {
printf ("unknown argument: %s\n",s);
- exit (ret);
+ exit (retcode);
}
}
if (!cmd) cmd = ""; /* prevent SEGV */
if (!strcmp (cmd,"check")) { /* check for new messages */
if (!src) src = "INBOX";
- if (dst || merge || rwcopyp || kwcopyp)
- printf ("usage: %s check [-d[ebug]] [-v[erbose]] [mailbox]\n",pgm);
+ if (dst || merge || rwcopyp || kwcopyp) printf (usage2,pgm,usgchk);
else if (mail_status (source = (*src == '{') ?
mail_open (NIL,src,OP_HALFOPEN |
(debugp ? OP_DEBUG : NIL)) : NIL,
- src,SA_MESSAGES | SA_RECENT | SA_UNSEEN)) ret = 0;
+ src,SA_MESSAGES | SA_RECENT | SA_UNSEEN))
+ retcode = 0;
}
else if (!strcmp (cmd,"create")) {
- if (!src || dst || merge || rwcopyp || kwcopyp)
- printf ("usage: %s create [-d[ebug]] [-v[erbose]] mailbox\n",pgm);
+ if (!src || dst || merge || rwcopyp || kwcopyp) printf (usage2,pgm,usgcre);
else if (mail_create (source = (*src == '{') ?
mail_open (NIL,src,OP_HALFOPEN |
(debugp ? OP_DEBUG : NIL)) : NIL,src))
- ret = 0;
+ retcode = 0;
}
else if (!strcmp (cmd,"delete")) {
- if (!src || dst || merge || rwcopyp || kwcopyp)
- printf ("usage: %s delete [-d[ebug]] [-v[erbose]] mailbox\n",pgm);
+ if (!src || dst || merge || rwcopyp || kwcopyp) printf (usage2,pgm,usgdel);
else if (mail_delete (source = (*src == '{') ?
mail_open (NIL,src,OP_HALFOPEN |
(debugp ? OP_DEBUG : NIL)) : NIL,src))
- ret = 0;
+ retcode = 0;
}
- else if (i = !strcmp (cmd,"rename")) {
- if (!src || !dst || merge || rwcopyp || kwcopyp)
- printf ("usage: %s %s [-d[ebug]] [-v[erbose]] src dst\n",pgm,cmd);
+ else if (!strcmp (cmd,"rename")) {
+ if (!src || !dst || merge || rwcopyp || kwcopyp) printf(usage2,pgm,usgren);
else if (mail_rename (source = (*src == '{') ?
mail_open (NIL,src,OP_HALFOPEN |
(debugp ? OP_DEBUG : NIL)) : NIL,src,dst))
- ret = 0;
+ retcode = 0;
}
+
else if ((i = !strcmp (cmd,"move")) || !strcmp (cmd,"copy")) {
- if (!src || !dst || merge)
- printf("usage: %s %s [-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] src dst\n",
- pgm,cmd);
+ if (!src || !dst || merge) printf (usage3,pgm,cmd,usgcpymov);
else if (source = mail_open (NIL,src,((i || rwcopyp) ? NIL : OP_READONLY) |
(debugp ? OP_DEBUG : NIL))) {
dest = NIL; /* open destination stream if network */
if ((*dst != '{') || (dest = mail_open (NIL,dst,OP_HALFOPEN |
(debugp ? OP_DEBUG : NIL)))) {
- if (mbxcopy (source,dest,dst,T,i,merge)) ret = 0;
+ if (mbxcopy (source,dest,dst,T,i,merge)) retcode = 0;
}
}
}
else if ((i = !strcmp (cmd,"appenddelete")) || !strcmp (cmd,"append")) {
- if (!src || !dst || merge)
- printf("usage: %s %s [-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] src dst\n",
- pgm,cmd);
+ if (!src || !dst || merge) printf (usage3,pgm,cmd,usgappdel);
else if (source = mail_open (NIL,src,((i || rwcopyp) ? NIL : OP_READONLY) |
(debugp ? OP_DEBUG : NIL))) {
dest = NIL; /* open destination stream if network */
if ((*dst != '{') || (dest = mail_open (NIL,dst,OP_HALFOPEN |
(debugp ? OP_DEBUG : NIL)))) {
- if (mbxcopy (source,dest,dst,NIL,i,merge)) ret = 0;
+ if (mbxcopy (source,dest,dst,NIL,i,merge)) retcode = 0;
}
}
}
else if (!strcmp (cmd,"prune")) {
if (!src || !dst || merge || rwcopyp || kwcopyp ||
- !(criteria = mail_criteria (dst)))
- printf ("usage: %s prune [-d[ebug]] [-v[erbose]] mailbox search_criteria\n",
- pgm);
+ !(criteria = mail_criteria (dst))) printf (usage2,pgm,usgprn);
else if ((source = mail_open (NIL,src,(debugp ? OP_DEBUG : NIL))) &&
mail_search_full (source,NIL,criteria,SE_FREE)) {
for (m = 1, s = t = NIL, len = start = last = 0; m <= source->nmsgs; m++)
@@ -309,9 +314,7 @@
}
else if (!strcmp (cmd,"transfer")) {
- if (!src || !dst)
- printf ("usage: %s transfer [-d[ebug]] [-v[erbose]] [-rw[copy]]\n [-kw[copy]] [-m[erge] m] src dst\n",
- pgm);
+ if (!src || !dst) printf (usage2,pgm,usgxfr);
else if ((*src == '{') && /* open source mailbox */
!(source = mail_open (NIL,src,OP_HALFOPEN |
(debugp ? OP_DEBUG : NIL))));
@@ -339,7 +342,7 @@
mail_list (source,tmp,"*");
rewind (f);
/* read back mailbox names */
- while (ret && (fgets (tmp,MAILTMPLEN-1,f))) {
+ for (retcode = 0; !retcode && (fgets (tmp,MAILTMPLEN-1,f)); ) {
if (t = strchr (tmp+1,'\n')) *t = '\0';
for (t = mbx,t1 = dest ? dest->mailbox : "",c = NIL; (c != '}') && *t1;
*t++ = c= *t1++);
@@ -362,7 +365,7 @@
}
if (source = mail_open (source,tmp+1,(debugp ? OP_DEBUG : NIL) |
(rwcopyp ? NIL : OP_READONLY))) {
- if (mbxcopy (source,dest,mbx,T,NIL,merge)) ret = 0;
+ if (!mbxcopy (source,dest,mbx,T,NIL,merge)) retcode = 1;
if (source->dtb->flags & DR_LOCAL) source = mail_close (source);
}
else printf ("can't open source mailbox %s\n",tmp+1);
@@ -371,33 +374,33 @@
}
else {
- printf ("%s version %s\n\nusage: %s command [switches] arguments\n",
- pgm,version,pgm);
- puts (" check [-d[ebug]] [-v[erbose]] [mailbox]");
+ printf ("%s version %s\n\n",pgm,version);
+ printf (usage2,pgm,"command [switches] arguments",pgm);
+ printf (" %s\n",usgchk);
puts (" ;; report number of messages and new messages");
- puts (" create [-d[ebug]] [-v[erbose]] mailbox");
+ printf (" %s\n",usgcre);
puts (" ;; create new mailbox");
- puts (" delete [-d[ebug]] [-v[erbose]] mailbox");
+ printf (" %s\n",usgdel);
puts (" ;; delete existing mailbox");
- puts (" rename [-d[ebug]] [-v[erbose]] src dst");
+ printf (" %s\n",usgren);
puts (" ;; rename mailbox to a new name");
- puts (" copy [-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] src dst");
- puts (" move [-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] src dst");
+ printf (" copy %s\n",usgcpymov);
+ printf (" move %s\n",usgcpymov);
puts (" ;; create new mailbox and copy/move messages");
- puts (" append [-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] src dst");
- puts (" appenddelete [-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] src dst");
+ printf (" append %s\n",usgappdel);
+ printf (" appenddelete %s\n",usgappdel);
puts (" ;; copy/move messages to existing mailbox");
- puts (" prune [-d[ebug]] [-v[erbose]] mailbox search_criteria");
+ printf (" %s\n",usgprn);
puts (" ;; prune mailbox of messages matching criteria");
- puts (" transfer [-d[ebug]] [-v[erbose]] [-rw[copy]] [-kw[copy]] [-m[erge] m] src dst");
+ printf (" %s\n",usgxfr);
puts (" ;; copy source hierarchy to destination");
puts (" ;; -merge modes are prompt, append, or suffix=xxxx");
}
/* close streams */
if (source) mail_close (source);
if (dest) mail_close (dest);
- exit (ret);
- return ret; /* stupid compilers */
+ exit (retcode);
+ return retcode; /* stupid compilers */
}
/* Copy mailbox
Modified: trunk/M/lib/imap/src/osdep/amiga/dummy.c
===================================================================
--- trunk/M/lib/imap/src/osdep/amiga/dummy.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/amiga/dummy.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 9 May 1991
- * Last Edited: 30 August 2006
+ * Last Edited: 17 October 2006
*/
@@ -153,6 +153,7 @@
void dummy_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents)
{
+ DRIVER *drivers;
char *s,test[MAILTMPLEN],file[MAILTMPLEN];
long i;
if (!pat || !*pat) { /* empty pattern? */
@@ -181,8 +182,16 @@
/* do the work */
dummy_list_work (stream,s,test,contents,0);
/* always an INBOX */
- if (pmatch ("INBOX",ucase (test)))
- dummy_listed (stream,NIL,"INBOX",LATT_NOINFERIORS,contents);
+ if (pmatch ("INBOX",ucase (test))) {
+ /* done if have a dirfmt INBOX */
+ for (drivers = (DRIVER *) mail_parameters (NIL,GET_DRIVERS,NIL);
+ drivers && !(!(drivers->flags & DR_DISABLE) &&
+ (drivers->flags & DR_DIRFMT) &&
+ (*drivers->valid) ("INBOX")); drivers = drivers->next);
+ /* list INBOX appropriately */
+ dummy_listed (stream,drivers ? '/' : NIL,"INBOX",
+ drivers ? NIL : LATT_NOINFERIORS,contents);
+ }
}
}
@@ -266,12 +275,12 @@
if (dp = opendir (tmp)) { /* do nothing if can't open directory */
/* see if a non-namespace directory format */
for (drivers = (DRIVER *) mail_parameters (NIL,GET_DRIVERS,NIL), dt = NIL;
- !dt && drivers; drivers = drivers->next)
+ dir && !dt && drivers; drivers = drivers->next)
if (!(drivers->flags & DR_DISABLE) && (drivers->flags & DR_DIRFMT) &&
- (*drivers->valid) (tmp))
+ (*drivers->valid) (dir))
dt = mail_parameters ((*drivers->open) (NIL),GET_DIRFMTTEST,NIL);
/* list it if at top-level */
- if (!level && dir && pmatch_full (dir,pat,'/'))
+ if (!level && dir && pmatch_full (dir,pat,'/') && !pmatch (dir,"INBOX"))
dummy_listed (stream,'/',dir,dt ? NIL : LATT_NOSELECT,contents);
/* scan directory, ignore . and .. */
if (!dir || dir[(len = strlen (dir)) - 1] == '/') while (d = readdir (dp))
@@ -293,14 +302,17 @@
/* only interested in file type */
switch (sbuf.st_mode & S_IFMT) {
case S_IFDIR: /* directory? */
- if (pmatch_full (tmp,pat,'/')) {
- if (!dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents)) break;
- strcat (tmp,"/"); /* set up for dmatch call */
+ if (!pmatch (tmp,"INBOX")) {
+ if (pmatch_full (tmp,pat,'/')) {
+ if (!dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents))
+ break;
+ strcat(tmp,"/");/* set up for dmatch call */
+ }
+ /* try again with trailing / */
+ else if (pmatch_full (strcat (tmp,"/"),pat,'/') &&
+ !dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents))
+ break;
}
- /* try again with trailing / */
- else if (pmatch_full (strcat (tmp,"/"),pat,'/') &&
- !dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents))
- break;
if (dmatch (tmp,pat,'/') &&
(level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL)))
dummy_list_work (stream,tmp,pat,contents,level+1);
Modified: trunk/M/lib/imap/src/osdep/amiga/mh.c
===================================================================
--- trunk/M/lib/imap/src/osdep/amiga/mh.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/amiga/mh.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 23 February 1992
- * Last Edited: 13 September 2006
+ * Last Edited: 19 October 2006
*/
@@ -158,7 +158,7 @@
static char *mh_profile = NIL; /* holds MH profile */
static char *mh_pathname = NIL; /* holds MH path name */
-static long mh_once = 0; /* already through this code */
+static long mh_once = 0; /* already snarled once */
static long mh_allow_inbox =NIL;/* allow INBOX as well as #mhinbox */
/* MH mail validate mailbox
@@ -184,33 +184,36 @@
{
struct stat sbuf;
unsigned long i;
- /* name must be #MHINBOX or #mh/... */
+ int ret = NIL;
+ /* non-mh name? */
if (!((mh_allow_inbox && !compare_cstring (name,"INBOX")) ||
((name[0] == '#') && ((name[1] == 'm') || (name[1] == 'M')) &&
((name[2] == 'h') || (name[2] == 'H')) &&
((name[3] == '/') || !compare_cstring (name+3,"INBOX"))))) {
- /* valid if in hierarchy (list kludge) */
+ /* yes, valid if in hierarchy (list kludge) */
char *s,*t,altname[MAILTMPLEN];
/* see if non-NS name within mh hierarchy */
if ((name[0] != '#') && (s = mh_path (tmp)) && (i = strlen (s)) &&
(t = mailboxfile (tmp,name)) && !strncmp (t,s,i) && (tmp[i] == '/')) {
sprintf (altname,"#mh%.900s",tmp+i);
- return mh_isvalid (altname,tmp,synonly);
+ /* can't do synonly here! */
+ ret = mh_isvalid (altname,tmp,NIL);
}
- errno = EINVAL; /* bogus name */
- return NIL;
+ else errno = EINVAL; /* bogus name */
}
- if (!mh_path (tmp)) { /* lose if no mh path */
+ else if (mh_path (tmp)) { /* INBOX, #mhinbox, or #mh/ name */
+ /* all done if syntax only check & not INBOX */
+ if (synonly && compare_cstring (name,"INBOX")) return T;
+ errno = NIL; /* zap error */
+ /* validate name as directory */
+ ret = ((stat (mh_file (tmp,name),&sbuf) == 0) &&
+ (sbuf.st_mode & S_IFMT) == S_IFDIR);
+ }
+ else if (!mh_once++) { /* only report error once */
sprintf (tmp,"%.900s not found, mh format names disabled",mh_profile);
mm_log (tmp,WARN);
- return NIL;
}
- /* all done if syntax only check & not INBOX */
- if (synonly && compare_cstring (name,"INBOX")) return T;
- errno = NIL; /* zap error */
- /* validate name as directory */
- return ((stat (mh_file (tmp,name),&sbuf) == 0) &&
- (sbuf.st_mode & S_IFMT) == S_IFDIR);
+ return ret;
}
/* MH mail test for valid mailbox
@@ -242,38 +245,36 @@
char *s,*t,*v;
int fd;
struct stat sbuf;
- /* have MH path yet? */
- if (!mh_pathname && !mh_once++) {
- if (!mh_profile) { /* have MH profile? */
- sprintf (tmp,"%s/%s",myhomedir (),MHPROFILE);
- mh_profile = cpystr (tmp);
- }
- if ((fd = open (tmp,O_RDONLY,NIL)) < 0) return NIL;
- fstat (fd,&sbuf); /* yes, get size and read file */
- read (fd,(t = (char *) fs_get (sbuf.st_size + 1)),sbuf.st_size);
- close (fd); /* don't need the file any more */
- t[sbuf.st_size] = '\0'; /* tie it off */
+ if (!mh_profile) { /* build mh_profile and mh_pathname now */
+ sprintf (tmp,"%s/%s",myhomedir (),MHPROFILE);
+ if ((fd = open (mh_profile = cpystr (tmp),O_RDONLY,NIL)) >= 0) {
+ fstat (fd,&sbuf); /* yes, get size and read file */
+ read (fd,(t = (char *) fs_get (sbuf.st_size + 1)),sbuf.st_size);
+ close (fd); /* don't need the file any more */
+ t[sbuf.st_size] = '\0'; /* tie it off */
/* parse profile file */
- for (s = strtok (t,"\r\n"); s && *s; s = strtok (NIL,"\r\n")) {
+ for (s = strtok (t,"\r\n"); s && *s; s = strtok (NIL,"\r\n")) {
/* found space in line? */
- if (v = strpbrk (s," \t")) {
- *v++ = '\0'; /* tie off, is keyword "Path:"? */
- if (!strcmp (lcase (s),"path:")) {
+ if (v = strpbrk (s," \t")) {
+ *v++ = '\0'; /* tie off, is keyword "Path:"? */
+ if (!strcmp (lcase (s),"path:")) {
/* skip whitespace */
- while ((*v == ' ') || (*v == '\t')) ++v;
- if (*v == '/') s = v; /* absolute path? */
- else sprintf (s = tmp,"%s/%s",myhomedir (),v);
+ while ((*v == ' ') || (*v == '\t')) ++v;
+ /* absolute path? */
+ if (*v == '/') s = v;
+ else sprintf (s = tmp,"%s/%s",myhomedir (),v);
/* copy name */
- mh_pathname = cpystr (s);
- break; /* don't need to look at rest of file */
+ mh_pathname = cpystr (s);
+ break; /* don't need to look at rest of file */
+ }
}
}
+ fs_give ((void **) &t); /* flush profile text */
+ if (!mh_pathname) { /* default path if not in the profile */
+ sprintf (tmp,"%s/%s",myhomedir (),MHPATH);
+ mh_pathname = cpystr (tmp);
+ }
}
- fs_give ((void **) &t); /* flush profile text */
- if (!mh_pathname) { /* default path if not in the profile */
- sprintf (tmp,"%s/%s",myhomedir (),MHPATH);
- mh_pathname = cpystr (tmp);
- }
}
return mh_pathname;
}
@@ -506,7 +507,7 @@
int i;
char tmp[MAILTMPLEN];
/* is mailbox valid? */
- if (!mh_isvalid (mailbox,tmp,NIL)){
+ if (!mh_isvalid (mailbox,tmp,NIL)) {
sprintf (tmp,"Can't delete mailbox %.80s: no such mailbox",mailbox);
mm_log (tmp,ERROR);
return NIL;
@@ -683,6 +684,7 @@
break;
}
SNX (&bs); /* eat the line feed, drop in */
+ --j;
case '\012': /* line feed? */
i += 2; /* count a CRLF */
/* header size known yet? */
Modified: trunk/M/lib/imap/src/osdep/amiga/mix.c
===================================================================
--- trunk/M/lib/imap/src/osdep/amiga/mix.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/amiga/mix.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 1 March 2006
- * Last Edited: 29 September 2006
+ * Last Edited: 25 October 2006
*/
@@ -166,6 +166,8 @@
long mix_index_update (MAILSTREAM *stream,FILE **idxf,long flag);
FILE *mix_status_open (MAILSTREAM *stream,long flags);
long mix_status_update (MAILSTREAM *stream,FILE **statf,long flag);
+FILE *mix_data_open (MAILSTREAM *stream,int *fd,long *size,
+ unsigned long newsize);
FILE *mix_sortcache_open (MAILSTREAM *stream);
long mix_sortcache_update (MAILSTREAM *stream,FILE **sortcache);
char *mix_read_record (FILE *f,char *buf,unsigned long buflen);
@@ -247,7 +249,7 @@
struct stat sbuf;
/* validate name as directory */
return (!(errno = ((strlen (name) > NETMAXMBX) ? ENAMETOOLONG : NIL)) &&
- mix_dir (dir,name) && mix_file (meta,dir,MIXMETA) &&
+ *mix_dir (dir,name) && mix_file (meta,dir,MIXMETA) &&
!stat (dir,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFDIR) &&
!stat (meta,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFREG));
}
@@ -459,14 +461,18 @@
{
DIR *dirp;
struct direct *d;
- char *s;
- char tmp[MAILTMPLEN];
+ int fd = -1;
+ char *s,tmp[MAILTMPLEN];
if (!mix_isvalid (mailbox,tmp))
sprintf (tmp,"Can't delete mailbox %.80s: no such mailbox",mailbox);
- /* delete index */
+ else if (((fd = open (tmp,O_RDONLY,NIL)) < 0) || flock (fd,LOCK_EX|LOCK_NB))
+ sprintf (tmp,"Can't lock mailbox for delete: %.80s",mailbox);
+ /* delete metadata */
else if (unlink (tmp)) sprintf (tmp,"Can't delete mailbox %.80s index: %80s",
mailbox,strerror (errno));
- else { /* get directory name */
+ else {
+ close (fd); /* close descriptor on deleted metadata */
+ /* get directory name */
*(s = strrchr (tmp,'/')) = '\0';
if (dirp = opendir (tmp)) { /* open directory */
*s++ = '/'; /* restore delimiter */
@@ -485,6 +491,7 @@
}
return T; /* always success */
}
+ if (fd >= 0) close (fd); /* close any descriptor on metadata */
MM_LOG (tmp,ERROR); /* something failed */
return NIL;
}
@@ -500,8 +507,11 @@
{
char c,*s,tmp[MAILTMPLEN],tmp1[MAILTMPLEN];
struct stat sbuf;
+ int fd = -1;
if (!mix_isvalid (old,tmp))
sprintf (tmp,"Can't rename mailbox %.80s: no such mailbox",old);
+ else if (((fd = open (tmp,O_RDONLY,NIL)) < 0) || flock (fd,LOCK_EX|LOCK_NB))
+ sprintf (tmp,"Can't lock mailbox for rename: %.80s",old);
else if (mix_dirfmttest ((s = strrchr (newname,'/')) ? s + 1 : newname))
sprintf (tmp,"Can't rename to mailbox %.80s: invalid MIX-format name",
newname);
@@ -524,7 +534,10 @@
return NIL;
*s = c; /* restore full name */
}
- if (!rename (tmp,tmp1)) return LONGT;
+ if (!rename (tmp,tmp1)) {
+ close (fd); /* close descriptor on metadata */
+ return LONGT;
+ }
}
/* RFC 3501 requires this */
@@ -552,11 +565,15 @@
/* free directory list */
if (a = (void *) names) fs_give ((void **) &a);
if (lasterror) errno = lasterror;
- else return mix_create (NIL,"INBOX");
+ else {
+ close (fd); /* close descriptor on metadata */
+ return mix_create (NIL,"INBOX");
+ }
}
sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",
old,newname,strerror (errno));
}
+ if (fd >= 0) close (fd); /* close any descriptor on metadata */
MM_LOG (tmp,ERROR); /* something failed */
return NIL;
}
@@ -667,7 +684,7 @@
char *mix_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *length,
long flags)
{
- unsigned long i,j;
+ unsigned long i,j,k;
int fd;
char *s,tmp[MAILTMPLEN];
MESSAGECACHE *elt;
@@ -696,11 +713,16 @@
!strncmp (LOCAL->buf,MSGTOK,MSGTSZ) &&
(elt->private.uid == strtoul ((char *) LOCAL->buf + MSGTSZ,&s,16)) &&
(*s++ == ':') && (s = strchr (s,':')) &&
- (elt->rfc822_size == strtoul (s+1,&s,16)) && (*s++ == ':') &&
+ (k = strtoul (s+1,&s,16)) && (*s++ == ':') &&
(s < (char *) (LOCAL->buf + elt->private.msg.header.offset))) {
/* won, set offset and size of message */
i = elt->private.msg.header.offset;
*length = elt->private.msg.header.text.size;
+ if (k != elt->rfc822_size) {
+ sprintf (tmp,"Inconsistency in mix message size, uid=%.08x (%lu != %lu)",
+ elt->private.uid,elt->rfc822_size,k);
+ MM_LOG (tmp,WARN);
+ }
}
else { /* document the problem */
LOCAL->buf[100] = '\0'; /* tie off buffer at no more than 100 octets */
@@ -940,7 +962,7 @@
LOCAL->lastsnarf = time (0);/* note time of last snarf */
}
/* open index file */
- if (idxf = mix_index_open (stream,NIL)) {
+ if (idxf = mix_index_open (stream,stream->rdonly ? NIL : LONGT)) {
/* expunging OK if global flag set */
if (mail_parameters (NIL,GET_EXPUNGEATPING,NIL)) LOCAL->expok = T;
/* process metadata/index/status */
@@ -1298,7 +1320,7 @@
{
do if (set->last > size) { /* sanity check */
char tmp[MAILTMPLEN];
- sprintf (tmp,"Unexpected short mix message file %.80s %ld < %ld",
+ sprintf (tmp,"Unexpected short mix message file %.80s %lu < %lu",
file,size,set->last);
MM_LOG (tmp,ERROR);
return NIL; /* don't burp this file at all */
@@ -1318,20 +1340,15 @@
{
FDDATA d;
STRING st;
- MESSAGECACHE *elt;
- struct stat sbuf;
- int fd;
- unsigned long i,j,uid,uidv;
- char *t,tmp[2*MAILTMPLEN];
- long ret;
- MAILSTREAM *astream = NIL;
+ char tmp[2*MAILTMPLEN];
+ long ret = mix_isvalid (mailbox,LOCAL->buf);
mailproxycopy_t pc =
(mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);
+ MAILSTREAM *astream = NIL;
FILE *idxf = NIL;
FILE *msgf = NIL;
FILE *statf = NIL;
- /* make sure valid mailbox */
- if (!(ret = mix_isvalid (mailbox,LOCAL->buf))) switch (errno) {
+ if (!ret) switch (errno) { /* make sure valid mailbox */
case NIL: /* no error in stat() */
if (pc) return (*pc) (stream,sequence,mailbox,options);
sprintf (tmp,"Not a MIX-format mailbox: %.80s",mailbox);
@@ -1345,51 +1362,37 @@
else if (!(ret = ((options & CP_UID) ? mail_uid_sequence (stream,sequence) :
mail_sequence (stream,sequence))));
/* acquire stream to append */
- else if (!(astream = mail_open (NIL,mailbox,OP_SILENT))) {
- sprintf (tmp,"Can't open copy mailbox: %.80s",strerror (errno));
- MM_LOG (tmp,ERROR);
- ret = NIL;
- }
-
- else if ((idxf = mix_index_open (astream,LONGT)) &&
- (statf = mix_status_open (astream,MSO_WRITE))) {
+ else if (ret = ((astream = mail_open (NIL,mailbox,OP_SILENT)) &&
+ (idxf = mix_index_open (astream,LONGT)) &&
+ (statf = mix_parse (astream,idxf,MSO_WRITE))) ?
+ LONGT : NIL) {
+ int fd;
+ unsigned long i;
+ MESSAGECACHE *elt;
+ unsigned long newsize,hdrsize,size;
MIXLOCAL *local = (MIXLOCAL *) astream->local;
- copyuid_t cu = (copyuid_t) mail_parameters (NIL,GET_COPYUID,NIL);
- SEARCHSET *source = cu ? mail_newsearchset () : NIL;
- SEARCHSET *dest = cu ? mail_newsearchset () : NIL;
- unsigned long seq = mix_modseq (local->indexseq);
- unsigned long cursize,hdrsize;
+ unsigned long seq = mix_modseq (local->metaseq);
+ /* make sure new modseq fits */
+ if (local->indexseq > seq) seq = local->indexseq + 1;
+ if (local->statusseq > seq) seq = local->statusseq + 1;
/* calculate size of per-message header */
sprintf (local->buf,MSRFMT,MSGTOK,0,0,0,0,0,0,0,'+',0,0,0);
hdrsize = strlen (local->buf);
- /* make sure new modseq fits */
- if (local->indexseq > seq) seq = local->indexseq + 1;
- if (local->statusseq > seq) seq = local->statusseq + 1;
+
MM_CRITICAL (stream); /* go critical */
astream->silent = T; /* no events here */
- if (ret = (((fd = open (mix_file_data(local->buf,local->dir,local->newmsg),
- O_RDWR,NIL)) >= 0) &&
- (msgf = fdopen (fd,"r+b")))) {
- fstat (fd,&sbuf); /* get current file size */
- fseek (msgf,sbuf.st_size,SEEK_SET);
- /* if non-empty what is size after delivery? */
- if (cursize = sbuf.st_size)
- for (i = 1; (cursize < MIXDATAROLL) && (i <= stream->nmsgs); ++i)
- if ((elt = mail_elt (stream,i))->sequence)
- cursize += hdrsize + elt->rfc822_size;
- /* if too big, roll to a new file */
- if (cursize > MIXDATAROLL) {
- fclose (msgf); /* close old file, create new one */
- while (((fd = open (mix_file_data
- (local->buf,local->dir,
- local->newmsg = mix_modseq (local->newmsg)),
- O_RDWR | O_CREAT | O_EXCL,
- (int) mail_parameters (NIL,GET_MBXPROTECTION,NIL)))
- < 0) || !(msgf = fdopen (fd,"r+b")))
- if (fd >= 0) close (fd);
- }
-
- if (ret) for (i = 1,uid = uidv = 0; ret && (i <= stream->nmsgs); ++i)
+ /* calculate size that will be added */
+ for (i = 1, newsize = 0; i <= stream->nmsgs; ++i)
+ if ((elt = mail_elt (stream,i))->sequence)
+ newsize += hdrsize + elt->rfc822_size;
+ /* open data file */
+ if (msgf = mix_data_open (astream,&fd,&size,newsize)) {
+ char *t;
+ unsigned long j,uid,uidv;
+ copyuid_t cu = (copyuid_t) mail_parameters (NIL,GET_COPYUID,NIL);
+ SEARCHSET *source = cu ? mail_newsearchset () : NIL;
+ SEARCHSET *dest = cu ? mail_newsearchset () : NIL;
+ for (i = 1,uid = uidv = 0; ret && (i <= stream->nmsgs); ++i)
if (((elt = mail_elt (stream,i))->sequence) && elt->rfc822_size) {
/* is message in current message file? */
if ((LOCAL->msgfd < 0) ||
@@ -1428,55 +1431,51 @@
mail_append_set (source,mail_uid (stream,i));
}
}
- }
- else { /* message file open failed */
- sprintf (tmp,"Error opening copy message file: %.80s",
- strerror (errno));
- MM_LOG (tmp,ERROR);
- if (fd >= 0) close (fd); /* clean up in case fdopen() failure */
- }
- if (msgf) { /* take no action if no open message file */
- /* if error... */
- if (!ret || (fflush (msgf) == EOF)) {
- /* revert file */
- ftruncate (fd,sbuf.st_size);
- close (fd); /* make sure that fclose doesn't corrupt us */
- if (errno) {
+ /* finish write if success */
+ if (ret && (ret = !fflush (msgf))) {
+ fclose (msgf); /* all good, close the msg file now */
+ /* write new metadata, index, and status */
+ local->metaseq = local->indexseq = local->statusseq = seq;
+ if (ret = (mix_meta_update (astream) &&
+ mix_index_update (astream,&idxf,LONGT))) {
+ /* success, delete if doing a move */
+ if (options & CP_MOVE)
+ for (i = 1; i <= stream->nmsgs; i++)
+ if ((elt = mail_elt (stream,i))->sequence) {
+ elt->deleted = T;
+ elt->private.mod = LOCAL->statusseq = seq;
+ MM_FLAGS (stream,elt->msgno);
+ }
+ /* done with status file now */
+ mix_status_update (astream,&statf,LONGT);
+ /* return sets if doing COPYUID */
+ if (cu) (*cu) (stream,mailbox,astream->uid_validity,source,dest);
+ source = dest = NIL; /* don't free these sets now */
+ }
+ }
+ else { /* error */
+ if (errno) { /* output error message if system call error */
sprintf (tmp,"Message copy failed: %.80s",strerror (errno));
MM_LOG (tmp,ERROR);
}
- ret = NIL; /* make sure error is set now */
+ ftruncate (fd,size); /* revert file */
+ close (fd); /* make sure that fclose doesn't corrupt us */
+ fclose (msgf); /* free the stdio resources */
}
- fclose (msgf); /* close the msg file now */
- if (ret) { /* if success */
- /* write new metadata, index, and status */
- local->metaseq = local->indexseq = local->statusseq = seq;
- ret = (mix_meta_update (astream) &&
- mix_index_update (astream,&idxf,LONGT) &&
- mix_status_update (astream,&statf,LONGT));
- }
- }
-
- if (ret) { /* if still success, delete if doing a move */
- if ((options & CP_MOVE) && (statf = mix_status_open (stream,MSO_WRITE))){
- for (i = 1; i <= stream->nmsgs; i++)
- if ((elt = mail_elt (stream,i))->sequence) {
- elt->deleted = T;
- elt->private.mod = LOCAL->statusseq = seq;
- MM_FLAGS (stream,elt->msgno);
- }
- mix_status_update (stream,&statf,LONGT);
- }
- /* return sets if doing COPYUID */
- if (cu) (*cu) (stream,mailbox,astream->uid_validity,source,dest);
- }
- else { /* flush any sets we may have built */
+ /* flush any sets remaining */
mail_free_searchset (&source);
mail_free_searchset (&dest);
}
+ else { /* message file open failed */
+ sprintf (tmp,"Error opening copy message file: %.80s",
+ strerror (errno));
+ MM_LOG (tmp,ERROR);
+ ret = NIL;
+ }
MM_NOCRITICAL (stream);
}
+ else MM_LOG ("Can't open copy mailbox",ERROR);
if (statf) fclose (statf); /* close status if still open */
if (idxf) fclose (idxf); /* close index if still open */
/* finished with append stream */
@@ -1494,21 +1493,13 @@
long mix_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data)
{
- MESSAGECACHE elt;
- MAILSTREAM *astream;
STRING *message;
- struct stat sbuf;
- int fd;
char *flags,*date,tmp[MAILTMPLEN];
- long ret;
- FILE *idxf = NIL;
- FILE *msgf = NIL;
- FILE *statf = NIL;
+ /* N.B.: can't use LOCAL->buf for tmp */
+ long ret = mix_isvalid (mailbox,tmp);
/* default stream to prototype */
if (!stream) stream = user_flags (&mixproto);
- /* N.B.: can't use LOCAL->buf for tmp */
- /* make sure valid mailbox */
- if (!(ret = mix_isvalid (mailbox,tmp))) switch (errno) {
+ if (!ret) switch (errno) { /* if not valid mailbox */
case ENOENT: /* no such file? */
if (ret = compare_cstring (mailbox,"INBOX") ?
NIL : mix_create (NIL,"INBOX"))
@@ -1520,49 +1511,36 @@
MM_LOG (tmp,ERROR);
break;
}
+
/* get first message */
if (ret && MM_APPEND (af) (stream,data,&flags,&date,&message)) {
- if (!(astream = mail_open (NIL,mailbox,OP_SILENT))) {
- sprintf (tmp,"Can't open append mailbox: %.80s",strerror (errno));
- MM_LOG (tmp,ERROR);
- ret = NIL;
- }
-
- else if ((idxf = mix_index_open (astream,LONGT)) &&
- (statf = mix_status_open (astream,MSO_WRITE))) {
+ MAILSTREAM *astream;
+ FILE *idxf = NIL;
+ FILE *msgf = NIL;
+ FILE *statf = NIL;
+ if (ret = ((astream = mail_open (NIL,mailbox,OP_SILENT)) &&
+ (idxf = mix_index_open (astream,LONGT)) &&
+ (statf = mix_parse (astream,idxf,MSO_WRITE))) ? LONGT : NIL) {
+ int fd;
+ unsigned long size,hdrsize;
+ MESSAGECACHE elt;
MIXLOCAL *local = (MIXLOCAL *) astream->local;
- appenduid_t au = (appenduid_t) mail_parameters (NIL,GET_APPENDUID,NIL);
- SEARCHSET *dst = au ? mail_newsearchset () : NIL;
unsigned long seq = mix_modseq (local->metaseq);
- unsigned long cursize,hdrsize;
+ /* make sure new modseq fits */
+ if (local->indexseq > seq) seq = local->indexseq + 1;
+ if (local->statusseq > seq) seq = local->statusseq + 1;
/* calculate size of per-message header */
sprintf (local->buf,MSRFMT,MSGTOK,0,0,0,0,0,0,0,'+',0,0,0);
hdrsize = strlen (local->buf);
- /* make sure new modseq fits */
- if (local->indexseq > seq) seq = local->indexseq + 1;
- if (local->statusseq > seq) seq = local->statusseq + 1;
MM_CRITICAL (astream); /* go critical */
astream->silent = T; /* no events here */
- if (ret = (((fd = open (mix_file_data (tmp,local->dir,local->newmsg),
- O_RDWR,NIL)) >= 0) &&
- (msgf = fdopen (fd,"r+b")))) {
- fstat (fd,&sbuf); /* get current file size */
- fseek (msgf,sbuf.st_size,SEEK_SET);
- /* if non-empty what is size after delivery? */
- if (cursize = sbuf.st_size) cursize += hdrsize + SIZE (message);
- /* if too big, roll to a new file */
- if (cursize > MIXDATAROLL) {
- fclose (msgf); /* close old file, create new one */
- while (((fd = open (mix_file_data
- (local->buf,local->dir,
- local->newmsg = mix_modseq (local->newmsg)),
- O_RDWR | O_CREAT | O_EXCL,
- (int)mail_parameters(NIL,GET_MBXPROTECTION,NIL)))
- < 0) || !(msgf = fdopen (fd,"r+b")))
- if (fd >= 0) close (fd);
- }
-
- while (ret && message) {/* guard against zero-length */
+ /* open data file */
+ if (msgf = mix_data_open (astream,&fd,&size,hdrsize + SIZE (message))) {
+ appenduid_t au = (appenduid_t) mail_parameters (NIL,GET_APPENDUID,NIL);
+ SEARCHSET *dst = au ? mail_newsearchset () : NIL;
+ while (ret && message) {/* while good to go and have messages */
+ errno = NIL; /* in case one of these causes failure */
+ /* guard against zero-length */
if (!(ret = SIZE (message)))
MM_LOG ("Append of zero-length message",ERROR);
else if (date && !(ret = mail_parse_date (&elt,date))) {
@@ -1578,39 +1556,40 @@
MM_APPEND (af) (stream,data,&flags,&date,&message);
}
}
+
+ /* finish write if success */
+ if (ret && (ret = !fflush (msgf))) {
+ fclose (msgf); /* all good, close the msg file now */
+ /* write new metadata, index, and status */
+ local->metaseq = local->indexseq = local->statusseq = seq;
+ if ((ret = (mix_meta_update (astream) &&
+ mix_index_update (astream,&idxf,LONGT) &&
+ mix_status_update (astream,&statf,LONGT))) && au) {
+ (*au) (mailbox,astream->uid_validity,dst);
+ dst = NIL; /* don't free this set now */
+ }
+ }
+ else { /* failure */
+ if (errno) { /* output error message if system call error */
+ sprintf (tmp,"Message append failed: %.80s",strerror (errno));
+ MM_LOG (tmp,ERROR);
+ }
+ ftruncate (fd,size); /* revert all writes to file*/
+ close (fd); /* make sure that fclose doesn't corrupt us */
+ fclose (msgf); /* free the stdio resources */
+ }
+ /* flush any set remaining */
+ mail_free_searchset (&dst);
}
else { /* message file open failed */
sprintf (tmp,"Error opening append message file: %.80s",
strerror (errno));
MM_LOG (tmp,ERROR);
- if (fd >= 0) close (fd);/* clean up in case fdopen() failure */
+ ret = NIL;
}
- if (msgf) { /* take no action if no open message file */
- /* if error... */
- if (!ret || (fflush (msgf) == EOF)) {
- /* revert file */
- ftruncate (fd,sbuf.st_size);
- close (fd); /* make sure that fclose doesn't corrupt us */
- if (errno) {
- sprintf (tmp,"Message append failed: %.80s",strerror (errno));
- MM_LOG (tmp,ERROR);
- }
- ret = NIL; /* make sure error is set now */
- }
- fclose (msgf); /* close the msg file now */
- if (ret) { /* if success */
- /* write new metadata, index, and status */
- local->metaseq = local->indexseq = local->statusseq = seq;
- ret = (mix_meta_update (astream) &&
- mix_index_update (astream,&idxf,LONGT) &&
- mix_status_update (astream,&statf,LONGT));
- }
- }
- /* return sets if doing APPENDUID */
- if (au && ret) (*au) (mailbox,astream->uid_validity,dst);
- else mail_free_searchset (&dst);
MM_NOCRITICAL (astream); /* release critical */
}
+ else MM_LOG ("Can't open append mailbox",ERROR);
if (statf) fclose (statf); /* close status if still open */
if (idxf) fclose (idxf); /* close index if still open */
if (astream) mail_close (astream);
@@ -1633,7 +1612,7 @@
{
MESSAGECACHE *elt;
int c,cs;
- unsigned long i,uf,hoff;
+ unsigned long i,j,k,uf,hoff;
long sf = mail_parse_flags (stream,flags,&uf);
/* swell the cache */
mail_exists (stream,++stream->nmsgs);
@@ -1671,8 +1650,9 @@
/* copy message */
for (i = 1, cs = 0; i <= elt->rfc822_size; ++i) {
if (elt->private.msg.header.text.size) {
- if (msg->cursize) {
- if (fwrite (msg->curpos,1,msg->cursize,f) == EOF) return NIL;
+ if (msg->cursize) { /* blat entire chunk if have it */
+ for (j = msg->cursize; j; j -= k)
+ if (!(k = fwrite (msg->curpos,1,j,f))) return NIL;
i += msg->cursize; /* advance to next chunk */
}
SETPOS (msg,GETPOS (msg) + msg->cursize);
@@ -1708,16 +1688,21 @@
/* MIX mail (re-)read metadata, possibly index, and status
* Accepts: MAIL stream
* open index file
- * flags (non-zero to open status for write)
+ * flags for mix_status_open()
* Returns: open status file, or NIL if failure
*/
+static char *shortmsg =
+ "message %lu (UID=%.08lx) truncated by %lu byte(s) (%lu < %lu)";
+
FILE *mix_parse (MAILSTREAM *stream,FILE *idxf,long flags)
{
unsigned long i,j;
char *s;
struct stat sbuf;
FILE *ret = NIL;
+ short metarepairneeded = 0;
+ short indexrepairneeded = 0;
short silent = stream->silent;
fstat (LOCAL->mfd,&sbuf); /* get current size of metadata file */
if (sbuf.st_size > LOCAL->buflen) {
@@ -1804,34 +1789,36 @@
}
/* sequence changed from last time? */
else if (j || (i > LOCAL->indexseq)) {
- unsigned long uid;
- char *msg,tmp[MAILTMPLEN];
- unsigned long nmsgs = 0; /* start with no messages */
+ unsigned long uid,nmsgs,curfile,curfilesize,curpos;
+ char *t,*msg,tmp[MAILTMPLEN];
+ /* start with no messages */
+ curfile = curfilesize = curpos = nmsgs = 0;
LOCAL->indexseq = i; /* update sequence, get first elt */
while ((s = mix_read_record (idxf,LOCAL->buf,LOCAL->buflen)) && *s)
switch (*s) {
case ':': /* message record */
- if (isxdigit (*++s) && (uid = strtoul (s,&s,16)) &&
- (uid <= stream->uid_last) &&
- (*s++ == ':') && isdigit (*s) && isdigit (s[1]) &&
- isdigit (s[2]) && isdigit (s[3]) && isdigit (s[4]) &&
- isdigit (s[5]) && isdigit (s[6]) && isdigit (s[7]) &&
- isdigit (s[8]) && isdigit (s[9]) && isdigit (s[10]) &&
- isdigit (s[11]) && isdigit (s[12]) && isdigit (s[13]) &&
- ((s[14] == '+') || (s[14] == '-')) &&
- isdigit (s[15]) && isdigit (s[16]) && isdigit (s[17]) &&
- isdigit (s[18]) && (s[19] == ':') && isxdigit (s[20])) {
- unsigned int y = (((*s - '0') * 1000) + ((s[1] - '0') * 100) +
- ((s[2] - '0') * 10) + s[3] - '0') - BASEYEAR;
- unsigned int m = ((s[4] - '0') * 10) + s[5] - '0';
- unsigned int d = ((s[6] - '0') * 10) + s[7] - '0';
- unsigned int hh = ((s[8] - '0') * 10) + s[9] - '0';
- unsigned int mm = ((s[10] - '0') * 10) + s[11] - '0';
- unsigned int ss = ((s[12] - '0') * 10) + s[13] - '0';
- unsigned int z = (s[14] == '-') ? 1 : 0;
- unsigned int zh = ((s[15] - '0') * 10) + s[16] - '0';
- unsigned int zm = ((s[17] - '0') * 10) + s[18] - '0';
- unsigned long size = strtoul (s+20,&s,16);
+ if (!(isxdigit (*++s) && (uid = strtoul (s,&t,16)))) msg = "UID";
+ else if (!((*t++ == ':') && isdigit (*t) && isdigit (t[1]) &&
+ isdigit (t[2]) && isdigit (t[3]) && isdigit (t[4]) &&
+ isdigit (t[5]) && isdigit (t[6]) && isdigit (t[7]) &&
+ isdigit (t[8]) && isdigit (t[9]) && isdigit (t[10]) &&
+ isdigit (t[11]) && isdigit (t[12]) && isdigit (t[13]) &&
+ ((t[14] == '+') || (t[14] == '-')) &&
+ isdigit (t[15]) && isdigit (t[16]) && isdigit (t[17]) &&
+ isdigit (t[18]))) msg = "internaldate";
+ else if ((*(s = t+19) != ':') || !isxdigit (*++s)) msg = "size";
+ else {
+ unsigned int y = (((*t - '0') * 1000) + ((t[1] - '0') * 100) +
+ ((t[2] - '0') * 10) + t[3] - '0') - BASEYEAR;
+ unsigned int m = ((t[4] - '0') * 10) + t[5] - '0';
+ unsigned int d = ((t[6] - '0') * 10) + t[7] - '0';
+ unsigned int hh = ((t[8] - '0') * 10) + t[9] - '0';
+ unsigned int mm = ((t[10] - '0') * 10) + t[11] - '0';
+ unsigned int ss = ((t[12] - '0') * 10) + t[13] - '0';
+ unsigned int z = (t[14] == '-') ? 1 : 0;
+ unsigned int zh = ((t[15] - '0') * 10) + t[16] - '0';
+ unsigned int zm = ((t[17] - '0') * 10) + t[18] - '0';
+ unsigned long size = strtoul (s,&s,16);
if ((*s++ == ':') && isxdigit (*s)) {
unsigned long file = strtoul (s,&s,16);
if ((*s++ == ':') && isxdigit (*s)) {
@@ -1840,9 +1827,21 @@
unsigned long hpos = strtoul (s,&s,16);
if ((*s++ == ':') && isxdigit (*s)) {
unsigned long hsiz = strtoul (s,&s,16);
- /* ignore expansion values */
+ if (uid > stream->uid_last) {
+ sprintf (tmp,"mix index invalid UID (%08lx < %08lx)",
+ uid,stream->uid_last);
+ if (stream->rdonly) {
+ MM_LOG (tmp,ERROR);
+ return NIL;
+ }
+ strcat (tmp,", repaired");
+ MM_LOG (tmp,WARN);
+ stream->uid_last = uid;
+ metarepairneeded = T;
+ }
+
+ /* ignore expansion values */
if (*s++ == ':') {
-
MESSAGECACHE *elt;
++nmsgs; /* this is another mesage */
/* within current known range of messages? */
@@ -1880,6 +1879,7 @@
return NIL;
}
}
+
/* time to create a new message? */
if (nmsgs > stream->nmsgs) {
/* defer announcing until later */
@@ -1896,10 +1896,63 @@
elt->hours = hh; elt->minutes = mm;
elt->seconds = ss; elt->zoccident = z;
elt->zhours = zh; elt->zminutes = zm;
+
+ /* message in same file? */
+ if (curfile == file) {
+ if (pos < curpos) {
+ MESSAGECACHE *plt = mail_elt (stream,elt->msgno-1);
+ /* uh-oh, calculate delta? */
+ i = curpos - pos;
+ sprintf (tmp,shortmsg,plt->msgno,plt->private.uid,
+ i,pos,curpos);
+ /* possible to fix? */
+ if (!stream->rdonly && (i < plt->rfc822_size)) {
+ plt->rfc822_size -= i;
+ if (plt->rfc822_size <
+ plt->private.msg.header.text.size)
+ plt->private.msg.header.text.size =
+ plt->rfc822_size;
+ strcat (tmp,", repaired");
+ indexrepairneeded = T;
+ }
+ MM_LOG (tmp,WARN);
+ }
+ }
+ else { /* new file, restart */
+ if (stat (mix_file_data (LOCAL->buf,LOCAL->dir,
+ curfile = file),&sbuf)) {
+ sprintf (tmp,"Missing mix data file: %.500s",
+ LOCAL->buf);
+ MM_LOG (tmp,ERROR);
+ return NIL;
+ }
+ curfile = file;
+ curfilesize = sbuf.st_size;
+ }
+ curpos = pos + elt->private.msg.header.offset +
+ elt->rfc822_size;
+ /* short file? */
+ if (curfilesize < curpos) {
+ /* uh-oh, calculate delta? */
+ i = curpos - curfilesize;
+ sprintf (tmp,shortmsg,elt->msgno,elt->private.uid,
+ i,curfilesize,curpos);
+ /* possible to fix? */
+ if (!stream->rdonly && (i < elt->rfc822_size)) {
+ elt->rfc822_size -= i;
+ if (elt->rfc822_size <
+ elt->private.msg.header.text.size)
+ elt->private.msg.header.text.size =
+ elt->rfc822_size;
+ strcat (tmp,", repaired");
+ indexrepairneeded = T;
+ }
+ MM_LOG (tmp,WARN);
+ }
}
break;
+
}
-
else msg = "expansion";
}
else msg = "header size";
@@ -1910,7 +1963,6 @@
}
else msg = "file#";
}
- else msg = "UID, internaldate or size";
sprintf (tmp,"Error in %s in mix index file: %.500s",msg,s);
MM_LOG (tmp,ERROR);
return NIL;
@@ -1924,8 +1976,10 @@
if (LOCAL->expok) while (nmsgs < stream->nmsgs)
mail_expunged (stream,stream->nmsgs);
}
- /* all is well, open status */
- ret = mix_status_open (stream,flags);
+ /* repair index if needed and open status */
+ ret = ((metarepairneeded ? mix_meta_update (stream) : T) &&
+ (indexrepairneeded ? mix_index_update (stream,&idxf,NIL) : T)) ?
+ mix_status_open (stream,flags) : NIL;
}
if (ret) { /* still happy? */
stream->silent = silent; /* now notify upper level */
@@ -1990,9 +2044,6 @@
* Accepts: MAIL stream
* flags (non-zero to open for write)
* Returns: open FILE, or NIL if failure
- *
- * Note: mix_parse() calls this with the same flags that are passed to
- * mix_status_open().
*/
FILE *mix_index_open (MAILSTREAM *stream,long flags)
@@ -2085,8 +2136,11 @@
}
else if (!stream->nmsgs); /* do nothing if mailbox empty */
/* get sequence */
- else if (!(i = mix_read_sequence (statf)) || (i < LOCAL->statusseq))
- MM_LOG ("Error in mix status file sequence record",ERROR);
+ else if (!(i = mix_read_sequence (statf)) || (i < LOCAL->statusseq)) {
+ sprintf (LOCAL->buf,"Error in mix status sequence record, i=%lu, seq=%lu",
+ i,LOCAL->statusseq);
+ MM_LOG (LOCAL->buf,ERROR);
+ }
/* sequence changed from last time? */
else if (i > LOCAL->statusseq) {
LOCAL->statusseq = i; /* update sequence, get first elt */
@@ -2167,6 +2221,7 @@
{
FILE *f = *statf;
unsigned long i;
+ char tmp[MAILTMPLEN];
rewind (f); /* let's start at the very beginning */
ftruncate (fileno (f),0); /* ...a very good place to start... */
/* write sequence */
@@ -2182,13 +2237,15 @@
(fDRAFT * elt->draft) + (elt->valid ? fOLD : NIL),
elt->private.mod);
if (ferror (f)) {
- MM_LOG ("Error updating mix status file",ERROR);
+ sprintf (tmp,"Error updating mix status file: %.80s",strerror (errno));
+ MM_LOG (tmp,ERROR);
return NIL;
}
}
if (flag) { /* close index if requested */
if (fclose (f)) {
- MM_LOG ("Error closing mix status file",ERROR);
+ sprintf (tmp,"Error closing mix status file: %.80s",strerror (errno));
+ MM_LOG (tmp,ERROR);
return NIL;
}
else *statf = NIL; /* note that status is closed */
@@ -2196,6 +2253,61 @@
return LONGT;
}
+/* MIX data file routines */
+
+
+/* MIX open data file
+ * Accepts: MAIL stream
+ * pointer to returned fd if success
+ * pointer to returned size if success
+ * size of new data to be added
+ * Returns: open FILE, or NIL if failure
+ *
+ * The curend test assumes that the last message of the mailbox is the furthest
+ * point that the current data file extends, and thus that is all that needs to
+ * be tested for short file prevention.
+ */
+
+FILE *mix_data_open (MAILSTREAM *stream,int *fd,long *size,
+ unsigned long newsize)
+{
+ FILE *msgf = NIL;
+ struct stat sbuf;
+ MESSAGECACHE *elt = stream->nmsgs ? mail_elt (stream,stream->nmsgs) : NIL;
+ unsigned long curend = (elt && (elt->private.spare.data == LOCAL->newmsg)) ?
+ elt->private.special.offset + elt->private.msg.header.offset +
+ elt->rfc822_size : 0;
+ if ((*fd = open (mix_file_data (LOCAL->buf,LOCAL->dir,LOCAL->newmsg),
+ O_RDWR,NIL)) >= 0) {
+ fstat (*fd,&sbuf); /* get current file size */
+ /* can we use this file? */
+ if ((curend <= sbuf.st_size) &&
+ (!sbuf.st_size || ((sbuf.st_size + newsize) <= MIXDATAROLL)))
+ *size = sbuf.st_size; /* yes, return current size */
+ else { /* short file or becoming too long */
+ if (curend > sbuf.st_size) {
+ char tmp[MAILTMPLEN];
+ sprintf (tmp,"short mix message file %lx (%ld > %ld), rolling",
+ LOCAL->newmsg,curend,sbuf.st_size);
+ MM_LOG (tmp,WARN); /* shouldn't happen */
+ }
+ close (*fd); /* roll to a new file */
+ while ((*fd = open (mix_file_data
+ (LOCAL->buf,LOCAL->dir,
+ LOCAL->newmsg = mix_modseq (LOCAL->newmsg)),
+ O_RDWR | O_CREAT | O_EXCL,sbuf.st_mode)) < 0);
+ *size = 0; /* brand new file */
+ fchmod (*fd,sbuf.st_mode);/* with same mode as previous file */
+ }
+ }
+ if (*fd >= 0) { /* have a data file? */
+ /* yes, get stdio and set position */
+ if (msgf = fdopen (*fd,"r+b")) fseek (msgf,*size,SEEK_SET);
+ else close (*fd); /* fdopen() failed? */
+ }
+ return msgf; /* return results */
+}
+
/* MIX open sortcache
* Accepts: MAIL stream
* Returns: open FILE, or NIL if failure or could only get readonly sortcache
@@ -2522,15 +2634,18 @@
/* MIX mail build directory name
* Accepts: destination string
* source
- * Returns: destination
+ * Returns: destination or empty string if error
*/
char *mix_dir (char *dst,char *name)
{
char *s;
- if (!(mailboxfile (dst,name) && *dst)) return mailboxfile (dst,"~/INBOX");
+ /* empty string if mailboxfile fails */
+ if (!mailboxfile (dst,name)) *dst = '\0';
+ /* driver-selected INBOX */
+ else if (!*dst) mailboxfile (dst,"~/INBOX");
/* tie off unnecessary trailing / */
- if ((s = strrchr (dst,'/')) && !s[1]) *s = '\0';
+ else if ((s = strrchr (dst,'/')) && !s[1]) *s = '\0';
return dst;
}
Modified: trunk/M/lib/imap/src/osdep/amiga/mmdf.c
===================================================================
--- trunk/M/lib/imap/src/osdep/amiga/mmdf.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/amiga/mmdf.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 20 December 1989
- * Last Edited: 21 September 2006
+ * Last Edited: 6 October 2006
*/
@@ -227,6 +227,8 @@
SIZEDTEXT text; /* current text */
unsigned long textlen; /* current text length */
char *line; /* returned line */
+ char *linebuf; /* line readin buffer */
+ unsigned long linebuflen; /* current line readin buffer length */
} MMDFLOCAL;
@@ -619,6 +621,8 @@
LOCAL->buflen = CHUNKSIZE - 1;
LOCAL->text.data = (unsigned char *) fs_get (CHUNKSIZE);
LOCAL->text.size = CHUNKSIZE - 1;
+ LOCAL->linebuf = (char *) fs_get (CHUNKSIZE);
+ LOCAL->linebuflen = CHUNKSIZE - 1;
stream->sequence++; /* bump sequence number */
/* make lock for read/write access */
@@ -1447,6 +1451,7 @@
/* free local text buffers */
if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
if (LOCAL->text.data) fs_give ((void **) &LOCAL->text.data);
+ if (LOCAL->linebuf) fs_give ((void **) &LOCAL->linebuf);
if (LOCAL->line) fs_give ((void **) &LOCAL->line);
/* nuke the local data */
fs_give ((void **) &stream->local);
@@ -1478,15 +1483,15 @@
if (dotlock_lock (file,lock,fd)) {
close (fd); /* get fresh fd in case of timing race */
if ((fd = open (file,flags,mode)) >= 0) flock (fd,op);
- else dotlock_unlock (lock); /* open failed, free the dotlock */
+ /* open failed, free the dotlock */
+ else dotlock_unlock (lock);
}
else flock (fd,op); /* paranoid way failed, just flock() it */
}
(*bn) (BLOCK_NONE,NIL);
return fd;
}
-
-
+
/* MMDF unlock and close mailbox
* Accepts: file descriptor
* (optional) mailbox stream to check atime/mtime
@@ -1988,8 +1993,6 @@
{
unsigned long i,j,k,m;
char *s,*t,*te;
- char *tmp = (char *) fs_get (CHUNKSIZE);
- unsigned long tmplen = CHUNKSIZE;
char *ret = "";
/* flush old buffer */
if (LOCAL->line) fs_give ((void **) &LOCAL->line);
@@ -2009,11 +2012,13 @@
while ((s < t) && (*s != '\n')) ++s;
/* difficult case if line spans buffer */
if ((i = s - bs->curpos) == bs->cursize) {
- if (i > tmplen) { /* have space in tmp buffer? */
- fs_give ((void **) &tmp);
- tmp = (char *) fs_get (tmplen = i);
+ /* have space in line buffer? */
+ if (i > LOCAL->linebuflen) {
+ fs_give ((void **) &LOCAL->linebuf);
+ LOCAL->linebuf = (char *) fs_get (LOCAL->linebuflen = i);
}
- memcpy (tmp,bs->curpos,i);/* remember what we have so far */
+ /* remember what we have so far */
+ memcpy (LOCAL->linebuf,bs->curpos,i);
/* load next buffer */
SETPOS (bs,k = GETPOS (bs) + i);
/* end of fast scan */
@@ -2026,6 +2031,7 @@
--s; /* back up */
break; /* exit loop */
}
+
/* final character-at-a-time scan */
while ((s < t) && (*s != '\n')) ++s;
/* huge line? */
@@ -2035,10 +2041,10 @@
for (m = SIZE (bs); m && (SNX (bs) != '\n'); --m,++j);
SETPOS (bs,k); /* go back to where it started */
}
-
/* got size of data, make buffer for return */
ret = LOCAL->line = (char *) fs_get (i + j + 2);
- memcpy (ret,tmp,i); /* copy first chunk */
+ /* copy first chunk */
+ memcpy (ret,LOCAL->linebuf,i);
while (j) { /* copy remainder */
if (!bs->cursize) SETPOS (bs,GETPOS (bs));
memcpy (ret + i,bs->curpos,k = min (j,bs->cursize));
@@ -2066,7 +2072,6 @@
*size -= i; /* reduce length of line */
ret[*size - 1] = '\n'; /* force newline at end */
}
- fs_give ((void **) &tmp); /* done with tmp buffer */
return ret;
}
Modified: trunk/M/lib/imap/src/osdep/amiga/mx.c
===================================================================
--- trunk/M/lib/imap/src/osdep/amiga/mx.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/amiga/mx.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 3 May 1996
- * Last Edited: 13 September 2006
+ * Last Edited: 22 October 2006
*/
@@ -178,8 +178,8 @@
struct stat sbuf;
errno = NIL; /* zap error */
/* validate name as directory */
- return ((strlen (name) <= NETMAXMBX) && !stat (mx_file (tmp,name),&sbuf) &&
- ((sbuf.st_mode & S_IFMT) == S_IFDIR) &&
+ return ((strlen (name) <= NETMAXMBX) && *mx_file (tmp,name) &&
+ !stat (tmp,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFDIR) &&
!stat (MXINDEX (tmp,name),&sbuf) &&
((sbuf.st_mode & S_IFMT) == S_IFREG));
}
@@ -919,8 +919,7 @@
mail_sequence (stream,sequence))));
/* acquire stream to append to */
else if (!(astream = mail_open (NIL,mailbox,OP_SILENT))) {
- sprintf (tmp,"Can't open copy mailbox: %s",strerror (errno));
- MM_LOG (tmp,ERROR);
+ MM_LOG ("Can't open copy mailbox",ERROR);
ret = NIL;
}
else {
@@ -1019,8 +1018,7 @@
/* get first message */
if (!MM_APPEND (af) (stream,data,&flags,&date,&message)) return NIL;
if (!(astream = mail_open (NIL,mailbox,OP_SILENT))) {
- sprintf (tmp,"Can't open append mailbox: %s",strerror (errno));
- MM_LOG (tmp,ERROR);
+ MM_LOG ("Can't open append mailbox",ERROR);
return NIL;
}
MM_CRITICAL (astream); /* go critical */
@@ -1140,9 +1138,12 @@
char *mx_file (char *dst,char *name)
{
char *s;
- if (!(mailboxfile (dst,name) && *dst)) return mailboxfile (dst,"~/INBOX");
+ /* empty string if mailboxfile fails */
+ if (!mailboxfile (dst,name)) *dst = '\0';
+ /* driver-selected INBOX */
+ else if (!*dst) mailboxfile (dst,"~/INBOX");
/* tie off unnecessary trailing / */
- if ((s = strrchr (dst,'/')) && !s[1]) *s = '\0';
+ else if ((s = strrchr (dst,'/')) && !s[1]) *s = '\0';
return dst;
}
Modified: trunk/M/lib/imap/src/osdep/amiga/unix.c
===================================================================
--- trunk/M/lib/imap/src/osdep/amiga/unix.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/amiga/unix.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 20 December 1989
- * Last Edited: 21 September 2006
+ * Last Edited: 6 October 2006
*/
@@ -72,6 +72,8 @@
SIZEDTEXT text; /* current text */
unsigned long textlen; /* current text length */
char *line; /* returned line */
+ char *linebuf; /* line readin buffer */
+ unsigned long linebuflen; /* current line readin buffer length */
} UNIXLOCAL;
@@ -464,6 +466,8 @@
LOCAL->buflen = CHUNKSIZE - 1;
LOCAL->text.data = (unsigned char *) fs_get (CHUNKSIZE);
LOCAL->text.size = CHUNKSIZE - 1;
+ LOCAL->linebuf = (char *) fs_get (CHUNKSIZE);
+ LOCAL->linebuflen = CHUNKSIZE - 1;
stream->sequence++; /* bump sequence number */
/* make lock for read/write access */
@@ -1298,6 +1302,7 @@
/* free local text buffers */
if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
if (LOCAL->text.data) fs_give ((void **) &LOCAL->text.data);
+ if (LOCAL->linebuf) fs_give ((void **) &LOCAL->linebuf);
if (LOCAL->line) fs_give ((void **) &LOCAL->line);
/* nuke the local data */
fs_give ((void **) &stream->local);
@@ -1329,15 +1334,15 @@
if (dotlock_lock (file,lock,fd)) {
close (fd); /* get fresh fd in case of timing race */
if ((fd = open (file,flags,mode)) >= 0) flock (fd,op);
- else dotlock_unlock (lock); /* open failed, free the dotlock */
+ /* open failed, free the dotlock */
+ else dotlock_unlock (lock);
}
else flock (fd,op); /* paranoid way failed, just flock() it */
}
(*bn) (BLOCK_NONE,NIL);
return fd;
}
-
-
+
/* UNIX unlock and close mailbox
* Accepts: file descriptor
* (optional) mailbox stream to check atime/mtime
@@ -1811,8 +1816,6 @@
{
unsigned long i,j,k,m;
char *s,*t,*te;
- char *tmp = (char *) fs_get (CHUNKSIZE);
- unsigned long tmplen = CHUNKSIZE;
char *ret = "";
/* flush old buffer */
if (LOCAL->line) fs_give ((void **) &LOCAL->line);
@@ -1832,11 +1835,13 @@
while ((s < t) && (*s != '\n')) ++s;
/* difficult case if line spans buffer */
if ((i = s - bs->curpos) == bs->cursize) {
- if (i > tmplen) { /* have space in tmp buffer? */
- fs_give ((void **) &tmp);
- tmp = (char *) fs_get (tmplen = i);
+ /* have space in line buffer? */
+ if (i > LOCAL->linebuflen) {
+ fs_give ((void **) &LOCAL->linebuf);
+ LOCAL->linebuf = (char *) fs_get (LOCAL->linebuflen = i);
}
- memcpy (tmp,bs->curpos,i);/* remember what we have so far */
+ /* remember what we have so far */
+ memcpy (LOCAL->linebuf,bs->curpos,i);
/* load next buffer */
SETPOS (bs,k = GETPOS (bs) + i);
/* end of fast scan */
@@ -1849,6 +1854,7 @@
--s; /* back up */
break; /* exit loop */
}
+
/* final character-at-a-time scan */
while ((s < t) && (*s != '\n')) ++s;
/* huge line? */
@@ -1858,10 +1864,10 @@
for (m = SIZE (bs); m && (SNX (bs) != '\n'); --m,++j);
SETPOS (bs,k); /* go back to where it started */
}
-
/* got size of data, make buffer for return */
ret = LOCAL->line = (char *) fs_get (i + j + 2);
- memcpy (ret,tmp,i); /* copy first chunk */
+ /* copy first chunk */
+ memcpy (ret,LOCAL->linebuf,i);
while (j) { /* copy remainder */
if (!bs->cursize) SETPOS (bs,GETPOS (bs));
memcpy (ret + i,bs->curpos,k = min (j,bs->cursize));
@@ -1883,7 +1889,6 @@
*size = i; /* return that to user */
}
else *size = 0; /* end of data, return empty */
- fs_give ((void **) &tmp);
return ret;
}
Modified: trunk/M/lib/imap/src/osdep/nt/unixnt.c
===================================================================
--- trunk/M/lib/imap/src/osdep/nt/unixnt.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/nt/unixnt.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 20 December 1989
- * Last Edited: 30 August 2006
+ * Last Edited: 6 October 2006
*/
@@ -73,6 +73,8 @@
SIZEDTEXT text; /* current text */
unsigned long textlen; /* current text length */
char *line; /* returned line */
+ char *linebuf; /* line readin buffer */
+ unsigned long linebuflen; /* current line readin buffer length */
} UNIXLOCAL;
@@ -447,6 +449,8 @@
LOCAL->buf = (char *) fs_get ((LOCAL->buflen = CHUNKSIZE) + 1);
LOCAL->text.data = (unsigned char *) fs_get (CHUNKSIZE);
LOCAL->text.size = CHUNKSIZE - 1;
+ LOCAL->linebuf = (char *) fs_get (CHUNKSIZE);
+ LOCAL->linebuflen = CHUNKSIZE - 1;
stream->sequence++; /* bump sequence number */
if (!stream->rdonly) { /* make lock for read/write access */
if ((fd = lockname (tmp,stream->mailbox,NIL)) < 0)
@@ -1245,6 +1249,7 @@
/* free local text buffers */
if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
if (LOCAL->text.data) fs_give ((void **) &LOCAL->text.data);
+ if (LOCAL->linebuf) fs_give ((void **) &LOCAL->linebuf);
if (LOCAL->line) fs_give ((void **) &LOCAL->line);
/* nuke the local data */
fs_give ((void **) &stream->local);
@@ -1770,8 +1775,6 @@
{
unsigned long i,j,k,m;
char *s,*t,*te;
- char *tmp = (char *) fs_get (CHUNKSIZE);
- unsigned long tmplen = CHUNKSIZE;
char *ret = "";
/* flush old buffer */
if (LOCAL->line) fs_give ((void **) &LOCAL->line);
@@ -1791,11 +1794,13 @@
while ((s < t) && (*s != '\n')) ++s;
/* difficult case if line spans buffer */
if ((i = s - bs->curpos) == bs->cursize) {
- if (i > tmplen) { /* have space in tmp buffer? */
- fs_give ((void **) &tmp);
- tmp = (char *) fs_get (tmplen = i);
+ /* have space in line buffer? */
+ if (i > LOCAL->linebuflen) {
+ fs_give ((void **) &LOCAL->linebuf);
+ LOCAL->linebuf = (char *) fs_get (LOCAL->linebuflen = i);
}
- memcpy (tmp,bs->curpos,i);/* remember what we have so far */
+ /* remember what we have so far */
+ memcpy (LOCAL->linebuf,bs->curpos,i);
/* load next buffer */
SETPOS (bs,k = GETPOS (bs) + i);
/* end of fast scan */
@@ -1808,6 +1813,7 @@
--s; /* back up */
break; /* exit loop */
}
+
/* final character-at-a-time scan */
while ((s < t) && (*s != '\n')) ++s;
/* huge line? */
@@ -1817,10 +1823,10 @@
for (m = SIZE (bs); m && (SNX (bs) != '\n'); --m,++j);
SETPOS (bs,k); /* go back to where it started */
}
-
/* got size of data, make buffer for return */
ret = LOCAL->line = (char *) fs_get (i + j + 2);
- memcpy (ret,tmp,i); /* copy first chunk */
+ /* copy first chunk */
+ memcpy (ret,LOCAL->linebuf,i);
while (j) { /* copy remainder */
if (!bs->cursize) SETPOS (bs,GETPOS (bs));
memcpy (ret + i,bs->curpos,k = min (j,bs->cursize));
@@ -1842,7 +1848,6 @@
*size = i; /* return that to user */
}
else *size = 0; /* end of data, return empty */
- fs_give ((void **) &tmp);
return ret;
}
Modified: trunk/M/lib/imap/src/osdep/os2/unixnt.c
===================================================================
--- trunk/M/lib/imap/src/osdep/os2/unixnt.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/os2/unixnt.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 20 December 1989
- * Last Edited: 30 August 2006
+ * Last Edited: 6 October 2006
*/
@@ -73,6 +73,8 @@
SIZEDTEXT text; /* current text */
unsigned long textlen; /* current text length */
char *line; /* returned line */
+ char *linebuf; /* line readin buffer */
+ unsigned long linebuflen; /* current line readin buffer length */
} UNIXLOCAL;
@@ -447,6 +449,8 @@
LOCAL->buf = (char *) fs_get ((LOCAL->buflen = CHUNKSIZE) + 1);
LOCAL->text.data = (unsigned char *) fs_get (CHUNKSIZE);
LOCAL->text.size = CHUNKSIZE - 1;
+ LOCAL->linebuf = (char *) fs_get (CHUNKSIZE);
+ LOCAL->linebuflen = CHUNKSIZE - 1;
stream->sequence++; /* bump sequence number */
if (!stream->rdonly) { /* make lock for read/write access */
if ((fd = lockname (tmp,stream->mailbox,NIL)) < 0)
@@ -1245,6 +1249,7 @@
/* free local text buffers */
if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
if (LOCAL->text.data) fs_give ((void **) &LOCAL->text.data);
+ if (LOCAL->linebuf) fs_give ((void **) &LOCAL->linebuf);
if (LOCAL->line) fs_give ((void **) &LOCAL->line);
/* nuke the local data */
fs_give ((void **) &stream->local);
@@ -1770,8 +1775,6 @@
{
unsigned long i,j,k,m;
char *s,*t,*te;
- char *tmp = (char *) fs_get (CHUNKSIZE);
- unsigned long tmplen = CHUNKSIZE;
char *ret = "";
/* flush old buffer */
if (LOCAL->line) fs_give ((void **) &LOCAL->line);
@@ -1791,11 +1794,13 @@
while ((s < t) && (*s != '\n')) ++s;
/* difficult case if line spans buffer */
if ((i = s - bs->curpos) == bs->cursize) {
- if (i > tmplen) { /* have space in tmp buffer? */
- fs_give ((void **) &tmp);
- tmp = (char *) fs_get (tmplen = i);
+ /* have space in line buffer? */
+ if (i > LOCAL->linebuflen) {
+ fs_give ((void **) &LOCAL->linebuf);
+ LOCAL->linebuf = (char *) fs_get (LOCAL->linebuflen = i);
}
- memcpy (tmp,bs->curpos,i);/* remember what we have so far */
+ /* remember what we have so far */
+ memcpy (LOCAL->linebuf,bs->curpos,i);
/* load next buffer */
SETPOS (bs,k = GETPOS (bs) + i);
/* end of fast scan */
@@ -1808,6 +1813,7 @@
--s; /* back up */
break; /* exit loop */
}
+
/* final character-at-a-time scan */
while ((s < t) && (*s != '\n')) ++s;
/* huge line? */
@@ -1817,10 +1823,10 @@
for (m = SIZE (bs); m && (SNX (bs) != '\n'); --m,++j);
SETPOS (bs,k); /* go back to where it started */
}
-
/* got size of data, make buffer for return */
ret = LOCAL->line = (char *) fs_get (i + j + 2);
- memcpy (ret,tmp,i); /* copy first chunk */
+ /* copy first chunk */
+ memcpy (ret,LOCAL->linebuf,i);
while (j) { /* copy remainder */
if (!bs->cursize) SETPOS (bs,GETPOS (bs));
memcpy (ret + i,bs->curpos,k = min (j,bs->cursize));
@@ -1842,7 +1848,6 @@
*size = i; /* return that to user */
}
else *size = 0; /* end of data, return empty */
- fs_give ((void **) &tmp);
return ret;
}
Modified: trunk/M/lib/imap/src/osdep/unix/Makefile
===================================================================
--- trunk/M/lib/imap/src/osdep/unix/Makefile 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/unix/Makefile 2006-11-07 00:18:21 UTC (rev 7153)
@@ -21,7 +21,7 @@
# Internet: [email protected]
#
# Date: 11 May 1989
-# Last Edited: 30 August 2006
+# Last Edited: 23 October 2006
# Command line build parameters
@@ -133,7 +133,7 @@
# Standard distribution build parameters
DEFAULTAUTHENTICATORS=ext md5 pla log
-DEFAULTDRIVERS=imap nntp pop3 mh mx mix mbx tenex mtx mmdf unix news phile
+DEFAULTDRIVERS=imap nntp pop3 mx mix mbx tenex mtx mmdf unix news mh phile
CHUNKSIZE=65536
# Normally no need to change any of these
@@ -841,7 +841,7 @@
# Cleanup
clean:
- sh -c '$(RM) auths.c crexcl.c nfstest.c linkage.[ch] siglocal.c osdep*.[ch] *.o ARCHIVE *FLAGS *TYPE $(ARCHIVE) || true'
+ sh -c '$(RM) auths.c crexcl.c linkage.[ch] siglocal.c osdep*.[ch] *.o ARCHIVE *FLAGS *TYPE $(ARCHIVE) || true'
# Dependencies
@@ -879,7 +879,7 @@
osdep.o:mail.h misc.h env.h fs.h ftl.h nl.h tcp.h \
osdep.h env_unix.h tcp_unix.h \
osdep.c env_unix.c fs_unix.c ftl_unix.c nl_unix.c tcp_unix.c ip_unix.c\
- auths.c crexcl.c flockcyg.c flocklnx.c flocksim.c nfstest.c fsync.c \
+ auths.c crexcl.c flockcyg.c flocklnx.c flocksim.c fsync.c \
gethstid.c getspnam.c \
gr_wait.c gr_wait4.c gr_waitp.c \
kerb_mit.c \
@@ -916,10 +916,6 @@
@echo osdepssl.c not found...try make clean and new make
@false
-nfstest.c:
- @echo nfstest.c not found...try make clean and new make
- @false
-
siglocal.c:
@echo siglocal.c not found...try make clean and new make
@false
@@ -960,7 +956,7 @@
$(LN) sig_$(SIGTYPE).c siglocal.c
$(LN) crx_$(CRXTYPE).c crexcl.c
$(LN) ip$(IP)_unix.c ip_unix.c
- sh -c '(test -f /usr/include/sys/statvfs.h -a $(OS) != sc5 -a $(OS) != sco) && $(LN) nfstnew.c nfstest.c || $(LN) nfstold.c nfstest.c'
+ sh -c '(test $(OS) = sc5 -o $(OS) = sco -o ! -f /usr/include/sys/statvfs.h) && echo -DNOFSTATVFS >> OSCFLAGS || fgrep statvfs64 /usr/include/sys/statvfs.h > /dev/null || echo -DNOFSTATVFS64 >> OSCFLAGS'
# Password checkers
Modified: trunk/M/lib/imap/src/osdep/unix/dummy.c
===================================================================
--- trunk/M/lib/imap/src/osdep/unix/dummy.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/unix/dummy.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 9 May 1991
- * Last Edited: 30 August 2006
+ * Last Edited: 17 October 2006
*/
@@ -153,6 +153,7 @@
void dummy_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents)
{
+ DRIVER *drivers;
char *s,test[MAILTMPLEN],file[MAILTMPLEN];
long i;
if (!pat || !*pat) { /* empty pattern? */
@@ -181,8 +182,16 @@
/* do the work */
dummy_list_work (stream,s,test,contents,0);
/* always an INBOX */
- if (pmatch ("INBOX",ucase (test)))
- dummy_listed (stream,NIL,"INBOX",LATT_NOINFERIORS,contents);
+ if (pmatch ("INBOX",ucase (test))) {
+ /* done if have a dirfmt INBOX */
+ for (drivers = (DRIVER *) mail_parameters (NIL,GET_DRIVERS,NIL);
+ drivers && !(!(drivers->flags & DR_DISABLE) &&
+ (drivers->flags & DR_DIRFMT) &&
+ (*drivers->valid) ("INBOX")); drivers = drivers->next);
+ /* list INBOX appropriately */
+ dummy_listed (stream,drivers ? '/' : NIL,"INBOX",
+ drivers ? NIL : LATT_NOINFERIORS,contents);
+ }
}
}
@@ -266,12 +275,12 @@
if (dp = opendir (tmp)) { /* do nothing if can't open directory */
/* see if a non-namespace directory format */
for (drivers = (DRIVER *) mail_parameters (NIL,GET_DRIVERS,NIL), dt = NIL;
- !dt && drivers; drivers = drivers->next)
+ dir && !dt && drivers; drivers = drivers->next)
if (!(drivers->flags & DR_DISABLE) && (drivers->flags & DR_DIRFMT) &&
- (*drivers->valid) (tmp))
+ (*drivers->valid) (dir))
dt = mail_parameters ((*drivers->open) (NIL),GET_DIRFMTTEST,NIL);
/* list it if at top-level */
- if (!level && dir && pmatch_full (dir,pat,'/'))
+ if (!level && dir && pmatch_full (dir,pat,'/') && !pmatch (dir,"INBOX"))
dummy_listed (stream,'/',dir,dt ? NIL : LATT_NOSELECT,contents);
/* scan directory, ignore . and .. */
if (!dir || dir[(len = strlen (dir)) - 1] == '/') while (d = readdir (dp))
@@ -293,14 +302,17 @@
/* only interested in file type */
switch (sbuf.st_mode & S_IFMT) {
case S_IFDIR: /* directory? */
- if (pmatch_full (tmp,pat,'/')) {
- if (!dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents)) break;
- strcat (tmp,"/"); /* set up for dmatch call */
+ if (!pmatch (tmp,"INBOX")) {
+ if (pmatch_full (tmp,pat,'/')) {
+ if (!dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents))
+ break;
+ strcat(tmp,"/");/* set up for dmatch call */
+ }
+ /* try again with trailing / */
+ else if (pmatch_full (strcat (tmp,"/"),pat,'/') &&
+ !dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents))
+ break;
}
- /* try again with trailing / */
- else if (pmatch_full (strcat (tmp,"/"),pat,'/') &&
- !dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents))
- break;
if (dmatch (tmp,pat,'/') &&
(level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL)))
dummy_list_work (stream,tmp,pat,contents,level+1);
Modified: trunk/M/lib/imap/src/osdep/unix/flocksim.c
===================================================================
--- trunk/M/lib/imap/src/osdep/unix/flocksim.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/unix/flocksim.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,13 +23,21 @@
* Internet: [email protected]
*
* Date: 10 April 2001
- * Last Edited: 30 August 2006
+ * Last Edited: 25 October 2006
*/
#undef flock /* name is used as a struct for fcntl */
#undef fork /* make damn sure that we don't use vfork!! */
-#include "nfstest.c" /* get NFS tester */
+#ifndef NOFSTATVFS /* thank you, SUN. NOT! */
+# ifndef NOFSTATVFS64
+# ifndef _LARGEFILE64_SOURCE
+# define _LARGEFILE64_SOURCE
+# endif /* _LARGEFILE64_SOURCE */
+# endif /* NOFSTATVFFS64 */
+#include <sys/statvfs.h>
+#endif /* NOFSTATVFS */
+
#ifndef NSIG /* don't know if this can happen */
#define NSIG 32 /* a common maximum */
#endif
@@ -44,6 +52,8 @@
{
char tmp[MAILTMPLEN];
int logged = 0;
+ struct stat sbuf;
+ struct ustat usbuf;
struct flock fl;
/* lock zero bytes at byte 0 */
fl.l_whence = SEEK_SET; fl.l_start = fl.l_len = 0;
@@ -62,6 +72,8 @@
errno = EINVAL;
return -1;
}
+ /* always return success if disabled */
+ if (mail_parameters (NIL,GET_DISABLEFCNTLLOCK,NIL)) return 0;
/* Make fcntl() locking of NFS files be a no-op the way it is with flock()
* on BSD. This is because the rpc.statd/rpc.lockd daemons don't work very
@@ -70,12 +82,57 @@
* on NFS-mounted files. If you are wise, you'll use IMAP instead of NFS
* for mail files.
*
- * Sun alleges that it doesn't matter, because they say they have fixed all
- * the rpc.statd/rpc.lockd bugs. This is absolutely not true; huge amounts
- * of user and support time have been wasted in cluster-wide hangs.
+ * Sun alleges that it doesn't matter, and that they have fixed all the
+ * rpc.statd/rpc.lockd bugs. As of October 2006, that is still false.
+ *
+ * We need three tests for three major historical variants in SVR4:
+ * 1) In NFSv2, ustat() would return -1 in f_tinode for NFS.
+ * 2) When fstatvfs() was introduced with NFSv3, ustat() was "fixed".
+ * 3) When 64-bit filesystems were introduced, fstatvfs() would return
+ * EOVERFLOW; you have to use fstatvfs64() even though you don't care
+ * about any of the affected values.
+ *
+ * We can't use fstatfs() because fstatfs():
+ * . is documented as being deprecated in SVR4.
+ * . has inconsistent calling conventions (there are two additional int
+ * arguments on Solaris and I don't know what they do).
+ * . returns inconsistent statfs structs. On Solaris, the file system type
+ * is a short called f_fstyp. On AIX, it's an int called f_type that is
+ * documented as always being 0!
+ *
+ * For what it's worth, here's the scoop on fstatfs() elsewhere:
+ *
+ * On Linux, the file system type is a long called f_type that has a file
+ * system type code. A different module (flocklnx.c) uses this because
+ * some knothead "improved" flock() to return ENOLCK on NFS files instead
+ * of being a successful no-op. This "improvement" apparently has been
+ * reverted, but not before it got to many systems in the field.
+ *
+ * On BSD, it's a short called either f_otype or f_type that is documented
+ * as always being zero. Fortunately, BSD has flock() the way it's supposed
+ * to be, and none of this nonsense is necessary.
*/
- if (test_nfs (fd) || mail_parameters (NIL,GET_DISABLEFCNTLLOCK,NIL))
- return 0; /* fcntl() locking disabled, return success */
+ if (!fstat (fd,&sbuf)) { /* no hope of working if can't fstat()! */
+ /* Any base type that begins with "nfs" or "afs" is considered to be a
+ * network filesystem.
+ */
+#ifndef NOFSTATVFS
+ struct statvfs vsbuf;
+#ifndef NOFSTATVFS64
+ struct statvfs64 vsbuf64;
+ if (!fstatvfs64 (fd,&vsbuf64) && (vsbuf64.f_basetype[1] == 'f') &&
+ (vsbuf64.f_basetype[2] == 's') &&
+ ((vsbuf64.f_basetype[0] == 'n') || (vsbuf64.f_basetype[0] == 'a')))
+ return 0;
+#endif /* NOFSTATVFS64 */
+ if (!fstatvfs (fd,&vsbuf) && (vsbuf.f_basetype[1] == 'f') &&
+ (vsbuf.f_basetype[2] == 's') &&
+ ((vsbuf.f_basetype[0] == 'n') || (vsbuf.f_basetype[0] == 'a')))
+ return 0;
+#endif /* NOFSTATVFS */
+ if (!ustat (sbuf.st_dev,&usbuf) && !++usbuf.f_tinode) return 0;
+ }
+
/* do the lock */
while (fcntl (fd,(op & LOCK_NB) ? F_SETLK : F_SETLKW,&fl))
if (errno != EINTR) {
Modified: trunk/M/lib/imap/src/osdep/unix/mh.c
===================================================================
--- trunk/M/lib/imap/src/osdep/unix/mh.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/unix/mh.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 23 February 1992
- * Last Edited: 13 September 2006
+ * Last Edited: 19 October 2006
*/
@@ -158,7 +158,7 @@
static char *mh_profile = NIL; /* holds MH profile */
static char *mh_pathname = NIL; /* holds MH path name */
-static long mh_once = 0; /* already through this code */
+static long mh_once = 0; /* already snarled once */
static long mh_allow_inbox =NIL;/* allow INBOX as well as #mhinbox */
/* MH mail validate mailbox
@@ -184,33 +184,36 @@
{
struct stat sbuf;
unsigned long i;
- /* name must be #MHINBOX or #mh/... */
+ int ret = NIL;
+ /* non-mh name? */
if (!((mh_allow_inbox && !compare_cstring (name,"INBOX")) ||
((name[0] == '#') && ((name[1] == 'm') || (name[1] == 'M')) &&
((name[2] == 'h') || (name[2] == 'H')) &&
((name[3] == '/') || !compare_cstring (name+3,"INBOX"))))) {
- /* valid if in hierarchy (list kludge) */
+ /* yes, valid if in hierarchy (list kludge) */
char *s,*t,altname[MAILTMPLEN];
/* see if non-NS name within mh hierarchy */
if ((name[0] != '#') && (s = mh_path (tmp)) && (i = strlen (s)) &&
(t = mailboxfile (tmp,name)) && !strncmp (t,s,i) && (tmp[i] == '/')) {
sprintf (altname,"#mh%.900s",tmp+i);
- return mh_isvalid (altname,tmp,synonly);
+ /* can't do synonly here! */
+ ret = mh_isvalid (altname,tmp,NIL);
}
- errno = EINVAL; /* bogus name */
- return NIL;
+ else errno = EINVAL; /* bogus name */
}
- if (!mh_path (tmp)) { /* lose if no mh path */
+ else if (mh_path (tmp)) { /* INBOX, #mhinbox, or #mh/ name */
+ /* all done if syntax only check & not INBOX */
+ if (synonly && compare_cstring (name,"INBOX")) return T;
+ errno = NIL; /* zap error */
+ /* validate name as directory */
+ ret = ((stat (mh_file (tmp,name),&sbuf) == 0) &&
+ (sbuf.st_mode & S_IFMT) == S_IFDIR);
+ }
+ else if (!mh_once++) { /* only report error once */
sprintf (tmp,"%.900s not found, mh format names disabled",mh_profile);
mm_log (tmp,WARN);
- return NIL;
}
- /* all done if syntax only check & not INBOX */
- if (synonly && compare_cstring (name,"INBOX")) return T;
- errno = NIL; /* zap error */
- /* validate name as directory */
- return ((stat (mh_file (tmp,name),&sbuf) == 0) &&
- (sbuf.st_mode & S_IFMT) == S_IFDIR);
+ return ret;
}
/* MH mail test for valid mailbox
@@ -242,38 +245,36 @@
char *s,*t,*v;
int fd;
struct stat sbuf;
- /* have MH path yet? */
- if (!mh_pathname && !mh_once++) {
- if (!mh_profile) { /* have MH profile? */
- sprintf (tmp,"%s/%s",myhomedir (),MHPROFILE);
- mh_profile = cpystr (tmp);
- }
- if ((fd = open (tmp,O_RDONLY,NIL)) < 0) return NIL;
- fstat (fd,&sbuf); /* yes, get size and read file */
- read (fd,(t = (char *) fs_get (sbuf.st_size + 1)),sbuf.st_size);
- close (fd); /* don't need the file any more */
- t[sbuf.st_size] = '\0'; /* tie it off */
+ if (!mh_profile) { /* build mh_profile and mh_pathname now */
+ sprintf (tmp,"%s/%s",myhomedir (),MHPROFILE);
+ if ((fd = open (mh_profile = cpystr (tmp),O_RDONLY,NIL)) >= 0) {
+ fstat (fd,&sbuf); /* yes, get size and read file */
+ read (fd,(t = (char *) fs_get (sbuf.st_size + 1)),sbuf.st_size);
+ close (fd); /* don't need the file any more */
+ t[sbuf.st_size] = '\0'; /* tie it off */
/* parse profile file */
- for (s = strtok (t,"\r\n"); s && *s; s = strtok (NIL,"\r\n")) {
+ for (s = strtok (t,"\r\n"); s && *s; s = strtok (NIL,"\r\n")) {
/* found space in line? */
- if (v = strpbrk (s," \t")) {
- *v++ = '\0'; /* tie off, is keyword "Path:"? */
- if (!strcmp (lcase (s),"path:")) {
+ if (v = strpbrk (s," \t")) {
+ *v++ = '\0'; /* tie off, is keyword "Path:"? */
+ if (!strcmp (lcase (s),"path:")) {
/* skip whitespace */
- while ((*v == ' ') || (*v == '\t')) ++v;
- if (*v == '/') s = v; /* absolute path? */
- else sprintf (s = tmp,"%s/%s",myhomedir (),v);
+ while ((*v == ' ') || (*v == '\t')) ++v;
+ /* absolute path? */
+ if (*v == '/') s = v;
+ else sprintf (s = tmp,"%s/%s",myhomedir (),v);
/* copy name */
- mh_pathname = cpystr (s);
- break; /* don't need to look at rest of file */
+ mh_pathname = cpystr (s);
+ break; /* don't need to look at rest of file */
+ }
}
}
+ fs_give ((void **) &t); /* flush profile text */
+ if (!mh_pathname) { /* default path if not in the profile */
+ sprintf (tmp,"%s/%s",myhomedir (),MHPATH);
+ mh_pathname = cpystr (tmp);
+ }
}
- fs_give ((void **) &t); /* flush profile text */
- if (!mh_pathname) { /* default path if not in the profile */
- sprintf (tmp,"%s/%s",myhomedir (),MHPATH);
- mh_pathname = cpystr (tmp);
- }
}
return mh_pathname;
}
@@ -506,7 +507,7 @@
int i;
char tmp[MAILTMPLEN];
/* is mailbox valid? */
- if (!mh_isvalid (mailbox,tmp,NIL)){
+ if (!mh_isvalid (mailbox,tmp,NIL)) {
sprintf (tmp,"Can't delete mailbox %.80s: no such mailbox",mailbox);
mm_log (tmp,ERROR);
return NIL;
@@ -683,6 +684,7 @@
break;
}
SNX (&bs); /* eat the line feed, drop in */
+ --j;
case '\012': /* line feed? */
i += 2; /* count a CRLF */
/* header size known yet? */
Modified: trunk/M/lib/imap/src/osdep/unix/mix.c
===================================================================
--- trunk/M/lib/imap/src/osdep/unix/mix.c 2006-11-07 00:15:57 UTC (rev 7152)
+++ trunk/M/lib/imap/src/osdep/unix/mix.c 2006-11-07 00:18:21 UTC (rev 7153)
@@ -23,7 +23,7 @@
* Internet: [email protected]
*
* Date: 1 March 2006
- * Last Edited: 29 September 2006
+ * Last Edited: 25 October 2006
*/
@@ -166,6 +166,8 @@
long mix_index_update (MAILSTREAM *stream,FILE **idxf,long flag);
FILE *mix_status_open (MAILSTREAM *stream,long flags);
long mix_status_update (MAILSTREAM *stream,FILE **statf,long flag);
+FILE *mix_data_open (MAILSTREAM *stream,int *fd,long *size,
+ unsigned long newsize);
FILE *mix_sortcache_open (MAILSTREAM *stream);
long mix_sortcache_update (MAILSTREAM *stream,FILE **sortcache);
char *mix_read_record (FILE *f,char *buf,unsigned long buflen);
@@ -247,7 +249,7 @@
struct stat sbuf;
/* validate name as directory */
return (!(errno = ((strlen (name) > NETMAXMBX) ? ENAMETOOLONG : NIL)) &&
- mix_dir (dir,name) && mix_file (meta,dir,MIXMETA) &&
+ *mix_dir (dir,name) && mix_file (meta,dir,MIXMETA) &&
!stat (dir,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFDIR) &&
!stat (meta,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFREG));
}
@@ -459,14 +461,18 @@
{
DIR *dirp;
struct direct *d;
- char *s;
- char tmp[MAILTMPLEN];
+ int fd = -1;
+ char *s,tmp[MAILTMPLEN];
if (!mix_isvalid (mailbox,tmp))
sprintf (tmp,"Can't delete mailbox %.80s: no such mailbox",mailbox);
- /* delete index */
+ else if (((fd = open (tmp,O_RDONLY,NIL)) < 0) || flock (fd,LOCK_EX|LOCK_NB))
+ sprintf (tmp,"Can't lock mailbox for delete: %.80s",mailbox);
+ /* delete metadata */
else if (unlink (tmp)) sprintf (tmp,"Can't delete mailbox %.80s index: %80s",
mailbox,strerror (errno));
- else { /* get directory name */
+ else {
+ close (fd); /* close descriptor on deleted metadata */
+ /* get directory name */
*(s = strrchr (tmp,'/')) = '\0';
if (dirp = opendir (tmp)) { /* open directory */
*s++ = '/'; /* restore delimiter */
@@ -485,6 +491,7 @@
}
return T; /* always success */
}
+ if (fd >= 0) close (fd); /* close any descriptor on metadata */
MM_LOG (tmp,ERROR); /* something failed */
return NIL;
}
@@ -500,8 +507,11 @@
{
char c,*s,tmp[MAILTMPLEN],tmp1[MAILTMPLEN];
struct stat sbuf;
+ int fd = -1;
if (!mix_isvalid (old,tmp))
sprintf (tmp,"Can't rename mailbox %.80s: no such mailbox",old);
+ else if (((fd = open (tmp,O_RDONLY,NIL)) < 0) || flock (fd,LOCK_EX|LOCK_NB))
+ sprintf (tmp,"Can't lock mailbox for rename: %.80s",old);
else if (mix_dirfmttest ((s = strrchr (newname,'/')) ? s + 1 : newname))
sprintf (tmp,"Can't rename to mailbox %.80s: invalid MIX-format name",
newname);
@@ -524,7 +534,10 @@
return NIL;
*s = c; /* restore full name */
}
- if (!rename (tmp,tmp1)) return LONGT;
+ if (!rename (tmp,tmp1)) {
+ close (fd); /* close descriptor on metadata */
+ return LONGT;
+ }
}
/* RFC 3501 requires this */
@@ -552,11 +565,15 @@
/* free directory list */
if (a = (void *) names) fs_give ((void **) &a);
if (lasterror) errno = lasterror;
- else return mix_create (NIL,"INBOX");
+ else {
+ close (fd); /* close descriptor on metadata */
+ return mix_create (NIL,"INBOX");
+ }
}
sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",
old,newname,strerror (errno));
}
+ if (fd >= 0) close (fd); /* close any descriptor on metadata */
MM_LOG (tmp,ERROR); /* something failed */
return NIL;
}
@@ -667,7 +684,7 @@
char *mix_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *length,
long flags)
{
- unsigned long i,j;
+ unsigned long i,j,k;
int fd;
char *s,tmp[MAILTMPLEN];
MESSAGECACHE *elt;
@@ -696,11 +713,16 @@
!strncmp (LOCAL->buf,MSGTOK,MSGTSZ) &&
(elt->private.uid == strtoul ((char *) LOCAL->buf + MSGTSZ,&s,16)) &&
(*s++ == ':') && (s = strchr (s,':')) &&
- (elt->rfc822_size == strtoul (s+1,&s,16)) && (*s++ == ':') &&
+ (k = strtoul (s+1,&s,16)) && (*s++ == ':') &&
(s < (char *) (LOCAL->buf + elt->private.msg.header.offset))) {
/* won, set offset and size of message */
i = elt->private.msg.header.offset;
*length = elt->private.msg.header.text.size;
+ if (k != elt->rfc822_size) {
+ sprintf (tmp,"Inconsistency in mix message size, uid=%.08x (%lu != %lu)",
+ elt->private.uid,elt->rfc822_size,k);
+ MM_LOG (tmp,WARN);
+ }
}
else { /* document the problem */
LOCAL->buf[100] = '\0'; /* tie off buffer at no more than 100 octets */
@@ -940,7 +962,7 @@
LOCAL->lastsnarf = time (0);/* note time of last snarf */
}
/* open index file */
- if (idxf = mix_index_open (stream,NIL)) {
+ if (idxf = mix_index_open (stream,stream->rdonly ? NIL : LONGT)) {
/* expunging OK if global flag set */
if (mail_parameters (NIL,GET_EXPUNGEATPING,NIL)) LOCAL->expok = T;
/* process metadata/index/status */
@@ -1298,7 +1320,7 @@
{
do if (set->last > size) { /* sanity check */
char tmp[MAILTMPLEN];
- sprintf (tmp,"Unexpected short mix message file %.80s %ld < %ld",
+ sprintf (tmp,"Unexpected short mix message file %.80s %lu < %lu",
file,size,set->last);
MM_LOG (tmp,ERROR);
return NIL; /* don't burp this file at all */
@@ -1318,20 +1340,15 @@
{
FDDATA d;
STRING st;
- MESSAGECACHE *elt;
- struct stat sbuf;
- int fd;
- unsigned long i,j,uid,uidv;
- char *t,tmp[2*MAILTMPLEN];
- long ret;
- MAILSTREAM *astream = NIL;
+ char tmp[2*MAILTMPLEN];
+ long ret = mix_isvalid (mailbox,LOCAL->buf);
mailproxycopy_t pc =
(mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);
+ MAILSTREAM *astream = NIL;
FILE *idxf = NIL;
FILE *msgf = NIL;
FILE *statf = NIL;
- /* make sure valid mailbox */
- if (!(ret = mix_isvalid (mailbox,LOCAL->buf))) switch (errno) {
+ if (!ret) switch (errno) { /* make sure valid mailbox */
case NIL: /* no error in stat() */
if (pc) return (*pc) (stream,sequence,mailbox,options);
sprintf (tmp,"Not a MIX-format mailbox: %.80s",mailbox);
@@ -1345,51 +1362,37 @@
else if (!(ret = ((options & CP_UID) ? mail_uid_sequence (stream,sequence) :
mail_sequence (stream,sequence))));
/* acquire stream to append */
- else if (!(astream = mail_open (NIL,mailbox,OP_SILENT))) {
- sprintf (tmp,"Can't open copy mailbox: %.80s",strerror (errno));
- MM_LOG (tmp,ERROR);
- ret = NIL;
- }
-
- else if ((idxf = mix_index_open (astream,LONGT)) &&
- (statf = mix_status_open (astream,MSO_WRITE))) {
+ else if (ret = ((astream = mail_open (NIL,mailbox,OP_SILENT)) &&
+ (idxf = mix_index_open (astream,LONGT)) &&
+ (statf = mix_parse (astream,idxf,MSO_WRITE))) ?
+ LONGT : NIL) {
+ int fd;
+ unsigned long i;
+ MESSAGECACHE *elt;
+ unsigned long newsize,hdrsize,size;
MIXLOCAL *local = (MIXLOCAL *) astream->local;
- copyuid_t cu = (copyuid_t) mail_parameters (NIL,GET_COPYUID,NIL);
- SEARCHSET *source = cu ? mail_newsearchset () : NIL;
- SEARCHSET *dest = cu ? mail_newsearchset () : NIL;
- unsigned long seq = mix_modseq (local->indexseq);
- unsigned long cursize,hdrsize;
+ unsigned long seq = mix_modseq (local->metaseq);
+ /* make sure new modseq fits */
+ if (local->indexseq > seq) seq = local->indexseq + 1;
+ if (local->statusseq > seq) seq = local->statusseq + 1;
/* calculate size of per-message header */
sprintf (local->buf,MSRFMT,MSGTOK,0,0,0,0,0,0,0,'+',0,0,0);
hdrsize = strlen (local->buf);
- /* make sure new modseq fits */
- if (local->indexseq > seq) seq = local->indexseq + 1;
- if (local->statusseq > seq) seq = local->statusseq + 1;
+
MM_CRITICAL (stream); /* go critical */
astream->silent = T; /* no events here */
- if (ret = (((fd = open (mix_file_data(local->buf,local->dir,local->newmsg),
- O_RDWR,NIL)) >= 0) &&
- (msgf = fdopen (fd,"r+b")))) {
- fstat (fd,&sbuf); /* get current file size */
- fseek (msgf,sbuf.st_size,SEEK_SET);
- /* if non-empty what is size after delivery? */
- if (cursize = sbuf.st_size)
- for (i = 1; (cursize < MIXDATAROLL) && (i <= stream->nmsgs); ++i)
- if ((elt = mail_elt (stream,i))->sequence)
- cursize += hdrsize + elt->rfc822_size;
- /* if too big, roll to a new file */
- if (cursize > MIXDATAROLL) {
- fclose (msgf); /* close old file, create new one */
- while (((fd = open (mix_file_data
- (local->buf,local->dir,
- local->newmsg = mix_modseq (local->newmsg)),
- O_RDWR | O_CREAT | O_EXCL,
- (int) mail_parameters (NIL,GET_MBXPROTECTION,NIL)))
- < 0) || !(msgf = fdopen (fd,"r+b")))
- if (fd >= 0) close (fd);
- }
-
- if (ret) for (i = 1,uid = uidv = 0; ret && (i <= stream->nmsgs); ++i)
+ /* calculate size that will be added */
+ for (i = 1, newsize = 0; i <= stream->nmsgs; ++i)
+ if ((elt = mail_elt (stream,i))->sequence)
+ newsize += hdrsize + elt->rfc822_size;
+ /* open data file */
+ if (msgf = mix_data_open (astream,&fd,&size,newsize)) {
+ char *t;
+ unsigned long j,uid,uidv;
+ copyuid_t cu = (copyuid_t) mail_parameters (NIL,GET_COPYUID,NIL);
+ SEARCHSET *source = cu ? mail_newsearchset () : NIL;
+ SEARCHSET *dest = cu ? mail_newsearchset () : NIL;
+ for (i = 1,uid = uidv = 0; ret && (i <= stream->nmsgs); ++i)
if (((elt = mail_elt (stream,i))->sequence) && elt->rfc822_size) {
/* is message in current message file? */
if ((LOCAL->msgfd < 0) ||
@@ -1428,55 +1431,51 @@
mail_append_set (source,mail_uid (stream,i));
}
}
- }
- else { /* message file open failed */
- sprintf (tmp,"Error opening copy message file: %.80s",
- strerror (errno));
- MM_LOG (tmp,ERROR);
- if (fd >= 0) close (fd); /* clean up in case fdopen() failure */
- }
- if (msgf) { /* take no action if no open message file */
- /* if error... */
- if (!ret || (fflush (msgf) == EOF)) {
- /* revert file */
- ftruncate (fd,sbuf.st_size);
- close (fd); /* make sure that fclose doesn't corrupt us */
- if (errno) {
+ /* finish write if success */
+ if (ret && (ret = !fflush (msgf))) {
+ fclose (msgf); /* all good, close the msg file now */
+ /* write new metadata, index, and status */
+ local->metaseq = local->indexseq = local->statusseq = seq;
+ if (ret = (mix_meta_update (astream) &&
+ mix_index_update (astream,&idxf,LONGT))) {
+ /* success, delete if doing a move */
+ if (options & CP_MOVE)
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.