The original sidebar patch contained a half-implemented attempt to use
realpath() mailbox paths for comparison.  (Presumably so the open
mailbox remains highlighted despite symlink issues).

Add realpath to the Context, and set it when opening a mailbox.
Remove sidebar ifdef for the buffy member, and always set it there too.

Change the sidebar to use the realpath for comparion everywhere.

mutt_buffy_check() is using stat device and inode for comparison.
Perhaps this can be changed to use realpath instead, but that's beyond
the scope of this patch.

-- 
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA
# HG changeset patch
# User Kevin McCarthy <[email protected]>
# Date 1466612580 25200
#      Wed Jun 22 09:23:00 2016 -0700
# Node ID a14bf89dadf37b306fab2bd9272c6e704f59d5ec
# Parent  c8613259dc38fbda3cec2fea188eb0071e7ba34a
Change sidebar to consistently use realpath for context and buffy comparison.

The original sidebar patch contained a half-implemented attempt to use
realpath() mailbox paths for comparison.  (Presumably so the open mailbox
remains highlighted despite symlink issues).

Add realpath to the Context, and set it when opening a mailbox.
Remove sidebar ifdef for the buffy member, and always set it there too.

Change the sidebar to use the realpath for comparion everywhere.

mutt_buffy_check() is using stat device and inode for comparison.
Perhaps this can be changed to use realpath instead, but that's beyond
the scope of this patch.

