On Fri, 11 Oct 2002, Stefan Schmidt via RT wrote:
Show quoted text>
> Sending: 2178 UID FETCH
>
107545,107546,107547,107548,107549,107550,107551,107552,107553,107554,107555,107556,107557,107558,107559,[...]110181,110182,110183,110184,110185 FLAGS
Show quoted text>
> Sent 18509 bytes
> Read: * BYE [ALERT] Fatal error: max atom size too
> small: No such file or directory [...]
> our postmaster's opinion on this is: that command is
> simply to long ;)
Hi, Stefan. Thank you for your bug report. Thank you
especially for including the debug output! You would be
surprised at the number of times I receive bug reports
with no debugging output. It is very frustrating
because I usually cannot do anything without it.
However, since you _did_ include the debug output, I
can see right away what the problem is and your
postmaster is correct; the list of message numbers is
exceeding a limit imposed by your server.
According to RFC2683, "IMAP4 Implementation
Recommendations", client programs should limit command
lines to 1000 octets (not including literal data, such
as APPEND message text) and servers should be prepared
to accept up to at least 8000 octets. While this RFC
provides "recommendations" only, it is clear that
limiting the size of a client message to some value is
an IMAP-compliant behavior, so your server does not
have a bug. In fact, it looks to me like the fetch
command in the sample you sent exceeds even the 8000
octet value, although I did not count the bytes!
Anyway, the point is that your new server probably
imposes a limit that the previous version did not
impose. However, both behaviors are IMAP-compliant.
Although it is possible to make your sample FETCH
request in a much shorter message, Mail::IMAPClient
unfortunately does not do so. I've known for some time
that this problem was at least a theoretical
possibility but no one has ever reported it until you.
Congratulations, you're the first. ;-) I will consider
fixing this in a future release but will probably not
send you a patch since there are a number of
work-arounds available to you.
First, you could break the requests up so that you're
never FETCHing more than about 1000 messages in one
method call. This would require some minor changes to
your logic but they're relatively straightforward and
should not be difficult. One thousand messages would
still put you over the 1000 octets recommended by
RFC2683 but it sounds like your server will accept this
and that's the most important thing.
Another way to get around this (and in my opinion the
best) would be to attempt to condense the raw list of
messages into a more compact list. Since RFC2060 allows
ranges to be specified (in the format ${begin}:$end),
you could loop through your result set and convert the
raw list of messages into a comma-separated list of
ranges, ie:
<tag> UID FETCH
103471:103566,103568:104209,104215:105610 FLAGS
This gives you a message set spanning 103471-105610
(over 2000 messages), excluding hypothetical missing
message UID's, and takes a fraction of the bandwidth.
However, it would be a little more tedious (though
perhaps not that difficult) to construct this list. If
you decide to implement this please consider donating
the code to Mail::IMAPClient ;-)
A third compromise that just occurred to me is to turn
off the UID parameter and specify a range of
"1:" . $imap->message_count. Once the UID parameter is
turned off, Mail::IMAPClient starts sending simple
message sequence numbers instead of message UID's, so,
as long as no EXPUNGEs are done between the select
method and the message_count method, this technique
should work and be quite easy to implement. In the
example code, it requires two changes. They are:
$imap->Uid(0); # Turn off the UID
parameter -- CHANGE #1
foreach my $f (@folders) {
$fsize=$ksize=$seen=$unseen=0;
$imap->examine($f);
$imap->select();
$flaghash=$imap->flags("1:" .
$imap->message_count); #CHANGE #2
for my $k (keys %$flaghash) {
if
(grep(/Seen/,@{$flaghash->{$k}})) {
$seen++;
} else {
$unseen++;
}
$size=$imap->size($k);
$fsize=$fsize+$size;
}
However, using any techniques besides the first (in
which we break up the command into multiple requests)
can cause you to have problems on the client side if
too much data start pouring in from the server. Testing
will either confirm this or eliminate it as something
to worry about.
I think this e-mail should allow you to move forward.
Good luck with your programming! And please don't
hesitate to e-mail me if you have further questions or
if I have failed to explain this clearly to you.
Thank you,
Dave
Cheers,
Dave