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 */
signature.asc
Description: PGP signature
