]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/IMAP.pm
imap: support LIST command
[public-inbox.git] / lib / PublicInbox / IMAP.pm
index a2d59e5cccca9014e26416820bfdb4aca83b87d7..ca9a0ea7d420feb3dcaa562d84fb2f8f2efe72c7 100644 (file)
@@ -20,6 +20,7 @@ use fields qw(imapd logged_in ibx long_cb -login_tag
 use PublicInbox::Eml;
 use PublicInbox::DS qw(now);
 use PublicInbox::Syscall qw(EPOLLIN EPOLLONESHOT);
+use Text::ParseWords qw(parse_line);
 use Errno qw(EAGAIN);
 my $Address;
 for my $mod (qw(Email::Address::XS Mail::Address)) {
@@ -335,6 +336,20 @@ sub cmd_status ($$$;@) {
        "$tag OK Status complete\r\n";
 }
 
+my %patmap = ('*' => '.*', '%' => '[^\.]*');
+sub cmd_list ($$$$) {
+       my ($self, $tag, $refname, $wildcard) = @_;
+       my $l = $self->{imapd}->{inboxlist};
+       if ($refname eq '' && $wildcard eq '') {
+               # request for hierarchy delimiter
+               $l = [ qq[* LIST (\\Noselect) "." ""\r\n] ];
+       } elsif ($refname ne '' || $wildcard ne '*') {
+               $wildcard =~ s!([^a-z0-9_])!$patmap{$1} // "\Q$1"!eig;
+               $l = [ grep(/ \Q$refname\E$wildcard\r\n\z/s, @$l) ];
+       }
+       \(join('', @$l, "$tag OK List complete\r\n"));
+}
+
 sub cmd_uid_fetch ($$$;@) {
        my ($self, $tag, $range, @want) = @_;
        my $ibx = $self->{ibx} or return "$tag BAD No mailbox selected\r\n";
@@ -423,7 +438,8 @@ sub args_ok ($$) { # duplicated from PublicInbox::NNTP
 # returns 1 if we can continue, 0 if not due to buffered writes or disconnect
 sub process_line ($$) {
        my ($self, $l) = @_;
-       my ($tag, $req, @args) = split(/[ \t]+/, $l);
+       my ($tag, $req, @args) = parse_line('[ \t]+', 0, $l);
+       pop(@args) if (@args && !defined($args[-1]));
        if (@args && uc($req) eq 'UID') {
                $req .= "_".(shift @args);
        }