diff --git a/buffy.c b/buffy.c
--- a/buffy.c
+++ b/buffy.c
@@ -196,27 +196,23 @@
   else
     b->size = 0;
   return;
 }
 
 static BUFFY *buffy_new (const char *path)
 {
   BUFFY* buffy;
-#ifdef USE_SIDEBAR
   char rp[PATH_MAX] = "";
   char *r = NULL;
-#endif
 
   buffy = (BUFFY *) safe_calloc (1, sizeof (BUFFY));
   strfcpy (buffy->path, path, sizeof (buffy->path));
-#ifdef USE_SIDEBAR
   r = realpath (path, rp);
   strfcpy (buffy->realpath, r ? rp : path, sizeof (buffy->realpath));
-#endif
   buffy->next = NULL;
   buffy->magic = 0;
 
   return buffy;
 }
 
 static void buffy_free (BUFFY **mailbox)
 {
@@ -224,20 +220,17 @@
 }
 
 int mutt_parse_mailboxes (BUFFER *path, BUFFER *s, unsigned long data, BUFFER 
*err)
 {
   BUFFY **tmp,*tmp1;
   char buf[_POSIX_PATH_MAX];
   struct stat sb;
   char f1[PATH_MAX];
-#ifndef USE_SIDEBAR
-  char f2[PATH_MAX];
-#endif
-  char *p, *q;
+  char *p;
 
   while (MoreArgs (s))
   {
     mutt_extract_token (path, s, 0);
     strfcpy (buf, path->data, sizeof (buf));
 
     if(data == MUTT_UNMAILBOXES && mutt_strcmp(buf,"*") == 0)
     {
@@ -257,23 +250,17 @@
 
     /* Skip empty tokens. */
     if(!*buf) continue;
 
     /* avoid duplicates */
     p = realpath (buf, f1);
     for (tmp = &Incoming; *tmp; tmp = &((*tmp)->next))
     {
-#ifdef USE_SIDEBAR
-      q = (*tmp)->realpath;
-      if (mutt_strcmp (p ? p : buf, q) == 0)
-#else
-      q = realpath ((*tmp)->path, f2);
-      if (mutt_strcmp (p ? p : buf, q ? q : (*tmp)->path) == 0)
-#endif
+      if (mutt_strcmp (p ? p : buf, (*tmp)->realpath) == 0)
       {
        dprint(3,(debugfile,"mailbox '%s' already registered as '%s'\n", buf, 
(*tmp)->path));
        break;
       }
     }
 
     if(data == MUTT_UNMAILBOXES)
     {
diff --git a/buffy.h b/buffy.h
--- a/buffy.h
+++ b/buffy.h
@@ -21,19 +21,18 @@
 
 /*parameter to mutt_parse_mailboxes*/
 #define MUTT_MAILBOXES   1
 #define MUTT_UNMAILBOXES 2 
 
 typedef struct buffy_t
 {
   char path[_POSIX_PATH_MAX];
-#ifdef USE_SIDEBAR
-  char realpath[_POSIX_PATH_MAX];
-#endif
+  char realpath[_POSIX_PATH_MAX]; /* used for duplicate detection, context 
comparison,
+                                     and the sidebar */
   off_t size;
   struct buffy_t *next;
 #ifdef USE_SIDEBAR
   struct buffy_t *prev;
 #endif
   short new;                   /* mailbox has new mail */
 
   /* These next three are only set when OPTMAILCHECKSTATS is set */
diff --git a/curs_main.c b/curs_main.c
--- a/curs_main.c
+++ b/curs_main.c
@@ -1221,19 +1221,16 @@
          if (!buf[0])
          {
             mutt_window_clearline (MuttMessageWindow, 0);
            break;
          }
        }
 
        mutt_expand_path (buf, sizeof (buf));
-#ifdef USE_SIDEBAR
-       mutt_sb_set_open_buffy (buf);
-#endif
        if (mx_get_magic (buf) <= 0)
        {
          mutt_error (_("%s is not a mailbox."), buf);
          break;
        }
        mutt_str_replace (&CurrentFolder, buf);
 
        /* keepalive failure in mutt_enter_fname may kill connection. #3028 */
@@ -1273,16 +1270,20 @@
                                        (option (OPTREADONLY) || op == 
OP_MAIN_CHANGE_FOLDER_READONLY) ?
                                        MUTT_READONLY : 0, NULL)) != NULL)
        {
          menu->current = ci_first_message ();
        }
        else
          menu->current = 0;
 
+#ifdef USE_SIDEBAR
+        mutt_sb_set_open_buffy ();
+#endif
+
        mutt_clear_error ();
        mutt_buffy_check(1); /* force the buffy check after we have changed
                              the folder */
        menu->redraw = REDRAW_FULL;
        set_option (OPTSEARCHINVALID);
        break;
 
       case OP_DISPLAY_MESSAGE:
diff --git a/imap/imap.c b/imap/imap.c
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -583,17 +583,19 @@
   imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
   if (!*buf)
     strfcpy (buf, "INBOX", sizeof (buf));
   FREE(&(idata->mailbox));
   idata->mailbox = safe_strdup (buf);
   imap_qualify_path (buf, sizeof (buf), &mx, idata->mailbox);
 
   FREE (&(ctx->path));
+  FREE (&(ctx->realpath));
   ctx->path = safe_strdup (buf);
+  ctx->realpath = safe_strdup (ctx->path);
 
   idata->ctx = ctx;
 
   /* clear mailbox status */
   idata->status = 0;
   memset (idata->ctx->rights, 0, sizeof (idata->ctx->rights));
   idata->newMailCount = 0;
 
diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
@@ -562,21 +562,17 @@
 #define MUTT_IGNORE  (1<<0)    /* -z */
 #define MUTT_BUFFY   (1<<1)    /* -Z */
 #define MUTT_NOSYSRC (1<<2)    /* -n */
 #define MUTT_RO      (1<<3)    /* -R */
 #define MUTT_SELECT  (1<<4)    /* -y */
 
 int main (int argc, char **argv)
 {
-#ifdef USE_SIDEBAR
-  char folder[PATH_MAX] = "";
-#else
   char folder[_POSIX_PATH_MAX] = "";
-#endif
   char *subject = NULL;
   char *includeFile = NULL;
   char *draftFile = NULL;
   char *newMagic = NULL;
   HEADER *msg = NULL;
   LIST *attach = NULL;
   LIST *commands = NULL;
   LIST *queries = NULL;
@@ -1197,25 +1193,16 @@
        exit (0);
       }
     }
 
     if (!folder[0])
       strfcpy (folder, NONULL(Spoolfile), sizeof (folder));
     mutt_expand_path (folder, sizeof (folder));
 
