NeoMutt  2018-07-16 +952-a2da0a
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 <regex.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "config/lib.h"
#include "email/lib.h"
#include "conn/conn.h"
#include "mutt.h"
#include "browser.h"
#include "context.h"
#include "curs_lib.h"
#include "format_flags.h"
#include "globals.h"
#include "keymap.h"
#include "mailbox.h"
#include "maildir/lib.h"
#include "menu.h"
#include "mutt_attach.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "mx.h"
#include "opcodes.h"
#include "options.h"
#include "sendlib.h"
#include "sort.h"
#include "imap/imap.h"
#include "nntp/nntp.h"
#include "pop/pop.h"
+ Include dependency graph for browser.c:

Go to the source code of this file.

Functions

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, unsigned long data, enum FormatFlag 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)
 Initilise a browser state. More...
 
static int examine_directory (struct Menu *menu, struct BrowserState *state, 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::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::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::menu_tag() More...
 
void mutt_browser_select_dir (const char *f)
 Remember the last directory selected. More...
 
void mutt_select_file (char *file, size_t filelen, int flags, char ***files, int *numfiles)
 Let the user select a file. More...
 

Variables

bool BrowserAbbreviateMailboxes
 Config: Abbreviate mailboxes using '~' and '=' in the browser. More...
 
char * FolderFormat
 Config: printf-like format string for the browser's display of folders. More...
 
char * GroupIndexFormat
 Config: (nntp) printf-like format string for the browser's display of newsgroups. More...
 
char * NewsgroupsCharset
 Config: (nntp) Character set of newsgroups' descriptions. More...
 
bool ShowOnlyUnread
 Config: (nntp) Only show subscribed newsgroups with unread articles. More...
 
short SortBrowser
 Config: Sort method for the browser. More...
 
char * 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 char OldLastDir [PATH_MAX] = ""
 
static char LastDir [PATH_MAX] = ""
 

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

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 116 of file browser.c.

117 {
118  for (size_t c = 0; c < state->entrylen; c++)
119  {
120  FREE(&((state->entry)[c].name));
121  FREE(&((state->entry)[c].desc));
122  }
123 #ifdef USE_IMAP
124  FREE(&state->folder);
125 #endif
126  FREE(&state->entry);
127 }
char * folder
Definition: browser.h:97
size_t entrylen
number of real entries
Definition: browser.h:93
#define FREE(x)
Definition: memory.h:46
struct FolderFile * entry
Definition: browser.h:92

+ Here is the caller graph for this function:

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 137 of file browser.c.

138 {
139  struct FolderFile *pa = (struct FolderFile *) a;
140  struct FolderFile *pb = (struct FolderFile *) b;
141 
142  /* inbox should be sorted ahead of its siblings */
143  int r = mutt_inbox_cmp(pa->name, pb->name);
144  if (r == 0)
145  r = mutt_str_strcoll(pa->name, pb->name);
146  return (SortBrowser & SORT_REVERSE) ? -r : r;
147 }
char * name
Definition: browser.h:65
Browser entry representing a folder/dir.
Definition: browser.h:56
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:1628
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort.h:78
short SortBrowser
Config: Sort method for the browser.
Definition: browser.c:82
int mutt_str_strcoll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:676

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 157 of file browser.c.

158 {
159  struct FolderFile *pa = (struct FolderFile *) a;
160  struct FolderFile *pb = (struct FolderFile *) b;
161 
162  int r = mutt_str_strcoll(pa->desc, pb->desc);
163 
164  return (SortBrowser & SORT_REVERSE) ? -r : r;
165 }
char * desc
Definition: browser.h:66
Browser entry representing a folder/dir.
Definition: browser.h:56
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort.h:78
short SortBrowser
Config: Sort method for the browser.
Definition: browser.c:82
int mutt_str_strcoll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:676

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 175 of file browser.c.

176 {
177  struct FolderFile *pa = (struct FolderFile *) a;
178  struct FolderFile *pb = (struct FolderFile *) b;
179 
180  int r = pa->mtime - pb->mtime;
181 
182  return (SortBrowser & SORT_REVERSE) ? -r : r;
183 }
time_t mtime
Definition: browser.h:60
Browser entry representing a folder/dir.
Definition: browser.h:56
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort.h:78
short SortBrowser
Config: Sort method for the browser.
Definition: browser.c:82

+ Here is the caller graph for this function:

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 193 of file browser.c.

194 {
195  struct FolderFile *pa = (struct FolderFile *) a;
196  struct FolderFile *pb = (struct FolderFile *) b;
197 
198  int r = pa->size - pb->size;
199 
200  return (SortBrowser & SORT_REVERSE) ? -r : r;
201 }
off_t size
Definition: browser.h:59
Browser entry representing a folder/dir.
Definition: browser.h:56
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort.h:78
short SortBrowser
Config: Sort method for the browser.
Definition: browser.c:82

+ Here is the caller graph for this function:

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 211 of file browser.c.

212 {
213  struct FolderFile *pa = (struct FolderFile *) a;
214  struct FolderFile *pb = (struct FolderFile *) b;
215 
216  int r = 0;
217  if (pa->has_mailbox && pb->has_mailbox)
218  r = pa->msg_count - pb->msg_count;
219  else if (pa->has_mailbox)
220  r = -1;
221  else
222  r = 1;
223 
224  return (SortBrowser & SORT_REVERSE) ? -r : r;
225 }
bool has_mailbox
Definition: browser.h:79
Browser entry representing a folder/dir.
Definition: browser.h:56
int msg_count
total number of messages
Definition: browser.h:69
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort.h:78
short SortBrowser
Config: Sort method for the browser.
Definition: browser.c:82

+ Here is the caller graph for this function:

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 235 of file browser.c.

236 {
237  struct FolderFile *pa = (struct FolderFile *) a;
238  struct FolderFile *pb = (struct FolderFile *) b;
239 
240  int r = 0;
241  if (pa->has_mailbox && pb->has_mailbox)
242  r = pa->msg_unread - pb->msg_unread;
243  else if (pa->has_mailbox)
244  r = -1;
245  else
246  r = 1;
247 
248  return (SortBrowser & SORT_REVERSE) ? -r : r;
249 }
int msg_unread
number of unread messages
Definition: browser.h:70
bool has_mailbox
Definition: browser.h:79
Browser entry representing a folder/dir.
Definition: browser.h:56
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort.h:78
short SortBrowser
Config: Sort method for the browser.
Definition: browser.c:82

+ Here is the caller graph for this function:

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 263 of file browser.c.

264 {
265  struct FolderFile *pa = (struct FolderFile *) a;
266  struct FolderFile *pb = (struct FolderFile *) b;
267 
268  if ((mutt_str_strcoll(pa->desc, "../") == 0) || (mutt_str_strcoll(pa->desc, "..") == 0))
269  return -1;
270  if ((mutt_str_strcoll(pb->desc, "../") == 0) || (mutt_str_strcoll(pb->desc, "..") == 0))
271  return 1;
272 
273  switch (SortBrowser & SORT_MASK)
274  {
275  case SORT_COUNT:
276  return browser_compare_count(a, b);
277  case SORT_DATE:
278  return browser_compare_date(a, b);
279  case SORT_DESC:
280  return browser_compare_desc(a, b);
281  case SORT_SIZE:
282  return browser_compare_size(a, b);
283  case SORT_UNREAD:
284  return browser_compare_count_new(a, b);
285  case SORT_SUBJECT:
286  default:
287  return browser_compare_subject(a, b);
288  }
289 }
static int browser_compare_date(const void *a, const void *b)
Compare the date of two browser entries.
Definition: browser.c:175
#define SORT_COUNT
Sort by number of emails in a folder.
Definition: sort.h:60
char * desc
Definition: browser.h:66
#define SORT_UNREAD
Sort by the number of unread emails.
Definition: sort.h:61
static int browser_compare_desc(const void *a, const void *b)
Compare the descriptions of two browser entries.
Definition: browser.c:157
static int browser_compare_count(const void *a, const void *b)
Compare the message count of two browser entries.
Definition: browser.c:211
#define SORT_DESC
Sort by the folder&#39;s description.
Definition: sort.h:65
#define SORT_SIZE
Sort by the size of the email.
Definition: sort.h:46
#define SORT_DATE
Sort by the date the email was sent.
Definition: sort.h:45
Browser entry representing a folder/dir.
Definition: browser.h:56
static int browser_compare_count_new(const void *a, const void *b)
Compare the new count of two browser entries.
Definition: browser.c:235
static int browser_compare_size(const void *a, const void *b)
Compare the size of two browser entries.
Definition: browser.c:193
static int browser_compare_subject(const void *a, const void *b)
Compare the subject of two browser entries.
Definition: browser.c:137
#define SORT_SUBJECT
Sort by the email&#39;s subject.
Definition: sort.h:48
short SortBrowser
Config: Sort method for the browser.
Definition: browser.c:82
int mutt_str_strcoll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:676
#define SORT_MASK
Mask for the sort id.
Definition: sort.h:77

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 298 of file browser.c.

299 {
300  switch (SortBrowser & SORT_MASK)
301  {
302  /* Also called "I don't care"-sort-method. */
303  case SORT_ORDER:
304  return;
305 #ifdef USE_NNTP
306  case SORT_SIZE:
307  case SORT_DATE:
308  if (OptNews)
309  return;
310 #endif
311  default:
312  break;
313  }
314 
315  qsort(state->entry, state->entrylen, sizeof(struct FolderFile), browser_compare);
316 }
#define SORT_SIZE
Sort by the size of the email.
Definition: sort.h:46
#define SORT_DATE
Sort by the date the email was sent.
Definition: sort.h:45
Browser entry representing a folder/dir.
Definition: browser.h:56
size_t entrylen
number of real entries
Definition: browser.h:93
static int browser_compare(const void *a, const void *b)
Sort the items in the browser.
Definition: browser.c:263
short SortBrowser
Config: Sort method for the browser.
Definition: browser.c:82
#define SORT_MASK
Mask for the sort id.
Definition: sort.h:77
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:42
struct FolderFile * entry
Definition: browser.h:92
#define SORT_ORDER
Sort by the order the messages appear in the mailbox.
Definition: sort.h:50

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 325 of file browser.c.

326 {
327  struct stat st;
328  char fullpath[PATH_MAX];
329 
330  mutt_path_concat(fullpath, folder, path, sizeof(fullpath));
331 
332  if (stat(fullpath, &st) == 0)
333  return S_ISDIR(st.st_mode);
334 
335  return false;
336 }
#define PATH_MAX
Definition: mutt.h:46
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:323

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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,
unsigned long  data,
enum FormatFlag  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 358 of file browser.c.

362 {
363  char fn[SHORT_STRING], fmt[SHORT_STRING], permission[11];
364  char *t_fmt = NULL;
365  struct Folder *folder = (struct Folder *) data;
366  struct passwd *pw = NULL;
367  struct group *gr = NULL;
368  int optional = (flags & MUTT_FORMAT_OPTIONAL);
369 
370  switch (op)
371  {
372  case 'C':
373  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
374  snprintf(buf, buflen, fmt, folder->num + 1);
375  break;
376 
377  case 'd':
378  case 'D':
379  if (folder->ff->local)
380  {
381  int do_locales = true;
382 
383  if (op == 'D')
384  {
385  t_fmt = NONULL(DateFormat);
386  if (*t_fmt == '!')
387  {
388  t_fmt++;
389  do_locales = false;
390  }
391  }
392  else
393  {
394  time_t tnow = time(NULL);
395  t_fmt = tnow - folder->ff->mtime < 31536000 ? "%b %d %H:%M" : "%b %d %Y";
396  }
397 
398  if (!do_locales)
399  setlocale(LC_TIME, "C");
400  char date[SHORT_STRING];
401  strftime(date, sizeof(date), t_fmt, localtime(&folder->ff->mtime));
402  if (!do_locales)
403  setlocale(LC_TIME, "");
404 
405  mutt_format_s(buf, buflen, prec, date);
406  }
407  else
408  mutt_format_s(buf, buflen, prec, "");
409  break;
410 
411  case 'f':
412  {
413  char *s = NULL;
414 
415  s = NONULL(folder->ff->name);
416 
417  snprintf(fn, sizeof(fn), "%s%s", s,
418  folder->ff->local ?
419  (S_ISLNK(folder->ff->mode) ?
420  "@" :
421  (S_ISDIR(folder->ff->mode) ?
422  "/" :
423  ((folder->ff->mode & S_IXUSR) != 0 ? "*" : ""))) :
424  "");
425 
426  mutt_format_s(buf, buflen, prec, fn);
427  break;
428  }
429  case 'F':
430  if (folder->ff->local)
431  {
432  snprintf(permission, sizeof(permission), "%c%c%c%c%c%c%c%c%c%c",
433  S_ISDIR(folder->ff->mode) ? 'd' : (S_ISLNK(folder->ff->mode) ? 'l' : '-'),
434  (folder->ff->mode & S_IRUSR) != 0 ? 'r' : '-',
435  (folder->ff->mode & S_IWUSR) != 0 ? 'w' : '-',
436  (folder->ff->mode & S_ISUID) != 0 ?
437  's' :
438  (folder->ff->mode & S_IXUSR) != 0 ? 'x' : '-',
439  (folder->ff->mode & S_IRGRP) != 0 ? 'r' : '-',
440  (folder->ff->mode & S_IWGRP) != 0 ? 'w' : '-',
441  (folder->ff->mode & S_ISGID) != 0 ?
442  's' :
443  (folder->ff->mode & S_IXGRP) != 0 ? 'x' : '-',
444  (folder->ff->mode & S_IROTH) != 0 ? 'r' : '-',
445  (folder->ff->mode & S_IWOTH) != 0 ? 'w' : '-',
446  (folder->ff->mode & S_ISVTX) != 0 ?
447  't' :
448  (folder->ff->mode & S_IXOTH) != 0 ? 'x' : '-');
449  mutt_format_s(buf, buflen, prec, permission);
450  }
451 #ifdef USE_IMAP
452  else if (folder->ff->imap)
453  {
454  /* mark folders with subfolders AND mail */
455  snprintf(permission, sizeof(permission), "IMAP %c",
456  (folder->ff->inferiors && folder->ff->selectable) ? '+' : ' ');
457  mutt_format_s(buf, buflen, prec, permission);
458  }
459 #endif
460  else
461  mutt_format_s(buf, buflen, prec, "");
462  break;
463 
464  case 'g':
465  if (folder->ff->local)
466  {
467  gr = getgrgid(folder->ff->gid);
468  if (gr)
469  mutt_format_s(buf, buflen, prec, gr->gr_name);
470  else
471  {
472  snprintf(fmt, sizeof(fmt), "%%%sld", prec);
473  snprintf(buf, buflen, fmt, folder->ff->gid);
474  }
475  }
476  else
477  mutt_format_s(buf, buflen, prec, "");
478  break;
479 
480  case 'i':
481  {
482  char *s = NULL;
483  if (folder->ff->desc)
484  s = folder->ff->desc;
485  else
486  s = folder->ff->name;
487 
488  snprintf(fn, sizeof(fn), "%s%s", s,
489  folder->ff->local ?
490  (S_ISLNK(folder->ff->mode) ?
491  "@" :
492  (S_ISDIR(folder->ff->mode) ?
493  "/" :
494  ((folder->ff->mode & S_IXUSR) != 0 ? "*" : ""))) :
495  "");
496 
497  mutt_format_s(buf, buflen, prec, fn);
498  break;
499  }
500 
501  case 'l':
502  if (folder->ff->local)
503  {
504  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
505  snprintf(buf, buflen, fmt, folder->ff->nlink);
506  }
507  else
508  mutt_format_s(buf, buflen, prec, "");
509  break;
510 
511  case 'm':
512  if (!optional)
513  {
514  if (folder->ff->has_mailbox)
515  {
516  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
517  snprintf(buf, buflen, fmt, folder->ff->msg_count);
518  }
519  else
520  mutt_format_s(buf, buflen, prec, "");
521  }
522  else if (!folder->ff->msg_count)
523  optional = 0;
524  break;
525 
526  case 'N':
527  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
528  snprintf(buf, buflen, fmt, folder->ff->new ? 'N' : ' ');
529  break;
530 
531  case 'n':
532  if (!optional)
533  {
534  if (folder->ff->has_mailbox)
535  {
536  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
537  snprintf(buf, buflen, fmt, folder->ff->msg_unread);
538  }
539  else
540  mutt_format_s(buf, buflen, prec, "");
541  }
542  else if (!folder->ff->msg_unread)
543  optional = 0;
544  break;
545 
546  case 's':
547  if (folder->ff->local)
548  {
549  mutt_str_pretty_size(fn, sizeof(fn), folder->ff->size);
550  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
551  snprintf(buf, buflen, fmt, fn);
552  }
553  else
554  mutt_format_s(buf, buflen, prec, "");
555  break;
556 
557  case 't':
558  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
559  snprintf(buf, buflen, fmt, folder->ff->tagged ? '*' : ' ');
560  break;
561 
562  case 'u':
563  if (folder->ff->local)
564  {
565  pw = getpwuid(folder->ff->uid);
566  if (pw)
567  mutt_format_s(buf, buflen, prec, pw->pw_name);
568  else
569  {
570  snprintf(fmt, sizeof(fmt), "%%%sld", prec);
571  snprintf(buf, buflen, fmt, folder->ff->uid);
572  }
573  }
574  else
575  mutt_format_s(buf, buflen, prec, "");
576  break;
577 
578  default:
579  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
580  snprintf(buf, buflen, fmt, op);
581  break;
582  }
583 
584  if (optional)
585  mutt_expando_format(buf, buflen, col, cols, if_str, folder_format_str, data, 0);
586  else if (flags & MUTT_FORMAT_OPTIONAL)
587  mutt_expando_format(buf, buflen, col, cols, else_str, folder_format_str, data, 0);
588 
589  return src;
590 }
int msg_unread
number of unread messages
Definition: browser.h:70
mode_t mode
Definition: browser.h:58
time_t mtime
Definition: browser.h:60
#define NONULL(x)
Definition: string2.h:39
bool has_mailbox
Definition: browser.h:79
#define SHORT_STRING
Definition: string2.h:34
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, unsigned long data, enum FormatFlag flags)
Format a string for the folder browser - Implements format_t.
Definition: browser.c:358
char * desc
Definition: browser.h:66
bool new
true if mailbox has "new mail"
Definition: browser.h:68
gid_t gid
Definition: browser.h:62
WHERE char * DateFormat
Config: strftime format string for the d expando.
Definition: globals.h:107
struct FolderFile * ff
Definition: browser.h:49
off_t size
Definition: browser.h:59
bool selectable
Definition: browser.h:76
uid_t uid
Definition: browser.h:61
nlink_t nlink
Definition: browser.h:63
char * name
Definition: browser.h:65
int num
Definition: browser.h:50
allow optional field processing
Definition: format_flags.h:36
bool imap
Definition: browser.h:75
A folder/dir in the browser.
Definition: browser.h:47
int msg_count
total number of messages
Definition: browser.h:69
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1061
bool tagged
Definition: browser.h:81
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: string.c:1015
bool local
folder is on local filesystem
Definition: browser.h:80
bool inferiors
Definition: browser.h:77
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, enum FormatFlag flags)
Expand expandos (x) in a string.
Definition: muttlib.c:816

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 602 of file browser.c.

