summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2019-11-19 14:24:18 -0700
committerSean Whitton <spwhitton@spwhitton.name>2019-11-19 14:24:18 -0700
commitdbb78c50b157f00fc15bb668fc82f90ab7170110 (patch)
tree8b9692cfa3ab98df048c43c873d9c546a65f4500 /lib
parent033748acdf7ef1ba00a91b35d3cf0671d0603ac5 (diff)
downloaddotfiles-dbb78c50b157f00fc15bb668fc82f90ab7170110.tar.gz
rewrite expand-annex-mboxes in perl, fixing a bug
Archived mboxes with a '.' in the name, before the file extension, were not being expanded. This should also improve performance.
Diffstat (limited to 'lib')
-rw-r--r--lib/perl5/Local/Homedir/Mail.pm70
1 files changed, 65 insertions, 5 deletions
diff --git a/lib/perl5/Local/Homedir/Mail.pm b/lib/perl5/Local/Homedir/Mail.pm
index 7b2a0bcf..b8140e05 100644
--- a/lib/perl5/Local/Homedir/Mail.pm
+++ b/lib/perl5/Local/Homedir/Mail.pm
@@ -20,11 +20,15 @@ use strict;
use warnings;
use constant THIRTYONE => 31 * 24 * 60 * 60;
+use File::Spec::Functions qw(catfile);
+use File::Temp qw(tempdir);
+use File::Path qw(remove_tree);
use IO::Compress::Gzip qw(gzip $GzipError);
+use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
use Mail::Box::Manager;
use Exporter 'import';
-our @EXPORT_OK = qw( archive_to_mbox );
+our @EXPORT_OK = qw( archive_to_mbox expand_mbox );
sub archive_to_mbox {
my ($source_path, $mbox_path, $expanded_path) = @_;
@@ -73,10 +77,66 @@ sub archive_to_mbox {
gzip($mbox_path, "$mbox_path.gz")
or die "gzip failed: $GzipError\n";
unlink $mbox_path if -e "$mbox_path.gz";
- chmod 500, "$expanded_path/cur", "$expanded_path/new",
- "$expanded_path/tmp";
- chmod 400,
- glob "$expanded_path/cur/* $expanded_path/new/* $expanded_path/tmp/*";
+ make_maildir_readonly($expanded_path);
+}
+
+sub expand_mbox {
+ my ($source_path, $expanded_path) = @_;
+ my $lockfile = $expanded_path . ".lock";
+
+ # check whether we got halfway there, or we finished it
+ if (-e $lockfile) {
+ remove_tree($expanded_path);
+ unlink $lockfile;
+ } elsif (-e $expanded_path) {
+ return;
+ }
+
+ # lock this one
+ open my $touch_fh, '>', $lockfile;
+ close $touch_fh;
+
+ # unzip it to (what is hopefully a) tmpfs, since Mail::Box can
+ # only accept a path to an unzipped mbox
+ my $dir = tempdir(CLEANUP => 1, DIR => "/tmp");
+ chmod 0700, $dir;
+ my $unzipped = catfile($dir, "unzip.mbox");
+ gunzip($source_path, $unzipped) or die "gunzip failed: $GunzipError\n";
+
+ my $mgr = Mail::Box::Manager->new();
+ my $source = $mgr->open(
+ $unzipped,
+ access => 'r',
+ keep_dups => 1,
+ type => 'mbox'
+ );
+ my $expanded = $mgr->open(
+ $expanded_path,
+ access => 'a',
+ create => 1,
+ keep_dups => 1,
+ type => 'maildir'
+ );
+
+ foreach my $message ($source->messages()) {
+ $message->label(flagged => 0, seen => 1);
+ $mgr->copyMessage($expanded, $message);
+ }
+ $mgr->closeAllFolders;
+ make_maildir_readonly($expanded_path);
+
+ # mark as done
+ unlink $lockfile;
+
+ # nuke the tempdir now to avoid running out of ramdisk if we're
+ # expanding a lot of mboxes
+ remove_tree($dir);
+}
+
+sub make_maildir_readonly {
+ chmod 0500, catfile($_[0], "cur"), catfile($_[0], "new"),
+ catfile($_[0], "tmp");
+ chmod 0400, glob "$_[0]/cur/* $_[0]/new/* $_[0]/tmp/*";
}
1;