-#ifdef USE_SIDEBAR
-    {
-      char tmpfolder[PATH_MAX] = "";
-      strfcpy (tmpfolder, folder, sizeof (tmpfolder));
-      if (!realpath (tmpfolder, folder))
-        strfcpy (folder, tmpfolder, sizeof (tmpfolder));
-    }
-#endif
-
     mutt_str_replace (&CurrentFolder, folder);
     mutt_str_replace (&LastFolder, folder);
 
     if (flags & MUTT_IGNORE)
     {
       /* check to see if there are any messages in the folder */
       switch (mx_check_empty (folder))
       {
@@ -1229,17 +1216,17 @@
     }
 
     mutt_folder_hook (folder);
 
     if((Context = mx_open_mailbox (folder, ((flags & MUTT_RO) || option 
(OPTREADONLY)) ? MUTT_READONLY : 0, NULL))
        || !explicit_folder)
     {
 #ifdef USE_SIDEBAR
-      mutt_sb_set_open_buffy (folder);
+      mutt_sb_set_open_buffy ();
 #endif
       mutt_index_menu ();
       if (Context)
        FREE (&Context);
     }
 #ifdef USE_IMAP
     imap_logout_all ();
 #endif
diff --git a/mutt.h b/mutt.h
--- a/mutt.h
+++ b/mutt.h
@@ -898,16 +898,17 @@
   int (*close_msg) (struct _context *, struct _message *);
   int (*commit_msg) (struct _context *, struct _message *);
   int (*open_new_msg) (struct _message *, struct _context *, HEADER *);
 };
 
 typedef struct _context
 {
   char *path;
+  char *realpath;               /* used for buffy comparison and the sidebar */
   FILE *fp;
   time_t atime;
   time_t mtime;
   off_t size;
   off_t vsize;
   char *pattern;                /* limit pattern string */
   pattern_t *limit_pattern;     /* compiled limit pattern */
   HEADER **hdrs;
diff --git a/mx.c b/mx.c
--- a/mx.c
+++ b/mx.c
@@ -623,16 +623,18 @@
 {
   CONTEXT *ctx = pctx;
   int rc;
 
   if (!ctx)
     ctx = safe_malloc (sizeof (CONTEXT));
   memset (ctx, 0, sizeof (CONTEXT));
   ctx->path = safe_strdup (path);
+  if (! (ctx->realpath = realpath (ctx->path, NULL)) )
+    ctx->realpath = safe_strdup (ctx->path);
 
   ctx->msgnotreadyet = -1;
   ctx->collapsed = 0;
 
   for (rc=0; rc < RIGHTSMAX; rc++)
     mutt_bit_set(ctx->rights,rc);
 
   if (flags & MUTT_QUIET)
@@ -735,16 +737,17 @@
   if (ctx->id_hash)
     hash_destroy (&ctx->id_hash, NULL);
   mutt_clear_threads (ctx);
   for (i = 0; i < ctx->msgcount; i++)
     mutt_free_header (&ctx->hdrs[i]);
   FREE (&ctx->hdrs);
   FREE (&ctx->v2r);
   FREE (&ctx->path);
+  FREE (&ctx->realpath);
   FREE (&ctx->pattern);
   if (ctx->limit_pattern) 
     mutt_pattern_free (&ctx->limit_pattern);
   safe_fclose (&ctx->fp);
   memset (ctx, 0, sizeof (CONTEXT));
 }
 
 /* save changes to disk */
diff --git a/pop.c b/pop.c
--- a/pop.c
+++ b/pop.c
@@ -416,17 +416,19 @@
   mutt_account_tourl (&acct, &url);
   url.path = NULL;
   url_ciss_tostring (&url, buf, sizeof (buf), 0);
   conn = mutt_conn_find (NULL, &acct);
   if (!conn)
     return -1;
 
   FREE (&ctx->path);
+  FREE (&ctx->realpath);
   ctx->path = safe_strdup (buf);
+  ctx->realpath = safe_strdup (ctx->path);
 
   pop_data = safe_calloc (1, sizeof (POP_DATA));
   pop_data->conn = conn;
   ctx->data = pop_data;
 
   if (pop_open_connection (pop_data) < 0)
     return -1;
 
diff --git a/sidebar.c b/sidebar.c
--- a/sidebar.c
+++ b/sidebar.c
@@ -143,17 +143,17 @@
     return src;
 
   dest[0] = 0; /* Just in case there's nothing to do */
 
   BUFFY *b = sbe->buffy;
   if (!b)
     return src;
 
-  int c = Context && (mutt_strcmp (Context->path, b->path) == 0);
+  int c = Context && (mutt_strcmp (Context->realpath, b->realpath) == 0);
 
   optional = flags & MUTT_FORMAT_OPTIONAL;
 
   switch (op)
   {
     case 'B':
       mutt_format_s (dest, destlen, prefix, sbe->box);
       break;
@@ -402,17 +402,17 @@
 
     if (!new_only)
       continue;
 
     if ((b == OpnBuffy) || (b->msg_unread  > 0) || b->new ||
         (b == HilBuffy) || (b->msg_flagged > 0))
       continue;
 
-    if (Context && (strcmp (b->path, Context->path) == 0))
+    if (Context && (mutt_strcmp (b->realpath, Context->realpath) == 0))
       /* Spool directory */
       continue;
 
     if (mutt_find_list (SidebarWhitelist, b->path))
       /* Explicitly asked to be visible */
       continue;
 
     b->is_hidden = 1;
@@ -643,19 +643,18 @@
     else if ((b->msg_unread > 0) || (b->new))
       SETCOLOR(MT_COLOR_NEW);
     else if (b->msg_flagged > 0)
       SETCOLOR(MT_COLOR_FLAGGED);
     else
       SETCOLOR(MT_COLOR_NORMAL);
 
     mutt_window_move (MuttSidebarWindow, row, 0);
-    if (Context && Context->path &&
-        (!strcmp (b->path, Context->path)||
-         !strcmp (b->realpath, Context->path)))
+    if (Context && Context->realpath &&
+        !mutt_strcmp (b->realpath, Context->realpath))
     {
       b->msg_unread  = Context->unread;
       b->msg_count   = Context->msgcount;
       b->msg_flagged = Context->flagged;
     }
 
     /* compute length of Maildir without trailing separator */
     size_t maildirlen = strlen (Maildir);
@@ -839,18 +838,17 @@
   /* Even if the sidebar's hidden,
    * we should take note of the new data. */
   BUFFY *b = Incoming;
   if (!ctx || !b)
     return;
 
   for (; b; b = b->next)
   {
-    if (!strcmp (b->path,     ctx->path) ||
-        !strcmp (b->realpath, ctx->path))
+    if (!mutt_strcmp (b->realpath, ctx->realpath))
     {
       b->msg_unread  = ctx->unread;
       b->msg_count   = ctx->msgcount;
       b->msg_flagged = ctx->flagged;
       break;
     }
   }
 }
@@ -870,37 +868,35 @@
 
   if (!HilBuffy)
     return NULL;
 
   return HilBuffy->path;
 }
 
 /**
- * mutt_sb_set_open_buffy - Set the OpnBuffy based on a mailbox path
- * @path: Mailbox path
+ * mutt_sb_set_open_buffy - Set the OpnBuffy based on a the global Context
  *
  * Search through the list of mailboxes.  If a BUFFY has a matching path, set
  * OpnBuffy to it.
  */