605 {
606  if (state->entrylen == state->entrymax)
607  {
608  /* need to allocate more space */
609  mutt_mem_realloc(&state->entry, sizeof(struct FolderFile) * (state->entrymax += 256));
610  memset(&state->entry[state->entrylen], 0, sizeof(struct FolderFile) * 256);
611  if (menu)
612  menu->data = state->entry;
613  }
614 
615  if (s)
616  {
617  (state->entry)[state->entrylen].mode = s->st_mode;
618  (state->entry)[state->entrylen].mtime = s->st_mtime;
619  (state->entry)[state->entrylen].size = s->st_size;
620  (state->entry)[state->entrylen].gid = s->st_gid;
621  (state->entry)[state->entrylen].uid = s->st_uid;
622  (state->entry)[state->entrylen].nlink = s->st_nlink;
623 
624  (state->entry)[state->entrylen].local = true;
625  }
626  else
627  (state->entry)[state->entrylen].local = false;
628 
629  if (m)
630  {
631  (state->entry)[state->entrylen].has_mailbox = true;
632  (state->entry)[state->entrylen].new = m->has_new;
633  (state->entry)[state->entrylen].msg_count = m->msg_count;
634  (state->entry)[state->entrylen].msg_unread = m->msg_unread;
635  }
636 
637  (state->entry)[state->entrylen].name = mutt_str_strdup(name);
638  (state->entry)[state->entrylen].desc = mutt_str_strdup(desc ? desc : name);
639 #ifdef USE_IMAP
640  (state->entry)[state->entrylen].imap = false;
641 #endif
642 #ifdef USE_NNTP
643  if (OptNews)
644  (state->entry)[state->entrylen].nd = data;
645 #endif
646  (state->entrylen)++;
647 }
mode_t mode
Definition: browser.h:58
int msg_count
total number of messages
Definition: mailbox.h:86
int msg_unread
number of unread messages
Definition: mailbox.h:87
bool has_new
mailbox has new mail
Definition: mailbox.h:83
const char * name
Definition: pgpmicalg.c:42
unsigned int entrymax
max entry
Definition: browser.h:94
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:124
Browser entry representing a folder/dir.
Definition: browser.h:56
size_t entrylen
number of real entries
Definition: browser.h:93
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:384
void * data
extra data for the current menu
Definition: menu.h:60
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:42
struct FolderFile * entry
Definition: browser.h:92

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Initilise a browser state.

