about summary refs log tree commit homepage
path: root/lib/PublicInbox/MdirReader.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/MdirReader.pm')
-rw-r--r--lib/PublicInbox/MdirReader.pm22
1 files changed, 20 insertions, 2 deletions
diff --git a/lib/PublicInbox/MdirReader.pm b/lib/PublicInbox/MdirReader.pm
index c6a0e7a8..e0ff676d 100644
--- a/lib/PublicInbox/MdirReader.pm
+++ b/lib/PublicInbox/MdirReader.pm
@@ -2,18 +2,36 @@
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 
 # Maildirs for now, MH eventually
+# ref: https://cr.yp.to/proto/maildir.html
+#        https://wiki2.dovecot.org/MailboxFormat/Maildir
 package PublicInbox::MdirReader;
 use strict;
 use v5.10.1;
 
+# returns Maildir flags from a basename ('' for no flags, undef for invalid)
+sub maildir_basename_flags {
+        my (@f) = split(/:/, $_[0], -1);
+        return if (scalar(@f) > 2 || substr($f[0], 0, 1) eq '.');
+        $f[1] // return ''; # "new"
+        $f[1] =~ /\A2,([A-Za-z]*)\z/ ? $1 : undef; # "cur"
+}
+
+# same as above, but for full path name
+sub maildir_path_flags {
+        my ($f) = @_;
+        my $i = rindex($f, '/');
+        $i >= 0 ? maildir_basename_flags(substr($f, $i + 1)) : undef;
+}
+
 sub maildir_each_file ($$;@) {
         my ($dir, $cb, @arg) = @_;
         $dir .= '/' unless substr($dir, -1) eq '/';
         for my $d (qw(new/ cur/)) {
                 my $pfx = $dir.$d;
                 opendir my $dh, $pfx or next;
-                while (defined(my $fn = readdir($dh))) {
-                        $cb->($pfx.$fn, @arg) if $fn =~ /:2,[A-Za-z]*\z/;
+                while (defined(my $bn = readdir($dh))) {
+                        maildir_basename_flags($bn) // next;
+                        $cb->($pfx.$bn, @arg);
                 }
         }
 }