NeoMutt  2020-06-26-30-g76c339
Teaching an old dog new tricks
DOXYGEN
browser.c File Reference

GUI component for displaying/selecting items from a list. More...

#include "config.h"
#include <dirent.h>
#include <errno.h>
#include <grp.h>
#include <limits.h>
#include <locale.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "browser.h"
#include "context.h"
#include "format_flags.h"
#include "globals.h"
#include "keymap.h"
#include "mutt_attach.h"
#include "mutt_mailbox.h"
#include "mutt_menu.h"
#include "muttlib.h"
#include "mx.h"
#include "opcodes.h"
#include "options.h"
#include "sendlib.h"
#include "imap/lib.h"
#include "nntp/lib.h"
+ Include dependency graph for browser.c:

Go to the source code of this file.

Functions

static void init_lastdir (void)
 Initialise the browser directories. More...
 
void mutt_browser_cleanup (void)
 Clean up working Buffers. More...
 
static void destroy_state (struct BrowserState *state)
 Free the BrowserState. More...
 
static int browser_compare_subject (const void *a, const void *b)
 Compare the subject of two browser entries. More...
 
static int browser_compare_desc (const void *a, const void *b)
 Compare the descriptions of two browser entries. More...
 
static int browser_compare_date (const void *a, const void *b)
 Compare the date of two browser entries. More...
 
static int browser_compare_size (const void *a, const void *b)
 Compare the size of two browser entries. More...
 
static int browser_compare_count (const void *a, const void *b)
 Compare the message count of two browser entries. More...
 
static int browser_compare_count_new (const void *a, const void *b)
 Compare the new count of two browser entries. More...
 
static int browser_compare (const void *a, const void *b)
 Sort the items in the browser. More...
 
static void browser_sort (struct BrowserState *state)
 Sort the entries in the browser. More...
 
static bool link_is_dir (const char *folder, const char *path)
 Does this symlink point to a directory? More...
 
static const char * folder_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the folder browser - Implements format_t. More...
 
static void add_folder (struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *s, struct Mailbox *m, void *data)
 Add a folder to the browser list. More...
 
static void init_state (struct BrowserState *state, struct Menu *menu)
 Initialise a browser state. More...
 
static int examine_directory (struct Menu *menu, struct BrowserState *state, const char *d, const char *prefix)
 Get list of all files/newsgroups with mask. More...
 
static int examine_mailboxes (struct Menu *menu, struct BrowserState *state)
 Get list of mailboxes/subscribed newsgroups. More...
 
static int select_file_search (struct Menu *menu, regex_t *rx, int line)
 Menu search callback for matching files - Implements Menu::search() More...
 
static void folder_make_entry (char *buf, size_t buflen, struct Menu *menu, int line)
 Format a menu item for the folder browser - Implements Menu::make_entry() More...
 
static void browser_highlight_default (struct BrowserState *state, struct Menu *menu)
 Decide which browser item should be highlighted. More...
 
static void init_menu (struct BrowserState *state, struct Menu *menu, char *title, size_t titlelen, bool mailbox)
 Set up a new menu. More...
 
static int file_tag (struct Menu *menu, int sel, int act)
 Tag an entry in the menu - Implements Menu::tag() More...
 
void mutt_browser_select_dir (const char *f)
 Remember the last directory selected. More...
 
static int mutt_dlg_browser_observer (struct NotifyCallback *nc)
 Listen for config changes affecting the Browser menu - Implements observer_t. More...
 
void mutt_buffer_select_file (struct Buffer *file, SelectFileFlags flags, char ***files, int *numfiles)
 Let the user select a file. More...
 
void mutt_select_file (char *file, size_t filelen, SelectFileFlags flags, char ***files, int *numfiles)
 Let the user select a file. More...
 

Variables

bool C_BrowserAbbreviateMailboxes
 Config: Abbreviate mailboxes using '~' and '=' in the browser. More...
 
char * C_FolderFormat
 Config: printf-like format string for the browser's display of folders. More...
 
char * C_GroupIndexFormat
 Config: (nntp) printf-like format string for the browser's display of newsgroups. More...
 
char * C_NewsgroupsCharset
 Config: (nntp) Character set of newsgroups' descriptions. More...
 
bool C_ShowOnlyUnread
 Config: (nntp) Only show subscribed newsgroups with unread articles. More...
 
short C_SortBrowser
 Config: Sort method for the browser. More...
 
char * C_VfolderFormat
 Config: (notmuch) printf-like format string for the browser's display of virtual folders. More...
 
static const struct Mapping FolderHelp []
 
static struct Mapping FolderNewsHelp []
 
static struct Buffer LastDir = { 0 }
 
static struct Buffer LastDirBackup = { 0 }
 

Detailed Description

GUI component for displaying/selecting items from a list.

Authors
  • Michael R. Elkins

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file browser.c.

Function Documentation

◆ init_lastdir()

static void init_lastdir ( void  )
static

Initialise the browser directories.

These keep track of where the browser used to be looking.

Definition at line 107 of file browser.c.

108 {
109  static bool done = false;
110  if (!done)
111  {
114  done = true;
115  }
116 }
static struct Buffer LastDirBackup
Definition: browser.c:100
#define PATH_MAX
Definition: mutt.h:44
static struct Buffer LastDir
Definition: browser.c:99
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_browser_cleanup()

void mutt_browser_cleanup ( void  )

Clean up working Buffers.

Definition at line 121 of file browser.c.

122 {
125 }
static struct Buffer LastDirBackup
Definition: browser.c:100
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
static struct Buffer LastDir
Definition: browser.c:99
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ destroy_state()

static void destroy_state ( struct BrowserState state)
static

Free the BrowserState.

Parameters
stateState to free

Frees up the memory allocated for the local-global variables.

Definition at line 133 of file browser.c.

134 {
135  for (size_t c = 0; c < state->entrylen; c++)
136  {
137  FREE(&((state->entry)[c].name));
138  FREE(&((state->entry)[c].desc));
139  }
140 #ifdef USE_IMAP
141  FREE(&state->folder);
142 #endif
143  FREE(&state->entry);
144 }
char * folder
Definition: browser.h:102
size_t entrylen
number of real entries
Definition: browser.h:98
#define FREE(x)
Definition: memory.h:40
struct FolderFile * entry
Definition: browser.h:97
+ Here is the caller graph for this function:

◆ browser_compare_subject()

static int browser_compare_subject ( const void *  a,
const void *  b 
)
static

Compare the subject of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 154 of file browser.c.

155 {
156  const struct FolderFile *pa = (const struct FolderFile *) a;
157  const struct FolderFile *pb = (const struct FolderFile *) b;
158 
159  /* inbox should be sorted ahead of its siblings */
160  int r = mutt_inbox_cmp(pa->name, pb->name);
161  if (r == 0)
162  r = mutt_str_coll(pa->name, pb->name);
163  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
164 }
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:74
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:652
char * name
Definition: browser.h:70
Browser entry representing a folder/dir.
Definition: browser.h:61
int mutt_inbox_cmp(const char *a, const char *b)
do two folders share the same path and one is an inbox
Definition: muttlib.c:1683
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_desc()

static int browser_compare_desc ( const void *  a,
const void *  b 
)
static

Compare the descriptions of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 174 of file browser.c.

175 {
176  const struct FolderFile *pa = (const struct FolderFile *) a;
177  const struct FolderFile *pb = (const struct FolderFile *) b;
178 
179  int r = mutt_str_coll(pa->desc, pb->desc);
180 
181  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
182 }
char * desc
Definition: browser.h:71
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:74
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:652
Browser entry representing a folder/dir.
Definition: browser.h:61
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_date()

static int browser_compare_date ( const void *  a,
const void *  b 
)
static

Compare the date of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 192 of file browser.c.

193 {
194  const struct FolderFile *pa = (const struct FolderFile *) a;
195  const struct FolderFile *pb = (const struct FolderFile *) b;
196 
197  int r = pa->mtime - pb->mtime;
198 
199  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
200 }
time_t mtime
Definition: browser.h:65
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:74
Browser entry representing a folder/dir.
Definition: browser.h:61
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the caller graph for this function:

◆ browser_compare_size()

static int browser_compare_size ( const void *  a,
const void *  b 
)
static

Compare the size of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 210 of file browser.c.

211 {
212  const struct FolderFile *pa = (const struct FolderFile *) a;
213  const struct FolderFile *pb = (const struct FolderFile *) b;
214 
215  int r = pa->size - pb->size;
216 
217  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
218 }
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:74
off_t size
Definition: browser.h:64
Browser entry representing a folder/dir.
Definition: browser.h:61
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the caller graph for this function:

◆ browser_compare_count()

static int browser_compare_count ( const void *  a,
const void *  b 
)
static

Compare the message count of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 228 of file browser.c.

229 {
230  const struct FolderFile *pa = (const struct FolderFile *) a;
231  const struct FolderFile *pb = (const struct FolderFile *) b;
232 
233  int r = 0;
234  if (pa->has_mailbox && pb->has_mailbox)
235  r = pa->msg_count - pb->msg_count;
236  else if (pa->has_mailbox)
237  r = -1;
238  else
239  r = 1;
240 
241  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
242 }
bool has_mailbox
Definition: browser.h:84
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:74
Browser entry representing a folder/dir.
Definition: browser.h:61
int msg_count
total number of messages
Definition: browser.h:74
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the caller graph for this function:

◆ browser_compare_count_new()

static int browser_compare_count_new ( const void *  a,
const void *  b 
)
static

Compare the new count of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 252 of file browser.c.

253 {
254  const struct FolderFile *pa = (const struct FolderFile *) a;
255  const struct FolderFile *pb = (const struct FolderFile *) b;
256 
257  int r = 0;
258  if (pa->has_mailbox && pb->has_mailbox)
259  r = pa->msg_unread - pb->msg_unread;
260  else if (pa->has_mailbox)
261  r = -1;
262  else
263  r = 1;
264 
265  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
266 }
int msg_unread
number of unread messages
Definition: browser.h:75
bool has_mailbox
Definition: browser.h:84
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:74
Browser entry representing a folder/dir.
Definition: browser.h:61
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the caller graph for this function:

◆ browser_compare()

static int browser_compare ( const void *  a,
const void *  b 
)
static

Sort the items in the browser.

Parameters
aFirst item
bSecond item
Return values
-1a precedes b
0a and b are identical
1b precedes a

Wild compare function that calls the others. It's useful because it provides a way to tell "../" is always on the top of the list, independently of the sort method.

Definition at line 280 of file browser.c.

281 {
282  const struct FolderFile *pa = (const struct FolderFile *) a;
283  const struct FolderFile *pb = (const struct FolderFile *) b;
284 
285  if ((mutt_str_coll(pa->desc, "../") == 0) || (mutt_str_coll(pa->desc, "..") == 0))
286  return -1;
287  if ((mutt_str_coll(pb->desc, "../") == 0) || (mutt_str_coll(pb->desc, "..") == 0))
288  return 1;
289 
290  switch (C_SortBrowser & SORT_MASK)
291  {
292  case SORT_COUNT:
293  return browser_compare_count(a, b);
294  case SORT_DATE:
295  return browser_compare_date(a, b);
296  case SORT_DESC:
297  return browser_compare_desc(a, b);
298  case SORT_SIZE:
299  return browser_compare_size(a, b);
300  case SORT_UNREAD:
301  return browser_compare_count_new(a, b);
302  case SORT_SUBJECT:
303  default:
304  return browser_compare_subject(a, b);
305  }
306 }
static int browser_compare_date(const void *a, const void *b)
Compare the date of two browser entries.
Definition: browser.c:192
char * desc
Definition: browser.h:71
static int browser_compare_desc(const void *a, const void *b)
Compare the descriptions of two browser entries.
Definition: browser.c:174
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:74
static int browser_compare_count(const void *a, const void *b)
Compare the message count of two browser entries.
Definition: browser.c:228
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:652
Sort by the size of the email.
Definition: sort2.h:51
Browser entry representing a folder/dir.
Definition: browser.h:61
static int browser_compare_count_new(const void *a, const void *b)
Compare the new count of two browser entries.
Definition: browser.c:252
static int browser_compare_size(const void *a, const void *b)
Compare the size of two browser entries.
Definition: browser.c:210
static int browser_compare_subject(const void *a, const void *b)
Compare the subject of two browser entries.
Definition: browser.c:154
Sort by the number of unread emails.
Definition: sort2.h:66
Sort by the folder&#39;s description.
Definition: sort2.h:70
Sort by number of emails in a folder.
Definition: sort2.h:65
Sort by the date the email was sent.
Definition: sort2.h:50
Sort by the email&#39;s subject.
Definition: sort2.h:53
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_sort()

