At 3PM -0500 on 12/02/13 you (Bret Martin) wrote:
>
> To close the loop on this, I ended up doing the following, although it
> seems to fail on mailboxes with large numbers of messages (on the
> order of 10,000 or so; I didn't test carefully enough to find the
> exact number)
>
> use Mail::IMAPClient;
> use Socket;
> use strict;
>
> socketpair( my $dovecot, my $client, AF_UNIX, SOCK_STREAM, PF_UNSPEC );
>
> unless ( fork() ) {
> open( STDIN, '<&', $client );
> open( STDOUT, '>&', $client );
> exec( '/usr/lib/dovecot/imap' );
> }
> close( $client );
>
> my $imap = Mail::IMAPClient->new( Socket => $dovecot );
>
> foreach my $folder( sort $imap->folders() ) {
> print( "$folder\n" );
> $imap->select( $folder );
> $imap->set_flag( 'Seen', $imap->search( 'ALL' ) );
> }
You're not specifying Ranges in the ->new call, and you're calling
->search in list context; either of these will force ->search to return
a complete list of message numbers, which you are then trying to pass
back in a single IMAP command. You want to either loop through the
messages or set Ranges and call ->search in scalar context to get an
(object which stringifies to an) IMAP range specification, which will be
much shorter than the whole list.
Ben