[PATCH] remove temporary uncompressed maildirs [Was: Compressed maildirs possible?]

2015-10-17 Thread Ian Zimmerman
On 2015-10-15 21:29 -0700, Ian Zimmerman wrote:

> > > Can the compressed folder code handle the case where the archived file
> > > is something like .zip or .tar, and contains a whole maildir?  From
> > > reading that part of the manual it seems it should be possible, but I
> > > thought I'd check before playing with my precious archives.

> It mostly works, but there is a small problem: the temprary directory is
> not cleaned up.  Looking at the code in compress.c, I see this:
> 
> /* remove the temporary mailbox */
> void remove_file (CONTEXT* ctx)
> {
>   if (ctx->magic == M_MBOX || ctx->magic == M_MMDF)
> remove (ctx->path);
> }
> 
> So, looks like the case of a maildir wasn't considered, at least not in
> the version I have.  Is yours different?
> 
> Looks like this should be easy to patch, would there be interest in such
> a patch?

Preliminary patch attached.  Critical comments most welcome. 

-- 
Please *no* private copies of mailing list or newsgroup messages.
Rule 420: All persons more than eight miles high to leave the court.
diff --git a/Makefile.am b/Makefile.am
index b57d494..e806bc9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -45,7 +45,7 @@ mutt_DEPENDENCIES = @MUTT_LIB_OBJECTS@ @LIBOBJS@ $(LIBIMAPDEPS) \
 
 DEFS=-DPKGDATADIR=\"$(pkgdatadir)\" -DSYSCONFDIR=\"$(sysconfdir)\" \
 	-DBINDIR=\"$(bindir)\" -DMUTTLOCALEDIR=\"$(datadir)/locale\" \
-	-DHAVE_CONFIG_H=1
+	-DHAVE_CONFIG_H=1 -D_XOPEN_SOURCE=500
 
 AM_CPPFLAGS=-I. -I$(top_srcdir) $(IMAP_INCLUDES) $(GPGME_CFLAGS) -Iintl
 
diff --git a/compress.c b/compress.c
index 9bbf211..9f6058a 100644
--- a/compress.c
+++ b/compress.c
@@ -231,8 +231,20 @@ void restore_path (CONTEXT* ctx)
 /* remove the temporary mailbox */
 void remove_file (CONTEXT* ctx)
 {
-  if (ctx->magic == M_MBOX || ctx->magic == M_MMDF)
+  switch (ctx->magic) {
+  case M_MBOX:
+  case M_MMDF:
 remove (ctx->path);
+break;
+  case M_MAILDIR:
+  case M_MH:
+mutt_rmtree(ctx->path);
+break;
+  default:
+dprint (1, (debugfile, "unknown mailbox format: \"%s\", %d\n",
+ctx->path, ctx->magic));
+break;
+  }
 }
 
 int mutt_open_read_compressed (CONTEXT *ctx)
diff --git a/muttlib.c b/muttlib.c
index 7d32aec..dbd720c 100644
--- a/muttlib.c
+++ b/muttlib.c
@@ -45,6 +45,11 @@
 #include 
 #include 
 #include 
+#include 
+
+/* This is only an estimate which enables an optimization in nftw().
+ * Nothing terrible will happen if it is exceeded. */
+#define MUTT_MBDIR_DEPTH 5
 
 BODY *mutt_new_body (void)
 {
@@ -1971,3 +1976,31 @@ void mutt_encode_path (char *dest, size_t dlen, const char *src)
   strfcpy (dest, (rc == 0) ? NONULL(p) : NONULL(src), dlen);
   FREE ();
 }
