[SVN] r450 - /branches/cvsmerge/cyrus-cvs/imap/mbdump.c
debian at incase.de
debian at incase.de
Fri May 12 09:47:52 UTC 2006
Author: sven
Date: Fri May 12 11:47:51 2006
New Revision: 450
URL: https://mail.incase.de/viewcvs?rev=450&root=cyrus22&view=rev
Log:
remove limit on the size of mailbox files that can be received by UNDUMP
(write file directly to disk rather than reading the literal into memory)
Modified:
branches/cvsmerge/cyrus-cvs/imap/mbdump.c
Modified: branches/cvsmerge/cyrus-cvs/imap/mbdump.c
URL: https://mail.incase.de/viewcvs/branches/cvsmerge/cyrus-cvs/imap/mbdump.c?rev=450&root=cyrus22&r1=449&r2=450&view=diff
==============================================================================
--- branches/cvsmerge/cyrus-cvs/imap/mbdump.c (original)
+++ branches/cvsmerge/cyrus-cvs/imap/mbdump.c Fri May 12 11:47:51 2006
@@ -1,5 +1,5 @@
/* mbdump.c -- Mailbox dump routines
- * $Id: mbdump.c,v 1.30 2004/05/22 03:45:51 rjs3 Exp $
+ * $Id: mbdump.c,v 1.31 2006/05/11 17:43:18 murch Exp $
* Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -585,6 +585,10 @@
while(1) {
char fnamebuf[MAX_MAILBOX_PATH + 1024];
char *seen_file = NULL;
+ int isnowait, sawdigit;
+ unsigned long size;
+ unsigned long cutoff = ULONG_MAX / 10;
+ unsigned digit, cutlim = ULONG_MAX % 10;
c = getastring(pin, pout, &file);
if(c != ' ') {
@@ -676,11 +680,41 @@
continue;
}
-
- c = getbastring(pin, pout, &data);
- if(c != ' ' && c != ')') {
+
+ /* read size of literal */
+ c = prot_getc(pin);
+ if (c != '{') {
r = IMAP_PROTOCOL_ERROR;
goto done;
+ }
+
+ size = isnowait = sawdigit = 0;
+ while ((c = prot_getc(pin)) != EOF && isdigit(c)) {
+ sawdigit = 1;
+ digit = c - '0';
+ /* check for overflow */
+ if (size > cutoff || (size == cutoff && digit > cutlim)) {
+ fatal("literal too big", EC_IOERR);
+ }
+ size = size*10 + digit;
+ }
+ if (c == '+') {
+ isnowait++;
+ c = prot_getc(pin);
+ }
+ if (c == '}') {
+ c = prot_getc(pin);
+ if (c == '\r') c = prot_getc(pin);
+ }
+ if (!sawdigit || c != '\n') {
+ r = IMAP_PROTOCOL_ERROR;
+ goto done;
+ }
+
+ if (!isnowait) {
+ /* Tell client to send the message */
+ prot_printf(pout, "+ go ahead\r\n");
+ prot_flush(pout);
}
if(userid && !strcmp(file.s, "SUBS")) {
@@ -742,7 +776,7 @@
if(strncmp(file.s, "cyrus.", 6)) {
/* it doesn't match cyrus.*, so its a message file.
* charge it against the quota */
- quotaused += data.len;
+ quotaused += size;
}
}
@@ -760,10 +794,24 @@
goto done;
}
- if(write(curfile,data.s,data.len) == -1) {
- syslog(LOG_ERR, "IOERROR: writing %s: %m", fnamebuf);
- r = IMAP_IOERROR;
- goto done;
+ /* write data to file */
+ while (size) {
+ char buf[4096+1];
+ int n = prot_read(pin, buf, size > 4096 ? 4096 : size);
+ if (!n) {
+ syslog(LOG_ERR,
+ "IOERROR: reading message: unexpected end of file");
+ r = IMAP_IOERROR;
+ goto done;
+ }
+
+ size -= n;
+
+ if (write(curfile, buf, n) != n) {
+ syslog(LOG_ERR, "IOERROR: writing %s: %m", fnamebuf);
+ r = IMAP_IOERROR;
+ goto done;
+ }
}
close(curfile);
@@ -777,7 +825,12 @@
unlink(fnamebuf);
}
- if(c == ')') break;
+ c = prot_getc(pin);
+ if (c == ')') break;
+ if (c != ' ') {
+ r = IMAP_PROTOCOL_ERROR;
+ goto done;
+ }
}
if(!r && quotaused) {
More information about the Pkg-Cyrus-imapd-Debian-devel
mailing list