Re: [PATCH v3 3/3] notmuch-mutt: check that the search cache Maildir is not a real Maildir

2023-06-21 Thread David Bremner
Paul Wise  writes:

> This prevents data loss when users configure the search cache Maildir to be a
> real Maildir containing their real mail data, since the search cache Maildir
> is expected to contain only symlinks to the real mail data.
>
> Prevents: 

Was there a change from V2? I might have missed it if so.

d
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH v3 3/3] notmuch-mutt: check that the search cache Maildir is not a real Maildir

2023-06-21 Thread David Bremner
Paul Wise  writes:

> This prevents data loss when users configure the search cache Maildir to be a
> real Maildir containing their real mail data, since the search cache Maildir
> is expected to contain only symlinks to the real mail data.
>
> Prevents: 

v2 applied to master
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


[PATCH v3 3/3] notmuch-mutt: check that the search cache Maildir is not a real Maildir

2023-05-27 Thread Paul Wise
This prevents data loss when users configure the search cache Maildir to be a
real Maildir containing their real mail data, since the search cache Maildir
is expected to contain only symlinks to the real mail data.

Prevents: 
---
 contrib/notmuch-mutt/notmuch-mutt | 46 +++
 1 file changed, 46 insertions(+)

diff --git a/contrib/notmuch-mutt/notmuch-mutt 
b/contrib/notmuch-mutt/notmuch-mutt
index 875fd032..b81252c8 100755
--- a/contrib/notmuch-mutt/notmuch-mutt
+++ b/contrib/notmuch-mutt/notmuch-mutt
@@ -13,6 +13,7 @@ use warnings;
 
 use File::Path;
 use File::Basename;
+use File::Find;
 use Getopt::Long qw(:config no_getopt_compat);
 use Mail::Header;
 use Mail::Box::Maildir;
@@ -25,6 +26,50 @@ my $xdg_cache_dir = "$ENV{HOME}/.cache";
 $xdg_cache_dir = $ENV{XDG_CACHE_HOME} if $ENV{XDG_CACHE_HOME};
 my $cache_dir = "$xdg_cache_dir/notmuch/mutt";
 
+sub die_dir($$) {
+my ($maildir, $error) = @_;
+die "notmuch-mutt: search cache maildir $maildir $error\n".
+"Please ensure that the notmuch-mutt search cache Maildir\n".
+"contains no subfolders or real mail data, only symlinks to mail\n";
+}
+
+sub die_subdir($$$) {
+my ($maildir, $subdir, $error) = @_;
+die_dir($maildir, "subdir $subdir $error");
+}
+
+# check that the search cache maildir is that and not a real maildir
+# otherwise there could be data loss when the search cache is emptied
+sub check_search_cache_maildir($) {
+my ($maildir) = (@_);
+
+return unless -e $maildir;
+
+-d $maildir or die_dir($maildir, 'is not a directory');
+
+opendir(my $mdh, $maildir) or die_dir($maildir, "cannot be opened: $!");
+my @contents = grep { !/^\.\.?$/ } readdir $mdh;
+closedir $mdh;
+
+my @required = ('cur', 'new', 'tmp');
+foreach my $d (@required) {
+-l "$maildir/$d" and die_dir($maildir, "contains symlink $d");
+-e "$maildir/$d" or die_subdir($maildir, $d, 'is missing');
+-d "$maildir/$d" or die_subdir($maildir, $d, 'is not a directory');
+find(sub {
+$_ eq '.' and return;
+$_ eq '..' and return;
+-l $_ or die_subdir($maildir, $d, "contains non-symlink $_");
+}, "$maildir/$d");
+}
+
+my %required = map { $_ => 1 } @required;
+foreach my $d (@contents) {
+-l "$maildir/$d" and die_dir( $maildir, "contains symlink $d");
+-d "$maildir/$d" or die_dir( $maildir, "contains non-directory $d");
+exists($required{$d}) or die_dir( $maildir, "contains directory $d");
+}
+}
 
 # create an empty search cache maildir (if missing) or empty existing one
 sub empty_search_cache_maildir($) {
@@ -45,6 +90,7 @@ sub search($$$) {
 push @args, "--duplicate=1" if $remove_dups;
 push @args, $query;
 
+check_search_cache_maildir($maildir);
 empty_search_cache_maildir($maildir);
 open my $pipe, '-|', @args or die "Running @args failed: $!\n";
 while (<$pipe>) {
-- 
2.40.1

___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org