Reinhard Proessler wrote:
Hello!
In december 2005 was a thread about downloading multible messages
via pop3 with Outlook as email client. The reason for this problem
was a wrong or broken handling of MS Outlook with the UIDL of cyrus
imapd(pop3d).
Cyrus Imapd uses a UIDL with variable length (rfc conform) but Outlook
can not handle this variable length and starts over to download the
message if it meets a point where the UIDL changes.
Well. The problem is caused by Outlook.
But I have to fix this problem, but I can not fix Outlook, you know.
Now my questions:
Has anybody out there already started to work on a patch for the cyrus
server?
Are there any suggestions where to patch the (correct working) imapd|popd?
You could try the attached patch and let me know if it solves the problem.
--
Kenneth Murchison
Systems Programmer
Project Cyrus Developer/Maintainer
Carnegie Mellon University
Index: imap/pop3d.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/pop3d.c,v
retrieving revision 1.167
diff -u -r1.167 pop3d.c
--- imap/pop3d.c 11 Apr 2005 06:57:35 -0000 1.167
+++ imap/pop3d.c 21 Feb 2006 19:11:39 -0000
@@ -882,13 +882,13 @@
prot_printf(popd_out, "-ERR No such message\r\n");
}
else if (mboxstruct.pop3_new_uidl) {
- prot_printf(popd_out, "+OK %u %lu.%u\r\n", msg,
+ prot_printf(popd_out, "+OK %u %lu.%.10u\r\n", msg,
mboxstruct.uidvalidity,
popd_msg[msg].uid);
}
else {
/* old uidl format */
- prot_printf(popd_out, "+OK %u %u\r\n",
+ prot_printf(popd_out, "+OK %u %.10u\r\n",
msg, popd_msg[msg].uid);
}
}
@@ -897,11 +897,12 @@
for (msg = 1; msg <= popd_exists; msg++) {
if (!popd_msg[msg].deleted) {
if (mboxstruct.pop3_new_uidl) {
- prot_printf(popd_out, "%u %lu.%u\r\n", msg,
+ prot_printf(popd_out, "%u %lu.%.10u\r\n", msg,
mboxstruct.uidvalidity,
popd_msg[msg].uid);
} else {
- prot_printf(popd_out, "%u %u\r\n", msg,
+ /* old uidl format */
+ prot_printf(popd_out, "%u %.10u\r\n", msg,
popd_msg[msg].uid);
}
}
Index: lib/prot.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/lib/prot.c,v
retrieving revision 1.86
diff -u -r1.86 prot.c
--- lib/prot.c 27 Feb 2004 22:08:56 -0000 1.86
+++ lib/prot.c 21 Feb 2006 19:11:39 -0000
@@ -856,78 +856,20 @@
}
/*
- * Stripped-down version of printf() that works on protection streams
- * Only understands '%ld', '%lu', '%d', %u', '%s', '%c', and '%%'
- * in the format string.
+ * Version of printf() that works on protection streams
*/
int prot_printf(struct protstream *s, const char *fmt, ...)
{
va_list pvar;
- char *percent, *p;
- long l;
- unsigned long ul;
- int i;
- unsigned u;
- char buf[30];
- va_start(pvar, fmt);
+ char buf[2048];
assert(s->write);
- while ((percent = strchr(fmt, '%')) != 0) {
- prot_write(s, fmt, percent-fmt);
- switch (*++percent) {
- case '%':
- prot_putc('%', s);
- break;
-
- case 'l':
- switch (*++percent) {
- case 'd':
- l = va_arg(pvar, long);
- snprintf(buf, sizeof(buf), "%ld", l);
- prot_write(s, buf, strlen(buf));
- break;
-
- case 'u':
- ul = va_arg(pvar, long);
- snprintf(buf, sizeof(buf), "%lu", ul);
- prot_write(s, buf, strlen(buf));
- break;
-
- default:
- abort();
- }
- break;
-
- case 'd':
- i = va_arg(pvar, int);
- snprintf(buf, sizeof(buf), "%d", i);
- prot_write(s, buf, strlen(buf));
- break;
-
- case 'u':
- u = va_arg(pvar, int);
- snprintf(buf, sizeof(buf), "%u", u);
- prot_write(s, buf, strlen(buf));
- break;
-
- case 's':
- p = va_arg(pvar, char *);
- prot_write(s, p, strlen(p));
- break;
-
- case 'c':
- i = va_arg(pvar, int);
- prot_putc(i, s);
- break;
-
- default:
- abort();
- }
- fmt = percent+1;
- }
- prot_write(s, fmt, strlen(fmt));
+ va_start(pvar, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, pvar);
va_end(pvar);
+
+ prot_write(s, buf, strlen(buf));
if (s->error || s->eof) return EOF;
return 0;
}
----
Cyrus Home Page: http://asg.web.cmu.edu/cyrus
Cyrus Wiki/FAQ: http://cyruswiki.andrew.cmu.edu
List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html