Parameters
stateBrowserState to initialise
menuCurrent menu

Definition at line 654 of file browser.c.

655 {
656  state->entrylen = 0;
657  state->entrymax = 256;
658  state->entry = mutt_mem_calloc(state->entrymax, sizeof(struct FolderFile));
659 #ifdef USE_IMAP
660  state->imap_browse = false;
661 #endif
662  if (menu)
663  menu->data = state->entry;
664 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
unsigned int entrymax
max entry
Definition: browser.h:94
Browser entry representing a folder/dir.
Definition: browser.h:56
size_t entrylen
number of real entries
Definition: browser.h:93
void * data
extra data for the current menu
Definition: menu.h:60
bool imap_browse
Definition: browser.h:96
struct FolderFile * entry
Definition: browser.h:92

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int examine_directory ( struct Menu menu,
struct BrowserState state,
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 675 of file browser.c.

677 {
678 #ifdef USE_NNTP
679  if (OptNews)
680  {
682 
683  init_state(state, menu);
684 
685  for (unsigned int i = 0; i < adata->groups_num; i++)
686  {
687  struct NntpMboxData *mdata = adata->groups_list[i];
688  if (!mdata)
689  continue;
690  if (prefix && *prefix && !mutt_str_startswith(mdata->group, prefix, CASE_MATCH))
691  continue;
692  if (Mask && Mask->regex &&
693  !((regexec(Mask->regex, mdata->group, 0, NULL, 0) == 0) ^ Mask->not))
694  {
695  continue;
696  }
697  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
698  }
699  }
700  else
701 #endif /* USE_NNTP */
702  {
703  struct stat s;
704  DIR *dp = NULL;
705  struct dirent *de = NULL;
706  char buffer[PATH_MAX + SHORT_STRING];
707 
708  while (stat(d, &s) == -1)
709  {
710  if (errno == ENOENT)
711  {
712  /* The last used directory is deleted, try to use the parent dir. */
713  char *c = strrchr(d, '/');
714 
715  if (c && (c > d))
716  {
717  *c = 0;
718  continue;
719  }
720  }
721  mutt_perror(d);
722  return -1;
723  }
724 
725  if (!S_ISDIR(s.st_mode))
726  {
727  mutt_error(_("%s is not a directory"), d);
728  return -1;
729  }
730 
732 
733  dp = opendir(d);
734  if (!dp)
735  {
736  mutt_perror(d);
737  return -1;
738  }
739 
740  init_state(state, menu);
741 
742  while ((de = readdir(dp)))
743  {
744  if (mutt_str_strcmp(de->d_name, ".") == 0)
745  continue; /* we don't need . */
746 
747  if (prefix && *prefix && !mutt_str_startswith(de->d_name, prefix, CASE_MATCH))
748  {
749  continue;
750  }
751  if (Mask && Mask->regex &&
752  !((regexec(Mask->regex, de->d_name, 0, NULL, 0) == 0) ^ Mask->not))
753  {
754  continue;
755  }
756 
757  mutt_path_concat(buffer, d, de->d_name, sizeof(buffer));
758  if (lstat(buffer, &s) == -1)
759  continue;
760 
761  /* No size for directories or symlinks */
762  if (S_ISDIR(s.st_mode) || S_ISLNK(s.st_mode))
763  s.st_size = 0;
764  else if (!S_ISREG(s.st_mode))
765  continue;
766 
767  struct MailboxNode *np = NULL;
768  STAILQ_FOREACH(np, &AllMailboxes, entries)
769  {
770  if (mutt_str_strcmp(buffer, np->m->path) != 0)
771  break;
772  }
773 
774  if (np && Context &&
776  {
779  }
780  add_folder(menu, state, de->d_name, NULL, &s, np ? np->m : NULL, NULL);
781  }
782  closedir(dp);
783  }
784  browser_sort(state);
785  return 0;
786 }
The "current" mailbox.
Definition: context.h:36
bool not
do not match
Definition: regex3.h:61
int msg_count
total number of messages
Definition: mailbox.h:86
#define SHORT_STRING
Definition: string2.h:34
#define mutt_perror(...)
Definition: logging.h:89
int msg_unread
number of unread messages
Definition: mailbox.h:87
regex_t * regex
compiled expression
Definition: regex3.h:60
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:602
#define _(a)
Definition: message.h:28
Match case when comparing strings.
Definition: string2.h:69
int mutt_mailbox_check(int force)
Check all AllMailboxes for new mail.
Definition: mailbox.c:538
NNTP-specific Account data -.
Definition: nntp.h:76
struct Mailbox * m
Definition: mailbox.h:139
struct Mailbox * mailbox
Definition: context.h:50
WHERE struct Regex * Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:181
char * group
Definition: nntp.h:141
void * mdata
driver specific data
Definition: mailbox.h:130
#define PATH_MAX
Definition: mutt.h:46
void * adata
Definition: account.h:41
unsigned int groups_num
Definition: nntp.h:99
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:298
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
NNTP-specific Mailbox data -.
Definition: nntp.h:139
struct MailboxList AllMailboxes
List of all Mailboxes.
Definition: mailbox.c:85
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:166
char path[PATH_MAX]
Definition: mailbox.h:78
#define mutt_error(...)
Definition: logging.h:88
void ** groups_list
Definition: nntp.h:101
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:323
List of Mailboxes.
Definition: mailbox.h:137
char realpath[PATH_MAX]
used for duplicate detection, context comparison, and the sidebar
Definition: mailbox.h:79
static void init_state(struct BrowserState *state, struct Menu *menu)
Initilise a browser state.
Definition: browser.c:654
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:42
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:612
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:80

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 795 of file browser.c.

796 {
797  struct stat s;
798 
799 #ifdef USE_NNTP
800  if (OptNews)
801  {
803 
804  init_state(state, menu);
805 
806  for (unsigned int i = 0; i < adata->groups_num; i++)
807  {
808  struct NntpMboxData *mdata = adata->groups_list[i];
809  if (mdata && (mdata->new || (mdata->subscribed && (mdata->unread || !ShowOnlyUnread))))
810  {
811  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
812  }
813  }
814  }
815  else
816 #endif
817  {
818  init_state(state, menu);
819 
821  return -1;
823 
824  struct MailboxNode *np = NULL;
825  STAILQ_FOREACH(np, &AllMailboxes, entries)
826  {
827  if (Context && (mutt_str_strcmp(np->m->realpath, Context->mailbox->realpath) == 0))
828  {
831  }
832 
833  char buffer[PATH_MAX];
834  mutt_str_strfcpy(buffer, np->m->path, sizeof(buffer));
836  mutt_pretty_mailbox(buffer, sizeof(buffer));
837 
838  switch (np->m->magic)
839  {
840  case MUTT_IMAP:
841  case MUTT_POP:
842  add_folder(menu, state, buffer, np->m->desc, NULL, np->m, NULL);
843  continue;
844  case MUTT_NOTMUCH:
845  case MUTT_NNTP:
846  add_folder(menu, state, np->m->path, np->m->desc, NULL, np->m, NULL);
847  continue;
848  default: /* Continue */
849  break;
850  }
851 
852  if (lstat(np->m->path, &s) == -1)
853  continue;
854 
855  if ((!S_ISREG(s.st_mode)) && (!S_ISDIR(s.st_mode)) && (!S_ISLNK(s.st_mode)))
856  continue;
857 
858  if (np->m->magic == MUTT_MAILDIR)
859  {
860  struct stat st2;
861  char md[PATH_MAX];
862 
863  snprintf(md, sizeof(md), "%s/new", np->m->path);
864  if (stat(md, &s) < 0)
865  s.st_mtime = 0;
866  snprintf(md, sizeof(md), "%s/cur", np->m->path);
867  if (stat(md, &st2) < 0)
868  st2.st_mtime = 0;
869  if (st2.st_mtime > s.st_mtime)
870  s.st_mtime = st2.st_mtime;
871  }
872 
873  add_folder(menu, state, buffer, np->m->desc, &s, np->m, NULL);
874  }
875  }
876  browser_sort(state);
877  return 0;
878 }
The "current" mailbox.
Definition: context.h:36
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: magic.h:43
int msg_count
total number of messages
Definition: mailbox.h:86
int msg_unread
number of unread messages
Definition: mailbox.h:87
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: magic.h:41
void mutt_pretty_mailbox(char *s, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:606
&#39;Maildir&#39; Mailbox type
Definition: magic.h:40
char * desc
Definition: mailbox.h:81
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:602
&#39;IMAP&#39; Mailbox type
Definition: magic.h:42
bool BrowserAbbreviateMailboxes
Config: Abbreviate mailboxes using &#39;~&#39; and &#39;=&#39; in the browser.
Definition: browser.c:77
int mutt_mailbox_check(int force)
Check all AllMailboxes for new mail.
Definition: mailbox.c:538
NNTP-specific Account data -.
Definition: nntp.h:76
bool subscribed
Definition: nntp.h:148
struct Mailbox * m
Definition: mailbox.h:139
struct Mailbox * mailbox
Definition: context.h:50
enum MailboxType magic
mailbox type
Definition: mailbox.h:99
char * group
Definition: nntp.h:141
void * mdata
driver specific data
Definition: mailbox.h:130
#define PATH_MAX
Definition: mutt.h:46
bool ShowOnlyUnread
Config: (nntp) Only show subscribed newsgroups with unread articles.
Definition: browser.c:81
void * adata
Definition: account.h:41
bool new
Definition: nntp.h:149
unsigned int groups_num
Definition: nntp.h:99
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:298
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:742
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
NNTP-specific Mailbox data -.
Definition: nntp.h:139
struct MailboxList AllMailboxes
List of all Mailboxes.
Definition: mailbox.c:85
char path[PATH_MAX]
Definition: mailbox.h:78
anum_t unread
Definition: nntp.h:147
void ** groups_list
Definition: nntp.h:101
#define STAILQ_EMPTY(head)
Definition: queue.h:346
List of Mailboxes.
Definition: mailbox.h:137
char realpath[PATH_MAX]
used for duplicate detection, context comparison, and the sidebar
Definition: mailbox.h:79
static void init_state(struct BrowserState *state, struct Menu *menu)
Initilise a browser state.
Definition: browser.c:654
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:42
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:612
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:80
&#39;POP3&#39; Mailbox type
Definition: magic.h:44

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

Definition at line 883 of file browser.c.

884 {
885 #ifdef USE_NNTP
886  if (OptNews)
887  return regexec(rx, ((struct FolderFile *) menu->data)[line].desc, 0, NULL, 0);
888 #endif
889  struct FolderFile current_ff = ((struct FolderFile *) menu->data)[line];
890  char *search_on = current_ff.desc ? current_ff.desc : current_ff.name;
891 
892  return regexec(rx, search_on, 0, NULL, 0);
893 }
char * desc
Definition: browser.h:66
char * name
Definition: browser.h:65
const char * line
Definition: common.c:35
Browser entry representing a folder/dir.
Definition: browser.h:56
void * data
extra data for the current menu
Definition: menu.h:60
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:42

+ Here is the caller graph for this function:

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::menu_make_entry()

Definition at line 898 of file browser.c.

899 {
900  struct Folder folder;
901 
902  folder.ff = &((struct FolderFile *) menu->data)[line];
903  folder.num = line;
904 
905 #ifdef USE_NNTP
906  if (OptNews)
907  {
908  mutt_expando_format(buf, buflen, 0, MuttIndexWindow->cols,
910  (unsigned long) &folder, MUTT_FORMAT_ARROWCURSOR);
911  }
912  else
913 #endif
914  {
915  mutt_expando_format(buf, buflen, 0, MuttIndexWindow->cols,
917  (unsigned long) &folder, MUTT_FORMAT_ARROWCURSOR);
918  }
919 }
#define NONULL(x)
Definition: string2.h:39
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, unsigned long data, enum FormatFlag flags)
Format a string for the folder browser - Implements format_t.
Definition: browser.c:358
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, unsigned long data, enum FormatFlag flags)
Format a string for the newsgroup menu - Implements format_t.
Definition: browse.c:54
struct FolderFile * ff
Definition: browser.h:49
const char * line
Definition: common.c:35
char * GroupIndexFormat
Config: (nntp) printf-like format string for the browser&#39;s display of newsgroups. ...
Definition: browser.c:79
A folder/dir in the browser.
Definition: browser.h:47
Browser entry representing a folder/dir.
Definition: browser.h:56
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
reserve space for arrow_cursor
Definition: format_flags.h:38
void * data
extra data for the current menu
Definition: menu.h:60
char * FolderFormat
Config: printf-like format string for the browser&#39;s display of folders.
Definition: browser.c:78
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:42
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, enum FormatFlag flags)
Expand expandos (x) in a string.
Definition: muttlib.c:816

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 929 of file browser.c.

930 {
931  menu->top = 0;
932  /* Reset menu position to 1.
933  * We do not risk overflow as the init_menu function changes
934  * current if it is bigger than state->entrylen.
935  */
936  if ((mutt_str_strcmp(state->entry[0].desc, "..") == 0) ||
937  (mutt_str_strcmp(state->entry[0].desc, "../") == 0))
938  {
939  /* Skip the first entry, unless there's only one entry. */
940  menu->current = (menu->max > 1);
941  }
942  else
943  {
944  menu->current = 0;
945  }
946 }
char * desc
Definition: browser.h:66
int top
entry that is the top of the current page
Definition: menu.h:84
int max
the number of entries in the menu
Definition: menu.h:62
int current
current entry
Definition: menu.h:61
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:612
struct FolderFile * entry
Definition: browser.h:92

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 956 of file browser.c.

958 {
959  menu->max = state->entrylen;
960 
961  if (menu->current >= menu->max)
962  menu->current = menu->max - 1;
963  if (menu->current < 0)
964  menu->current = 0;
965  if (menu->top > menu->current)
966  menu->top = 0;
967 
968  menu->tagged = 0;
969 
970 #ifdef USE_NNTP
971  if (OptNews)
972  {
973  if (mailbox)
974  snprintf(title, titlelen, _("Subscribed newsgroups"));
975  else
976  {
977  snprintf(title, titlelen, _("Newsgroups on server [%s]"),
979  }
980  }
981  else
982 #endif
983  {
984  if (mailbox)
985  {
986  menu->is_mailbox_list = true;
987  snprintf(title, titlelen, _("Mailboxes [%d]"), mutt_mailbox_check(0));
988  }
989  else
990  {
991  char path[PATH_MAX];
992  menu->is_mailbox_list = false;
993  mutt_str_strfcpy(path, LastDir, sizeof(path));
994  mutt_pretty_mailbox(path, sizeof(path));
995  snprintf(title, titlelen, _("Directory [%s], File mask: %s"), path,
996  NONULL(Mask ? Mask->pattern : NULL));
997  }
998  }
999 
1000  /* Browser tracking feature.
1001  * The goal is to highlight the good directory if LastDir is the parent dir
1002  * of OldLastDir (this occurs mostly when one hit "../"). It should also work
1003  * properly when the user is in examine_mailboxes-mode.
1004  */
1006  {
1007  char TargetDir[PATH_MAX] = "";
1008 
1009 #ifdef USE_IMAP
1010  /* Check what kind of dir OldLastDir is. */
1011  if (imap_path_probe(OldLastDir, NULL) == MUTT_IMAP)
1012  {
1013  mutt_str_strfcpy(TargetDir, OldLastDir, sizeof(TargetDir));
1014  imap_clean_path(TargetDir, sizeof(TargetDir));
1015  }
1016  else
1017 #endif
1018  mutt_str_strfcpy(TargetDir, strrchr(OldLastDir, '/') + 1, sizeof(TargetDir));
1019 
1020  /* If we get here, it means that LastDir is the parent directory of
1021  * OldLastDir. I.e., we're returning from a subdirectory, and we want
1022  * to position the cursor on the directory we're returning from. */
1023  bool matched = false;
1024  for (unsigned int i = 0; i < state->entrylen; i++)
1025  {
1026  if (mutt_str_strcmp(state->entry[i].name, TargetDir) == 0)
1027  {
1028  menu->current = i;
1029  matched = true;
1030  break;
1031  }
1032  }
1033  if (!matched)
1034  browser_highlight_default(state, menu);
1035  }
1036  else
1037  browser_highlight_default(state, menu);
1038 
1039  menu->redraw = REDRAW_FULL;
1040 }
#define NONULL(x)
Definition: string2.h:39
int redraw
when to redraw the screen
Definition: menu.h:63
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2479
struct ConnAccount account
Definition: connection.h:37
static char OldLastDir[PATH_MAX]
Definition: browser.c:107
void mutt_pretty_mailbox(char *s, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:606
#define _(a)
Definition: message.h:28
static char LastDir[PATH_MAX]
Definition: browser.c:108
&#39;IMAP&#39; Mailbox type
Definition: magic.h:42
Match case when comparing strings.
Definition: string2.h:69
int mutt_mailbox_check(int force)
Check all AllMailboxes for new mail.
Definition: mailbox.c:538
char host[128]
Definition: connaccount.h:34
char * name
Definition: browser.h:65
WHERE struct Regex * Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:181
#define PATH_MAX
Definition: mutt.h:46
int top
entry that is the top of the current page
Definition: menu.h:84
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:742
bool is_mailbox_list
Definition: menu.h:68
int tagged
number of tagged entries
Definition: menu.h:87
int max
the number of entries in the menu
Definition: menu.h:62
size_t entrylen
number of real entries
Definition: browser.h:93
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:166
struct Connection * conn
Definition: nntp.h:103
static void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: browser.c:929
int current
current entry
Definition: menu.h:61
char * pattern
printable version
Definition: regex3.h:59
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:42
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:612
struct FolderFile * entry
Definition: browser.h:92
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:80
void imap_clean_path(char *path, size_t plen)
Cleans an IMAP path using imap_fix_path.
Definition: util.c:331

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

Definition at line 1045 of file browser.c.

1046 {
1047  struct FolderFile *ff = &(((struct FolderFile *) menu->data)[sel]);
1048  if (S_ISDIR(ff->mode) || (S_ISLNK(ff->mode) && link_is_dir(LastDir, ff->name)))
1049  {
1050  mutt_error(_("Can't attach a directory"));
1051  return 0;
1052  }
1053 
1054  bool ot = ff->tagged;
1055  ff->tagged = ((act >= 0) ? act : !ff->tagged);
1056 
1057  return ff->tagged - ot;
1058 }
mode_t mode
Definition: browser.h:58
static bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
Definition: browser.c:325
#define _(a)
Definition: message.h:28
static char LastDir[PATH_MAX]
Definition: browser.c:108
char * name
Definition: browser.h:65
Browser entry representing a folder/dir.
Definition: browser.h:56
#define mutt_error(...)
Definition: logging.h:88
void * data
extra data for the current menu
Definition: menu.h:60
bool tagged
Definition: browser.h:81

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 1070 of file browser.c.

1071 {
1072  mutt_str_strfcpy(OldLastDir, f, sizeof(OldLastDir));
1073 
1074  /* Method that will fetch the parent path depending on the
1075  type of the path. */
1077 }
static char OldLastDir[PATH_MAX]
Definition: browser.c:107
static char LastDir[PATH_MAX]
Definition: browser.c:108
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:742
void mutt_get_parent_path(char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition: muttlib.c:1573

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Let the user select a file.

Parameters
[in]fileBuffer for the result
[in]filelenLength of buffer
[in]flagsFlags, e.g. MUTT_SEL_MULTI
[out]filesArray of selected files
[out]numfilesNumber of selected files

Definition at line 1087 of file browser.c.

1088 {
1089  char buf[PATH_MAX];
1090  char prefix[PATH_MAX] = "";
1091  char helpstr[LONG_STRING];
1092  char title[STRING];
1093  struct BrowserState state = { 0 };
1094  struct Menu *menu = NULL;
1095  struct stat st;
1096  int i, kill_prefix = 0;
1097  bool multiple = (flags & MUTT_SEL_MULTI);
1098  bool folder = (flags & MUTT_SEL_FOLDER);
1099  bool mailbox = (flags & MUTT_SEL_MAILBOX);
1100 
1101  /* Keeps in memory the directory we were in when hitting '='
1102  * to go directly to $folder (Folder)
1103  */
1104  char GotoSwapper[PATH_MAX] = "";
1105 
1106  mailbox = mailbox && folder;
1107 
1108 #ifdef USE_NNTP
1109  if (OptNews)
1110  {
1111  if (*file)
1112  mutt_str_strfcpy(prefix, file, sizeof(prefix));
1113  else
1114  {
1116 
1117  /* default state for news reader mode is browse subscribed newsgroups */
1118  mailbox = false;
1119  for (unsigned int j = 0; j < adata->groups_num; j++)
1120  {
1121  struct NntpMboxData *mdata = adata->groups_list[j];
1122  if (mdata && mdata->subscribed)
1123  {
1124  mailbox = true;
1125  break;
1126  }
1127  }
1128  }
1129  }
1130  else
1131 #endif
1132  if (*file)
1133  {
1134  mutt_expand_path(file, filelen);
1135 #ifdef USE_IMAP
1136  if (imap_path_probe(file, NULL) == MUTT_IMAP)
1137  {
1138  init_state(&state, NULL);
1139  state.imap_browse = true;
1140  if (imap_browse(file, &state) == 0)
1141  {
1142  mutt_str_strfcpy(LastDir, state.folder, sizeof(LastDir));
1143  browser_sort(&state);
1144  }
1145  }
1146  else
1147  {
1148 #endif
1149  for (i = mutt_str_strlen(file) - 1; i > 0 && file[i] != '/'; i--)
1150  ;
1151  if (i > 0)
1152  {
1153  if (file[0] == '/')
1154  {
1155  if (i > sizeof(LastDir) - 1)
1156  i = sizeof(LastDir) - 1;
1157  strncpy(LastDir, file, i);
1158  LastDir[i] = 0;
1159  }
1160  else
1161  {
1162  getcwd(LastDir, sizeof(LastDir));
1163  mutt_str_strcat(LastDir, sizeof(LastDir), "/");
1164  mutt_str_strncat(LastDir, sizeof(LastDir), file, i);
1165  }
1166  }
1167  else
1168  {
1169  if (file[0] == '/')
1170  strcpy(LastDir, "/");
1171  else
1172  getcwd(LastDir, sizeof(LastDir));
1173  }
1174 
1175  if (i <= 0 && file[0] != '/')
1176  mutt_str_strfcpy(prefix, file, sizeof(prefix));
1177  else
1178  mutt_str_strfcpy(prefix, file + i + 1, sizeof(prefix));
1179  kill_prefix = 1;
1180 #ifdef USE_IMAP
1181  }
1182 #endif
1183  }
1184  else
1185  {
1186  if (!folder)
1187  getcwd(LastDir, sizeof(LastDir));
1188  else
1189  {
1190  /* Whether we use the tracking feature of the browser depends
1191  * on which sort method we chose to use. This variable is defined
1192  * only to help readability of the code.
1193  */
1194  short browser_track;
1195 
1196  switch (SortBrowser & SORT_MASK)
1197  {
1198  case SORT_DESC:
1199  case SORT_SUBJECT:
1200  case SORT_ORDER:
1201  browser_track = 1;
1202  break;
1203 
1204  default:
1205  browser_track = 0;
1206  break;
1207  }
1208 
1209  /* We use mutt_browser_select_dir to initialize the two
1210  * variables (LastDir, OldLastDir) at the appropriate
1211  * values.
1212  *
1213  * We do it only when LastDir is not set (first pass there)
1214  * or when CurrentFolder and OldLastDir are not the same.
1215  * This code is executed only when we list files, not when
1216  * we press up/down keys to navigate in a displayed list.
1217  *
1218  * We only do this when CurrentFolder has been set (ie, not
1219  * when listing folders on startup with "neomutt -y").
1220  *
1221  * This tracker is only used when browser_track is true,
1222  * meaning only with sort methods SUBJECT/DESC for now.
1223  */
1224  if (CurrentFolder)
1225  {
1226  if (!LastDir[0])
1227  {
1228  /* If browsing in "local"-mode, than we chose to define LastDir to
1229  * MailDir
1230  */
1231  switch (mx_path_probe(CurrentFolder, NULL))
1232  {
1233  case MUTT_IMAP:
1234  case MUTT_MAILDIR:
1235  case MUTT_MBOX:
1236  case MUTT_MH:
1237  case MUTT_MMDF:
1238  if (Folder)
1240  else if (Spoolfile)
1242  break;
1243  default:
1245  break;
1246  }
1247  }
1248  else if (mutt_str_strcmp(CurrentFolder, OldLastDir) != 0)
1249  {
1251  }
1252  }
1253 
1254  /* When browser tracking feature is disabled, shoot a 0
1255  * on first char of OldLastDir to make it useless.
1256  */
1257  if (!browser_track)
1258  OldLastDir[0] = '\0';
1259  }
1260 
1261 #ifdef USE_IMAP
1262  if (!mailbox && (imap_path_probe(LastDir, NULL) == MUTT_IMAP))
1263  {
1264  init_state(&state, NULL);
1265  state.imap_browse = true;
1266  imap_browse(LastDir, &state);
1267  browser_sort(&state);
1268  }
1269  else
1270 #endif
1271  {
1272  i = mutt_str_strlen(LastDir);
1273  while (i && LastDir[--i] == '/')
1274  LastDir[i] = '\0';
1275  if (!LastDir[0])
1276  getcwd(LastDir, sizeof(LastDir));
1277  }
1278  }
1279 
1280  *file = 0;
1281 
1282  if (mailbox)
1283  {
1284  examine_mailboxes(NULL, &state);
1285  }
1286  else
1287 #ifdef USE_IMAP
1288  if (!state.imap_browse)
1289 #endif
1290  {
1291  if (examine_directory(NULL, &state, LastDir, prefix) == -1)
1292  goto bail;
1293  }
1294  menu = mutt_menu_new(MENU_FOLDER);
1297  menu->title = title;
1298  menu->data = state.entry;
1299  if (multiple)
1300  menu->menu_tag = file_tag;
1301 
1303  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_FOLDER,
1304 #ifdef USE_NNTP
1306 #endif
1307  FolderHelp);
1308  mutt_menu_push_current(menu);
1309 
1310  init_menu(&state, menu, title, sizeof(title), mailbox);
1311 
1312  while (true)
1313  {
1314  switch (i = mutt_menu_loop(menu))
1315  {
1316  case OP_GENERIC_SELECT_ENTRY:
1317 
1318  if (state.entrylen == 0)
1319  {
1320  mutt_error(_("No files match the file mask"));
1321  break;
1322  }
1323 
1324  if (S_ISDIR(state.entry[menu->current].mode) ||
1325  (S_ISLNK(state.entry[menu->current].mode) &&
1326  link_is_dir(LastDir, state.entry[menu->current].name))
1327 #ifdef USE_IMAP
1328  || state.entry[menu->current].inferiors
1329 #endif
1330  )
1331  {
1332  /* make sure this isn't a MH or maildir mailbox */
1333  if (mailbox)
1334  {
1335  mutt_str_strfcpy(buf, state.entry[menu->current].name, sizeof(buf));
1336  mutt_expand_path(buf, sizeof(buf));
1337  }
1338 #ifdef USE_IMAP
1339  else if (state.imap_browse)
1340  {
1341  mutt_str_strfcpy(buf, state.entry[menu->current].name, sizeof(buf));
1342  }
1343 #endif
1344  else
1345  {
1346  mutt_path_concat(buf, LastDir, state.entry[menu->current].name, sizeof(buf));
1347  }
1348 
1349  enum MailboxType magic = mx_path_probe(buf, NULL);
1350  if ((magic == MUTT_MAILBOX_ERROR) || (magic == MUTT_UNKNOWN)
1351 #ifdef USE_IMAP
1352  || state.entry[menu->current].inferiors
1353 #endif
1354  )
1355  {
1356  /* save the old directory */
1358 
1359  if (mutt_str_strcmp(state.entry[menu->current].name, "..") == 0)
1360  {
1361  if (mutt_str_strcmp("..", LastDir + mutt_str_strlen(LastDir) - 2) == 0)
1362  strcat(LastDir, "/..");
1363  else
1364  {
1365  char *p = strrchr(LastDir + 1, '/');
1366 
1367  if (p)
1368  *p = 0;
1369  else
1370  {
1371  if (LastDir[0] == '/')
1372  LastDir[1] = 0;
1373  else
1374  strcat(LastDir, "/..");
1375  }
1376  }
1377  }
1378  else if (mailbox)
1379  {
1380  mutt_str_strfcpy(LastDir, state.entry[menu->current].name, sizeof(LastDir));
1381  mutt_expand_path(LastDir, sizeof(LastDir));
1382  }
1383 #ifdef USE_IMAP
1384  else if (state.imap_browse)
1385  {
1386  int n;
1387 
1388  mutt_str_strfcpy(LastDir, state.entry[menu->current].name, sizeof(LastDir));
1389  /* tack on delimiter here */
1390  n = strlen(LastDir) + 1;
1391 
1392  /* special case "" needs no delimiter */
1393  struct Url *url = url_parse(state.entry[menu->current].name);
1394  if (url->path && (state.entry[menu->current].delim != '\0') &&
1395  (n < sizeof(LastDir)))
1396  {
1397  LastDir[n] = '\0';
1398  LastDir[n - 1] = state.entry[menu->current].delim;
1399  }
1400  url_free(&url);
1401  }
1402 #endif
1403  else
1404  {
1405  char tmp[PATH_MAX];
1406  mutt_path_concat(tmp, LastDir, state.entry[menu->current].name, sizeof(tmp));
1407  mutt_str_strfcpy(LastDir, tmp, sizeof(LastDir));
1408  }
1409 
1410  destroy_state(&state);
1411  if (kill_prefix)
1412  {
1413  prefix[0] = 0;
1414  kill_prefix = 0;
1415  }
1416  mailbox = false;
1417 #ifdef USE_IMAP
1418  if (state.imap_browse)
1419  {
1420  init_state(&state, NULL);
1421  state.imap_browse = true;
1422  imap_browse(LastDir, &state);
1423  browser_sort(&state);
1424  menu->data = state.entry;
1425  }
1426  else
1427 #endif
1428  {
1429  if (examine_directory(menu, &state, LastDir, prefix) == -1)
1430  {
1431  /* try to restore the old values */
1433  if (examine_directory(menu, &state, LastDir, prefix) == -1)
1434  {
1436  goto bail;
1437  }
1438  }
1439  /* resolve paths navigated from GUI */
1440  if (mutt_path_realpath(LastDir) == 0)
1441  break;
1442  }
1443 
1444  browser_highlight_default(&state, menu);
1445  init_menu(&state, menu, title, sizeof(title), mailbox);
1446  if (GotoSwapper[0])
1447  GotoSwapper[0] = '\0';
1448  break;
1449  }
1450  }
1451 
1452  if (mailbox || OptNews) /* USE_NNTP */
1453  {
1454  mutt_str_strfcpy(file, state.entry[menu->current].name, filelen);
1455  mutt_expand_path(file, filelen);
1456  }
1457 #ifdef USE_IMAP
1458  else if (state.imap_browse)
1459  mutt_str_strfcpy(file, state.entry[menu->current].name, filelen);
1460 #endif
1461  else
1462  mutt_path_concat(file, LastDir, state.entry[menu->current].name, filelen);
1463  /* fallthrough */
1464 
1465  case OP_EXIT:
1466 
1467  if (multiple)
1468  {
1469  char **tfiles = NULL;
1470 
1471  if (menu->tagged)
1472  {
1473  *numfiles = menu->tagged;
1474  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
1475  for (int j = 0, k = 0; j < state.entrylen; j++)
1476  {
1477  struct FolderFile ff = state.entry[j];
1478  if (ff.tagged)
1479  {
1480  char full[PATH_MAX];
1481  mutt_path_concat(full, LastDir, ff.name, sizeof(full));
1482  mutt_expand_path(full, sizeof(full));
1483  tfiles[k++] = mutt_str_strdup(full);
1484  }
1485  }
1486  *files = tfiles;
1487  }
1488  else if (file[0]) /* no tagged entries. return selected entry */
1489  {
1490  *numfiles = 1;
1491  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
1492  mutt_expand_path(file, filelen);
1493  tfiles[0] = mutt_str_strdup(file);
1494  *files = tfiles;
1495  }
1496  }
1497 
1498  destroy_state(&state);
1499  goto bail;
1500 
1501  case OP_BROWSER_TELL:
1502  if (state.entrylen)
1503  mutt_message("%s", state.entry[menu->current].name);
1504  break;
1505 
1506 #ifdef USE_IMAP
1507  case OP_BROWSER_TOGGLE_LSUB:
1508  bool_str_toggle(Config, "imap_list_subscribed", NULL);
1509 
1510  mutt_unget_event(0, OP_CHECK_NEW);
1511  break;
1512 
1513  case OP_CREATE_MAILBOX:
1514  if (!state.imap_browse)
1515  {
1516  mutt_error(_("Create is only supported for IMAP mailboxes"));
1517  break;
1518  }
1519 
1520  if (imap_mailbox_create(LastDir) == 0)
1521  {
1522  /* TODO: find a way to detect if the new folder would appear in
1523  * this window, and insert it without starting over. */
1524  destroy_state(&state);
1525  init_state(&state, NULL);
1526  state.imap_browse = true;
1527  imap_browse(LastDir, &state);
1528  browser_sort(&state);
1529  menu->data = state.entry;
1530  browser_highlight_default(&state, menu);
1531  init_menu(&state, menu, title, sizeof(title), mailbox);
1532  }
1533  /* else leave error on screen */
1534  break;
1535 
1536  case OP_RENAME_MAILBOX:
1537  if (!state.entry[menu->current].imap)
1538  mutt_error(_("Rename is only supported for IMAP mailboxes"));
1539  else
1540  {
1541  int nentry = menu->current;
1542 
1543  if (imap_mailbox_rename(state.entry[nentry].name) >= 0)
1544  {
1545  destroy_state(&state);
1546  init_state(&state, NULL);
1547  state.imap_browse = true;
1548  imap_browse(LastDir, &state);
1549  browser_sort(&state);
1550  menu->data = state.entry;
1551  browser_highlight_default(&state, menu);
1552  init_menu(&state, menu, title, sizeof(title), mailbox);
1553  }
1554  }
1555  break;
1556 
1557  case OP_DELETE_MAILBOX:
1558  if (!state.entry[menu->current].imap)
1559  mutt_error(_("Delete is only supported for IMAP mailboxes"));
1560  else
1561  {
1562  char msg[SHORT_STRING];
1563  int nentry = menu->current;
1564 
1565  // TODO(sileht): It could be better to select INBOX instead. But I
1566  // don't want to manipulate Context/AllMailboxes/mailbox->account here for now.
1567  // Let's just protect neomutt against crash for now. #1417
1568  if (mutt_str_strcmp(Context->mailbox->path, state.entry[nentry].name) == 0)
1569  {
1570  mutt_error(_("Can't delete currently selected mailbox"));
1571  break;
1572  }
1573 
1574  snprintf(msg, sizeof(msg), _("Really delete mailbox \"%s\"?"),
1575  state.entry[nentry].name);
1576  if (mutt_yesorno(msg, MUTT_NO) == MUTT_YES)
1577  {
1578  if (imap_delete_mailbox(Context->mailbox, state.entry[nentry].name) == 0)
1579  {
1580  /* free the mailbox from the browser */
1581  FREE(&((state.entry)[nentry].name));
1582  FREE(&((state.entry)[nentry].desc));
1583  /* and move all other entries up */
1584  if (nentry + 1 < state.entrylen)
1585  {
1586  memmove(state.entry + nentry, state.entry + nentry + 1,
1587  sizeof(struct FolderFile) * (state.entrylen - (nentry + 1)));
1588  }
1589  memset(&state.entry[state.entrylen - 1], 0, sizeof(struct FolderFile));
1590  state.entrylen--;
1591  mutt_message(_("Mailbox deleted"));
1592  init_menu(&state, menu, title, sizeof(title), mailbox);
1593  }
1594  else
1595  mutt_error(_("Mailbox deletion failed"));
1596  }
1597  else
1598  mutt_message(_("Mailbox not deleted"));
1599  }
1600  break;
1601 #endif
1602 
1603  case OP_GOTO_PARENT:
1604  case OP_CHANGE_DIRECTORY:
1605 
1606 #ifdef USE_NNTP
1607  if (OptNews)
1608  break;
1609 #endif
1610 
1611  mutt_str_strfcpy(buf, LastDir, sizeof(buf));
1612 #ifdef USE_IMAP
1613  if (!state.imap_browse)
1614 #endif
1615  {
1616  /* add '/' at the end of the directory name if not already there */
1617  size_t len = mutt_str_strlen(buf);
1618  if ((len > 0) && (buf[len - 1] != '/') && (sizeof(buf) > (len + 1)))
1619  {
1620  buf[len] = '/';
1621  buf[len + 1] = '\0';
1622  }
1623  }
1624 
1625  if (i == OP_CHANGE_DIRECTORY)
1626  {
1627  int ret = mutt_get_field(_("Chdir to: "), buf, sizeof(buf), MUTT_FILE);
1628  if (ret != 0)
1629  break;
1630  }
1631  else if (i == OP_GOTO_PARENT)
1632  mutt_get_parent_path(buf, buf, sizeof(buf));
1633 
1634  if (buf[0])
1635  {
1636  mailbox = false;
1637  mutt_expand_path(buf, sizeof(buf));
1638 #ifdef USE_IMAP
1639  if (imap_path_probe(buf, NULL) == MUTT_IMAP)
1640  {
1641  mutt_str_strfcpy(LastDir, buf, sizeof(LastDir));
1642  destroy_state(&state);
1643  init_state(&state, NULL);
1644  state.imap_browse = true;
1645  imap_browse(LastDir, &state);
1646  browser_sort(&state);
1647  menu->data = state.entry;
1648  browser_highlight_default(&state, menu);
1649  init_menu(&state, menu, title, sizeof(title), mailbox);
1650  }
1651  else
1652 #endif
1653  {
1654  if (*buf != '/')
1655  {
1656  /* in case dir is relative, make it relative to LastDir,
1657  * not current working dir */
1658  char tmp[PATH_MAX];
1659  mutt_path_concat(tmp, LastDir, buf, sizeof(tmp));
1660  mutt_str_strfcpy(buf, tmp, sizeof(buf));
1661  }
1662  /* Resolve path from <chdir>
1663  * Avoids buildup such as /a/b/../../c
1664  * Symlinks are always unraveled to keep code simple */
1665  if (mutt_path_realpath(buf) == 0)
1666  break;
1667 
1668  if (stat(buf, &st) == 0)
1669  {
1670  if (S_ISDIR(st.st_mode))
1671  {
1672  destroy_state(&state);
1673  if (examine_directory(menu, &state, buf, prefix) == 0)
1674  mutt_str_strfcpy(LastDir, buf, sizeof(LastDir));
1675  else
1676  {
1677  mutt_error(_("Error scanning directory"));
1678  if (examine_directory(menu, &state, LastDir, prefix) == -1)
1679  {
1680  goto bail;
1681  }
1682  }
1683  browser_highlight_default(&state, menu);
1684  init_menu(&state, menu, title, sizeof(title), mailbox);
1685  }
1686  else
1687  mutt_error(_("%s is not a directory"), buf);
1688  }
1689  else
1690  mutt_perror(buf);
1691  }
1692  }
1693  break;
1694 
1695  case OP_ENTER_MASK:
1696  {
1697  mutt_str_strfcpy(buf, Mask ? Mask->pattern : NULL, sizeof(buf));
1698  if (mutt_get_field(_("File Mask: "), buf, sizeof(buf), 0) != 0)
1699  break;
1700 
1701  mailbox = false;
1702  /* assume that the user wants to see everything */
1703  if (!buf[0])
1704  mutt_str_strfcpy(buf, ".", sizeof(buf));
1705 
1706  struct Buffer errmsg = { 0 };
1707  int rc = cs_str_string_set(Config, "mask", buf, NULL);
1708  if (CSR_RESULT(rc) != CSR_SUCCESS)
1709  {
1710  if (!mutt_buffer_is_empty(&errmsg))
1711  {
1712  mutt_error("%s", errmsg.data);
1713  FREE(&errmsg.data);
1714  }
1715  break;
1716  }
1717 
1718  destroy_state(&state);
1719 #ifdef USE_IMAP
1720  if (state.imap_browse)
1721  {
1722  init_state(&state, NULL);
1723  state.imap_browse = true;
1724  imap_browse(LastDir, &state);
1725  browser_sort(&state);
1726  menu->data = state.entry;
1727  init_menu(&state, menu, title, sizeof(title), mailbox);
1728  }
1729  else
1730 #endif
1731  if (examine_directory(menu, &state, LastDir, NULL) == 0)
1732  init_menu(&state, menu, title, sizeof(title), mailbox);
1733  else
1734  {
1735  mutt_error(_("Error scanning directory"));
1736  goto bail;
1737  }
1738  kill_prefix = 0;
1739  if (state.entrylen == 0)
1740  {
1741  mutt_error(_("No files match the file mask"));
1742  break;
1743  }
1744  break;
1745  }
1746 
1747  case OP_SORT:
1748  case OP_SORT_REVERSE:
1749 
1750  {
1751  bool resort = true;
1752  int sort = -1;
1753  int reverse = (i == OP_SORT_REVERSE);
1754 
1755  switch (mutt_multi_choice(
1756  (reverse) ?
1757  /* L10N: The highlighted letters must match the "Sort" options */
1758  _("Reverse sort by (d)ate, (a)lpha, si(z)e, d(e)scription, "
1759  "(c)ount, ne(w) count, or do(n)'t sort? ") :
1760  /* L10N: The highlighted letters must match the "Reverse Sort" options */
1761  _("Sort by (d)ate, (a)lpha, si(z)e, d(e)scription, (c)ount, "
1762  "ne(w) count, or do(n)'t sort? "),
1763  /* L10N: These must match the highlighted letters from "Sort" and "Reverse Sort" */
1764  _("dazecwn")))
1765  {
1766  case -1: /* abort */
1767  resort = false;
1768  break;
1769 
1770  case 1: /* (d)ate */
1771  sort = SORT_DATE;
1772  break;
1773 
1774  case 2: /* (a)lpha */
1775  sort = SORT_SUBJECT;
1776  break;
1777 
1778  case 3: /* si(z)e */
1779  sort = SORT_SIZE;
1780  break;
1781 
1782  case 4: /* d(e)scription */
1783  sort = SORT_DESC;
1784  break;
1785 
1786  case 5: /* (c)ount */
1787  sort = SORT_COUNT;
1788  break;
1789 
1790  case 6: /* ne(w) count */
1791  sort = SORT_UNREAD;
1792  break;
1793 
1794  case 7: /* do(n)'t sort */
1795  sort = SORT_ORDER;
1796  resort = false;
1797  break;
1798  }
1799  if (resort)
1800  {
1801  sort |= reverse ? SORT_REVERSE : 0;
1802  browser_sort(&state);
1803  browser_highlight_default(&state, menu);
1804  menu->redraw = REDRAW_FULL;
1805  }
1806  cs_str_native_set(Config, "sort_browser", sort, NULL);
1807  break;
1808  }
1809 
1810  case OP_TOGGLE_MAILBOXES:
1811  case OP_BROWSER_GOTO_FOLDER:
1812  case OP_CHECK_NEW:
1813  if (i == OP_TOGGLE_MAILBOXES)
1814  mailbox = !mailbox;
1815 
1816  if (i == OP_BROWSER_GOTO_FOLDER)
1817  {
1818  /* When in mailboxes mode, disables this feature */
1819  if (Folder)
1820  {
1821  mutt_debug(5, "= hit! Folder: %s, LastDir: %s\n", Folder, LastDir);
1822  if (!GotoSwapper[0])
1823  {
1824  if (mutt_str_strcmp(LastDir, Folder) != 0)
1825  {
1826  /* Stores into GotoSwapper LastDir, and swaps to Folder */
1827  mutt_str_strfcpy(GotoSwapper, LastDir, sizeof(GotoSwapper));
1830  }
1831  }
1832  else
1833  {
1835  mutt_str_strfcpy(LastDir, GotoSwapper, sizeof(LastDir));
1836  GotoSwapper[0] = '\0';
1837  }
1838  }
1839  }
1840  destroy_state(&state);
1841  prefix[0] = 0;
1842  kill_prefix = 0;
1843 
1844  if (mailbox)
1845  {
1846  examine_mailboxes(menu, &state);
1847  }
1848 #ifdef USE_IMAP
1849  else if (imap_path_probe(LastDir, NULL) == MUTT_IMAP)
1850  {
1851  init_state(&state, NULL);
1852  state.imap_browse = true;
1853  imap_browse(LastDir, &state);
1854  browser_sort(&state);
1855  menu->data = state.entry;
1856  }
1857 #endif
1858  else if (examine_directory(menu, &state, LastDir, prefix) == -1)
1859  goto bail;
1860  init_menu(&state, menu, title, sizeof(title), mailbox);
1861  break;
1862 
1863  case OP_MAILBOX_LIST:
1865  break;
1866 
1867  case OP_BROWSER_NEW_FILE:
1868 
1869  snprintf(buf, sizeof(buf), "%s/", LastDir);
1870  if (mutt_get_field(_("New file name: "), buf, sizeof(buf), MUTT_FILE) == 0)
1871  {
1872  mutt_str_strfcpy(file, buf, filelen);
1873  destroy_state(&state);
1874  goto bail;
1875  }
1876  break;
1877 
1878  case OP_BROWSER_VIEW_FILE:
1879  if (state.entrylen == 0)
1880  {
1881  mutt_error(_("No files match the file mask"));
1882  break;
1883  }
1884 
1885 #ifdef USE_IMAP
1886  if (state.entry[menu->current].selectable)
1887  {
1888  mutt_str_strfcpy(file, state.entry[menu->current].name, filelen);
1889  destroy_state(&state);
1890  goto bail;
1891  }
1892  else
1893 #endif
1894  if (S_ISDIR(state.entry[menu->current].mode) ||
1895  (S_ISLNK(state.entry[menu->current].mode) &&
1896  link_is_dir(LastDir, state.entry[menu->current].name)))
1897  {
1898  mutt_error(_("Can't view a directory"));
1899  break;
1900  }
1901  else
1902  {
1903  char buf2[PATH_MAX];
1904 
1905  mutt_path_concat(buf2, LastDir, state.entry[menu->current].name, sizeof(buf2));
1906  struct Body *b = mutt_make_file_attach(buf2);
1907  if (b)
1908  {
1909  mutt_view_attachment(NULL, b, MUTT_REGULAR, NULL, NULL);
1910  mutt_body_free(&b);
1911  menu->redraw = REDRAW_FULL;
1912  }
1913  else
1914  mutt_error(_("Error trying to view file"));
1915  }
1916  break;
1917 
1918 #ifdef USE_NNTP
1919  case OP_CATCHUP:
1920  case OP_UNCATCHUP:
1921  if (OptNews)
1922  {
1923  struct FolderFile *ff = &state.entry[menu->current];
1924  struct NntpMboxData *mdata = NULL;
1925 
1927  if (rc < 0)
1928  break;
1929 
1930  if (i == OP_CATCHUP)
1932  else
1934 
1935  if (mdata)
1936  {
1938  if (menu->current + 1 < menu->max)
1939  menu->current++;
1940  menu->redraw = REDRAW_MOTION_RESYNCH;
1941  }
1942  if (rc)
1943  menu->redraw = REDRAW_INDEX;
1945  }
1946  break;
1947 
1948  case OP_LOAD_ACTIVE:
1949  if (OptNews)
1950  {
1951  struct NntpAccountData *adata = CurrentNewsSrv;
1952 
1953  if (nntp_newsrc_parse(adata) < 0)
1954  break;
1955 
1956  for (unsigned int j = 0; j < adata->groups_num; j++)
1957  {
1958  struct NntpMboxData *mdata = adata->groups_list[j];
1959  if (mdata)
1960  mdata->deleted = true;
1961  }
1962  nntp_active_fetch(adata, true);
1963  nntp_newsrc_update(adata);
1964  nntp_newsrc_close(adata);
1965 
1966  destroy_state(&state);
1967  if (mailbox)
1968  examine_mailboxes(menu, &state);
1969  else
1970  {
1971  if (examine_directory(menu, &state, NULL, NULL) == -1)
1972  break;
1973  }
1974  init_menu(&state, menu, title, sizeof(title), mailbox);
1975  }
1976  break;
1977 #endif /* USE_NNTP */
1978 
1979 #if defined(USE_IMAP) || defined(USE_NNTP)
1980  case OP_BROWSER_SUBSCRIBE:
1981  case OP_BROWSER_UNSUBSCRIBE:
1982 #endif
1983 #ifdef USE_NNTP
1984  case OP_SUBSCRIBE_PATTERN:
1985  case OP_UNSUBSCRIBE_PATTERN:
1986  if (OptNews)
1987  {
1988  struct NntpAccountData *adata = CurrentNewsSrv;
1989  regex_t rx;
1990  memset(&rx, 0, sizeof(rx));
1991  char *s = buf;
1992  int j = menu->current;
1993 
1994  if (i == OP_SUBSCRIBE_PATTERN || i == OP_UNSUBSCRIBE_PATTERN)
1995  {
1996  char tmp[STRING];
1997  int err;
1998 
1999  buf[0] = 0;
2000  if (i == OP_SUBSCRIBE_PATTERN)
2001  snprintf(tmp, sizeof(tmp), _("Subscribe pattern: "));
2002  else
2003  snprintf(tmp, sizeof(tmp), _("Unsubscribe pattern: "));
2004  if (mutt_get_field(tmp, buf, sizeof(buf), 0) != 0 || !buf[0])
2005  {
2006  break;
2007  }
2008 
2009  err = REGCOMP(&rx, s, REG_NOSUB);
2010  if (err != 0)
2011  {
2012  regerror(err, &rx, buf, sizeof(buf));
2013  regfree(&rx);
2014  mutt_error("%s", buf);
2015  break;
2016  }
2017  menu->redraw = REDRAW_FULL;
2018  j = 0;
2019  }
2020  else if (state.entrylen == 0)
2021  {
2022  mutt_error(_("No newsgroups match the mask"));
2023  break;
2024  }
2025 
2026  int rc = nntp_newsrc_parse(adata);
2027  if (rc < 0)
2028  break;
2029 
2030  for (; j < state.entrylen; j++)
2031  {
2032  struct FolderFile *ff = &state.entry[j];
2033 
2034  if (i == OP_BROWSER_SUBSCRIBE || i == OP_BROWSER_UNSUBSCRIBE ||
2035  regexec(&rx, ff->name, 0, NULL, 0) == 0)
2036  {
2037  if (i == OP_BROWSER_SUBSCRIBE || i == OP_SUBSCRIBE_PATTERN)
2038  mutt_newsgroup_subscribe(adata, ff->name);
2039  else
2040  mutt_newsgroup_unsubscribe(adata, ff->name);
2041  }
2042  if (i == OP_BROWSER_SUBSCRIBE || i == OP_BROWSER_UNSUBSCRIBE)
2043  {
2044  if (menu->current + 1 < menu->max)
2045  menu->current++;
2046  menu->redraw = REDRAW_MOTION_RESYNCH;
2047  break;
2048  }
2049  }
2050  if (i == OP_SUBSCRIBE_PATTERN)
2051  {
2052  for (unsigned int k = 0; adata && (k < adata->groups_num); k++)
2053  {
2054  struct NntpMboxData *mdata = adata->groups_list[k];
2055  if (mdata && mdata->group && !mdata->subscribed)
2056  {
2057  if (regexec(&rx, mdata->group, 0, NULL, 0) == 0)
2058  {
2059  mutt_newsgroup_subscribe(adata, mdata->group);
2060  add_folder(menu, &state, mdata->group, NULL, NULL, NULL, mdata);
2061  }
2062  }
2063  }
2064  init_menu(&state, menu, title, sizeof(title), mailbox);
2065  }
2066  if (rc > 0)
2067  menu->redraw = REDRAW_FULL;
2068  nntp_newsrc_update(adata);
2069  nntp_clear_cache(adata);
2070  nntp_newsrc_close(adata);
2071  if (i != OP_BROWSER_SUBSCRIBE && i != OP_BROWSER_UNSUBSCRIBE)
2072  regfree(&rx);
2073  }
2074 #ifdef USE_IMAP
2075  else
2076 #endif /* USE_IMAP && USE_NNTP */
2077 #endif /* USE_NNTP */
2078 #ifdef USE_IMAP
2079  {
2080  char tmp[STRING];
2081  mutt_str_strfcpy(tmp, state.entry[menu->current].name, sizeof(tmp));
2082  mutt_expand_path(tmp, sizeof(tmp));
2083  imap_subscribe(tmp, i == OP_BROWSER_SUBSCRIBE);
2084  }
2085 #endif /* USE_IMAP */
2086  }
2087  }
2088 
2089 bail:
2090 
2091  if (menu)
2092  {
2093  mutt_menu_pop_current(menu);
2094  mutt_menu_destroy(&menu);
2095  }
2096 
2097  if (GotoSwapper[0])
2098  GotoSwapper[0] = '\0';
2099 }
struct Url url
Definition: url.c:45
mode_t mode
Definition: browser.h:58
The "current" mailbox.
Definition: context.h:36
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
#define SORT_COUNT
Sort by number of emails in a folder.
Definition: sort.h:60
static bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
Definition: browser.c:325
#define SHORT_STRING
Definition: string2.h:34
int redraw
when to redraw the screen
Definition: menu.h:63
#define mutt_perror(...)
Definition: logging.h:89
struct NntpMboxData * mutt_newsgroup_catchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Catchup newsgroup.
Definition: newsrc.c:1286
GUI selectable list of items.
Definition: menu.h:56
#define CSR_RESULT(x)
Definition: set.h:61
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2479
static void destroy_state(struct BrowserState *state)
Free the BrowserState.
Definition: browser.c:116
static char OldLastDir[PATH_MAX]
Definition: browser.c:107
int cs_str_string_set(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: set.c:657
#define mutt_message(...)
Definition: logging.h:87
#define SORT_UNREAD
Sort by the number of unread emails.
Definition: sort.h:61
int imap_delete_mailbox(struct Mailbox *m, char *path)
Delete a mailbox.
Definition: imap.c:635
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:67
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
int mutt_yesorno(const char *msg, int def)
Ask the user a Yes/No question.
Definition: curs_lib.c:330
&#39;Maildir&#39; Mailbox type
Definition: magic.h:40
int nntp_active_fetch(struct NntpAccountData *adata, bool new)
Fetch list of all newsgroups from server.
Definition: nntp.c:2046
static int file_tag(struct Menu *menu, int sel, int act)
Tag an entry in the menu - Implements Menu::menu_tag()
Definition: browser.c:1045
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:162
State of the file/mailbox browser.
Definition: browser.h:90
&#39;mmdf&#39; Mailbox type
Definition: magic.h:38
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:602
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
Definition: newsrc.c:852
String manipulation buffer.
Definition: buffer.h:33
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:668
General file/mailbox browser.
Definition: keymap.h:71
#define _(a)
Definition: message.h:28
WHERE struct ConfigSet * Config
Wrapper around the user&#39;s config settings.
Definition: globals.h:39
static char LastDir[PATH_MAX]
Definition: browser.c:108
int imap_mailbox_create(const char *path)
Create a new IMAP mailbox.
Definition: browse.c:364
&#39;IMAP&#39; Mailbox type
Definition: magic.h:42
View using default method.
Definition: mutt.h:106
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:663
int menu
menu definition for keymap entries.
Definition: menu.h:64
#define LONG_STRING
Definition: string2.h:36
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::menu_make_entry()
Definition: browser.c:898
static int select_file_search(struct Menu *menu, regex_t *rx, int line)
Menu search callback for matching files - Implements Menu::menu_search()
Definition: browser.c:883
char * mutt_str_strncat(char *d, size_t l, const char *s, size_t sl)
Concatenate two strings.
Definition: string.c:431
void url_free(struct Url **u)
Free the contents of a URL.
Definition: url.c:290
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: menu.h:96
NNTP-specific Account data -.
Definition: nntp.h:76
bool subscribed
Definition: nntp.h:148
The body of an email.
Definition: body.h:33
char * mutt_compile_help(char *buf, size_t buflen, int menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:115
#define MUTT_SEL_FOLDER
Definition: browser.h:42
char * folder
Definition: browser.h:97
bool selectable
Definition: browser.h:76
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:157
#define SORT_DESC
Sort by the folder&#39;s description.
Definition: sort.h:65
struct Mailbox * mailbox
Definition: context.h:50
struct Body * mutt_make_file_attach(const char *path)
Create a file attachment.
Definition: sendlib.c:1591
enum MailboxType magic
mailbox type
Definition: mailbox.h:99
static int examine_mailboxes(struct Menu *menu, struct BrowserState *state)
Get list of mailboxes/subscribed newsgroups.
Definition: browser.c:795
char * name
Definition: browser.h:65
WHERE char * HomeDir
User&#39;s home directory.
Definition: globals.h:47
WHERE struct Regex * Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:181
char * group
Definition: nntp.h:141
struct NntpMboxData * mutt_newsgroup_uncatchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Uncatchup newsgroup.
Definition: newsrc.c:1322
size_t mutt_path_realpath(char *buf)
resolve path, unraveling symlinks
Definition: path.c:456
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: globals.h:52
bool imap
Definition: browser.h:75
#define SORT_SIZE
Sort by the size of the email.
Definition: sort.h:46
void * mdata
driver specific data
Definition: mailbox.h:130
#define SORT_DATE
Sort by the date the email was sent.
Definition: sort.h:45
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:45
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:792
A folder/dir in the browser.
Definition: browser.h:47
Browser entry representing a folder/dir.
Definition: browser.h:56
&#39;mbox&#39; Mailbox type
Definition: magic.h:37
#define PATH_MAX
Definition: mutt.h:46
MailboxType
Supported mailbox formats.
Definition: magic.h:33
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
void * adata
Definition: account.h:41
struct NntpMboxData * mutt_newsgroup_unsubscribe(struct NntpAccountData *adata, char *group)
Unsubscribe newsgroup.
Definition: newsrc.c:1258
char * data
pointer to data
Definition: buffer.h:35
unsigned int groups_num
Definition: nntp.h:99
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:298
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:742
Error occurred examining mailbox.
Definition: magic.h:35
#define mutt_get_field(A, B, C, D)
Definition: curs_lib.h:78
#define MUTT_SEL_MULTI
Definition: browser.h:41
NNTP-specific Mailbox data -.
Definition: nntp.h:139
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
Definition: newsrc.c:172
int tagged
number of tagged entries
Definition: menu.h:87
#define MUTT_FILE
do file completion
Definition: mutt.h:59
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:131
char * path
Definition: url.h:74
int max
the number of entries in the menu
Definition: menu.h:62
int(* menu_tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: menu.h:113
size_t entrylen
number of real entries
Definition: browser.h:93
char path[PATH_MAX]
Definition: mailbox.h:78
int(* menu_search)(struct Menu *menu, regex_t *rx, int line)
Search a menu for a item matching a regex.
Definition: menu.h:105
#define MUTT_SEL_MAILBOX
Definition: browser.h:40
char * title
the title of this menu
Definition: menu.h:58
bool mutt_mailbox_list(void)
List the mailboxes with new mail.
Definition: mailbox.c:598
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:402
static void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: browser.c:929
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:56
#define STRING
Definition: string2.h:35
#define SORT_SUBJECT
Sort by the email&#39;s subject.
Definition: sort.h:48
bool deleted
Definition: nntp.h:151
void mutt_browser_select_dir(const char *f)
Remember the last directory selected.
Definition: browser.c:1070
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:956
Mailbox wasn&#39;t recognised.
Definition: magic.h:36
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:384
static int examine_directory(struct Menu *menu, struct BrowserState *state, char *d, const char *prefix)
Get list of all files/newsgroups with mask.
Definition: browser.c:675
#define mutt_error(...)
Definition: logging.h:88
&#39;MH&#39; Mailbox type
Definition: magic.h:39
void ** groups_list
Definition: nntp.h:101
int imap_browse(char *path, struct BrowserState *state)
IMAP hook into the folder browser.
Definition: browse.c:183
#define FREE(x)
Definition: memory.h:46
int imap_mailbox_rename(const char *path)
Rename a mailbox.
Definition: browse.c:416
void * data
extra data for the current menu
Definition: menu.h:60
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:323
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
WHERE char * Spoolfile
Config: Inbox.
Definition: globals.h:147
bool tagged
Definition: browser.h:81
int mutt_view_attachment(FILE *fp, struct Body *a, int flag, struct Email *e, struct AttachCtx *actx)
View an attachment.
Definition: mutt_attach.c:383
int bool_str_toggle(struct ConfigSet *cs, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:247
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort.h:78
int nntp_newsrc_update(struct NntpAccountData *adata)
Update .newsrc file.
Definition: newsrc.c:449
int current
current entry
Definition: menu.h:61
char * pattern
printable version
Definition: regex3.h:59
static void init_state(struct BrowserState *state, struct Menu *menu)
Initilise a browser state.
Definition: browser.c:654
bool inferiors
Definition: browser.h:77
short SortBrowser
Config: Sort method for the browser.
Definition: browser.c:82
static const struct Mapping FolderHelp[]
Definition: browser.c:85
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:285
enum MailboxType mx_path_probe(const char *path, struct stat *st)
Find a mailbox that understands a path.
Definition: mx.c:1438
static struct Mapping FolderNewsHelp[]
Definition: browser.c:95
bool imap_browse
Definition: browser.h:96
#define SORT_MASK
Mask for the sort id.
Definition: sort.h:77
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:42
char delim
Definition: browser.h:73
char * help
quickref for the current menu
Definition: menu.h:59
struct NntpMboxData * mutt_newsgroup_subscribe(struct NntpAccountData *adata, char *group)
Subscribe newsgroup.
Definition: newsrc.c:1232
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:612
struct FolderFile * entry
Definition: browser.h:92
#define REGCOMP(X, Y, Z)
Compile a regular expression.
Definition: regex3.h:52
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:80
int imap_subscribe(char *path, bool subscribe)
Subscribe to a mailbox.
Definition: imap.c:1391
void mutt_get_parent_path(char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition: muttlib.c:1573
int cs_str_native_set(const struct ConfigSet *cs, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: set.c:800
#define SORT_ORDER
Sort by the order the messages appear in the mailbox.
Definition: sort.h:50

+ Here is the caller graph for this function:

Variable Documentation

bool BrowserAbbreviateMailboxes

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

Definition at line 77 of file browser.c.

char* FolderFormat

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

Definition at line 78 of file browser.c.

char* GroupIndexFormat

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

Definition at line 79 of file browser.c.

char* NewsgroupsCharset

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

Definition at line 80 of file browser.c.

bool ShowOnlyUnread

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

Definition at line 81 of file browser.c.

short SortBrowser

Config: Sort method for the browser.

Definition at line 82 of file browser.c.

char* VfolderFormat

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

Definition at line 83 of file browser.c.

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 85 of file browser.c.

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 95 of file browser.c.

char OldLastDir[PATH_MAX] = ""
static

Definition at line 107 of file browser.c.

char LastDir[PATH_MAX] = ""
static

Definition at line 108 of file browser.c.