+
+static int _mutt_remove_it(const char* fpath, const struct stat* sb,
+   int typeflag, struct FTW* ftwbuf)
+{
+  int retval;
+
+  if (typeflag == FTW_DP)
+retval = rmdir(fpath);
+  else
+retval = unlink(fpath);
+
+  if (retval != 0) {
+retval = errno;
+errno = 0;
+  }
+
+  return retval;
+}
+
+void _mutt_rmtree(const char* dirpath, const char* src, int line)
+{
+  int retval;
+
+  retval = nftw(dirpath, _mutt_remove_it, MUTT_MBDIR_DEPTH, FTW_DEPTH|FTW_PHYS);
+  if (retval != 0)
+dprint (1, (debugfile, "%s:%d: ERROR: nftw(\"%s\"): %s (%d)\n",
+src, line, dirpath, strerror (retval), retval));
+}
diff --git a/protos.h b/protos.h
index 9639a85..f804403 100644
--- a/protos.h
+++ b/protos.h
@@ -219,6 +219,8 @@ void mutt_merge_envelopes(ENVELOPE* base, ENVELOPE** extra);
 void mutt_message_to_7bit (BODY *, FILE *);
 #define mutt_mktemp(a,b) _mutt_mktemp (a, b, __FILE__, __LINE__)
 void _mutt_mktemp (char *, size_t, const char *, int);
+#define mutt_rmtree(dirpath) (_mutt_rmtree ((dirpath), __FILE__, __LINE__))
+void _mutt_rmtree (const char *, const char *, int);
 void mutt_normalize_time (struct tm *);
 void mutt_paddstr (int, const char *);
 void mutt_parse_mime_message (CONTEXT *ctx, HEADER *);


Re: Compressed maildirs possible?

2015-10-15 Thread Ian Zimmerman
On 2015-09-17 18:22 -0500, David Champion wrote:

> > Can the compressed folder code handle the case where the archived file
> > is something like .zip or .tar, and contains a whole maildir?  From
> > reading that part of the manual it seems it should be possible, but I
> > thought I'd check before playing with my precious archives.
> 
> Yes. (Just tar, make copies, and experiment.)  Your hook event can
> be anything -- even bulk folder encryption is an option.
> 
> I've done both these in the past, but not at present so I'm afraid I
> don't have any specific examples.  I finally decided that compress-hook
> was suboptimal, and instead I use dynamic compression and deduplication
> at the filesystem layer.  It's delightful.

It mostly works, but there is a small problem: the temprary directory is
not cleaned up.  Looking at the code in compress.c, I see this:

/* remove the temporary mailbox */
void remove_file (CONTEXT* ctx)
{
  if (ctx->magic == M_MBOX || ctx->magic == M_MMDF)
remove (ctx->path);
}

So, looks like the case of a maildir wasn't considered, at least not in
the version I have.  Is yours different?

Looks like this should be easy to patch, would there be interest in such
a patch?

-- 
Please *no* private copies of mailing list or newsgroup messages.
Rule 420: All persons more than eight miles high to leave the court.


Compressed maildirs possible?

2015-09-17 Thread Ian Zimmerman
Can the compressed folder code handle the case where the archived file
is something like .zip or .tar, and contains a whole maildir?  From
reading that part of the manual it seems it should be possible, but I
thought I'd check before playing with my precious archives.

-- 
Please *no* private copies of mailing list or newsgroup messages.
Rule 420: All persons more than eight miles high to leave the court.


Re: Compressed maildirs possible?

2015-09-17 Thread David Champion
* On 17 Sep 2015, Ian Zimmerman wrote: 
> Can the compressed folder code handle the case where the archived file
> is something like .zip or .tar, and contains a whole maildir?  From
> reading that part of the manual it seems it should be possible, but I
> thought I'd check before playing with my precious archives.

Yes. (Just tar, make copies, and experiment.)  Your hook event can
be anything -- even bulk folder encryption is an option.

I've done both these in the past, but not at present so I'm afraid I
don't have any specific examples.  I finally decided that compress-hook
was suboptimal, and instead I use dynamic compression and deduplication
at the filesystem layer.  It's delightful.

-- 
David Champion • d...@bikeshed.us