From 36b7d017145bac2f883cca12289e66b6b369a5e3 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 27 Jul 2015 23:45:09 +0200 Subject: [PATCH] Enable fine-grained control on the mailboxes to consider. Add 3 options: - list-mailbox - list-select-opts - ignore-mailbox The first two control the initial LIST command, while the last one is a regular expression to filter out mailboxes to exclude from the LIST response. --- imapsync | 11 +++++++++-- imapsync.1 | 46 ++++++++++++++++++++++++++++++++++++++++++-- lib/Net/IMAP/Sync.pm | 7 ++++--- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/imapsync b/imapsync index 2a1bfcc..cc34287 100755 --- a/imapsync +++ b/imapsync @@ -66,7 +66,11 @@ usage(1) if defined $COMMAND and (($COMMAND eq 'delete' and !@ARGV) or $COMMAND my $CONF = read_config( delete $CONFIG{config} // $NAME , [qw/_ local remote/] , database => qr/\A(\P{Control}+)\z/ - , logfile => qr/\A(\P{Control}+)\z/ ); + , logfile => qr/\A(\/\P{Control}+)\z/ + , 'list-mailbox' => qr/\A([\x01-\x09\x0B\x0C\x0E-\x7F]+)\z/ + , 'list-select-opts' => qr/\A([\x21\x23\x24\x26\x27\x2B-\x5B\x5E-\x7A\x7C-\x7E]+)\z/ + , 'ignore-mailbox' => qr/\A([\x01-\x09\x0B\x0C\x0E-\x7F]+)\z/ + ); my ($DBFILE, $LOCKFILE, $LOGGER_FD); { @@ -238,7 +242,8 @@ foreach my $name (qw/local remote/) { my $list = '"" '; my @params; if (!defined $COMMAND or $COMMAND eq 'repair') { - $list .= '"*"' unless @ARGV; + $list = '('.uc($CONF->{_}->{'list-select-opts'}).') '.$list if defined $CONF->{_}->{'list-select-opts'}; + $list .= (defined $CONF->{_}->{'list-mailbox'} ? '('.$CONF->{_}->{'list-mailbox'}.')' : '*') unless @ARGV; @params = ('SUBSCRIBED', 'STATUS (UIDVALIDITY UIDNEXT HIGHESTMODSEQ)'); } $list .= $#ARGV == 0 ? Net::IMAP::Sync::quote($ARGV[0]) @@ -404,6 +409,8 @@ my @MAILBOXES; my $sth_subscribe = $DBH->prepare(q{UPDATE mailboxes SET subscribed = ? WHERE idx = ?}); @MAILBOXES = keys %mailboxes; + @MAILBOXES = grep !/$CONF->{_}->{'ignore-mailbox'}/, @MAILBOXES + if defined $CONF->{_}->{'ignore-mailbox'}; foreach my $mailbox (@MAILBOXES) { check_delim($mailbox); # ensure that the delimiter match diff --git a/imapsync.1 b/imapsync.1 index e274943..59093ef 100644 --- a/imapsync.1 +++ b/imapsync.1 @@ -73,8 +73,14 @@ Go back to step 1 to proceed with the next unsynchronized mailbox. .PP By default \fBimapsync\fR synchronizes each mailbox listed by the \(lqLIST "" "*"\(rq IMAP command; -providing extra arguments limits the synchronization to the given -\fIMAILBOX\fRes only. +the \fIlist-mailbox\fR, \fIlist-select-opts\fR and \fIignore-mailbox\fR +options from the configuration file can be used to shrink that list and +save bandwidth. +However if some extra argument are provided on the command line, +\fBimapsync\fR ignores said options and synchronizes the given +\fIMAILBOX\fRes instead. Note that each \fIMAILBOX\fR is taken \(lqas +is\(rq; in particular, it must be UTF-7 encoded, unquoted, and the list +wildcards \(oq*\(cq and \(oq%\(cq are not interpolated. .PP If the synchronization was interrupted during a previous run while some @@ -181,6 +187,42 @@ This option is only available in the default section. (Default: \(lq\fIhost\fR.db\)\(rq, where \fIhost\fR is taken from the \(lq[remote]\(rq or \(lq[local]\(rq sections, in that order. +.TP +.I list-mailbox +A space separated list of mailbox patterns to use when issuing the +initial LIST command (overridden by the \fIMAILBOX\fRes given as +command-line arguments). +Note that each pattern containing special characters such as spaces or +brackets (see [RFC3501] for the exact syntax) must be quoted. +Furthermore, non-ASCII names must be UTF\-7 encoded. +Two wildcards are available: a \(oq*\(cq character matches zero or more +characters, while a \(oq%\(cq character matches zero or more characters +up to the mailbox's hierarchy delimiter. +This option is only available in the default section. +(The default pattern, \(lq*\(rq, matches all visible mailboxes on the +server.) + +.TP +.I list-select-opts +An optional space separated list of selectors for the initial LIST +command. (Requires a server supporting the LIST-EXTENDED [RFC5258] +extension.) Useful values are +\(lqSUBSCRIBED\(rq (to list only subscribed mailboxes), +\(lqREMOTE\(rq (to also list remote mailboxes on a server supporting +mailbox referrals), and \(lqRECURSIVEMATCH\(rq (to list parent mailboxes +with children matching one of the \fIlist-mailbox\fR pattern above). +This option is only available in the default section. + +.TP +.I ignore-mailbox +An optional Perl Compatible Regular Expressions (PCRE) covering +mailboxes to exclude: +any (UTF-7 encoded, unquoted) mailbox listed in the initial LIST +responses is ignored if it matches the given expression. +Note that the \fIMAILBOX\fRes given as command-line arguments bypass the +check and are always considered for synchronization. +This option is only available in the default section. + .TP .I logfile A file name to use to log debug and informational messages. This option is diff --git a/lib/Net/IMAP/Sync.pm b/lib/Net/IMAP/Sync.pm index 3faab63..48f61c1 100644 --- a/lib/Net/IMAP/Sync.pm +++ b/lib/Net/IMAP/Sync.pm @@ -78,10 +78,11 @@ sub read_config($$%) { foreach my $section (@$sections) { my $conf = defined $h->{_} ? { %{$h->{_}} } : {}; # default section $configs{$section} = $conf; - next unless defined $section and $section ne '_'; - die "No such section $section\n" unless defined $h->{$section}; - $conf->{$_} = $h->{$section}->{$_} foreach keys %{$h->{$section}}; + if ($section ne '_') { + die "No such section $section\n" unless defined $h->{$section}; + $conf->{$_} = $h->{$section}->{$_} foreach keys %{$h->{$section}}; + } # default values $conf->{type} //= 'imaps'; -- 2.39.2