static void browser_sort ( struct BrowserState state)
static

Sort the entries in the browser.

Parameters
stateBrowser state

Call to qsort using browser_compare function. Some specific sort methods are not used via NNTP.

Definition at line 315 of file browser.c.

316 {
317  switch (C_SortBrowser & SORT_MASK)
318  {
319  /* Also called "I don't care"-sort-method. */
320  case SORT_ORDER:
321  return;
322 #ifdef USE_NNTP
323  case SORT_SIZE:
324  case SORT_DATE:
325  if (OptNews)
326  return;
327 #endif
328  default:
329  break;
330  }
331 
332  qsort(state->entry, state->entrylen, sizeof(struct FolderFile), browser_compare);
333 }
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:74
Sort by the size of the email.
Definition: sort2.h:51
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:55
Browser entry representing a folder/dir.
Definition: browser.h:61
size_t entrylen
number of real entries
Definition: browser.h:98
static int browser_compare(const void *a, const void *b)
Sort the items in the browser.
Definition: browser.c:280
Sort by the date the email was sent.
Definition: sort2.h:50
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:45
struct FolderFile * entry
Definition: browser.h:97
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ link_is_dir()

static bool link_is_dir ( const char *  folder,
const char *  path 
)
static

Does this symlink point to a directory?

Parameters
folderFolder
pathLink name
Return values
trueLinks to a directory
falseOtherwise

Definition at line 342 of file browser.c.

