<<< Date Index >>>     <<< Thread Index >>>

Re: [PATCH] Following symlinks when deleting mail



Bardur Arantsson wrote:
[--snip--]
... and apparently I suck at remembering to actually attach patches. Here it is (or should be... let's home the Gmane NNTP gateway doesn't remove attachments)

--
Bardur Arantsson
<bardur@xxxxxxxxxxxx>
<bardur@xxxxxxxxxxxxxxx>

- You don't get to wear slippers when you're raising the Evil
One!
                                        Richard Richard, 'Bottom'
diff -urN mutt-1.5.7/init.h mutt-1.5.7.patched/init.h
--- mutt-1.5.7/init.h   2005-01-27 19:54:12.000000000 +0100
+++ mutt-1.5.7.patched/init.h   2005-02-10 15:20:47.073440904 +0100
@@ -431,6 +431,14 @@
   ** for deletion.  This applies when you either explicitly delete a message,
   ** or when you save it to another folder.
   */
+  { "unlink_follow", DT_BOOL, R_NONE, OPTUNLINKFOLLOW, 0 },
+  /*
+  ** .pp
+  ** If this option is \fIset\fP, mutt will follow symlinks when removing
+  ** messages from directory-based (MH or Maildir) mailboxes. If the
+  ** option is \fIunset\fP, mutt will not follow symlinks when deleting
+  ** messages from a directory-based mailbox.
+  */ 
   { "digest_collapse", DT_BOOL, R_NONE, OPTDIGESTCOLLAPSE, 1},
   /*
   ** .pp
diff -urN mutt-1.5.7/mh.c mutt-1.5.7.patched/mh.c
--- mutt-1.5.7/mh.c     2005-01-27 19:48:04.000000000 +0100
+++ mutt-1.5.7.patched/mh.c     2005-02-10 15:20:47.074440752 +0100
@@ -1395,6 +1395,31 @@
   return (0);
 }
 
+/*
+ * Remove the destination of a symlink (does nothing if the given path
+ * is not a symlink or if the symlink is a dangling link). This
+ * function only follows the symlink once.
+ */
+static void mh_unlink_symdest(char *path)
+{
+  char tmp[_POSIX_PATH_MAX];
+  int len;
+  /* follow symlinks? */
+  if (option (OPTUNLINKFOLLOW))
+  {
+    len = readlink (path, tmp, sizeof(tmp)-1);
+    if (len >= 0)
+    {
+      tmp[len] = '\0';
+      unlink (tmp);
+    }
+    else if (errno != EINVAL) 
+    {
+      mutt_perror ("readlink");
+    }
+  }
+}
+
 int mh_sync_mailbox (CONTEXT * ctx, int *index_hint)
 {
   char path[_POSIX_PATH_MAX], tmp[_POSIX_PATH_MAX];
@@ -1416,7 +1441,10 @@
       snprintf (path, sizeof (path), "%s/%s", ctx->path, ctx->hdrs[i]->path);
       if (ctx->magic == M_MAILDIR
          || (option (OPTMHPURGE) && ctx->magic == M_MH))
+      {
+       mh_unlink_symdest (path);
        unlink (path);
+      }
       else if (ctx->magic == M_MH)
       {
        /* MH just moves files out of the way when you delete them */
@@ -1424,6 +1452,7 @@
        {
          snprintf (tmp, sizeof (tmp), "%s/,%s", ctx->path,
                    ctx->hdrs[i]->path);
+         mh_unlink_symdest (tmp);
          unlink (tmp);
          rename (path, tmp);
        }
diff -urN mutt-1.5.7/mutt.h mutt-1.5.7.patched/mutt.h
--- mutt-1.5.7/mutt.h   2005-01-27 19:53:51.000000000 +0100
+++ mutt-1.5.7.patched/mutt.h   2005-02-10 15:20:47.075440600 +0100
@@ -341,6 +341,7 @@
   OPTCONFIRMAPPEND,
   OPTCONFIRMCREATE,
   OPTDELETEUNTAG,
+  OPTUNLINKFOLLOW,
   OPTDIGESTCOLLAPSE,
   OPTDUPTHREADS,
   OPTEDITHDRS,