Hi, as I recently found out courier does not check for CRLF sequences at the end of lines. It just blindy inserts CR. In case there's already a CR there it will still insert, causing invalid IMAP transactions.
Here is a patch that fixes at least the easy places to correctly send out the mails. The patch to the POP3 server already proved that it works. There are more places in imap/fetch.c that I suspect to possibly cause trouble (for example dofetchmsgbody) but they are less easy to fix. With this patch it is checked first if the previous character was CR before CR is inserted. There is also a very small change in behaviour int the second hunk: the for look to find the end of line at the bottom dofetchheadersbuf() does not need to search the buffer starting at the first character to find LF. The "if" before already checked that and in case of a match jumped somewhere else. You can see the complete thing in the second hunk of the diff. Greetings, Eike
diff -Naurp courier-imap-4.1.1-orig/imap/fetch.c courier-imap-4.1.1/imap/fetch.c
--- courier-imap-4.1.1-orig/imap/fetch.c 2004-06-09 00:44:20.000000000 +0200
+++ courier-imap-4.1.1/imap/fetch.c 2006-05-31 13:31:08.000000000 +0200
@@ -1003,7 +1003,7 @@ char buf[BUFSIZ+2];
int goodheader;
unsigned long skipping;
unsigned long cnt;
-char *p;
+char *p, oldp = 0;
int ii;
rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
@@ -1098,24 +1098,27 @@ int ii;
}
}
--skipping;
- ++p;
+ oldp = *p++;
}
while (cnt)
{
if (*p == '\n')
{
- writes("\r");
- if (--cnt == 0) break;
+ if (oldp != '\r') {
+ writes("\r");
+ if (--cnt == 0) break;
+ }
writes("\n");
--cnt;
- ++p;
+ oldp = *p++;
continue;
}
- for (i=0; i<cnt; i++)
+ for (i=1; i<cnt; i++)
if (p[i] == '\n')
break;
writemem(p, i);
+ oldp = p[i - 1];
p += i;
cnt -= i;
header_count += i;
@@ -1181,6 +1184,8 @@ struct fetchheaderinfo finfo;
goodheader= (*headerfunc)(fi, "");
while (left)
{
+ char oldc = 0;
+
for (i=0; i<sizeof(buf1)-1 && i<left; i++)
{
c=getc(fp);
@@ -1242,10 +1247,14 @@ struct fetchheaderinfo finfo;
if (c == '\n')
{
(*func)(&finfo, buf1, i);
- buf1[0]='\r';
- i=1;
+ if (oldc != '\r') {
+ buf1[0]='\r';
+ i=1;
+ } else
+ i = 0;
}
buf1[i++]=c;
+ oldc = c;
if (c == '\n') break;
}
(*func)(&finfo, buf1, i);
@@ -1288,7 +1297,7 @@ static void rfc822(FILE *fp, struct fetc
struct rfc2045 *rfcp)
{
unsigned long n=0;
-int c;
+int c, oldc = 0;
char buf[BUFSIZ];
unsigned long i;
@@ -1303,7 +1312,9 @@ unsigned long i;
while ((c=getc(fp)) != EOF)
{
++n;
- if (c == '\n') ++n;
+ if ((c == '\n') && (oldc != '\r'))
+ ++n;
+ oldc = c;
}
if (fseek(fp, 0L, SEEK_SET) == -1)
@@ -1327,7 +1338,8 @@ unsigned long i;
writemem(buf, i);
i=0;
}
- buf[i++]='\r';
+ if (oldc != '\r')
+ buf[i++]='\r';
if (--n == 0) break;
}
@@ -1337,6 +1349,7 @@ unsigned long i;
i=0;
}
buf[i++]=c;
+ oldc = c;
--n;
++body_count;
}
@@ -1348,7 +1361,7 @@ static void rfc822header(FILE *fp, struc
struct rfc2045 *rfcp)
{
unsigned long n=0;
-int c;
+int c, oldc = 0;
char buf[BUFSIZ];
unsigned long i;
int eol;
@@ -1369,9 +1382,11 @@ int eol;
if (c != '\n')
{
eol=0;
+ oldc = c;
continue;
}
- ++n;
+ if (oldc != '\r')
+ ++n;
if (eol) break;
eol=1;
}
@@ -1389,6 +1404,7 @@ int eol;
i=0;
while (n)
{
+ oldc = c;
c=getc(fp);
if (c == '\n')
{
@@ -1397,7 +1413,8 @@ int eol;
writemem(buf, i);
i=0;
}
- buf[i++]='\r';
+ if (oldc != '\r')
+ buf[i++]='\r';
if (--n == 0) break;
}
@@ -1420,7 +1437,7 @@ static void rfc822text(FILE *fp, struct
off_t start_pos, end_pos, start_body;
off_t nlines, nbodylines;
unsigned long i;
-int c;
+int oldc = 0;
char buf[BUFSIZ];
unsigned long l;
@@ -1444,6 +1461,8 @@ unsigned long l;
l=0;
while (i)
{
+ int c;
+
c=getc(fp);
if (c == EOF)
{
@@ -1459,7 +1478,8 @@ unsigned long l;
if (c == '\n' && i)
{
--i;
- buf[l++]='\r';
+ if (oldc != '\r')
+ buf[l++]='\r';
if (l >= sizeof(BUFSIZ))
{
writemem(buf, l);
@@ -1467,6 +1487,7 @@ unsigned long l;
}
}
buf[l++]=c;
+ oldc = c;
++body_count;
}
writemem(buf, l);
diff -Naurp courier-imap-4.1.1-orig/imap/pop3dserver.c courier-imap-4.1.1/imap/pop3dserver.c
--- courier-imap-4.1.1-orig/imap/pop3dserver.c 2005-10-01 17:32:16.000000000 +0200
+++ courier-imap-4.1.1/imap/pop3dserver.c 2006-05-31 11:32:36.000000000 +0200
@@ -133,11 +133,18 @@ int c, lastc;
lastc='\n';
while ((c=getc(f)) >= 0)
{
- if (c == '\n') ++m->size;
+ /* LF will be expanded to CRLF if CR is not present */
+ if ((c == '\n') && (lastc != '\r'))
+ ++m->size;
++m->size;
lastc=c;
}
- if (lastc != '\n') m->size += 2;
+ if (lastc != '\n') {
+ if (lastc != '\r')
+ m->size += 2;
+ else
+ m->size++;
+ }
if (ferror(f))
{
@@ -668,15 +675,20 @@ unsigned long *cntr;
{
if (inheader)
{
- if (c == '\n') inheader=0;
+ if ((c == '\n') || (c == '\r'))
+ inheader=0;
}
else if ( (*lptr)-- == 0) break;
}
if (c == '.')
printchar('.');
+ } else if ((lastc == '\r') && (c != '\n')) {
+ printchar('\n');
+ lastc = '\n';
}
- if (c == '\n') printchar('\r');
+ if ((c == '\n') && (lastc != '\r'))
+ printchar('\r');
printchar(c);
++*cntr;
}
@@ -687,7 +699,12 @@ unsigned long *cntr;
acctout("INFO: I/O error disconnect");
exit(1);
}
- if (lastc != '\n') printed(printf("\r\n"));
+ if (lastc != '\n') {
+ if (lastc != '\r')
+ printed(printf("\r\n"));
+ else
+ printchar('\n');
+ }
printed(printf(".\r\n"));
fflush(stdout);
fclose(f);
pgpvmtS2ybLNK.pgp
Description: PGP signature
_______________________________________________ Courier-imap mailing list [email protected] Unsubscribe: https://lists.sourceforge.net/lists/listinfo/courier-imap