-BUFFY *mutt_sb_set_open_buffy (const char *path)
+BUFFY *mutt_sb_set_open_buffy (void)
 {
   /* Even if the sidebar is hidden */
 
   BUFFY *b = Incoming;
 
-  if (!path || !b)
+  OpnBuffy = NULL;
+
+  if (!Context || !b)
     return NULL;
 
-  OpnBuffy = NULL;
-
   for (; b; b = b->next)
   {
-    if (!strcmp (b->path,     path) ||
-        !strcmp (b->realpath, path))
+    if (!mutt_strcmp (b->realpath, Context->realpath))
     {
       OpnBuffy = b;
       HilBuffy = b;
       break;
     }
   }
 
   return OpnBuffy;
@@ -932,17 +928,17 @@
     if (!BotBuffy)
       BotBuffy = b;
     if (!Outgoing)
       Outgoing = b;
     if (!OpnBuffy && Context)
     {
       /* This might happen if the user "unmailboxes *", then
        * "mailboxes" our current mailbox back again */
-      if (mutt_strcmp (b->path, Context->path) == 0)
+      if (mutt_strcmp (b->realpath, Context->realpath) == 0)
         OpnBuffy = b;
     }
   }
   else
   {
     BUFFY *replacement = buffy_going (b);
     if (TopBuffy == b)
       TopBuffy = replacement;
diff --git a/sidebar.h b/sidebar.h
--- a/sidebar.h
+++ b/sidebar.h
@@ -23,11 +23,11 @@
 #include "mutt.h"
 #include "buffy.h"
 
 void         mutt_sb_change_mailbox (int op);
 void         mutt_sb_draw (void);
 const char * mutt_sb_get_highlight (void);
 void         mutt_sb_notify_mailbox (BUFFY *b, int created);
 void         mutt_sb_set_buffystats (const CONTEXT *ctx);
-BUFFY *      mutt_sb_set_open_buffy (const char *path);
+BUFFY *      mutt_sb_set_open_buffy (void);
 
 #endif /* SIDEBAR_H */

Attachment: signature.asc
Description: PGP signature

Reply via email to