343 {
344  struct stat st;
345  bool retval = false;
346 
347  struct Buffer *fullpath = mutt_buffer_pool_get();
348  mutt_buffer_concat_path(fullpath, folder, path);
349 
350  if (stat(mutt_b2s(fullpath), &st) == 0)
351  retval = S_ISDIR(st.st_mode);
352 
353  mutt_buffer_pool_release(&fullpath);
354 
355  return retval;
356 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ folder_format_str()

static const char* folder_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the folder browser - Implements format_t.

Expando Description
%C Current file number
%d Date/time folder was last modified
%D Date/time folder was last modified using $date_format.
%F File permissions
%f Filename (with suffix /, @ or *)
%g Group name (or numeric gid, if missing)
%i Description of the folder
%l Number of hard links
%m Number of messages in the mailbox
%N N if mailbox has new mail, blank otherwise
%n Number of unread messages in the mailbox
%s Size in bytes
%t * if the file is tagged, blank otherwise
%u Owner name (or numeric uid, if missing)

Definition at line 378 of file browser.c.

382 {
383  char fn[128], fmt[128];
384  struct Folder *folder = (struct Folder *) data;
385  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
386 
387  switch (op)
388  {
389  case 'C':
390  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
391  snprintf(buf, buflen, fmt, folder->num + 1);
392  break;
393 
394  case 'd':
395  case 'D':
396  if (folder->ff->local)
397  {
398  bool do_locales = true;
399 
400  char *t_fmt = NULL;
401  if (op == 'D')
402  {
403  t_fmt = NONULL(C_DateFormat);
404  if (*t_fmt == '!')
405  {
406  t_fmt++;
407  do_locales = false;
408  }
409  }
410  else
411  {
412  static const time_t one_year = 31536000;
413  t_fmt = ((mutt_date_epoch() - folder->ff->mtime) < one_year) ?
414  "%b %d %H:%M" :
415  "%b %d %Y";
416  }
417 
418  if (!do_locales)
419  setlocale(LC_TIME, "C");
420  char date[128];
421  mutt_date_localtime_format(date, sizeof(date), t_fmt, folder->ff->mtime);
422  if (!do_locales)
423  setlocale(LC_TIME, "");
424 
425  mutt_format_s(buf, buflen, prec, date);
426  }
427  else
428  mutt_format_s(buf, buflen, prec, "");
429  break;
430 
431  case 'f':
432  {
433  char *s = NULL;
434 
435  s = NONULL(folder->ff->name);
436 
437  snprintf(fn, sizeof(fn), "%s%s", s,
438  folder->ff->local ?
439  (S_ISLNK(folder->ff->mode) ?
440  "@" :
441  (S_ISDIR(folder->ff->mode) ?
442  "/" :
443  (((folder->ff->mode & S_IXUSR) != 0) ? "*" : ""))) :
444  "");
445 
446  mutt_format_s(buf, buflen, prec, fn);
447  break;
448  }
449  case 'F':
450  {
451  if (folder->ff->local)
452  {
453  char permission[11];
454  snprintf(permission, sizeof(permission), "%c%c%c%c%c%c%c%c%c%c",
455  S_ISDIR(folder->ff->mode) ? 'd' : (S_ISLNK(folder->ff->mode) ? 'l' : '-'),
456  ((folder->ff->mode & S_IRUSR) != 0) ? 'r' : '-',
457  ((folder->ff->mode & S_IWUSR) != 0) ? 'w' : '-',
458  ((folder->ff->mode & S_ISUID) != 0) ?
459  's' :
460  ((folder->ff->mode & S_IXUSR) != 0) ? 'x' : '-',
461  ((folder->ff->mode & S_IRGRP) != 0) ? 'r' : '-',
462  ((folder->ff->mode & S_IWGRP) != 0) ? 'w' : '-',
463  ((folder->ff->mode & S_ISGID) != 0) ?
464  's' :
465  ((folder->ff->mode & S_IXGRP) != 0) ? 'x' : '-',
466  ((folder->ff->mode & S_IROTH) != 0) ? 'r' : '-',
467  ((folder->ff->mode & S_IWOTH) != 0) ? 'w' : '-',
468  ((folder->ff->mode & S_ISVTX) != 0) ?
469  't' :
470  ((folder->ff->mode & S_IXOTH) != 0) ? 'x' : '-');
471  mutt_format_s(buf, buflen, prec, permission);
472  }
473 #ifdef USE_IMAP
474  else if (folder->ff->imap)
475  {
476  char permission[11];
477  /* mark folders with subfolders AND mail */
478  snprintf(permission, sizeof(permission), "IMAP %c",
479  (folder->ff->inferiors && folder->ff->selectable) ? '+' : ' ');
480  mutt_format_s(buf, buflen, prec, permission);
481  }
482 #endif
483  else
484  mutt_format_s(buf, buflen, prec, "");
485  break;
486  }
487 
488  case 'g':
489  if (folder->ff->local)
490  {
491  struct group *gr = getgrgid(folder->ff->gid);
492  if (gr)
493  mutt_format_s(buf, buflen, prec, gr->gr_name);
494  else
495  {
496  snprintf(fmt, sizeof(fmt), "%%%sld", prec);
497  snprintf(buf, buflen, fmt, folder->ff->gid);
498  }
499  }
500  else
501  mutt_format_s(buf, buflen, prec, "");
502  break;
503 
504  case 'i':
505  {
506  char *s = NULL;
507  if (folder->ff->desc)
508  s = folder->ff->desc;
509  else
510  s = folder->ff->name;
511 
512  snprintf(fn, sizeof(fn), "%s%s", s,
513  folder->ff->local ?
514  (S_ISLNK(folder->ff->mode) ?
515  "@" :
516  (S_ISDIR(folder->ff->mode) ?
517  "/" :
518  (((folder->ff->mode & S_IXUSR) != 0) ? "*" : ""))) :
519  "");
520 
521  mutt_format_s(buf, buflen, prec, fn);
522  break;
523  }
524 
525  case 'l':
526  if (folder->ff->local)
527  {
528  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
529  snprintf(buf, buflen, fmt, folder->ff->nlink);
530  }
531  else
532  mutt_format_s(buf, buflen, prec, "");
533  break;
534 
535  case 'm':
536  if (!optional)
537  {
538  if (folder->ff->has_mailbox)
539  {
540  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
541  snprintf(buf, buflen, fmt, folder->ff->msg_count);
542  }
543  else
544  mutt_format_s(buf, buflen, prec, "");
545  }
546  else if (folder->ff->msg_count == 0)
547  optional = false;
548  break;
549 
550  case 'N':
551  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
552  snprintf(buf, buflen, fmt, folder->ff->has_new_mail ? 'N' : ' ');
553  break;
554 
555  case 'n':
556  if (!optional)
557  {
558  if (folder->ff->has_mailbox)
559  {
560  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
561  snprintf(buf, buflen, fmt, folder->ff->msg_unread);
562  }
563  else
564  mutt_format_s(buf, buflen, prec, "");
565  }
566  else if (folder->ff->msg_unread == 0)
567  optional = false;
568  break;
569 
570  case 's':
571  if (folder->ff->local)
572  {
573  mutt_str_pretty_size(fn, sizeof(fn), folder->ff->size);
574  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
575  snprintf(buf, buflen, fmt, fn);
576  }
577  else
578  mutt_format_s(buf, buflen, prec, "");
579  break;
580 
581  case 't':
582  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
583  snprintf(buf, buflen, fmt, folder->ff->tagged ? '*' : ' ');
584  break;
585 
586  case 'u':
587  if (folder->ff->local)
588  {
589  struct passwd *pw = getpwuid(folder->ff->uid);
590  if (pw)
591  mutt_format_s(buf, buflen, prec, pw->pw_name);
592  else
593  {
594  snprintf(fmt, sizeof(fmt), "%%%sld", prec);
595  snprintf(buf, buflen, fmt, folder->ff->uid);
596  }
597  }
598  else
599  mutt_format_s(buf, buflen, prec, "");
600  break;
601 
602  default:
603  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
604  snprintf(buf, buflen, fmt, op);
605  break;
606  }
607 
608  if (optional)
609  {
610  mutt_expando_format(buf, buflen, col, cols, if_str, folder_format_str, data,
612  }
613  else if (flags & MUTT_FORMAT_OPTIONAL)
614  {
615  mutt_expando_format(buf, buflen, col, cols, else_str, folder_format_str,
616  data, MUTT_FORMAT_NO_FLAGS);
617  }
618 
619  return src;
620 }
int msg_unread
number of unread messages
Definition: browser.h:75
static const char * folder_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the folder browser - Implements format_t.
Definition: browser.c:378
mode_t mode
Definition: browser.h:63
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:414
time_t mtime
Definition: browser.h:65
#define NONULL(x)
Definition: string2.h:37
bool has_mailbox
Definition: browser.h:84
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:678
char * desc
Definition: browser.h:71
static int const char * fmt
Definition: acutest.h:488
gid_t gid
Definition: browser.h:67
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
struct FolderFile * ff
Definition: browser.h:54
off_t size
Definition: browser.h:64
bool selectable
Definition: browser.h:81
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:862
uid_t uid
Definition: browser.h:66
nlink_t nlink
Definition: browser.h:68
char * name
Definition: browser.h:70
int num
Definition: browser.h:55
bool imap
Definition: browser.h:80
A folder/dir in the browser.
Definition: browser.h:52
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1749
int msg_count
total number of messages
Definition: browser.h:74
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1223
WHERE char * C_DateFormat
Config: strftime format string for the d expando.
Definition: globals.h:106
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
bool tagged
Definition: browser.h:86
bool local
folder is on local filesystem
Definition: browser.h:85
bool inferiors
Definition: browser.h:82
bool has_new_mail
true if mailbox has "new mail"
Definition: browser.h:73
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_folder()

static void add_folder ( struct Menu menu,
struct BrowserState state,
const char *  name,
const char *  desc,
const struct stat *  s,
struct Mailbox m,
void *  data 
)
static

Add a folder to the browser list.

Parameters
menuMenu to use
stateBrowser state
nameName of folder
descDescription of folder
sstat info for the folder
mMailbox
dataData to associate with the folder

Definition at line 632 of file browser.c.

635 {
636  if ((!menu || menu->is_mailbox_list) && m && (m->flags & MB_HIDDEN))
637  {
638  return;
639  }
640 
641  if (state->entrylen == state->entrymax)
642  {
643  /* need to allocate more space */
644  mutt_mem_realloc(&state->entry, sizeof(struct FolderFile) * (state->entrymax += 256));
645  memset(&state->entry[state->entrylen], 0, sizeof(struct FolderFile) * 256);
646  if (menu)
647  menu->mdata = state->entry;
648  }
649 
650  if (s)
651  {
652  (state->entry)[state->entrylen].mode = s->st_mode;
653  (state->entry)[state->entrylen].mtime = s->st_mtime;
654  (state->entry)[state->entrylen].size = s->st_size;
655  (state->entry)[state->entrylen].gid = s->st_gid;
656  (state->entry)[state->entrylen].uid = s->st_uid;
657  (state->entry)[state->entrylen].nlink = s->st_nlink;
658 
659  (state->entry)[state->entrylen].local = true;
660  }
661  else
662  (state->entry)[state->entrylen].local = false;
663 
664  if (m)
665  {
666  (state->entry)[state->entrylen].has_mailbox = true;
667  (state->entry)[state->entrylen].has_new_mail = m->has_new;
668  (state->entry)[state->entrylen].msg_count = m->msg_count;
669  (state->entry)[state->entrylen].msg_unread = m->msg_unread;
670  }
671 
672  (state->entry)[state->entrylen].name = mutt_str_dup(name);
673  (state->entry)[state->entrylen].desc = mutt_str_dup(desc ? desc : name);
674 #ifdef USE_IMAP
675  (state->entry)[state->entrylen].imap = false;
676 #endif
677 #ifdef USE_NNTP
678  if (OptNews)
679  (state->entry)[state->entrylen].nd = data;
680 #endif
681  (state->entrylen)++;
682 }
mode_t mode
Definition: browser.h:63
int msg_count
Total number of messages.
Definition: mailbox.h:91
if(!test_colorize_)
Definition: acutest.h:499
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
unsigned int entrymax
max entry
Definition: browser.h:99
int flags
e.g. MB_NORMAL
Definition: mailbox.h:134
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
Browser entry representing a folder/dir.
Definition: browser.h:61
#define MB_HIDDEN
Definition: mailbox.h:38
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:84
bool is_mailbox_list
Definition: mutt_menu.h:91
size_t entrylen
number of real entries
Definition: browser.h:98
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:45
struct FolderFile * entry
Definition: browser.h:97
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_state()

static void init_state ( struct BrowserState state,
struct Menu menu 
)
static

Initialise a browser state.

Parameters
stateBrowserState to initialise
menuCurrent menu

Definition at line 689 of file browser.c.

690 {
691  state->entrylen = 0;
692  state->entrymax = 256;
693  state->entry = mutt_mem_calloc(state->entrymax, sizeof(struct FolderFile));
694 #ifdef USE_IMAP
695  state->imap_browse = false;
696 #endif
697  if (menu)
698  menu->mdata = state->entry;
699 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
unsigned int entrymax
max entry
Definition: browser.h:99
Browser entry representing a folder/dir.
Definition: browser.h:61
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:84
size_t entrylen
number of real entries
Definition: browser.h:98
bool imap_browse
Definition: browser.h:101
struct FolderFile * entry
Definition: browser.h:97
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ examine_directory()

static int examine_directory ( struct Menu menu,
struct BrowserState state,
const char *  d,
const char *  prefix 
)
static

Get list of all files/newsgroups with mask.

Parameters
menuCurrent Menu
stateState of browser
dDirectory
prefixFiles/newsgroups must match this prefix
Return values
0Success
-1Error

Definition at line 710 of file browser.c.

712 {
713  int rc = -1;
714  struct Buffer *buf = mutt_buffer_pool_get();
715 #ifdef USE_NNTP
716  if (OptNews)
717  {
719 
720  init_state(state, menu);
721 
722  for (unsigned int i = 0; i < adata->groups_num; i++)
723  {
724  struct NntpMboxData *mdata = adata->groups_list[i];
725  if (!mdata)
726  continue;
727  if (prefix && *prefix && !mutt_str_startswith(mdata->group, prefix))
728  continue;
729  if (!mutt_regex_match(C_Mask, mdata->group))
730  {
731  continue;
732  }
733  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
734  }
735  }
736  else
737 #endif /* USE_NNTP */
738  {
739  struct stat s;
740  DIR *dp = NULL;
741  struct dirent *de = NULL;
742 
743  while (stat(d, &s) == -1)
744  {
745  if (errno == ENOENT)
746  {
747  /* The last used directory is deleted, try to use the parent dir. */
748  char *c = strrchr(d, '/');
749 
750  if (c && (c > d))
751  {
752  *c = '\0';
753  continue;
754  }
755  }
756  mutt_perror(d);
757  goto ed_out;
758  }
759 
760  if (!S_ISDIR(s.st_mode))
761  {
762  mutt_error(_("%s is not a directory"), d);
763  goto ed_out;
764  }
765 
766  if (Context && Context->mailbox)
768 
769  dp = opendir(d);
770  if (!dp)
771  {
772  mutt_perror(d);
773  goto ed_out;
774  }
775 
776  init_state(state, menu);
777 
778  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
780  while ((de = readdir(dp)))
781  {
782  if (mutt_str_equal(de->d_name, "."))
783  continue; /* we don't need . */
784 
785  if (prefix && *prefix && !mutt_str_startswith(de->d_name, prefix))
786  {
787  continue;
788  }
789  if (!mutt_regex_match(C_Mask, de->d_name))
790  {
791  continue;
792  }
793 
794  mutt_buffer_concat_path(buf, d, de->d_name);
795  if (lstat(mutt_b2s(buf), &s) == -1)
796  continue;
797 
798  /* No size for directories or symlinks */
799  if (S_ISDIR(s.st_mode) || S_ISLNK(s.st_mode))
800  s.st_size = 0;
801  else if (!S_ISREG(s.st_mode))
802  continue;
803 
804  struct MailboxNode *np = NULL;
805  STAILQ_FOREACH(np, &ml, entries)
806  {
808  break;
809  }
810 
811  if (np && Context && Context->mailbox &&
813  {
816  }
817  add_folder(menu, state, de->d_name, NULL, &s, np ? np->mailbox : NULL, NULL);
818  }
820  closedir(dp);
821  }
822  browser_sort(state);
823  rc = 0;
824 ed_out:
826  return rc;
827 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
The "current" mailbox.
Definition: context.h:37
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
int msg_count
Total number of messages.
Definition: mailbox.h:91
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
Match any Mailbox type.
Definition: mailbox.h:45
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:158
static void add_folder(struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *s, struct Mailbox *m, void *data)
Add a folder to the browser list.
Definition: browser.c:632
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
Container for Accounts, Notifications.
Definition: neomutt.h:36
NNTP-specific Account data -.
Definition: lib.h:77
struct Mailbox * mailbox
Definition: context.h:50
char * group
Definition: lib.h:142
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:165
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:152
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int groups_num
Definition: lib.h:100
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:315
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
NNTP-specific Mailbox data -.
Definition: lib.h:140
#define mutt_error(...)
Definition: logging.h:84
WHERE struct Regex * C_Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:169
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:609
void ** groups_list
Definition: lib.h:102
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:84
List of Mailboxes.
Definition: mailbox.h:145
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:689
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:45
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ examine_mailboxes()

static int examine_mailboxes ( struct Menu menu,
struct BrowserState state 
)
static

Get list of mailboxes/subscribed newsgroups.

Parameters
menuCurrent menu
stateState of browser
Return values
0Success
-1Error

Definition at line 836 of file browser.c.

837 {
838  struct stat s;
839  struct Buffer *md = NULL;
840  struct Buffer *mailbox = NULL;
841 
842 #ifdef USE_NNTP
843  if (OptNews)
844  {
846 
847  init_state(state, menu);
848 
849  for (unsigned int i = 0; i < adata->groups_num; i++)
850  {
851  struct NntpMboxData *mdata = adata->groups_list[i];
852  if (mdata && (mdata->has_new_mail ||
853  (mdata->subscribed && (mdata->unread || !C_ShowOnlyUnread))))
854  {
855  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
856  }
857  }
858  }
859  else
860 #endif
861  {
862  init_state(state, menu);
863 
865  return -1;
866  mailbox = mutt_buffer_pool_get();
867  md = mutt_buffer_pool_get();
869 
870  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
872  struct MailboxNode *np = NULL;
873  STAILQ_FOREACH(np, &ml, entries)
874  {
875  if (!np->mailbox)
876  continue;
877 
878  if (Context && Context->mailbox &&
880  {
883  }
884 
885  mutt_buffer_strcpy(mailbox, mailbox_path(np->mailbox));
888 
889  switch (np->mailbox->type)
890  {
891  case MUTT_IMAP:
892  case MUTT_POP:
893  add_folder(menu, state, mutt_b2s(mailbox), np->mailbox->name, NULL,
894  np->mailbox, NULL);
895  continue;
896  case MUTT_NOTMUCH:
897  case MUTT_NNTP:
898  add_folder(menu, state, mailbox_path(np->mailbox), np->mailbox->name,
899  NULL, np->mailbox, NULL);
900  continue;
901  default: /* Continue */
902  break;
903  }
904 
905  if (lstat(mailbox_path(np->mailbox), &s) == -1)
906  continue;
907 
908  if ((!S_ISREG(s.st_mode)) && (!S_ISDIR(s.st_mode)) && (!S_ISLNK(s.st_mode)))
909  continue;
910 
911  if (np->mailbox->type == MUTT_MAILDIR)
912  {
913  struct stat st2;
914 
915  mutt_buffer_printf(md, "%s/new", mailbox_path(np->mailbox));
916  if (stat(mutt_b2s(md), &s) < 0)
917  s.st_mtime = 0;
918  mutt_buffer_printf(md, "%s/cur", mailbox_path(np->mailbox));
919  if (stat(mutt_b2s(md), &st2) < 0)
920  st2.st_mtime = 0;
921  if (st2.st_mtime > s.st_mtime)
922  s.st_mtime = st2.st_mtime;
923  }
924 
925  add_folder(menu, state, mutt_b2s(mailbox), np->mailbox->name, &s, np->mailbox, NULL);
926  }
928  }
929  browser_sort(state);
930 
931  mutt_buffer_pool_release(&mailbox);
933  return 0;
934 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
bool has_new_mail
Definition: lib.h:150
The "current" mailbox.
Definition: context.h:37
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
Match any Mailbox type.
Definition: mailbox.h:45
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:158
static void add_folder(struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *s, struct Mailbox *m, void *data)
Add a folder to the browser list.
Definition: browser.c:632
String manipulation buffer.
Definition: buffer.h:33
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:688
NNTP-specific Account data -.
Definition: lib.h:77
bool subscribed
Definition: lib.h:149
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
struct Mailbox * mailbox
Definition: context.h:50
char * group
Definition: lib.h:142
void * mdata
Driver specific data.
Definition: mailbox.h:136
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
#define mutt_b2s(buf)
Definition: buffer.h:41
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:152
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int groups_num
Definition: lib.h:100
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:315
bool C_ShowOnlyUnread
Config: (nntp) Only show subscribed newsgroups with unread articles.
Definition: browser.c:73
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
NNTP-specific Mailbox data -.
Definition: lib.h:140
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
anum_t unread
Definition: lib.h:148
bool C_BrowserAbbreviateMailboxes
Config: Abbreviate mailboxes using &#39;~&#39; and &#39;=&#39; in the browser.
Definition: browser.c:69
void ** groups_list
Definition: lib.h:102
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:84
List of Mailboxes.
Definition: mailbox.h:145
#define TAILQ_EMPTY(head)
Definition: queue.h:714
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:689
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:45
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ select_file_search()

static int select_file_search ( struct Menu menu,
regex_t *  rx,
int  line 
)
static

Menu search callback for matching files - Implements Menu::search()

Definition at line 939 of file browser.c.

940 {
941 #ifdef USE_NNTP
942  if (OptNews)
943  return regexec(rx, ((struct FolderFile *) menu->mdata)[line].desc, 0, NULL, 0);
944 #endif
945  struct FolderFile current_ff = ((struct FolderFile *) menu->mdata)[line];
946  char *search_on = current_ff.desc ? current_ff.desc : current_ff.name;
947 
948  return regexec(rx, search_on, 0, NULL, 0);
949 }
char * desc
Definition: browser.h:71
char * name
Definition: browser.h:70
Browser entry representing a folder/dir.
Definition: browser.h:61
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:84
int const char int line
Definition: acutest.h:617
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:45
+ Here is the caller graph for this function:

◆ folder_make_entry()

static void folder_make_entry ( char *  buf,
size_t  buflen,
struct Menu menu,
int  line 
)
static

Format a menu item for the folder browser - Implements Menu::make_entry()

Definition at line 954 of file browser.c.

955 {
956  struct Folder folder;
957 
958  folder.ff = &((struct FolderFile *) menu->mdata)[line];
959  folder.num = line;
960 
961 #ifdef USE_NNTP
962  if (OptNews)
963  {
964  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
966  (intptr_t) &folder, MUTT_FORMAT_ARROWCURSOR);
967  }
968  else
969 #endif
970  {
971  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
973  (intptr_t) &folder, MUTT_FORMAT_ARROWCURSOR);
974  }
975 }
static const char * folder_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the folder browser - Implements format_t.
Definition: browser.c:378
#define NONULL(x)
Definition: string2.h:37
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
char * C_FolderFormat
Config: printf-like format string for the browser&#39;s display of folders.
Definition: browser.c:70
struct FolderFile * ff
Definition: browser.h:54
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:862
const char * group_index_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the newsgroup menu - Implements format_t.
Definition: browse.c:52
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
A folder/dir in the browser.
Definition: browser.h:52
Browser entry representing a folder/dir.
Definition: browser.h:61
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:113
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:84
int const char int line
Definition: acutest.h:617
struct MuttWindow * win_index
Definition: mutt_menu.h:92
char * C_GroupIndexFormat
Config: (nntp) printf-like format string for the browser&#39;s display of newsgroups. ...
Definition: browser.c:71
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_highlight_default()

static void browser_highlight_default ( struct BrowserState state,
struct Menu menu 
)
static

Decide which browser item should be highlighted.

Parameters
stateBrowser state
menuCurrent Menu

This function takes a menu and a state and defines the current entry that should be highlighted.

Definition at line 985 of file browser.c.

986 {
987  menu->top = 0;
988  /* Reset menu position to 1.
989  * We do not risk overflow as the init_menu function changes
990  * current if it is bigger than state->entrylen. */
991  if (mutt_str_equal(state->entry[0].desc, "..") ||
992  mutt_str_equal(state->entry[0].desc, "../"))
993  {
994  /* Skip the first entry, unless there's only one entry. */
995  menu->current = (menu->max > 1);
996  }
997  else
998  {
999  menu->current = 0;
1000  }
1001 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
char * desc
Definition: browser.h:71
int top
Entry that is the top of the current page.
Definition: mutt_menu.h:105
int max
Number of entries in the menu.
Definition: mutt_menu.h:86
int current
Current entry.
Definition: mutt_menu.h:85
struct FolderFile * entry
Definition: browser.h:97
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_menu()

static void init_menu ( struct BrowserState state,
struct Menu menu,
char *  title,
size_t  titlelen,
bool  mailbox 
)
static

Set up a new menu.

Parameters
stateBrowser state
menuCurrent menu
titleBuffer for the title
titlelenLength of buffer
mailboxIf true, select mailboxes

Definition at line 1011 of file browser.c.

1013 {
1014  menu->max = state->entrylen;
1015 
1016  if (menu->current >= menu->max)
1017  menu->current = menu->max - 1;
1018  if (menu->current < 0)
1019  menu->current = 0;
1020  if (menu->top > menu->current)
1021  menu->top = 0;
1022 
1023  menu->tagged = 0;
1024 
1025 #ifdef USE_NNTP
1026  if (OptNews)
1027  {
1028  if (mailbox)
1029  snprintf(title, titlelen, _("Subscribed newsgroups"));
1030  else
1031  {
1032  snprintf(title, titlelen, _("Newsgroups on server [%s]"),
1034  }
1035  }
1036  else
1037 #endif
1038  {
1039  if (mailbox)
1040  {
1041  menu->is_mailbox_list = true;
1042  snprintf(title, titlelen, _("Mailboxes [%d]"),
1043  mutt_mailbox_check(Context ? Context->mailbox : NULL, 0));
1044  }
1045  else
1046  {
1047  struct Buffer *path = mutt_buffer_pool_get();
1048  menu->is_mailbox_list = false;
1049  mutt_buffer_copy(path, &LastDir);
1051 #ifdef USE_IMAP
1052  if (state->imap_browse && C_ImapListSubscribed)
1053  {
1054  snprintf(title, titlelen, _("Subscribed [%s], File mask: %s"),
1055  mutt_b2s(path), NONULL(C_Mask ? C_Mask->pattern : NULL));
1056  }
1057  else
1058 #endif
1059  {
1060  snprintf(title, titlelen, _("Directory [%s], File mask: %s"),
1061  mutt_b2s(path), NONULL(C_Mask ? C_Mask->pattern : NULL));
1062  }
1063  mutt_buffer_pool_release(&path);
1064  }
1065  }
1066 
1067  /* Browser tracking feature.
1068  * The goal is to highlight the good directory if LastDir is the parent dir
1069  * of LastDirBackup (this occurs mostly when one hit "../"). It should also work
1070  * properly when the user is in examine_mailboxes-mode. */
1072  {
1073  char target_dir[PATH_MAX] = { 0 };
1074 
1075 #ifdef USE_IMAP
1076  /* Check what kind of dir LastDirBackup is. */
1078  {
1079  mutt_str_copy(target_dir, mutt_b2s(&LastDirBackup), sizeof(target_dir));
1080  imap_clean_path(target_dir, sizeof(target_dir));
1081  }
1082  else
1083 #endif
1084  mutt_str_copy(target_dir, strrchr(mutt_b2s(&LastDirBackup), '/') + 1,
1085  sizeof(target_dir));
1086 
1087  /* If we get here, it means that LastDir is the parent directory of
1088  * LastDirBackup. I.e., we're returning from a subdirectory, and we want
1089  * to position the cursor on the directory we're returning from. */
1090  bool matched = false;
1091  for (unsigned int i = 0; i < state->entrylen; i++)
1092  {
1093  if (mutt_str_equal(state->entry[i].name, target_dir))
1094  {
1095  menu->current = i;
1096  matched = true;
1097  break;
1098  }
1099  }
1100  if (!matched)
1101  browser_highlight_default(state, menu);
1102  }
1103  else
1104  browser_highlight_default(state, menu);
1105 
1106  menu->redraw = REDRAW_FULL;
1107 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
The "current" mailbox.
Definition: context.h:37
WHERE bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: globals.h:216
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:45
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2351
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:688
char host[128]
Server to login to.
Definition: connaccount.h:53
static struct Buffer LastDirBackup
Definition: browser.c:100
struct Mailbox * mailbox
Definition: context.h:50
char * name
Definition: browser.h:70
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:165
#define PATH_MAX
Definition: mutt.h:44
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:152
int top
Entry that is the top of the current page.
Definition: mutt_menu.h:105
bool is_mailbox_list
Definition: mutt_menu.h:91
int tagged
Number of tagged entries.
Definition: mutt_menu.h:108
int max
Number of entries in the menu.
Definition: mutt_menu.h:86
size_t entrylen
number of real entries
Definition: browser.h:98
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:87
struct Connection * conn
Definition: lib.h:104
static void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: browser.c:985
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:724
void imap_clean_path(char *path, size_t plen)
Cleans an IMAP path using imap_fix_path.
Definition: util.c:335
WHERE struct Regex * C_Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:169
static struct Buffer LastDir
Definition: browser.c:99
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:84
int current
Current entry.
Definition: mutt_menu.h:85
char * pattern
printable version
Definition: regex3.h:90
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
bool imap_browse
Definition: browser.h:101
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:45
struct FolderFile * entry
Definition: browser.h:97
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ file_tag()

static int file_tag ( struct Menu menu,
int  sel,
int  act 
)
static

Tag an entry in the menu - Implements Menu::tag()

Definition at line 1112 of file browser.c.

1113 {
1114  struct FolderFile *ff = &(((struct FolderFile *) menu->mdata)[sel]);
1115  if (S_ISDIR(ff->mode) || (S_ISLNK(ff->mode) && link_is_dir(mutt_b2s(&LastDir), ff->name)))
1116  {
1117  mutt_error(_("Can't attach a directory"));
1118  return 0;
1119  }
1120 
1121  bool ot = ff->tagged;
1122  ff->tagged = ((act >= 0) ? act : !ff->tagged);
1123 
1124  return ff->tagged - ot;
1125 }
mode_t mode
Definition: browser.h:63
static bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
Definition: browser.c:342
#define _(a)
Definition: message.h:28
char * name
Definition: browser.h:70
#define mutt_b2s(buf)
Definition: buffer.h:41
Browser entry representing a folder/dir.
Definition: browser.h:61
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:84
#define mutt_error(...)
Definition: logging.h:84
static struct Buffer LastDir
Definition: browser.c:99
bool tagged
Definition: browser.h:86
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_browser_select_dir()

void mutt_browser_select_dir ( const char *  f)

Remember the last directory selected.

Parameters
fDirectory name to save

This function helps the browser to know which directory has been selected. It should be called anywhere a confirm hit is done to open a new directory/file which is a maildir/mbox.

We could check if the sort method is appropriate with this feature.

Definition at line 1137 of file browser.c.

1138 {
1139  init_lastdir();
1140 
1142 
1143  /* Method that will fetch the parent path depending on the type of the path. */
1144  char buf[PATH_MAX];
1145  mutt_get_parent_path(mutt_b2s(&LastDirBackup), buf, sizeof(buf));
1146  mutt_buffer_strcpy(&LastDir, buf);
1147 }
static void init_lastdir(void)
Initialise the browser directories.
Definition: browser.c:107
static struct Buffer LastDirBackup
Definition: browser.c:100
#define mutt_b2s(buf)
Definition: buffer.h:41
#define PATH_MAX
Definition: mutt.h:44
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
static struct Buffer LastDir
Definition: browser.c:99
void mutt_get_parent_path(const char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition: muttlib.c:1628
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_dlg_browser_observer()

static int mutt_dlg_browser_observer ( struct NotifyCallback nc)
static

Listen for config changes affecting the Browser menu - Implements observer_t.

Definition at line 1152 of file browser.c.

1153 {
1154  if (!nc->event_data || !nc->global_data)
1155  return -1;
1156  if (nc->event_type != NT_CONFIG)
1157  return 0;
1158 
1159  struct EventConfig *ec = nc->event_data;
1160  struct MuttWindow *dlg = nc->global_data;
1161 
1162  if (!mutt_str_equal(ec->name, "status_on_top"))
1163  return 0;
1164 
1165  struct MuttWindow *win_first = TAILQ_FIRST(&dlg->children);
1166 
1167  if ((C_StatusOnTop && (win_first->type == WT_INDEX)) ||
1168  (!C_StatusOnTop && (win_first->type != WT_INDEX)))
1169  {
1170  // Swap the Index and the IndexBar Windows
1171  TAILQ_REMOVE(&dlg->children, win_first, entries);
1172  TAILQ_INSERT_TAIL(&dlg->children, win_first, entries);
1173  }
1174 
1175  mutt_window_reflow(dlg);
1176  return 0;
1177 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:247
#define TAILQ_FIRST(head)
Definition: queue.h:716
A config-change event.
Definition: subset.h:70
A division of the screen.
Definition: mutt_window.h:108
An Index Window containing a selection list.
Definition: mutt_window.h:93
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:41
void * global_data
Data from notify_observer_add()
Definition: observer.h:44
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
void * event_data
Data from notify_send()
Definition: observer.h:43
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:36
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:432
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:121
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:125
const char * name
Name of config item that changed.
Definition: subset.h:73
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_select_file()

void mutt_buffer_select_file ( struct Buffer file,
SelectFileFlags  flags,
char ***  files,
int *  numfiles 
)

Let the user select a file.

Parameters
[in]fileBuffer for the result
[in]flagsFlags, see SelectFileFlags
[out]filesArray of selected files
[out]numfilesNumber of selected files

Definition at line 1186 of file browser.c.

1188 {
1189  char helpstr[1024];
1190  char title[256];
1191  struct BrowserState state = { 0 };
1192  struct Menu *menu = NULL;
1193  bool kill_prefix = false;
1194  bool multiple = (flags & MUTT_SEL_MULTI);
1195  bool folder = (flags & MUTT_SEL_FOLDER);
1196  bool mailbox = (flags & MUTT_SEL_MAILBOX);
1197 
1198  /* Keeps in memory the directory we were in when hitting '='
1199  * to go directly to $folder (#C_Folder) */
1200  char goto_swapper[PATH_MAX] = { 0 };
1201 
1202  mailbox = mailbox && folder;
1203 
1204  struct Buffer *OldLastDir = mutt_buffer_pool_get();
1205  struct Buffer *tmp = mutt_buffer_pool_get();
1206  struct Buffer *buf = mutt_buffer_pool_get();
1207  struct Buffer *prefix = mutt_buffer_pool_get();
1208 
1209  init_lastdir();
1210 
1211 #ifdef USE_NNTP
1212  if (OptNews)
1213  {
1214  if (mutt_buffer_is_empty(file))
1215  {
1217 
1218  /* default state for news reader mode is browse subscribed newsgroups */
1219  mailbox = false;
1220  for (size_t i = 0; i < adata->groups_num; i++)
1221  {
1222  struct NntpMboxData *mdata = adata->groups_list[i];
1223  if (mdata && mdata->subscribed)
1224  {
1225  mailbox = true;
1226  break;
1227  }
1228  }
1229  }
1230  else
1231  {
1232  mutt_buffer_copy(prefix, file);
1233  }
1234  }
1235  else
1236 #endif
1237  if (!mutt_buffer_is_empty(file))
1238  {
1240 #ifdef USE_IMAP
1241  if (imap_path_probe(mutt_b2s(file), NULL) == MUTT_IMAP)
1242  {
1243  init_state(&state, NULL);
1244  state.imap_browse = true;
1245  if (imap_browse(mutt_b2s(file), &state) == 0)
1246  {
1248  browser_sort(&state);
1249  }
1250  }
1251  else
1252  {
1253 #endif
1254  int i;
1255  for (i = mutt_buffer_len(file) - 1; (i > 0) && ((mutt_b2s(file))[i] != '/'); i--)
1256  ; // do nothing
1257 
1258  if (i > 0)
1259  {
1260  if ((mutt_b2s(file))[0] == '/')
1262  else
1263  {
1265  mutt_buffer_addch(&LastDir, '/');
1267  }
1268  }
1269  else
1270  {
1271  if ((mutt_b2s(file))[0] == '/')
1272  mutt_buffer_strcpy(&LastDir, "/");
1273  else
1275  }
1276 
1277  if ((i <= 0) && (mutt_b2s(file)[0] != '/'))
1278  mutt_buffer_copy(prefix, file);
1279  else
1280  mutt_buffer_strcpy(prefix, mutt_b2s(file) + i + 1);
1281  kill_prefix = true;
1282 #ifdef USE_IMAP
1283  }
1284 #endif
1285  }
1286  else
1287  {
1288  if (!folder)
1290  else
1291  {
1292  /* Whether we use the tracking feature of the browser depends
1293  * on which sort method we chose to use. This variable is defined
1294  * only to help readability of the code. */
1295  bool browser_track = false;
1296 
1297  switch (C_SortBrowser & SORT_MASK)
1298  {
1299  case SORT_DESC:
1300  case SORT_SUBJECT:
1301  case SORT_ORDER:
1302  browser_track = true;
1303  break;
1304  }
1305 
1306  /* We use mutt_browser_select_dir to initialize the two
1307  * variables (LastDir, LastDirBackup) at the appropriate
1308  * values.
1309  *
1310  * We do it only when LastDir is not set (first pass there)
1311  * or when CurrentFolder and LastDirBackup are not the same.
1312  * This code is executed only when we list files, not when
1313  * we press up/down keys to navigate in a displayed list.
1314  *
1315  * We only do this when CurrentFolder has been set (ie, not
1316  * when listing folders on startup with "neomutt -y").
1317  *
1318  * This tracker is only used when browser_track is true,
1319  * meaning only with sort methods SUBJECT/DESC for now. */
1320  if (CurrentFolder)
1321  {
1323  {
1324  /* If browsing in "local"-mode, than we chose to define LastDir to
1325  * MailDir */
1326  switch (mx_path_probe(CurrentFolder))
1327  {
1328  case MUTT_IMAP:
1329  case MUTT_MAILDIR:
1330  case MUTT_MBOX:
1331  case MUTT_MH:
1332  case MUTT_MMDF:
1333  if (C_Folder)
1335  else if (C_Spoolfile)
1337  break;
1338  default:
1340  break;
1341  }
1342  }
1344  {
1346  }
1347  }
1348 
1349  /* When browser tracking feature is disabled, clear LastDirBackup */
1350  if (!browser_track)
1352  }
1353 
1354 #ifdef USE_IMAP
1355  if (!mailbox && (imap_path_probe(mutt_b2s(&LastDir), NULL) == MUTT_IMAP))
1356  {
1357  init_state(&state, NULL);
1358  state.imap_browse = true;
1359  imap_browse(mutt_b2s(&LastDir), &state);
1360  browser_sort(&state);
1361  }
1362  else
1363 #endif
1364  {
1365  size_t i = mutt_buffer_len(&LastDir);
1366  while ((i > 0) && (mutt_b2s(&LastDir)[--i] == '/'))
1367  LastDir.data[i] = '\0';
1371  }
1372  }
1373 
1374  mutt_buffer_reset(file);
1375 
1376  struct MuttWindow *dlg =
1379  dlg->notify = notify_new();
1380 
1381  struct MuttWindow *index =
1384  index->notify = notify_new();
1385  notify_set_parent(index->notify, dlg->notify);
1386 
1387  struct MuttWindow *ibar =
1390  ibar->notify = notify_new();
1391  notify_set_parent(ibar->notify, dlg->notify);
1392 
1393  if (C_StatusOnTop)
1394  {
1395  mutt_window_add_child(dlg, ibar);
1396  mutt_window_add_child(dlg, index);
1397  }
1398  else
1399  {
1400  mutt_window_add_child(dlg, index);
1401  mutt_window_add_child(dlg, ibar);
1402  }
1403 
1405  dialog_push(dlg);
1406 
1407  menu = mutt_menu_new(MENU_FOLDER);
1408 
1409  menu->pagelen = index->state.rows;
1410  menu->win_index = index;
1411  menu->win_ibar = ibar;
1412 
1413  menu->make_entry = folder_make_entry;
1414  menu->search = select_file_search;
1415  menu->title = title;
1416  if (multiple)
1417  menu->tag = file_tag;
1418 
1419  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_FOLDER,
1420 #ifdef USE_NNTP
1422 #endif
1423  FolderHelp);
1424  mutt_menu_push_current(menu);
1425 
1426  if (mailbox)
1427  {
1428  examine_mailboxes(NULL, &state);
1429  }
1430  else
1431 #ifdef USE_IMAP
1432  if (!state.imap_browse)
1433 #endif
1434  {
1435  // examine_directory() calls add_folder() which needs the menu
1436  if (examine_directory(menu, &state, mutt_b2s(&LastDir), mutt_b2s(prefix)) == -1)
1437  goto bail;
1438  }
1439 
1440  init_menu(&state, menu, title, sizeof(title), mailbox);
1441  // only now do we have a valid state to attach
1442  menu->mdata = state.entry;
1443 
1444  while (true)
1445  {
1446  int op = mutt_menu_loop(menu);
1447  if (op >= 0)
1448  mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", OpStrings[op][0], op);
1449  switch (op)
1450  {
1451  case OP_DESCEND_DIRECTORY:
1452  case OP_GENERIC_SELECT_ENTRY:
1453 
1454  if (state.entrylen == 0)
1455  {
1456  mutt_error(_("No files match the file mask"));
1457  break;
1458  }
1459 
1460  if (S_ISDIR(state.entry[menu->current].mode) ||
1461  (S_ISLNK(state.entry[menu->current].mode) &&
1462  link_is_dir(mutt_b2s(&LastDir), state.entry[menu->current].name))
1463 #ifdef USE_IMAP
1464  || state.entry[menu->current].inferiors
1465 #endif
1466  )
1467  {
1468  /* make sure this isn't a MH or maildir mailbox */
1469  if (mailbox)
1470  {
1471  mutt_buffer_strcpy(buf, state.entry[menu->current].name);
1473  }
1474 #ifdef USE_IMAP
1475  else if (state.imap_browse)
1476  {
1477  mutt_buffer_strcpy(buf, state.entry[menu->current].name);
1478  }
1479 #endif
1480  else
1481  {
1483  state.entry[menu->current].name);
1484  }
1485 
1486  enum MailboxType type = mx_path_probe(mutt_b2s(buf));
1487  if ((op == OP_DESCEND_DIRECTORY) || (type == MUTT_MAILBOX_ERROR) ||
1488  (type == MUTT_UNKNOWN)
1489 #ifdef USE_IMAP
1490  || state.entry[menu->current].inferiors
1491 #endif
1492  )
1493  {
1494  /* save the old directory */
1495  mutt_buffer_copy(OldLastDir, &LastDir);
1496 
1497  if (mutt_str_equal(state.entry[menu->current].name, ".."))
1498  {
1499  size_t lastdirlen = mutt_buffer_len(&LastDir);
1500  if ((lastdirlen > 1) &&
1501  mutt_str_equal("..", mutt_b2s(&LastDir) + lastdirlen - 2))
1502  {
1503  mutt_buffer_addstr(&LastDir, "/..");
1504  }
1505  else
1506  {
1507  char *p = NULL;
1508  if (lastdirlen > 1)
1509  p = strrchr(mutt_b2s(&LastDir) + 1, '/');
1510 
1511  if (p)
1512  {
1513  *p = '\0';
1515  }
1516  else
1517  {
1518  if (mutt_b2s(&LastDir)[0] == '/')
1519  mutt_buffer_strcpy(&LastDir, "/");
1520  else
1521  mutt_buffer_addstr(&LastDir, "/..");
1522  }
1523  }
1524  }
1525  else if (mailbox)
1526  {
1527  mutt_buffer_strcpy(&LastDir, state.entry[menu->current].name);
1529  }
1530 #ifdef USE_IMAP
1531  else if (state.imap_browse)
1532  {
1533  mutt_buffer_strcpy(&LastDir, state.entry[menu->current].name);
1534  /* tack on delimiter here */
1535 
1536  /* special case "" needs no delimiter */
1537  struct Url *url = url_parse(state.entry[menu->current].name);
1538  if (url->path && (state.entry[menu->current].delim != '\0'))
1539  {
1540  mutt_buffer_addch(&LastDir, state.entry[menu->current].delim);
1541  }
1542  url_free(&url);
1543  }
1544 #endif
1545  else
1546  {
1548  state.entry[menu->current].name);
1549  mutt_buffer_copy(&LastDir, tmp);
1550  }
1551 
1552  destroy_state(&state);
1553  if (kill_prefix)
1554  {
1555  mutt_buffer_reset(prefix);
1556  kill_prefix = false;
1557  }
1558  mailbox = false;
1559 #ifdef USE_IMAP
1560  if (state.imap_browse)
1561  {
1562  init_state(&state, NULL);
1563  state.imap_browse = true;
1564  imap_browse(mutt_b2s(&LastDir), &state);
1565  browser_sort(&state);
1566  menu->mdata = state.entry;
1567  }
1568  else
1569 #endif
1570  {
1571  if (examine_directory(menu, &state, mutt_b2s(&LastDir), mutt_b2s(prefix)) == -1)
1572  {
1573  /* try to restore the old values */
1574  mutt_buffer_copy(&LastDir, OldLastDir);
1575  if (examine_directory(menu, &state, mutt_b2s(&LastDir),
1576  mutt_b2s(prefix)) == -1)
1577  {
1579  goto bail;
1580  }
1581  }
1582  /* resolve paths navigated from GUI */
1583  if (mutt_path_realpath(LastDir.data) == 0)
1584  break;
1585  }
1586 
1587  browser_highlight_default(&state, menu);
1588  init_menu(&state, menu, title, sizeof(title), mailbox);
1589  goto_swapper[0] = '\0';
1590  break;
1591  }
1592  }
1593  else if (op == OP_DESCEND_DIRECTORY)
1594  {
1595  mutt_error(_("%s is not a directory"), state.entry[menu->current].name);
1596  break;
1597  }
1598 
1599  if (mailbox || OptNews) /* USE_NNTP */
1600  {
1601  mutt_buffer_strcpy(file, state.entry[menu->current].name);
1603  }
1604 #ifdef USE_IMAP
1605  else if (state.imap_browse)
1606  mutt_buffer_strcpy(file, state.entry[menu->current].name);
1607 #endif
1608  else
1609  {
1611  state.entry[menu->current].name);
1612  }
1613  /* fallthrough */
1614 
1615  case OP_EXIT:
1616 
1617  if (multiple)
1618  {
1619  char **tfiles = NULL;
1620 
1621  if (menu->tagged)
1622  {
1623  *numfiles = menu->tagged;
1624  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
1625  for (int i = 0, j = 0; i < state.entrylen; i++)
1626  {
1627  struct FolderFile ff = state.entry[i];
1628  if (ff.tagged)
1629  {
1632  tfiles[j++] = mutt_buffer_strdup(tmp);
1633  }
1634  }
1635  *files = tfiles;
1636  }
1637  else if (!mutt_buffer_is_empty(file)) /* no tagged entries. return selected entry */
1638  {
1639  *numfiles = 1;
1640  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
1642  tfiles[0] = mutt_buffer_strdup(file);
1643  *files = tfiles;
1644  }
1645  }
1646 
1647  destroy_state(&state);
1648  goto bail;
1649 
1650  case OP_BROWSER_TELL:
1651  if (state.entrylen)
1652  mutt_message("%s", state.entry[menu->current].name);
1653  break;
1654 
1655 #ifdef USE_IMAP
1656  case OP_BROWSER_TOGGLE_LSUB:
1657  bool_str_toggle(NeoMutt->sub, "imap_list_subscribed", NULL);
1658 
1659  mutt_unget_event(0, OP_CHECK_NEW);
1660  break;
1661 
1662  case OP_CREATE_MAILBOX:
1663  if (!state.imap_browse)
1664  {
1665  mutt_error(_("Create is only supported for IMAP mailboxes"));
1666  break;
1667  }
1668 
1669  if (imap_mailbox_create(mutt_b2s(&LastDir)) == 0)
1670  {
1671  /* TODO: find a way to detect if the new folder would appear in
1672  * this window, and insert it without starting over. */
1673  destroy_state(&state);
1674  init_state(&state, NULL);
1675  state.imap_browse = true;
1676  imap_browse(mutt_b2s(&LastDir), &state);
1677  browser_sort(&state);
1678  menu->mdata = state.entry;
1679  browser_highlight_default(&state, menu);
1680  init_menu(&state, menu, title, sizeof(title), mailbox);
1681  }
1682  /* else leave error on screen */
1683  break;
1684 
1685  case OP_RENAME_MAILBOX:
1686  if (!state.entry[menu->current].imap)
1687  mutt_error(_("Rename is only supported for IMAP mailboxes"));
1688  else
1689  {
1690  int nentry = menu->current;
1691 
1692  if (imap_mailbox_rename(state.entry[nentry].name) >= 0)
1693  {
1694  destroy_state(&state);
1695  init_state(&state, NULL);
1696  state.imap_browse = true;
1697  imap_browse(mutt_b2s(&LastDir), &state);
1698  browser_sort(&state);
1699  menu->mdata = state.entry;
1700  browser_highlight_default(&state, menu);
1701  init_menu(&state, menu, title, sizeof(title), mailbox);
1702  }
1703  }
1704  break;
1705 
1706  case OP_DELETE_MAILBOX:
1707  if (!state.entry[menu->current].imap)
1708  mutt_error(_("Delete is only supported for IMAP mailboxes"));
1709  else
1710  {
1711  char msg[128];
1712  int nentry = menu->current;
1713 
1714  // TODO(sileht): It could be better to select INBOX instead. But I
1715  // don't want to manipulate Context/Mailboxes/mailbox->account here for now.
1716  // Let's just protect neomutt against crash for now. #1417
1717  if (mutt_str_equal(mailbox_path(Context->mailbox), state.entry[nentry].name))
1718  {
1719  mutt_error(_("Can't delete currently selected mailbox"));
1720  break;
1721  }
1722 
1723  snprintf(msg, sizeof(msg), _("Really delete mailbox \"%s\"?"),
1724  state.entry[nentry].name);
1725  if (mutt_yesorno(msg, MUTT_NO) == MUTT_YES)
1726  {
1727  if (imap_delete_mailbox(Context->mailbox, state.entry[nentry].name) == 0)
1728  {
1729  /* free the mailbox from the browser */
1730  FREE(&((state.entry)[nentry].name));
1731  FREE(&((state.entry)[nentry].desc));
1732  /* and move all other entries up */
1733  if ((nentry + 1) < state.entrylen)
1734  {
1735  memmove(state.entry + nentry, state.entry + nentry + 1,
1736  sizeof(struct FolderFile) * (state.entrylen - (nentry + 1)));
1737  }
1738  memset(&state.entry[state.entrylen - 1], 0, sizeof(struct FolderFile));
1739  state.entrylen--;
1740  mutt_message(_("Mailbox deleted"));
1741  init_menu(&state, menu, title, sizeof(title), mailbox);
1742  }
1743  else
1744  mutt_error(_("Mailbox deletion failed"));
1745  }
1746  else
1747  mutt_message(_("Mailbox not deleted"));
1748  }
1749  break;
1750 #endif
1751 
1752  case OP_GOTO_PARENT:
1753  case OP_CHANGE_DIRECTORY:
1754 
1755 #ifdef USE_NNTP
1756  if (OptNews)
1757  break;
1758 #endif
1759 
1760  mutt_buffer_copy(buf, &LastDir);
1761 #ifdef USE_IMAP
1762  if (!state.imap_browse)
1763 #endif
1764  {
1765  /* add '/' at the end of the directory name if not already there */
1766  size_t len = mutt_buffer_len(buf);
1767  if ((len > 0) && (mutt_b2s(&LastDir)[len - 1] != '/'))
1768  mutt_buffer_addch(buf, '/');
1769  }
1770 
1771  if (op == OP_CHANGE_DIRECTORY)
1772  {
1773  /* buf comes from the buffer pool, so defaults to size 1024 */
1774  int ret = mutt_buffer_get_field(_("Chdir to: "), buf, MUTT_FILE);
1775  if ((ret != 0) && mutt_buffer_is_empty(buf))
1776  break;
1777  }
1778  else if (op == OP_GOTO_PARENT)
1779  mutt_get_parent_path(mutt_b2s(buf), buf->data, buf->dsize);
1780 
1781  if (!mutt_buffer_is_empty(buf))
1782  {
1783  mailbox = false;
1785 #ifdef USE_IMAP
1786  if (imap_path_probe(mutt_b2s(buf), NULL) == MUTT_IMAP)
1787  {
1788  mutt_buffer_copy(&LastDir, buf);
1789  destroy_state(&state);
1790  init_state(&state, NULL);
1791  state.imap_browse = true;
1792  imap_browse(mutt_b2s(&LastDir), &state);
1793  browser_sort(&state);
1794  menu->mdata = state.entry;
1795  browser_highlight_default(&state, menu);
1796  init_menu(&state, menu, title, sizeof(title), mailbox);
1797  }
1798  else
1799 #endif
1800  {
1801  if (mutt_b2s(buf)[0] != '/')
1802  {
1803  /* in case dir is relative, make it relative to LastDir,
1804  * not current working dir */
1806  mutt_buffer_copy(buf, tmp);
1807  }
1808  /* Resolve path from <chdir>
1809  * Avoids buildup such as /a/b/../../c
1810  * Symlinks are always unraveled to keep code simple */
1811  if (mutt_path_realpath(buf->data) == 0)
1812  break;
1813 
1814  struct stat st;
1815  if (stat(mutt_b2s(buf), &st) == 0)
1816  {
1817  if (S_ISDIR(st.st_mode))
1818  {
1819  destroy_state(&state);
1820  if (examine_directory(menu, &state, mutt_b2s(buf), mutt_b2s(prefix)) == 0)
1821  mutt_buffer_copy(&LastDir, buf);
1822  else
1823  {
1824  mutt_error(_("Error scanning directory"));
1825  if (examine_directory(menu, &state, mutt_b2s(&LastDir),
1826  mutt_b2s(prefix)) == -1)
1827  {
1828  goto bail;
1829  }
1830  }
1831  browser_highlight_default(&state, menu);
1832  init_menu(&state, menu, title, sizeof(title), mailbox);
1833  }
1834  else
1835  mutt_error(_("%s is not a directory"), mutt_b2s(buf));
1836  }
1837  else
1838  mutt_perror(mutt_b2s(buf));
1839  }
1840  }
1841  break;
1842 
1843  case OP_ENTER_MASK:
1844  {
1845  mutt_buffer_strcpy(buf, C_Mask ? C_Mask->pattern : NULL);
1846  if (mutt_get_field(_("File Mask: "), buf->data, buf->dsize, MUTT_COMP_NO_FLAGS) != 0)
1847  break;
1848 
1849  mutt_buffer_fix_dptr(buf);
1850 
1851  mailbox = false;
1852  /* assume that the user wants to see everything */
1853  if (mutt_buffer_is_empty(buf))
1854  mutt_buffer_strcpy(buf, ".");
1855 
1856  struct Buffer errmsg = mutt_buffer_make(256);
1857  int rc = cs_subset_str_string_set(NeoMutt->sub, "mask", mutt_b2s(buf), &errmsg);
1858  if (CSR_RESULT(rc) != CSR_SUCCESS)
1859  {
1860  if (!mutt_buffer_is_empty(&errmsg))
1861  {
1862  mutt_error("%s", mutt_b2s(&errmsg));
1863  mutt_buffer_dealloc(&errmsg);
1864  }
1865  break;
1866  }
1867  mutt_buffer_dealloc(&errmsg);
1868 
1869  destroy_state(&state);
1870 #ifdef USE_IMAP
1871  if (state.imap_browse)
1872  {
1873  init_state(&state, NULL);
1874  state.imap_browse = true;
1875  imap_browse(mutt_b2s(&LastDir), &state);
1876  browser_sort(&state);
1877  menu->mdata = state.entry;
1878  init_menu(&state, menu, title, sizeof(title), mailbox);
1879  }
1880  else
1881 #endif
1882  if (examine_directory(menu, &state, mutt_b2s(&LastDir), NULL) == 0)
1883  init_menu(&state, menu, title, sizeof(title), mailbox);
1884  else
1885  {
1886  mutt_error(_("Error scanning directory"));
1887  goto bail;
1888  }
1889  kill_prefix = false;
1890  if (state.entrylen == 0)
1891  {
1892  mutt_error(_("No files match the file mask"));
1893  break;
1894  }
1895  break;
1896  }
1897 
1898  case OP_SORT:
1899  case OP_SORT_REVERSE:
1900 
1901  {
1902  bool resort = true;
1903  int sort = -1;
1904  int reverse = (op == OP_SORT_REVERSE);
1905 
1906  switch (mutt_multi_choice(
1907  (reverse) ?
1908  /* L10N: The highlighted letters must match the "Sort" options */
1909  _("Reverse sort by (d)ate, (a)lpha, si(z)e, d(e)scription, "
1910  "(c)ount, ne(w) count, or do(n)'t sort?") :
1911  /* L10N: The highlighted letters must match the "Reverse Sort" options */
1912  _("Sort by (d)ate, (a)lpha, si(z)e, d(e)scription, (c)ount, "
1913  "ne(w) count, or do(n)'t sort?"),
1914  /* L10N: These must match the highlighted letters from "Sort" and "Reverse Sort" */
1915  _("dazecwn")))
1916  {
1917  case -1: /* abort */
1918  resort = false;
1919  break;
1920 
1921  case 1: /* (d)ate */
1922  sort = SORT_DATE;
1923  break;
1924 
1925  case 2: /* (a)lpha */
1926  sort = SORT_SUBJECT;
1927  break;
1928 
1929  case 3: /* si(z)e */
1930  sort = SORT_SIZE;
1931  break;
1932 
1933  case 4: /* d(e)scription */
1934  sort = SORT_DESC;
1935  break;
1936 
1937  case 5: /* (c)ount */
1938  sort = SORT_COUNT;
1939  break;
1940 
1941  case 6: /* ne(w) count */
1942  sort = SORT_UNREAD;
1943  break;
1944 
1945  case 7: /* do(n)'t sort */
1946  sort = SORT_ORDER;
1947  resort = false;
1948  break;
1949  }
1950  if (resort)
1951  {
1952  sort |= reverse ? SORT_REVERSE : 0;
1953  cs_subset_str_native_set(NeoMutt->sub, "sort_browser", sort, NULL);
1954  browser_sort(&state);
1955  browser_highlight_default(&state, menu);
1956  menu->redraw = REDRAW_FULL;
1957  }
1958  else
1959  {
1960  cs_subset_str_native_set(NeoMutt->sub, "sort_browser", sort, NULL);
1961  }
1962  break;
1963  }
1964 
1965  case OP_TOGGLE_MAILBOXES:
1966  case OP_BROWSER_GOTO_FOLDER:
1967  case OP_CHECK_NEW:
1968  if (op == OP_TOGGLE_MAILBOXES)
1969  {
1970  mailbox = !mailbox;
1971  menu->is_mailbox_list = mailbox;
1972  }
1973 
1974  if (op == OP_BROWSER_GOTO_FOLDER)
1975  {
1976  /* When in mailboxes mode, disables this feature */
1977  if (C_Folder)
1978  {
1979  mutt_debug(LL_DEBUG3, "= hit! Folder: %s, LastDir: %s\n", C_Folder,
1980  mutt_b2s(&LastDir));
1981  if (goto_swapper[0] == '\0')
1982  {
1984  {
1985  /* Stores into goto_swapper LastDir, and swaps to C_Folder */
1986  mutt_str_copy(goto_swapper, mutt_b2s(&LastDir), sizeof(goto_swapper));
1989  }
1990  }
1991  else
1992  {
1994  mutt_buffer_strcpy(&LastDir, goto_swapper);
1995  goto_swapper[0] = '\0';
1996  }
1997  }
1998  }
1999  destroy_state(&state);
2000  mutt_buffer_reset(prefix);
2001  kill_prefix = false;
2002 
2003  if (mailbox)
2004  {
2005  examine_mailboxes(menu, &state);
2006  }
2007 #ifdef USE_IMAP
2008  else if (imap_path_probe(mutt_b2s(&LastDir), NULL) == MUTT_IMAP)
2009  {
2010  init_state(&state, NULL);
2011  state.imap_browse = true;
2012  imap_browse(mutt_b2s(&LastDir), &state);
2013  browser_sort(&state);
2014  menu->mdata = state.entry;
2015  }
2016 #endif
2017  else if (examine_directory(menu, &state, mutt_b2s(&LastDir), mutt_b2s(prefix)) == -1)
2018  goto bail;
2019  init_menu(&state, menu, title, sizeof(title), mailbox);
2020  break;
2021 
2022  case OP_MAILBOX_LIST:
2024  break;
2025 
2026  case OP_BROWSER_NEW_FILE:
2027  mutt_buffer_printf(buf, "%s/", mutt_b2s(&LastDir));
2028  /* buf comes from the buffer pool, so defaults to size 1024 */
2029  if (mutt_buffer_get_field(_("New file name: "), buf, MUTT_FILE) == 0)
2030  {
2031  mutt_buffer_copy(file, buf);
2032  destroy_state(&state);
2033  goto bail;
2034  }
2035  break;
2036 
2037  case OP_BROWSER_VIEW_FILE:
2038  if (state.entrylen == 0)
2039  {
2040  mutt_error(_("No files match the file mask"));
2041  break;
2042  }
2043 
2044 #ifdef USE_IMAP
2045  if (state.entry[menu->current].selectable)
2046  {
2047  mutt_buffer_strcpy(file, state.entry[menu->current].name);
2048  destroy_state(&state);
2049  goto bail;
2050  }
2051  else
2052 #endif
2053  if (S_ISDIR(state.entry[menu->current].mode) ||
2054  (S_ISLNK(state.entry[menu->current].mode) &&
2055  link_is_dir(mutt_b2s(&LastDir), state.entry[menu->current].name)))
2056  {
2057  mutt_error(_("Can't view a directory"));
2058  break;
2059  }
2060  else
2061  {
2062  char buf2[PATH_MAX];
2063 
2065  state.entry[menu->current].name, sizeof(buf2));
2066  struct Body *b = mutt_make_file_attach(buf2);
2067  if (b)
2068  {
2069  mutt_view_attachment(NULL, b, MUTT_VA_REGULAR, NULL, NULL, menu->win_index);
2070  mutt_body_free(&b);
2071  menu->redraw = REDRAW_FULL;
2072  }
2073  else
2074  mutt_error(_("Error trying to view file"));
2075  }
2076  break;
2077 
2078 #ifdef USE_NNTP
2079  case OP_CATCHUP:
2080  case OP_UNCATCHUP:
2081  {
2082  if (!OptNews)
2083  break;
2084 
2085  struct FolderFile *ff = &state.entry[menu->current];
2086  struct NntpMboxData *mdata = NULL;
2087 
2089  if (rc < 0)
2090  break;
2091 
2092  if (op == OP_CATCHUP)
2094  else
2096 
2097  if (mdata)
2098  {
2100  if ((menu->current + 1) < menu->max)
2101  menu->current++;
2102  menu->redraw = REDRAW_MOTION_RESYNC;
2103  }
2104  if (rc)
2105  menu->redraw = REDRAW_INDEX;
2107  break;
2108  }
2109 
2110  case OP_LOAD_ACTIVE:
2111  {
2112  if (!OptNews)
2113  break;
2114 
2115  struct NntpAccountData *adata = CurrentNewsSrv;
2116 
2117  if (nntp_newsrc_parse(adata) < 0)
2118  break;
2119 
2120  for (size_t i = 0; i < adata->groups_num; i++)
2121  {
2122  struct NntpMboxData *mdata = adata->groups_list[i];
2123  if (mdata)
2124  mdata->deleted = true;
2125  }
2126  nntp_active_fetch(adata, true);
2127  nntp_newsrc_update(adata);
2128  nntp_newsrc_close(adata);
2129 
2130  destroy_state(&state);
2131  if (mailbox)
2132  examine_mailboxes(menu, &state);
2133  else
2134  {
2135  if (examine_directory(menu, &state, NULL, NULL) == -1)
2136  break;
2137  }
2138  init_menu(&state, menu, title, sizeof(title), mailbox);
2139  break;
2140  }
2141 #endif /* USE_NNTP */
2142 
2143 #if defined(USE_IMAP) || defined(USE_NNTP)
2144  case OP_BROWSER_SUBSCRIBE:
2145  case OP_BROWSER_UNSUBSCRIBE:
2146 #endif
2147 #ifdef USE_NNTP
2148  case OP_SUBSCRIBE_PATTERN:
2149  case OP_UNSUBSCRIBE_PATTERN:
2150  if (OptNews)
2151  {
2152  struct NntpAccountData *adata = CurrentNewsSrv;
2153  regex_t rx;
2154  memset(&rx, 0, sizeof(rx));
2155  char *s = buf->data;
2156  int i = menu->current;
2157 
2158  if ((op == OP_SUBSCRIBE_PATTERN) || (op == OP_UNSUBSCRIBE_PATTERN))
2159  {
2160  char tmp2[256];
2161 
2162  mutt_buffer_reset(buf);
2163  if (op == OP_SUBSCRIBE_PATTERN)
2164  snprintf(tmp2, sizeof(tmp2), _("Subscribe pattern: "));
2165  else
2166  snprintf(tmp2, sizeof(tmp2), _("Unsubscribe pattern: "));
2167  /* buf comes from the buffer pool, so defaults to size 1024 */
2168  if ((mutt_buffer_get_field(tmp2, buf, MUTT_PATTERN) != 0) ||
2169  mutt_buffer_is_empty(buf))
2170  {
2171  break;
2172  }
2173 
2174  int err = REG_COMP(&rx, s, REG_NOSUB);
2175  if (err != 0)
2176  {
2177  regerror(err, &rx, buf->data, buf->dsize);
2178  regfree(&rx);
2179  mutt_error("%s", mutt_b2s(buf));
2180  break;
2181  }
2182  menu->redraw = REDRAW_FULL;
2183  i = 0;
2184  }
2185  else if (state.entrylen == 0)
2186  {
2187  mutt_error(_("No newsgroups match the mask"));
2188  break;
2189  }
2190 
2191  int rc = nntp_newsrc_parse(adata);
2192  if (rc < 0)
2193  break;
2194 
2195  for (; i < state.entrylen; i++)
2196  {
2197  struct FolderFile *ff = &state.entry[i];
2198 
2199  if ((op == OP_BROWSER_SUBSCRIBE) || (op == OP_BROWSER_UNSUBSCRIBE) ||
2200  (regexec(&rx, ff->name, 0, NULL, 0) == 0))
2201  {
2202  if ((op == OP_BROWSER_SUBSCRIBE) || (op == OP_SUBSCRIBE_PATTERN))
2203  mutt_newsgroup_subscribe(adata, ff->name);
2204  else
2205  mutt_newsgroup_unsubscribe(adata, ff->name);
2206  }
2207  if ((op == OP_BROWSER_SUBSCRIBE) || (op == OP_BROWSER_UNSUBSCRIBE))
2208  {
2209  if ((menu->current + 1) < menu->max)
2210  menu->current++;
2211  menu->redraw = REDRAW_MOTION_RESYNC;
2212  break;
2213  }
2214  }
2215  if (op == OP_SUBSCRIBE_PATTERN)
2216  {
2217  for (size_t j = 0; adata && (j < adata->groups_num); j++)
2218  {
2219  struct NntpMboxData *mdata = adata->groups_list[j];
2220  if (mdata && mdata->group && !mdata->subscribed)
2221  {
2222  if (regexec(&rx, mdata->group, 0, NULL, 0) == 0)
2223  {
2224  mutt_newsgroup_subscribe(adata, mdata->group);
2225  add_folder(menu, &state, mdata->group, NULL, NULL, NULL, mdata);
2226  }
2227  }
2228  }
2229  init_menu(&state, menu, title, sizeof(title), mailbox);
2230  }
2231  if (rc > 0)
2232  menu->redraw = REDRAW_FULL;
2233  nntp_newsrc_update(adata);
2234  nntp_clear_cache(adata);
2235  nntp_newsrc_close(adata);
2236  if ((op != OP_BROWSER_SUBSCRIBE) && (op != OP_BROWSER_UNSUBSCRIBE))
2237  regfree(&rx);
2238  }
2239 #ifdef USE_IMAP
2240  else
2241 #endif /* USE_IMAP && USE_NNTP */
2242 #endif /* USE_NNTP */
2243 #ifdef USE_IMAP
2244  {
2245  char tmp2[256];
2246  mutt_str_copy(tmp2, state.entry[menu->current].name, sizeof(tmp2));
2247  mutt_expand_path(tmp2, sizeof(tmp2));
2248  imap_subscribe(tmp2, (op == OP_BROWSER_SUBSCRIBE));
2249  }
2250 #endif /* USE_IMAP */
2251  }
2252  }
2253 
2254 bail:
2255  mutt_buffer_pool_release(&OldLastDir);
2258  mutt_buffer_pool_release(&prefix);
2259 
2260  if (menu)
2261  {
2262  mutt_menu_pop_current(menu);
2263  mutt_menu_free(&menu);
2264  dialog_pop();
2266  mutt_window_free(&dlg);
2267  }
2268 
2269  goto_swapper[0] = '\0';
2270 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
mode_t mode
Definition: browser.h:63
The "current" mailbox.
Definition: context.h:37
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:247
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:45
bool mutt_mailbox_list(void)
List the mailboxes with new mail.
Definition: mutt_mailbox.c:231
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
static bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
Definition: browser.c:342
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
GUI selectable list of items.
Definition: mutt_menu.h:80
#define CSR_RESULT(x)
Definition: set.h:52
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2351
static void destroy_state(struct BrowserState *state)
Free the BrowserState.
Definition: browser.c:133
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
static int mutt_dlg_browser_observer(struct NotifyCallback *nc)
Listen for config changes affecting the Browser menu - Implements observer_t.
Definition: browser.c:1152
#define mutt_message(...)
Definition: logging.h:83
int imap_delete_mailbox(struct Mailbox *m, char *path)
Delete a mailbox.
Definition: imap.c:498
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
Definition: newsrc.c:845
Window uses all available vertical space.
Definition: mutt_window.h:35
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
static int file_tag(struct Menu *menu, int sel, int act)
Tag an entry in the menu - Implements Menu::tag()
Definition: browser.c:1112
void dialog_pop(void)
Hide a Window from the user.
Definition: mutt_window.c:722
struct NntpMboxData * mutt_newsgroup_uncatchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Uncatchup newsgroup.
Definition: newsrc.c:1338
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
State of the file/mailbox browser.
Definition: browser.h:95
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: mutt_window.c:697
General file/mailbox browser.
Definition: keymap.h:76
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
char * mutt_buffer_strdup(struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
static void add_folder(struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *s, struct Mailbox *m, void *data)
Add a folder to the browser list.
Definition: browser.c:632
String manipulation buffer.
Definition: buffer.h:33
struct NntpMboxData * mutt_newsgroup_subscribe(struct NntpAccountData *adata, char *group)
Subscribe newsgroup.
Definition: newsrc.c:1249
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:813
#define _(a)
Definition: message.h:28
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
Error occurred examining Mailbox.
Definition: mailbox.h:46
int imap_mailbox_create(const char *path)
Create a new IMAP mailbox.
Definition: browse.c:385
const char * mutt_path_getcwd(struct Buffer *cwd)
Get the current working directory.
Definition: path.c:563
A division of the screen.
Definition: mutt_window.h:108
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:123
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:74
static void init_lastdir(void)
Initialise the browser directories.
Definition: browser.c:107
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
static void folder_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
Format a menu item for the folder browser - Implements Menu::make_entry()
Definition: browser.c:954
View using default method.
Definition: mutt_attach.h:42
static int select_file_search(struct Menu *menu, regex_t *rx, int line)
Menu search callback for matching files - Implements Menu::search()
Definition: browser.c:939
int cs_subset_str_string_set(const struct ConfigSubset *sub, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:395
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:64
NNTP-specific Account data -.
Definition: lib.h:77
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
bool subscribed
Definition: lib.h:149
The body of an email.
Definition: body.h:34
An Index Window containing a selection list.
Definition: mutt_window.h:93
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:47
char * HomeDir
User&#39;s home directory.
Definition: globals.h:50
char * folder
Definition: browser.h:102
bool selectable
Definition: browser.h:81
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:150
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:292
Sort by the size of the email.
Definition: sort2.h:51
size_t dsize
Length of data.
Definition: buffer.h:37
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:132
int nntp_active_fetch(struct NntpAccountData *adata, bool mark_new)
Fetch list of all newsgroups from server.
Definition: nntp.c:2059
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:377
struct Notify * notify
Notifications system.
Definition: mutt_window.h:123
static struct Buffer LastDirBackup
Definition: browser.c:100
struct Mailbox * mailbox
Definition: context.h:50
struct Body * mutt_make_file_attach(const char *path)
Create a file attachment.
Definition: sendlib.c:1655
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
struct MuttWindow * win_ibar
Definition: mutt_menu.h:93
const char * title
Title of this menu.
Definition: mutt_menu.h:82
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:55
static int examine_mailboxes(struct Menu *menu, struct BrowserState *state)
Get list of mailboxes/subscribed newsgroups.
Definition: browser.c:836
char * name
Definition: browser.h:70
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:53
char * group
Definition: lib.h:142
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
size_t mutt_path_realpath(char *buf)
resolve path, unraveling symlinks
Definition: path.c:440
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: globals.h:55
bool imap
Definition: browser.h:80
const char * OpStrings[][2]
Definition: opcodes.c:28
void * mdata
Driver specific data.
Definition: mailbox.h:136
Browser Dialog, mutt_buffer_select_file()
Definition: mutt_window.h:77
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
Window has a fixed size.
Definition: mutt_window.h:44
const char * help
Quickref for the current menu.
Definition: mutt_menu.h:83
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:42
#define mutt_b2s(buf)
Definition: buffer.h:41
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:912
struct Notify * notify_new(void)
Create a new notifications handler.
Definition: notify.c:49
Browser entry representing a folder/dir.
Definition: browser.h:61
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:113
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:84
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: globals.h:119
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
#define PATH_MAX
Definition: mutt.h:44
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:49
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
size_t mutt_buffer_strcpy_n(struct Buffer *buf, const char *s, size_t len)
Copy a string into a Buffer.
Definition: buffer.c:327
size_t mutt_buffer_addstr_n(struct Buffer *buf, const char *s, size_t len)
Add a string to a Buffer, expanding it if necessary.
Definition: buffer.c:99
char * data
Pointer to data.
Definition: buffer.h:35
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:240
unsigned int groups_num
Definition: lib.h:100
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:315
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
bool is_mailbox_list
Definition: mutt_menu.h:91
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
Definition: newsrc.c:167
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
struct NntpMboxData * mutt_newsgroup_unsubscribe(struct NntpAccountData *adata, char *group)
Unsubscribe newsgroup.
Definition: newsrc.c:1273
int(* tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:136
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:89
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:46
NNTP-specific Mailbox data -.
Definition: lib.h:140
int tagged
Number of tagged entries.
Definition: mutt_menu.h:108
bool notify_observer_add(struct Notify *notify, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:153
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
char * path
Path.
Definition: url.h:73
int max
Number of entries in the menu.
Definition: mutt_menu.h:86
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:564
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
size_t entrylen
number of real entries
Definition: browser.h:98
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:84
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:87
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: browser.h:45
static void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: browser.c:985
static int examine_directory(struct Menu *menu, struct BrowserState *state, const char *d, const char *prefix)
Get list of all files/newsgroups with mask.
Definition: browser.c:710
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1328
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:327
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
Log at debug level 1.
Definition: logging.h:40
bool deleted
Definition: lib.h:152
Sort by the number of unread emails.
Definition: sort2.h:66
WHERE char * C_Spoolfile
Config: Inbox.
Definition: globals.h:140
void mutt_browser_select_dir(const char *f)
Remember the last directory selected.
Definition: browser.c:1137
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:724
static void init_menu(struct BrowserState *state, struct Menu *menu, char *title, size_t titlelen, bool mailbox)
Set up a new menu.
Definition: browser.c:1011
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:40
#define mutt_error(...)
Definition: logging.h:84
WHERE struct Regex * C_Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:169
int imap_browse(const char *path, struct BrowserState *state)
IMAP hook into the folder browser.
Definition: browse.c:185
Sort by the folder&#39;s description.
Definition: sort2.h:70
void ** groups_list
Definition: lib.h:102
#define FREE(x)
Definition: memory.h:40
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
int imap_mailbox_rename(const char *path)
Rename a mailbox.
Definition: browse.c:437
static struct Buffer LastDir
Definition: browser.c:99
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:84
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:185
Sort by number of emails in a folder.
Definition: sort2.h:65
char * mutt_path_concat(char *d, const char *dir, const char *fname, size_t l)
Join a directory name and a filename.
Definition: path.c:351
void notify_set_parent(struct Notify *notify, struct Notify *parent)
Set the parent notification handler.
Definition: notify.c:82
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
bool tagged
Definition: browser.h:86
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
Definition: mutt_window.c:131
int nntp_newsrc_update(struct NntpAccountData *adata)
Update .newsrc file.
Definition: newsrc.c:445
int current
Current entry.
Definition: mutt_menu.h:85
char * pattern
printable version
Definition: regex3.h:90
Sort by the date the email was sent.
Definition: sort2.h:50
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:689
struct NntpMboxData * mutt_newsgroup_catchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Catchup newsgroup.
Definition: newsrc.c:1299
struct MuttWindow * win_index
Definition: mutt_menu.h:92
bool inferiors
Definition: browser.h:82
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
char * mutt_compile_help(char *buf, size_t buflen, enum MenuType menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:110
static const struct Mapping FolderHelp[]
Definition: browser.c:77
Window wants as much space as possible.
Definition: mutt_window.h:45
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
static struct Mapping FolderNewsHelp[]
Definition: browser.c:87
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
bool imap_browse
Definition: browser.h:101
Index Bar containing status info about the Index.
Definition: mutt_window.h:94
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:125
int(* search)(struct Menu *menu, regex_t *rx, int line)
Search a menu for a item matching a regex.
Definition: mutt_menu.h:127
void mutt_get_parent_path(const char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition: muttlib.c:1628
void(* make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:117
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:45
char delim
Definition: browser.h:78
Sort by the email&#39;s subject.
Definition: sort2.h:53
struct FolderFile * entry
Definition: browser.h:97
Log at debug level 3.
Definition: logging.h:42
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:85
int imap_subscribe(char *path, bool subscribe)
Subscribe to a mailbox.
Definition: imap.c:1229
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
Definition: mutt_attach.c:415
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the caller graph for this function:

◆ mutt_select_file()

void mutt_select_file ( char *  file,
size_t  filelen,
SelectFileFlags  flags,
char ***  files,
int *  numfiles 
)

Let the user select a file.

Parameters
[in]fileBuffer for the result
[in]filelenLength of buffer
[in]flagsFlags, see SelectFileFlags
[out]filesArray of selected files
[out]numfilesNumber of selected files

Definition at line 2280 of file browser.c.

2282 {
2283  struct Buffer *f_buf = mutt_buffer_pool_get();
2284 
2285  mutt_buffer_strcpy(f_buf, NONULL(file));
2286  mutt_buffer_select_file(f_buf, flags, files, numfiles);
2287  mutt_str_copy(file, mutt_b2s(f_buf), filelen);
2288 
2289  mutt_buffer_pool_release(&f_buf);
2290 }
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_select_file(struct Buffer *file, SelectFileFlags flags, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:1186
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:724
int const char * file
Definition: acutest.h:617
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_BrowserAbbreviateMailboxes

bool C_BrowserAbbreviateMailboxes

Config: Abbreviate mailboxes using '~' and '=' in the browser.

Definition at line 69 of file browser.c.

◆ C_FolderFormat

char* C_FolderFormat

Config: printf-like format string for the browser's display of folders.

Definition at line 70 of file browser.c.

◆ C_GroupIndexFormat

char* C_GroupIndexFormat

Config: (nntp) printf-like format string for the browser's display of newsgroups.

Definition at line 71 of file browser.c.

◆ C_NewsgroupsCharset

char* C_NewsgroupsCharset

Config: (nntp) Character set of newsgroups' descriptions.

Definition at line 72 of file browser.c.

◆ C_ShowOnlyUnread

bool C_ShowOnlyUnread

Config: (nntp) Only show subscribed newsgroups with unread articles.

Definition at line 73 of file browser.c.

◆ C_SortBrowser

short C_SortBrowser

Config: Sort method for the browser.

Definition at line 74 of file browser.c.

◆ C_VfolderFormat

char* C_VfolderFormat

Config: (notmuch) printf-like format string for the browser's display of virtual folders.

Definition at line 75 of file browser.c.

◆ FolderHelp

const struct Mapping FolderHelp[]
static
Initial value:
= {
{ N_("Exit"), OP_EXIT },
{ N_("Chdir"), OP_CHANGE_DIRECTORY },
{ N_("Goto"), OP_BROWSER_GOTO_FOLDER },
{ N_("Mask"), OP_ENTER_MASK },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Definition at line 77 of file browser.c.

◆ FolderNewsHelp

struct Mapping FolderNewsHelp[]
static
Initial value:
= {
{ N_("Exit"), OP_EXIT },
{ N_("List"), OP_TOGGLE_MAILBOXES },
{ N_("Subscribe"), OP_BROWSER_SUBSCRIBE },
{ N_("Unsubscribe"), OP_BROWSER_UNSUBSCRIBE },
{ N_("Catchup"), OP_CATCHUP },
{ N_("Mask"), OP_ENTER_MASK },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Definition at line 87 of file browser.c.

◆ LastDir

struct Buffer LastDir = { 0 }
static

Definition at line 99 of file browser.c.

◆ LastDirBackup

struct Buffer LastDirBackup = { 0 }
static

Definition at line 100 of file browser.c.