NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
browser.c File Reference

File/Mailbox Browser Dialog. More...

#include "config.h"
#include <dirent.h>
#include <errno.h>
#include <grp.h>
#include <limits.h>
#include <locale.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "browser.h"
#include "menu/lib.h"
#include "question/lib.h"
#include "send/lib.h"
#include "format_flags.h"
#include "mutt_attach.h"
#include "mutt_globals.h"
#include "mutt_mailbox.h"
#include "muttlib.h"
#include "mx.h"
#include "opcodes.h"
#include "options.h"
#include "imap/lib.h"
#include "nntp/lib.h"
#include "nntp/adata.h"
#include "nntp/mdata.h"
+ Include dependency graph for browser.c:

Go to the source code of this file.

Functions

static void init_lastdir (void)
 Initialise the browser directories. More...
 
void mutt_browser_cleanup (void)
 Clean up working Buffers. More...
 
static void destroy_state (struct BrowserState *state)
 Free the BrowserState. More...
 
static int browser_compare_subject (const void *a, const void *b)
 Compare the subject of two browser entries - Implements sort_t. More...
 
static int browser_compare_order (const void *a, const void *b)
 Compare the order of creation of two browser entries - Implements sort_t. More...
 
static int browser_compare_desc (const void *a, const void *b)
 Compare the descriptions of two browser entries - Implements sort_t. More...
 
static int browser_compare_date (const void *a, const void *b)
 Compare the date of two browser entries - Implements sort_t. More...
 
static int browser_compare_size (const void *a, const void *b)
 Compare the size of two browser entries - Implements sort_t. More...
 
static int browser_compare_count (const void *a, const void *b)
 Compare the message count of two browser entries - Implements sort_t. More...
 
static int browser_compare_count_new (const void *a, const void *b)
 Compare the new count of two browser entries - Implements sort_t. More...
 
static int browser_compare (const void *a, const void *b)
 Sort the items in the browser - Implements sort_t. More...
 
static void browser_sort (struct BrowserState *state)
 Sort the entries in the browser. More...
 
static bool link_is_dir (const char *folder, const char *path)
 Does this symlink point to a directory? More...
 
static const char * folder_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the folder browser - Implements format_t -
Expando Description
%C Current file number
%d Date/time folder was last modified
%D Date/time folder was last modified using `$date_format.
More...
 
static void add_folder (struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *s, struct Mailbox *m, void *data)
 Add a folder to the browser list. More...
 
static void init_state (struct BrowserState *state, struct Menu *menu)
 Initialise a browser state. More...
 
static int examine_directory (struct Mailbox *m, struct Menu *menu, struct BrowserState *state, const char *d, const char *prefix)
 Get list of all files/newsgroups with mask. More...
 
static int examine_mailboxes (struct Mailbox *m, struct Menu *menu, struct BrowserState *state)
 Get list of mailboxes/subscribed newsgroups. More...
 
static int select_file_search (struct Menu *menu, regex_t *rx, int line)
 Menu search callback for matching files - Implements Menu::search() -. More...
 
static void folder_make_entry (struct Menu *menu, char *buf, size_t buflen, int line)
 Format a menu item for the folder browser - Implements Menu::make_entry() -. More...
 
static void browser_highlight_default (struct BrowserState *state, struct Menu *menu)
 Decide which browser item should be highlighted. More...
 
static void init_menu (struct BrowserState *state, struct Menu *menu, struct Mailbox *m, struct MuttWindow *sbar)
 Set up a new menu. More...
 
static int file_tag (struct Menu *menu, int sel, int act)
 Tag an entry in the menu - Implements Menu::tag() -. More...
 
static int browser_config_observer (struct NotifyCallback *nc)
 Notification that a Config Variable has changed - Implements observer_t. More...
 
static int browser_window_observer (struct NotifyCallback *nc)
 Notification that a Window has changed - Implements observer_t. More...
 
void mutt_browser_select_dir (const char *f)
 Remember the last directory selected. More...
 
void mutt_buffer_select_file (struct Buffer *file, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
 Let the user select a file. More...
 
void mutt_select_file (char *file, size_t filelen, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
 Let the user select a file. More...
 

Variables

static const struct Mapping FolderHelp []
 Help Bar for the File/Dir/Mailbox browser dialog. More...
 
static const struct Mapping FolderNewsHelp []
 Help Bar for the NNTP Mailbox browser dialog. More...
 
static struct Buffer LastDir = { 0 }
 
static struct Buffer LastDirBackup = { 0 }
 

Detailed Description

File/Mailbox Browser Dialog.

Authors
  • Michael R. Elkins
  • R Primus

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

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

Definition in file browser.c.

Function Documentation

◆ init_lastdir()

static void init_lastdir ( void  )
static

Initialise the browser directories.

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

Definition at line 146 of file browser.c.

147 {
148  static bool done = false;
149  if (!done)
150  {
153  done = true;
154  }
155 }
static struct Buffer LastDirBackup
Definition: browser.c:139
#define PATH_MAX
Definition: mutt.h:40
static struct Buffer LastDir
Definition: browser.c:138
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_browser_cleanup()

void mutt_browser_cleanup ( void  )

Clean up working Buffers.

Definition at line 160 of file browser.c.

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

◆ destroy_state()

static void destroy_state ( struct BrowserState state)
static

Free the BrowserState.

Parameters
stateState to free

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

Definition at line 172 of file browser.c.

173 {
174  struct FolderFile *ff = NULL;
175  ARRAY_FOREACH(ff, &state->entry)
176  {
177  FREE(&ff->name);
178  FREE(&ff->desc);
179  }
180  ARRAY_FREE(&state->entry);
181 
182 #ifdef USE_IMAP
183  FREE(&state->folder);
184 #endif
185 }
char * desc
Definition: browser.h:63
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:198
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
struct BrowserStateEntry entry
Definition: browser.h:93
char * folder
Definition: browser.h:96
char * name
Definition: browser.h:62
Browser entry representing a folder/dir.
Definition: browser.h:53
#define FREE(x)
Definition: memory.h:40
+ Here is the caller graph for this function:

◆ browser_compare_subject()

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

Compare the subject of two browser entries - Implements sort_t.

Definition at line 190 of file browser.c.

191 {
192  const struct FolderFile *pa = (const struct FolderFile *) a;
193  const struct FolderFile *pb = (const struct FolderFile *) b;
194 
195  /* inbox should be sorted ahead of its siblings */
196  int r = mutt_inbox_cmp(pa->name, pb->name);
197  if (r == 0)
198  r = mutt_str_coll(pa->name, pb->name);
199  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
200  return (c_sort_browser & SORT_REVERSE) ? -r : r;
201 }
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:677
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * name
Definition: browser.h:62
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Browser entry representing a folder/dir.
Definition: browser.h:53
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:1611
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_order()

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

Compare the order of creation of two browser entries - Implements sort_t.

Note
This only affects browsing mailboxes and is a no-op for folders.

Definition at line 208 of file browser.c.

209 {
210  const struct FolderFile *pa = (const struct FolderFile *) a;
211  const struct FolderFile *pb = (const struct FolderFile *) b;
212 
213  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
214  return ((c_sort_browser & SORT_REVERSE) ? -1 : 1) * (pa->gen - pb->gen);
215 }
int gen
Definition: browser.h:83
Container for Accounts, Notifications.
Definition: neomutt.h:36
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Browser entry representing a folder/dir.
Definition: browser.h:53
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_desc()

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

Compare the descriptions of two browser entries - Implements sort_t.

Definition at line 220 of file browser.c.

221 {
222  const struct FolderFile *pa = (const struct FolderFile *) a;
223  const struct FolderFile *pb = (const struct FolderFile *) b;
224 
225  int r = mutt_str_coll(pa->desc, pb->desc);
226 
227  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
228  return (c_sort_browser & SORT_REVERSE) ? -r : r;
229 }
char * desc
Definition: browser.h:63
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:677
Container for Accounts, Notifications.
Definition: neomutt.h:36
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Browser entry representing a folder/dir.
Definition: browser.h:53
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_date()

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

Compare the date of two browser entries - Implements sort_t.

Definition at line 234 of file browser.c.

235 {
236  const struct FolderFile *pa = (const struct FolderFile *) a;
237  const struct FolderFile *pb = (const struct FolderFile *) b;
238 
239  int r = pa->mtime - pb->mtime;
240 
241  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
242  return (c_sort_browser & SORT_REVERSE) ? -r : r;
243 }
time_t mtime
Definition: browser.h:57
Container for Accounts, Notifications.
Definition: neomutt.h:36
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Browser entry representing a folder/dir.
Definition: browser.h:53
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_size()

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

Compare the size of two browser entries - Implements sort_t.

Definition at line 248 of file browser.c.

249 {
250  const struct FolderFile *pa = (const struct FolderFile *) a;
251  const struct FolderFile *pb = (const struct FolderFile *) b;
252 
253  int r = pa->size - pb->size;
254 
255  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
256  return (c_sort_browser & SORT_REVERSE) ? -r : r;
257 }
Container for Accounts, Notifications.
Definition: neomutt.h:36
off_t size
Definition: browser.h:56
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Browser entry representing a folder/dir.
Definition: browser.h:53
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_count()

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

Compare the message count of two browser entries - Implements sort_t.

Definition at line 262 of file browser.c.

263 {
264  const struct FolderFile *pa = (const struct FolderFile *) a;
265  const struct FolderFile *pb = (const struct FolderFile *) b;
266 
267  int r = 0;
268  if (pa->has_mailbox && pb->has_mailbox)
269  r = pa->msg_count - pb->msg_count;
270  else if (pa->has_mailbox)
271  r = -1;
272  else
273  r = 1;
274 
275  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
276  return (c_sort_browser & SORT_REVERSE) ? -r : r;
277 }
bool has_mailbox
Definition: browser.h:76
Container for Accounts, Notifications.
Definition: neomutt.h:36
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Browser entry representing a folder/dir.
Definition: browser.h:53
int msg_count
total number of messages
Definition: browser.h:66
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_count_new()

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

Compare the new count of two browser entries - Implements sort_t.

Definition at line 282 of file browser.c.

283 {
284  const struct FolderFile *pa = (const struct FolderFile *) a;
285  const struct FolderFile *pb = (const struct FolderFile *) b;
286 
287  int r = 0;
288  if (pa->has_mailbox && pb->has_mailbox)
289  r = pa->msg_unread - pb->msg_unread;
290  else if (pa->has_mailbox)
291  r = -1;
292  else
293  r = 1;
294 
295  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
296  return (c_sort_browser & SORT_REVERSE) ? -r : r;
297 }
int msg_unread
number of unread messages
Definition: browser.h:67
bool has_mailbox
Definition: browser.h:76
Container for Accounts, Notifications.
Definition: neomutt.h:36
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Browser entry representing a folder/dir.
Definition: browser.h:53
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare()

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

Sort the items in the browser - Implements sort_t.

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

307 {
308  const struct FolderFile *pa = (const struct FolderFile *) a;
309  const struct FolderFile *pb = (const struct FolderFile *) b;
310 
311  if ((mutt_str_coll(pa->desc, "../") == 0) || (mutt_str_coll(pa->desc, "..") == 0))
312  return -1;
313  if ((mutt_str_coll(pb->desc, "../") == 0) || (mutt_str_coll(pb->desc, "..") == 0))
314  return 1;
315 
316  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
317  switch (c_sort_browser & SORT_MASK)
318  {
319  case SORT_COUNT:
320  return browser_compare_count(a, b);
321  case SORT_DATE:
322  return browser_compare_date(a, b);
323  case SORT_DESC:
324  return browser_compare_desc(a, b);
325  case SORT_SIZE:
326  return browser_compare_size(a, b);
327  case SORT_UNREAD:
328  return browser_compare_count_new(a, b);
329  case SORT_SUBJECT:
330  return browser_compare_subject(a, b);
331  default:
332  case SORT_ORDER:
333  return browser_compare_order(a, b);
334  }
335 }
static int browser_compare_date(const void *a, const void *b)
Compare the date of two browser entries - Implements sort_t.
Definition: browser.c:234
char * desc
Definition: browser.h:63
static int browser_compare_order(const void *a, const void *b)
Compare the order of creation of two browser entries - Implements sort_t.
Definition: browser.c:208
static int browser_compare_desc(const void *a, const void *b)
Compare the descriptions of two browser entries - Implements sort_t.
Definition: browser.c:220
static int browser_compare_count(const void *a, const void *b)
Compare the message count of two browser entries - Implements sort_t.
Definition: browser.c:262
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:677
Container for Accounts, Notifications.
Definition: neomutt.h:36
Sort by the size of the email.
Definition: sort2.h:44
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:48
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Browser entry representing a folder/dir.
Definition: browser.h:53
static int browser_compare_count_new(const void *a, const void *b)
Compare the new count of two browser entries - Implements sort_t.
Definition: browser.c:282
static int browser_compare_size(const void *a, const void *b)
Compare the size of two browser entries - Implements sort_t.
Definition: browser.c:248
static int browser_compare_subject(const void *a, const void *b)
Compare the subject of two browser entries - Implements sort_t.
Definition: browser.c:190
Sort by the number of unread emails.
Definition: sort2.h:59
Sort by the folder&#39;s description.
Definition: sort2.h:63
Sort by number of emails in a folder.
Definition: sort2.h:58
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Sort by the date the email was sent.
Definition: sort2.h:43
Sort by the email&#39;s subject.
Definition: sort2.h:46
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_sort()

static void browser_sort ( struct BrowserState state)
static

Sort the entries in the browser.

Parameters
stateBrowser state

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

Definition at line 344 of file browser.c.

345 {
346  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
347  switch (c_sort_browser & SORT_MASK)
348  {
349 #ifdef USE_NNTP
350  case SORT_SIZE:
351  case SORT_DATE:
352  if (OptNews)
353  return;
354 #endif
355  default:
356  break;
357  }
358 
359  ARRAY_SORT(&state->entry, browser_compare);
360 }
struct BrowserStateEntry entry
Definition: browser.h:93
Container for Accounts, Notifications.
Definition: neomutt.h:36
Sort by the size of the email.
Definition: sort2.h:44
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
#define ARRAY_SORT(head, fn)
Sort an array.
Definition: array.h:271
static int browser_compare(const void *a, const void *b)
Sort the items in the browser - Implements sort_t.
Definition: browser.c:306
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Sort by the date the email was sent.
Definition: sort2.h:43
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:44
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ link_is_dir()

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

Does this symlink point to a directory?

Parameters
folderFolder
pathLink name
Return values
trueLinks to a directory
falseOtherwise

Definition at line 369 of file browser.c.

370 {
371  struct stat st;
372  bool retval = false;
373 
374  struct Buffer *fullpath = mutt_buffer_pool_get();
375  mutt_buffer_concat_path(fullpath, folder, path);
376 
377  if (stat(mutt_buffer_string(fullpath), &st) == 0)
378  retval = S_ISDIR(st.st_mode);
379 
380  mutt_buffer_pool_release(&fullpath);
381 
382  return retval;
383 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_folder()

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

Add a folder to the browser list.

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

Definition at line 662 of file browser.c.

665 {
666  if ((!menu || state->is_mailbox_list) && m && (m->flags & MB_HIDDEN))
667  {
668  return;
669  }
670 
671  struct FolderFile ff = { 0 };
672 
673  if (s)
674  {
675  ff.mode = s->st_mode;
676  ff.mtime = s->st_mtime;
677  ff.size = s->st_size;
678  ff.gid = s->st_gid;
679  ff.uid = s->st_uid;
680  ff.nlink = s->st_nlink;
681  ff.local = true;
682  }
683  else
684  ff.local = false;
685 
686  if (m)
687  {
688  ff.has_mailbox = true;
689  ff.gen = m->gen;
690  ff.has_new_mail = m->has_new;
691  ff.msg_count = m->msg_count;
692  ff.msg_unread = m->msg_unread;
693  }
694 
695  ff.name = mutt_str_dup(name);
696  ff.desc = mutt_str_dup(desc ? desc : name);
697 #ifdef USE_IMAP
698  ff.imap = false;
699 #endif
700 #ifdef USE_NNTP
701  if (OptNews)
702  ff.nd = data;
703 #endif
704 
705  ARRAY_ADD(&state->entry, ff);
706 }
int msg_unread
number of unread messages
Definition: browser.h:67
mode_t mode
Definition: browser.h:55
time_t mtime
Definition: browser.h:57
bool has_mailbox
Definition: browser.h:76
int msg_count
Total number of messages.
Definition: mailbox.h:91
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
char * desc
Definition: browser.h:63
gid_t gid
Definition: browser.h:59
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
struct BrowserStateEntry entry
Definition: browser.h:93
int gen
Definition: browser.h:83
off_t size
Definition: browser.h:56
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
uid_t uid
Definition: browser.h:58
nlink_t nlink
Definition: browser.h:60
char * name
Definition: browser.h:62
bool imap
Definition: browser.h:72
Browser entry representing a folder/dir.
Definition: browser.h:53
#define MB_HIDDEN
Definition: mailbox.h:38
int msg_count
total number of messages
Definition: browser.h:66
uint8_t flags
e.g. MB_NORMAL
Definition: mailbox.h:134
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition: array.h:152
struct NntpMboxData * nd
Definition: browser.h:80
bool local
folder is on local filesystem
Definition: browser.h:77
bool is_mailbox_list
Definition: browser.h:98
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:44
int gen
Generation number, for sorting.
Definition: mailbox.h:150
bool has_new_mail
true if mailbox has "new mail"
Definition: browser.h:65
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_state()

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

Initialise a browser state.

Parameters
stateBrowserState to initialise
menuCurrent menu

Definition at line 713 of file browser.c.

714 {
715  ARRAY_INIT(&state->entry);
716  ARRAY_RESERVE(&state->entry, 256);
717 #ifdef USE_IMAP
718  state->imap_browse = false;
719 #endif
720  if (menu)
721  menu->mdata = &state->entry;
722 }
#define ARRAY_RESERVE(head, num)
Reserve memory for the array.
Definition: array.h:185
struct BrowserStateEntry entry
Definition: browser.h:93
void * mdata
Private data.
Definition: lib.h:155
bool imap_browse
Definition: browser.h:95
#define ARRAY_INIT(head)
Initialize an array.
Definition: array.h:61
+ Here is the caller graph for this function:

◆ examine_directory()

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

Get list of all files/newsgroups with mask.

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

Definition at line 734 of file browser.c.

736 {
737  int rc = -1;
738  struct Buffer *buf = mutt_buffer_pool_get();
739 #ifdef USE_NNTP
740  if (OptNews)
741  {
743 
744  init_state(state, menu);
745 
746  for (unsigned int i = 0; i < adata->groups_num; i++)
747  {
748  struct NntpMboxData *mdata = adata->groups_list[i];
749  if (!mdata)
750  continue;
751  if (prefix && *prefix && !mutt_str_startswith(mdata->group, prefix))
752  continue;
753  const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
754  if (!mutt_regex_match(c_mask, mdata->group))
755  {
756  continue;
757  }
758  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
759  }
760  }
761  else
762 #endif /* USE_NNTP */
763  {
764  struct stat s;
765  DIR *dp = NULL;
766  struct dirent *de = NULL;
767 
768  while (stat(d, &s) == -1)
769  {
770  if (errno == ENOENT)
771  {
772  /* The last used directory is deleted, try to use the parent dir. */
773  char *c = strrchr(d, '/');
774 
775  if (c && (c > d))
776  {
777  *c = '\0';
778  continue;
779  }
780  }
781  mutt_perror(d);
782  goto ed_out;
783  }
784 
785  if (!S_ISDIR(s.st_mode))
786  {
787  mutt_error(_("%s is not a directory"), d);
788  goto ed_out;
789  }
790 
791  if (m)
792  mutt_mailbox_check(m, 0);
793 
794  dp = opendir(d);
795  if (!dp)
796  {
797  mutt_perror(d);
798  goto ed_out;
799  }
800 
801  init_state(state, menu);
802 
803  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
805  while ((de = readdir(dp)))
806  {
807  if (mutt_str_equal(de->d_name, "."))
808  continue; /* we don't need . */
809 
810  if (prefix && *prefix && !mutt_str_startswith(de->d_name, prefix))
811  {
812  continue;
813  }
814  const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
815  if (!mutt_regex_match(c_mask, de->d_name))
816  {
817  continue;
818  }
819 
820  mutt_buffer_concat_path(buf, d, de->d_name);
821  if (lstat(mutt_buffer_string(buf), &s) == -1)
822  continue;
823 
824  /* No size for directories or symlinks */
825  if (S_ISDIR(s.st_mode) || S_ISLNK(s.st_mode))
826  s.st_size = 0;
827  else if (!S_ISREG(s.st_mode))
828  continue;
829 
830  struct MailboxNode *np = NULL;
831  STAILQ_FOREACH(np, &ml, entries)
832  {
834  break;
835  }
836 
837  if (np && m && mutt_str_equal(np->mailbox->realpath, m->realpath))
838  {
839  np->mailbox->msg_count = m->msg_count;
840  np->mailbox->msg_unread = m->msg_unread;
841  }
842  add_folder(menu, state, de->d_name, NULL, &s, np ? np->mailbox : NULL, NULL);
843  }
845  closedir(dp);
846  }
847  browser_sort(state);
848  rc = 0;
849 ed_out:
851  return rc;
852 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
int msg_count
Total number of messages.
Definition: mailbox.h:91
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
#define mutt_error(...)
Definition: logging.h:88
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:141
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
Match any Mailbox type.
Definition: mailbox.h:45
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:164
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:662
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
#define mutt_perror(...)
Definition: logging.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:36
NNTP-specific Account data -.
Definition: adata.h:36
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition: helpers.c:243
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:137
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int groups_num
Definition: adata.h:59
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:344
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
NNTP-specific Mailbox data -.
Definition: mdata.h:32
Cached regular expression.
Definition: regex3.h:89
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:613
void ** groups_list
Definition: adata.h:61
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:78
List of Mailboxes.
Definition: mailbox.h:156
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:713
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:44
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:158
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ examine_mailboxes()

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

Get list of mailboxes/subscribed newsgroups.

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

Definition at line 862 of file browser.c.

863 {
864  struct stat s;
865  struct Buffer *md = NULL;
866  struct Buffer *mailbox = NULL;
867 
868 #ifdef USE_NNTP
869  if (OptNews)
870  {
872 
873  init_state(state, menu);
874 
875  for (unsigned int i = 0; i < adata->groups_num; i++)
876  {
877  const bool c_show_only_unread =
878  cs_subset_bool(NeoMutt->sub, "show_only_unread");
879  struct NntpMboxData *mdata = adata->groups_list[i];
880  if (mdata && (mdata->has_new_mail ||
881  (mdata->subscribed && (mdata->unread || !c_show_only_unread))))
882  {
883  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
884  }
885  }
886  }
887  else
888 #endif
889  {
890  init_state(state, menu);
891 
893  return -1;
894  mailbox = mutt_buffer_pool_get();
895  md = mutt_buffer_pool_get();
896 
897  mutt_mailbox_check(m, 0);
898 
899  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
901  struct MailboxNode *np = NULL;
902  STAILQ_FOREACH(np, &ml, entries)
903  {
904  if (!np->mailbox)
905  continue;
906 
907  if (m && mutt_str_equal(np->mailbox->realpath, m->realpath))
908  {
909  np->mailbox->msg_count = m->msg_count;
910  np->mailbox->msg_unread = m->msg_unread;
911  }
912 
913  mutt_buffer_strcpy(mailbox, mailbox_path(np->mailbox));
914  const bool c_browser_abbreviate_mailboxes =
915  cs_subset_bool(NeoMutt->sub, "browser_abbreviate_mailboxes");
916  if (c_browser_abbreviate_mailboxes)
918 
919  switch (np->mailbox->type)
920  {
921  case MUTT_IMAP:
922  case MUTT_POP:
923  add_folder(menu, state, mutt_buffer_string(mailbox),
924  np->mailbox->name, NULL, np->mailbox, NULL);
925  continue;
926  case MUTT_NOTMUCH:
927  case MUTT_NNTP:
928  add_folder(menu, state, mailbox_path(np->mailbox), np->mailbox->name,
929  NULL, np->mailbox, NULL);
930  continue;
931  default: /* Continue */
932  break;
933  }
934 
935  if (lstat(mailbox_path(np->mailbox), &s) == -1)
936  continue;
937 
938  if ((!S_ISREG(s.st_mode)) && (!S_ISDIR(s.st_mode)) && (!S_ISLNK(s.st_mode)))
939  continue;
940 
941  if (np->mailbox->type == MUTT_MAILDIR)
942  {
943  struct stat st2;
944 
945  mutt_buffer_printf(md, "%s/new", mailbox_path(np->mailbox));
946  if (stat(mutt_buffer_string(md), &s) < 0)
947  s.st_mtime = 0;
948  mutt_buffer_printf(md, "%s/cur", mailbox_path(np->mailbox));
949  if (stat(mutt_buffer_string(md), &st2) < 0)
950  st2.st_mtime = 0;
951  if (st2.st_mtime > s.st_mtime)
952  s.st_mtime = st2.st_mtime;
953  }
954 
955  add_folder(menu, state, mutt_buffer_string(mailbox), np->mailbox->name,
956  &s, np->mailbox, NULL);
957  }
959  }
960  browser_sort(state);
961 
962  mutt_buffer_pool_release(&mailbox);
964  return 0;
965 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
bool has_new_mail
Definition: mdata.h:42
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:141
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
Match any Mailbox type.
Definition: mailbox.h:45
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:164
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:662
String manipulation buffer.
Definition: buffer.h:33
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:603
NNTP-specific Account data -.
Definition: adata.h:36
bool subscribed
Definition: mdata.h:41
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
char * group
Definition: mdata.h:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:137
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int groups_num
Definition: adata.h:59
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:344
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
NNTP-specific Mailbox data -.
Definition: mdata.h:32
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
anum_t unread
Definition: mdata.h:40
void ** groups_list
Definition: adata.h:61
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:78
List of Mailboxes.
Definition: mailbox.h:156
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define TAILQ_EMPTY(head)
Definition: queue.h:721
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:713
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:44
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:158
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_highlight_default()

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

Decide which browser item should be highlighted.

Parameters
stateBrowser state
menuCurrent Menu

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

Definition at line 1021 of file browser.c.

1022 {
1023  menu->top = 0;
1024  /* Reset menu position to 1.
1025  * We do not risk overflow as the init_menu function changes
1026  * current if it is bigger than state->entrylen. */
1027  if (!ARRAY_EMPTY(&state->entry) &&
1028  (mutt_str_equal(ARRAY_FIRST(&state->entry)->desc, "..") ||
1029  mutt_str_equal(ARRAY_FIRST(&state->entry)->desc, "../")))
1030  {
1031  /* Skip the first entry, unless there's only one entry. */
1032  menu_set_index(menu, (menu->max > 1));
1033  }
1034  else
1035  {
1036  menu_set_index(menu, 0);
1037  }
1038 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
#define ARRAY_FIRST(head)
Convenience method to get the first element.
Definition: array.h:131
struct BrowserStateEntry entry
Definition: browser.h:93
int top
Entry that is the top of the current page.
Definition: lib.h:89
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:70
int max
Number of entries in the menu.
Definition: lib.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_menu()

static void init_menu ( struct BrowserState state,
struct Menu menu,
struct Mailbox m,
struct MuttWindow sbar 
)
static

Set up a new menu.

Parameters
stateBrowser state
menuCurrent menu
mMailbox
sbarStatus bar

Definition at line 1047 of file browser.c.

1049 {
1050  char title[256] = { 0 };
1051  menu->max = ARRAY_SIZE(&state->entry);
1052 
1053  int index = menu_get_index(menu);
1054  if (index >= menu->max)
1055  menu_set_index(menu, menu->max - 1);
1056  if (index < 0)
1057  menu_set_index(menu, 0);
1058  if (menu->top > index)
1059  menu->top = 0;
1060 
1061  menu->tagged = 0;
1062 
1063 #ifdef USE_NNTP
1064  if (OptNews)
1065  {
1066  if (state->is_mailbox_list)
1067  snprintf(title, sizeof(title), _("Subscribed newsgroups"));
1068  else
1069  {
1070  snprintf(title, sizeof(title), _("Newsgroups on server [%s]"),
1072  }
1073  }
1074  else
1075 #endif
1076  {
1077  if (state->is_mailbox_list)
1078  {
1079  snprintf(title, sizeof(title), _("Mailboxes [%d]"), mutt_mailbox_check(m, 0));
1080  }
1081  else
1082  {
1083  struct Buffer *path = mutt_buffer_pool_get();
1084  mutt_buffer_copy(path, &LastDir);
1086  const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
1087 #ifdef USE_IMAP
1088  const bool c_imap_list_subscribed =
1089  cs_subset_bool(NeoMutt->sub, "imap_list_subscribed");
1090  if (state->imap_browse && c_imap_list_subscribed)
1091  {
1092  snprintf(title, sizeof(title), _("Subscribed [%s], File mask: %s"),
1093  mutt_buffer_string(path), NONULL(c_mask ? c_mask->pattern : NULL));
1094  }
1095  else
1096 #endif
1097  {
1098  snprintf(title, sizeof(title), _("Directory [%s], File mask: %s"),
1099  mutt_buffer_string(path), NONULL(c_mask ? c_mask->pattern : NULL));
1100  }
1101  mutt_buffer_pool_release(&path);
1102  }
1103  }
1104  sbar_set_title(sbar, title);
1105 
1106  /* Browser tracking feature.
1107  * The goal is to highlight the good directory if LastDir is the parent dir
1108  * of LastDirBackup (this occurs mostly when one hit "../"). It should also work
1109  * properly when the user is in examine_mailboxes-mode. */
1111  {
1112  char target_dir[PATH_MAX] = { 0 };
1113 
1114 #ifdef USE_IMAP
1115  /* Check what kind of dir LastDirBackup is. */
1117  {
1118  mutt_str_copy(target_dir, mutt_buffer_string(&LastDirBackup), sizeof(target_dir));
1119  imap_clean_path(target_dir, sizeof(target_dir));
1120  }
1121  else
1122 #endif
1123  mutt_str_copy(target_dir, strrchr(mutt_buffer_string(&LastDirBackup), '/') + 1,
1124  sizeof(target_dir));
1125 
1126  /* If we get here, it means that LastDir is the parent directory of
1127  * LastDirBackup. I.e., we're returning from a subdirectory, and we want
1128  * to position the cursor on the directory we're returning from. */
1129  bool matched = false;
1130  struct FolderFile *ff = NULL;
1131  ARRAY_FOREACH(ff, &state->entry)
1132  {
1133  if (mutt_str_equal(ff->name, target_dir))
1134  {
1135  menu_set_index(menu, ARRAY_FOREACH_IDX);
1136  matched = true;
1137  break;
1138  }
1139  }
1140  if (!matched)
1141  browser_highlight_default(state, menu);
1142  }
1143  else
1144  browser_highlight_default(state, menu);
1145 
1147 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
#define NONULL(x)
Definition: string2.h:37
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
struct BrowserStateEntry entry
Definition: browser.h:93
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:603
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
char host[128]
Server to login to.
Definition: connaccount.h:53
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition: helpers.c:243
static struct Buffer LastDirBackup
Definition: browser.c:139
char * name
Definition: browser.h:62
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2402
Browser entry representing a folder/dir.
Definition: browser.h:53
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
#define PATH_MAX
Definition: mutt.h:40
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:137
int top
Entry that is the top of the current page.
Definition: lib.h:89
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:221
int tagged
Number of tagged entries.
Definition: lib.h:92
int max
Number of entries in the menu.
Definition: lib.h:71
struct Connection * conn
Definition: adata.h:63
static void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: browser.c:1021
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
void imap_clean_path(char *path, size_t plen)
Cleans an IMAP path using imap_fix_path.
Definition: util.c:188
Cached regular expression.
Definition: regex3.h:89
static struct Buffer LastDir
Definition: browser.c:138
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:78
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
char * pattern
printable version
Definition: regex3.h:91
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
bool imap_browse
Definition: browser.h:95
bool is_mailbox_list
Definition: browser.h:98
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:44
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_config_observer()

static int browser_config_observer ( struct NotifyCallback nc)
static

Notification that a Config Variable has changed - Implements observer_t.

Definition at line 1172 of file browser.c.

1173 {
1174  if ((nc->event_type != NT_CONFIG) || !nc->global_data || !nc->event_data)
1175  return -1;
1176 
1177  struct EventConfig *ev_c = nc->event_data;
1178 
1179  if (!mutt_str_equal(ev_c->name, "browser_abbreviate_mailboxes") &&
1180  !mutt_str_equal(ev_c->name, "date_format") && !mutt_str_equal(ev_c->name, "folder") &&
1181  !mutt_str_equal(ev_c->name, "folder_format") &&
1182  !mutt_str_equal(ev_c->name, "group_index_format") &&
1183  !mutt_str_equal(ev_c->name, "sort_browser"))
1184  {
1185  return 0;
1186  }
1187 
1188  struct Menu *menu = nc->global_data;
1190  mutt_debug(LL_DEBUG5, "config done, request WA_RECALC, MENU_REDRAW_FULL\n");
1191 
1192  return 0;
1193 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
Definition: lib.h:67
A config-change event.
Definition: subset.h:69
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void * event_data
Data from notify_send()
Definition: observer.h:44
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
Log at debug level 5.
Definition: logging.h:44
const char * name
Name of config item that changed.
Definition: subset.h:72
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_window_observer()

static int browser_window_observer ( struct NotifyCallback nc)
static

Notification that a Window has changed - Implements observer_t.

This function is triggered by changes to the windows.

  • Delete (this window): clean up the resources held by the Help Bar

Definition at line 1202 of file browser.c.

1203 {
1204  if ((nc->event_type != NT_WINDOW) || !nc->global_data || !nc->event_data)
1205  return -1;
1206 
1207  if (nc->event_subtype != NT_WINDOW_DELETE)
1208  return 0;
1209 
1210  struct MuttWindow *win_menu = nc->global_data;
1211  struct EventWindow *ev_w = nc->event_data;
1212  if (ev_w->win != win_menu)
1213  return 0;
1214 
1215  struct Menu *menu = win_menu->wdata;
1216 
1219 
1220  mutt_debug(LL_DEBUG5, "window delete done\n");
1221  return 0;
1222 }
Definition: lib.h:67
struct MuttWindow * win
Window that changed.
Definition: mutt_window.h:217
An Event that happened to a Window.
Definition: mutt_window.h:215
Window is about to be deleted.
Definition: mutt_window.h:206
static int browser_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t.
Definition: browser.c:1202
Container for Accounts, Notifications.
Definition: neomutt.h:36
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
int event_subtype
Send: Event subtype, e.g. NT_ACCOUNT_ADD.
Definition: observer.h:43
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
static int browser_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t.
Definition: browser.c:1172
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void * event_data
Data from notify_send()
Definition: observer.h:44
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:228
Log at debug level 5.
Definition: logging.h:44
void * wdata
Private data.
Definition: mutt_window.h:145
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_browser_select_dir()

void mutt_browser_select_dir ( const char *  f)

Remember the last directory selected.

Parameters
fDirectory name to save

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

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

Definition at line 1234 of file browser.c.

1235 {
1236  init_lastdir();
1237 
1239 
1240  /* Method that will fetch the parent path depending on the type of the path. */
1241  char buf[PATH_MAX];
1243  mutt_buffer_strcpy(&LastDir, buf);
1244 }
static void init_lastdir(void)
Initialise the browser directories.
Definition: browser.c:146
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
static struct Buffer LastDirBackup
Definition: browser.c:139
#define PATH_MAX
Definition: mutt.h:40
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
static struct Buffer LastDir
Definition: browser.c:138
void mutt_get_parent_path(const char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition: muttlib.c:1555
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_select_file()

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

Let the user select a file.

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

Definition at line 1254 of file browser.c.

1256 {
1257  struct BrowserState state = { { 0 } };
1258  struct Menu *menu = NULL;
1259  struct MuttWindow *dlg = NULL;
1260  bool kill_prefix = false;
1261  bool multiple = (flags & MUTT_SEL_MULTI);
1262  bool folder = (flags & MUTT_SEL_FOLDER);
1263  state.is_mailbox_list = (flags & MUTT_SEL_MAILBOX) && folder;
1264 
1265  /* Keeps in memory the directory we were in when hitting '='
1266  * to go directly to $folder (`$folder`) */
1267  char goto_swapper[PATH_MAX] = { 0 };
1268 
1269  struct Buffer *OldLastDir = mutt_buffer_pool_get();
1270  struct Buffer *tmp = mutt_buffer_pool_get();
1271  struct Buffer *buf = mutt_buffer_pool_get();
1272  struct Buffer *prefix = mutt_buffer_pool_get();
1273 
1274  init_lastdir();
1275 
1276 #ifdef USE_NNTP
1277  if (OptNews)
1278  {
1279  if (mutt_buffer_is_empty(file))
1280  {
1282 
1283  /* default state for news reader mode is browse subscribed newsgroups */
1284  state.is_mailbox_list = false;
1285  for (size_t i = 0; i < adata->groups_num; i++)
1286  {
1287  struct NntpMboxData *mdata = adata->groups_list[i];
1288  if (mdata && mdata->subscribed)
1289  {
1290  state.is_mailbox_list = true;
1291  break;
1292  }
1293  }
1294  }
1295  else
1296  {
1297  mutt_buffer_copy(prefix, file);
1298  }
1299  }
1300  else
1301 #endif
1302  if (!mutt_buffer_is_empty(file))
1303  {
1305 #ifdef USE_IMAP
1306  if (imap_path_probe(mutt_buffer_string(file), NULL) == MUTT_IMAP)
1307  {
1308  init_state(&state, NULL);
1309  state.imap_browse = true;
1310  if (imap_browse(mutt_buffer_string(file), &state) == 0)
1311  {
1313  browser_sort(&state);
1314  }
1315  }
1316  else
1317  {
1318 #endif
1319  int i;
1320  for (i = mutt_buffer_len(file) - 1;
1321  (i > 0) && ((mutt_buffer_string(file))[i] != '/'); i--)
1322  {
1323  ; // do nothing
1324  }
1325 
1326  if (i > 0)
1327  {
1328  if ((mutt_buffer_string(file))[0] == '/')
1330  else
1331  {
1333  mutt_buffer_addch(&LastDir, '/');
1335  }
1336  }
1337  else
1338  {
1339  if ((mutt_buffer_string(file))[0] == '/')
1340  mutt_buffer_strcpy(&LastDir, "/");
1341  else
1343  }
1344 
1345  if ((i <= 0) && (mutt_buffer_string(file)[0] != '/'))
1346  mutt_buffer_copy(prefix, file);
1347  else
1348  mutt_buffer_strcpy(prefix, mutt_buffer_string(file) + i + 1);
1349  kill_prefix = true;
1350 #ifdef USE_IMAP
1351  }
1352 #endif
1353  }
1354  else
1355  {
1356  if (!folder)
1358  else
1359  {
1360  /* Whether we use the tracking feature of the browser depends
1361  * on which sort method we chose to use. This variable is defined
1362  * only to help readability of the code. */
1363  bool browser_track = false;
1364 
1365  const short c_sort_browser = cs_subset_sort(NeoMutt->sub, "sort_browser");
1366  switch (c_sort_browser & SORT_MASK)
1367  {
1368  case SORT_DESC:
1369  case SORT_SUBJECT:
1370  case SORT_ORDER:
1371  browser_track = true;
1372  break;
1373  }
1374 
1375  /* We use mutt_browser_select_dir to initialize the two
1376  * variables (LastDir, LastDirBackup) at the appropriate
1377  * values.
1378  *
1379  * We do it only when LastDir is not set (first pass there)
1380  * or when CurrentFolder and LastDirBackup are not the same.
1381  * This code is executed only when we list files, not when
1382  * we press up/down keys to navigate in a displayed list.
1383  *
1384  * We only do this when CurrentFolder has been set (ie, not
1385  * when listing folders on startup with "neomutt -y").
1386  *
1387  * This tracker is only used when browser_track is true,
1388  * meaning only with sort methods SUBJECT/DESC for now. */
1389  if (CurrentFolder)
1390  {
1392  {
1393  /* If browsing in "local"-mode, than we chose to define LastDir to
1394  * MailDir */
1395  switch (mx_path_probe(CurrentFolder))
1396  {
1397  case MUTT_IMAP:
1398  case MUTT_MAILDIR:
1399  case MUTT_MBOX:
1400  case MUTT_MH:
1401  case MUTT_MMDF:
1402  {
1403  const char *const c_folder =
1404  cs_subset_string(NeoMutt->sub, "folder");
1405  const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
1406  if (c_folder)
1407  mutt_buffer_strcpy(&LastDir, c_folder);
1408  else if (c_spool_file)
1409  mutt_browser_select_dir(c_spool_file);
1410  break;
1411  }
1412  default:
1414  break;
1415  }
1416  }
1418  {
1420  }
1421  }
1422 
1423  /* When browser tracking feature is disabled, clear LastDirBackup */
1424  if (!browser_track)
1426  }
1427 
1428 #ifdef USE_IMAP
1429  if (!state.is_mailbox_list &&
1431  {
1432  init_state(&state, NULL);
1433  state.imap_browse = true;
1435  browser_sort(&state);
1436  }
1437  else
1438 #endif
1439  {
1440  size_t i = mutt_buffer_len(&LastDir);
1441  while ((i > 0) && (mutt_buffer_string(&LastDir)[--i] == '/'))
1442  LastDir.data[i] = '\0';
1446  }
1447  }
1448 
1449  mutt_buffer_reset(file);
1450 
1451  const struct Mapping *help_data = NULL;
1452 #ifdef USE_NNTP
1453  if (OptNews)
1454  help_data = FolderNewsHelp;
1455  else
1456 #endif
1457  help_data = FolderHelp;
1458 
1459  dlg = simple_dialog_new(MENU_FOLDER, WT_DLG_BROWSER, help_data);
1460 
1461  menu = dlg->wdata;
1462  menu->make_entry = folder_make_entry;
1463  menu->search = select_file_search;
1464  if (multiple)
1465  menu->tag = file_tag;
1466 
1467  struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
1468 
1469  struct MuttWindow *win_menu = menu->win;
1470 
1471  // NT_COLOR is handled by the SimpleDialog
1474 
1475  if (state.is_mailbox_list)
1476  {
1477  examine_mailboxes(m, NULL, &state);
1478  }
1479  else
1480 #ifdef USE_IMAP
1481  if (!state.imap_browse)
1482 #endif
1483  {
1484  // examine_directory() calls add_folder() which needs the menu
1485  if (examine_directory(m, menu, &state, mutt_buffer_string(&LastDir),
1486  mutt_buffer_string(prefix)) == -1)
1487  {
1488  goto bail;
1489  }
1490  }
1491 
1492  init_menu(&state, menu, m, sbar);
1493  // only now do we have a valid state to attach
1494  menu->mdata = &state.entry;
1495 
1496  int last_selected_mailbox = -1;
1497 
1498  while (true)
1499  {
1500  if (state.is_mailbox_list && (last_selected_mailbox >= 0) &&
1501  (last_selected_mailbox < menu->max))
1502  {
1503  menu_set_index(menu, last_selected_mailbox);
1504  }
1505  int op = menu_loop(menu);
1506  if (op >= 0)
1507  mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", OpStrings[op][0], op);
1508  int index = menu_get_index(menu);
1509  struct FolderFile *ff = ARRAY_GET(&state.entry, index);
1510  switch (op)
1511  {
1512  case OP_DESCEND_DIRECTORY:
1513  case OP_GENERIC_SELECT_ENTRY:
1514  {
1515  if (ARRAY_EMPTY(&state.entry))
1516  {
1517  mutt_error(_("No files match the file mask"));
1518  break;
1519  }
1520 
1521  if (S_ISDIR(ff->mode) ||
1522  (S_ISLNK(ff->mode) && link_is_dir(mutt_buffer_string(&LastDir), ff->name))
1523 #ifdef USE_IMAP
1524  || ff->inferiors
1525 #endif
1526  )
1527  {
1528  /* make sure this isn't a MH or maildir mailbox */
1529  if (state.is_mailbox_list)
1530  {
1531  mutt_buffer_strcpy(buf, ff->name);
1533  }
1534 #ifdef USE_IMAP
1535  else if (state.imap_browse)
1536  {
1537  mutt_buffer_strcpy(buf, ff->name);
1538  }
1539 #endif
1540  else
1541  {
1543  }
1544 
1545  enum MailboxType type = mx_path_probe(mutt_buffer_string(buf));
1546  if ((op == OP_DESCEND_DIRECTORY) || (type == MUTT_MAILBOX_ERROR) ||
1547  (type == MUTT_UNKNOWN)
1548 #ifdef USE_IMAP
1549  || ff->inferiors
1550 #endif
1551  )
1552  {
1553  /* save the old directory */
1554  mutt_buffer_copy(OldLastDir, &LastDir);
1555 
1556  if (mutt_str_equal(ff->name, ".."))
1557  {
1558  size_t lastdirlen = mutt_buffer_len(&LastDir);
1559  if ((lastdirlen > 1) &&
1560  mutt_str_equal("..", mutt_buffer_string(&LastDir) + lastdirlen - 2))
1561  {
1562  mutt_buffer_addstr(&LastDir, "/..");
1563  }
1564  else
1565  {
1566  char *p = NULL;
1567  if (lastdirlen > 1)
1568  p = strrchr(mutt_buffer_string(&LastDir) + 1, '/');
1569 
1570  if (p)
1571  {
1572  *p = '\0';
1574  }
1575  else
1576  {
1577  if (mutt_buffer_string(&LastDir)[0] == '/')
1578  mutt_buffer_strcpy(&LastDir, "/");
1579  else
1580  mutt_buffer_addstr(&LastDir, "/..");
1581  }
1582  }
1583  }
1584  else if (state.is_mailbox_list)
1585  {
1588  }
1589 #ifdef USE_IMAP
1590  else if (state.imap_browse)
1591  {
1593  /* tack on delimiter here */
1594 
1595  /* special case "" needs no delimiter */
1596  struct Url *url = url_parse(ff->name);
1597  if (url && url->path && (ff->delim != '\0'))
1598  {
1600  }
1601  url_free(&url);
1602  }
1603 #endif
1604  else
1605  {
1607  mutt_buffer_copy(&LastDir, tmp);
1608  }
1609 
1610  destroy_state(&state);
1611  if (kill_prefix)
1612  {
1613  mutt_buffer_reset(prefix);
1614  kill_prefix = false;
1615  }
1616  state.is_mailbox_list = false;
1617 #ifdef USE_IMAP
1618  if (state.imap_browse)
1619  {
1620  init_state(&state, NULL);
1621  state.imap_browse = true;
1623  browser_sort(&state);
1624  menu->mdata = &state.entry;
1625  }
1626  else
1627 #endif
1628  {
1629  if (examine_directory(m, menu, &state, mutt_buffer_string(&LastDir),
1630  mutt_buffer_string(prefix)) == -1)
1631  {
1632  /* try to restore the old values */
1633  mutt_buffer_copy(&LastDir, OldLastDir);
1634  if (examine_directory(m, menu, &state, mutt_buffer_string(&LastDir),
1635  mutt_buffer_string(prefix)) == -1)
1636  {
1638  goto bail;
1639  }
1640  }
1641  /* resolve paths navigated from GUI */
1642  if (mutt_path_realpath(LastDir.data) == 0)
1643  break;
1644  }
1645 
1646  browser_highlight_default(&state, menu);
1647  init_menu(&state, menu, m, sbar);
1648  goto_swapper[0] = '\0';
1649  break;
1650  }
1651  }
1652  else if (op == OP_DESCEND_DIRECTORY)
1653  {
1654  mutt_error(_("%s is not a directory"), ARRAY_GET(&state.entry, index)->name);
1655  break;
1656  }
1657 
1658  if (state.is_mailbox_list || OptNews) /* USE_NNTP */
1659  {
1660  mutt_buffer_strcpy(file, ff->name);
1662  }
1663 #ifdef USE_IMAP
1664  else if (state.imap_browse)
1665  mutt_buffer_strcpy(file, ff->name);
1666 #endif
1667  else
1668  {
1670  }
1671  }
1672  /* fallthrough */
1673 
1674  case OP_EXIT:
1675 
1676  if (multiple)
1677  {
1678  char **tfiles = NULL;
1679 
1680  if (menu->tagged)
1681  {
1682  *numfiles = menu->tagged;
1683  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
1684  size_t j = 0;
1685  ARRAY_FOREACH(ff, &state.entry)
1686  {
1687  if (ff->tagged)
1688  {
1691  tfiles[j++] = mutt_buffer_strdup(tmp);
1692  }
1693  }
1694  *files = tfiles;
1695  }
1696  else if (!mutt_buffer_is_empty(file)) /* no tagged entries. return selected entry */
1697  {
1698  *numfiles = 1;
1699  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
1701  tfiles[0] = mutt_buffer_strdup(file);
1702  *files = tfiles;
1703  }
1704  }
1705 
1706  destroy_state(&state);
1707  goto bail;
1708 
1709  case OP_BROWSER_TELL:
1710  if (!ARRAY_EMPTY(&state.entry))
1711  mutt_message("%s", ARRAY_GET(&state.entry, index)->name);
1712  break;
1713 
1714 #ifdef USE_IMAP
1715  case OP_BROWSER_TOGGLE_LSUB:
1716  bool_str_toggle(NeoMutt->sub, "imap_list_subscribed", NULL);
1717 
1718  mutt_unget_event(0, OP_CHECK_NEW);
1719  break;
1720 
1721  case OP_CREATE_MAILBOX:
1722  if (!state.imap_browse)
1723  {
1724  mutt_error(_("Create is only supported for IMAP mailboxes"));
1725  break;
1726  }
1727 
1729  {
1730  /* TODO: find a way to detect if the new folder would appear in
1731  * this window, and insert it without starting over. */
1732  destroy_state(&state);
1733  init_state(&state, NULL);
1734  state.imap_browse = true;
1736  browser_sort(&state);
1737  menu->mdata = &state.entry;
1738  browser_highlight_default(&state, menu);
1739  init_menu(&state, menu, m, sbar);
1740  }
1741  /* else leave error on screen */
1742  break;
1743 
1744  case OP_RENAME_MAILBOX:
1745  if (!ff->imap)
1746  mutt_error(_("Rename is only supported for IMAP mailboxes"));
1747  else
1748  {
1749  if (imap_mailbox_rename(ff->name) >= 0)
1750  {
1751  destroy_state(&state);
1752  init_state(&state, NULL);
1753  state.imap_browse = true;
1755  browser_sort(&state);
1756  menu->mdata = &state.entry;
1757  browser_highlight_default(&state, menu);
1758  init_menu(&state, menu, m, sbar);
1759  }
1760  }
1761  break;
1762 
1763  case OP_DELETE_MAILBOX:
1764  if (!ff->imap)
1765  mutt_error(_("Delete is only supported for IMAP mailboxes"));
1766  else
1767  {
1768  char msg[128];
1769 
1770  // TODO(sileht): It could be better to select INBOX instead. But I
1771  // don't want to manipulate Context/Mailboxes/mailbox->account here for now.
1772  // Let's just protect neomutt against crash for now. #1417
1773  if (mutt_str_equal(mailbox_path(m), ff->name))
1774  {
1775  mutt_error(_("Can't delete currently selected mailbox"));
1776  break;
1777  }
1778 
1779  snprintf(msg, sizeof(msg), _("Really delete mailbox \"%s\"?"), ff->name);
1780  if (mutt_yesorno(msg, MUTT_NO) == MUTT_YES)
1781  {
1782  if (imap_delete_mailbox(m, ff->name) == 0)
1783  {
1784  /* free the mailbox from the browser */
1785  FREE(&ff->name);
1786  FREE(&ff->desc);
1787  /* and move all other entries up */
1788  ARRAY_REMOVE(&state.entry, ff);
1789  mutt_message(_("Mailbox deleted"));
1790  init_menu(&state, menu, m, sbar);
1791  }
1792  else
1793  mutt_error(_("Mailbox deletion failed"));
1794  }
1795  else
1796  mutt_message(_("Mailbox not deleted"));
1797  }
1798  break;
1799 #endif
1800 
1801  case OP_GOTO_PARENT:
1802  case OP_CHANGE_DIRECTORY:
1803 
1804 #ifdef USE_NNTP
1805  if (OptNews)
1806  break;
1807 #endif
1808 
1809  mutt_buffer_copy(buf, &LastDir);
1810 #ifdef USE_IMAP
1811  if (!state.imap_browse)
1812 #endif
1813  {
1814  /* add '/' at the end of the directory name if not already there */
1815  size_t len = mutt_buffer_len(buf);
1816  if ((len > 0) && (mutt_buffer_string(&LastDir)[len - 1] != '/'))
1817  mutt_buffer_addch(buf, '/');
1818  }
1819 
1820  if (op == OP_CHANGE_DIRECTORY)
1821  {
1822  /* buf comes from the buffer pool, so defaults to size 1024 */
1823  int ret = mutt_buffer_get_field(_("Chdir to: "), buf, MUTT_FILE,
1824  false, NULL, NULL, NULL);
1825  if ((ret != 0) && mutt_buffer_is_empty(buf))
1826  break;
1827  }
1828  else if (op == OP_GOTO_PARENT)
1830 
1831  if (!mutt_buffer_is_empty(buf))
1832  {
1833  state.is_mailbox_list = false;
1835 #ifdef USE_IMAP
1836  if (imap_path_probe(mutt_buffer_string(buf), NULL) == MUTT_IMAP)
1837  {
1838  mutt_buffer_copy(&LastDir, buf);
1839  destroy_state(&state);
1840  init_state(&state, NULL);
1841  state.imap_browse = true;
1843  browser_sort(&state);
1844  menu->mdata = &state.entry;
1845  browser_highlight_default(&state, menu);
1846  init_menu(&state, menu, m, sbar);
1847  }
1848  else
1849 #endif
1850  {
1851  if (mutt_buffer_string(buf)[0] != '/')
1852  {
1853  /* in case dir is relative, make it relative to LastDir,
1854  * not current working dir */
1856  mutt_buffer_string(buf));
1857  mutt_buffer_copy(buf, tmp);
1858  }
1859  /* Resolve path from <chdir>
1860  * Avoids buildup such as /a/b/../../c
1861  * Symlinks are always unraveled to keep code simple */
1862  if (mutt_path_realpath(buf->data) == 0)
1863  break;
1864 
1865  struct stat st;
1866  if (stat(mutt_buffer_string(buf), &st) == 0)
1867  {
1868  if (S_ISDIR(st.st_mode))
1869  {
1870  destroy_state(&state);
1871  if (examine_directory(m, menu, &state, mutt_buffer_string(buf),
1872  mutt_buffer_string(prefix)) == 0)
1873  {
1874  mutt_buffer_copy(&LastDir, buf);
1875  }
1876  else
1877  {
1878  mutt_error(_("Error scanning directory"));
1879  if (examine_directory(m, menu, &state, mutt_buffer_string(&LastDir),
1880  mutt_buffer_string(prefix)) == -1)
1881  {
1882  goto bail;
1883  }
1884  }
1885  browser_highlight_default(&state, menu);
1886  init_menu(&state, menu, m, sbar);
1887  }
1888  else
1889  mutt_error(_("%s is not a directory"), mutt_buffer_string(buf));
1890  }
1891  else
1893  }
1894  }
1895  break;
1896 
1897  case OP_ENTER_MASK:
1898  {
1899  const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
1900  mutt_buffer_strcpy(buf, c_mask ? c_mask->pattern : NULL);
1901  if (mutt_get_field(_("File Mask: "), buf->data, buf->dsize,
1902  MUTT_COMP_NO_FLAGS, false, NULL, NULL) != 0)
1903  {
1904  break;
1905  }
1906 
1907  mutt_buffer_fix_dptr(buf);
1908 
1909  state.is_mailbox_list = false;
1910  /* assume that the user wants to see everything */
1911  if (mutt_buffer_is_empty(buf))
1912  mutt_buffer_strcpy(buf, ".");
1913 
1914  struct Buffer errmsg = mutt_buffer_make(256);
1915  int rc = cs_subset_str_string_set(NeoMutt->sub, "mask",
1916  mutt_buffer_string(buf), &errmsg);
1917  if (CSR_RESULT(rc) != CSR_SUCCESS)
1918  {
1919  if (!mutt_buffer_is_empty(&errmsg))
1920  {
1921  mutt_error("%s", mutt_buffer_string(&errmsg));
1922  mutt_buffer_dealloc(&errmsg);
1923  }
1924  break;
1925  }
1926  mutt_buffer_dealloc(&errmsg);
1927 
1928  destroy_state(&state);
1929 #ifdef USE_IMAP
1930  if (state.imap_browse)
1931  {
1932  init_state(&state, NULL);
1933  state.imap_browse = true;
1935  browser_sort(&state);
1936  menu->mdata = &state.entry;
1937  init_menu(&state, menu, m, sbar);
1938  }
1939  else
1940 #endif
1941  if (examine_directory(m, menu, &state, mutt_buffer_string(&LastDir), NULL) == 0)
1942  {
1943  init_menu(&state, menu, m, sbar);
1944  }
1945  else
1946  {
1947  mutt_error(_("Error scanning directory"));
1948  goto bail;
1949  }
1950  kill_prefix = false;
1951  if (ARRAY_EMPTY(&state.entry))
1952  {
1953  mutt_error(_("No files match the file mask"));
1954  break;
1955  }
1956  break;
1957  }
1958 
1959  case OP_SORT:
1960  case OP_SORT_REVERSE:
1961 
1962  {
1963  bool resort = true;
1964  int sort = -1;
1965  int reverse = (op == OP_SORT_REVERSE);
1966 
1967  switch (mutt_multi_choice(
1968  (reverse) ?
1969  /* L10N: The highlighted letters must match the "Sort" options */
1970  _("Reverse sort by (d)ate, (a)lpha, si(z)e, d(e)scription, "
1971  "(c)ount, ne(w) count, or do(n)'t sort?") :
1972  /* L10N: The highlighted letters must match the "Reverse Sort" options */
1973  _("Sort by (d)ate, (a)lpha, si(z)e, d(e)scription, (c)ount, "
1974  "ne(w) count, or do(n)'t sort?"),
1975  /* L10N: These must match the highlighted letters from "Sort" and "Reverse Sort" */
1976  _("dazecwn")))
1977  {
1978  case -1: /* abort */
1979  resort = false;
1980  break;
1981 
1982  case 1: /* (d)ate */
1983  sort = SORT_DATE;
1984  break;
1985 
1986  case 2: /* (a)lpha */
1987  sort = SORT_SUBJECT;
1988  break;
1989 
1990  case 3: /* si(z)e */
1991  sort = SORT_SIZE;
1992  break;
1993 
1994  case 4: /* d(e)scription */
1995  sort = SORT_DESC;
1996  break;
1997 
1998  case 5: /* (c)ount */
1999  sort = SORT_COUNT;
2000  break;
2001 
2002  case 6: /* ne(w) count */
2003  sort = SORT_UNREAD;
2004  break;
2005 
2006  case 7: /* do(n)'t sort */
2007  sort = SORT_ORDER;
2008  break;
2009  }
2010  if (resort)
2011  {
2012  sort |= reverse ? SORT_REVERSE : 0;
2013  cs_subset_str_native_set(NeoMutt->sub, "sort_browser", sort, NULL);
2014  browser_sort(&state);
2015  browser_highlight_default(&state, menu);
2017  }
2018  else
2019  {
2020  cs_subset_str_native_set(NeoMutt->sub, "sort_browser", sort, NULL);
2021  }
2022  break;
2023  }
2024 
2025  case OP_TOGGLE_MAILBOXES:
2026  case OP_BROWSER_GOTO_FOLDER:
2027  case OP_CHECK_NEW:
2028  if (state.is_mailbox_list)
2029  {
2030  last_selected_mailbox = menu->current;
2031  }
2032 
2033  if (op == OP_TOGGLE_MAILBOXES)
2034  {
2035  state.is_mailbox_list = !state.is_mailbox_list;
2036  }
2037 
2038  if (op == OP_BROWSER_GOTO_FOLDER)
2039  {
2040  /* When in mailboxes mode, disables this feature */
2041  const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
2042  if (c_folder)
2043  {
2044  mutt_debug(LL_DEBUG3, "= hit! Folder: %s, LastDir: %s\n", c_folder,
2046  if (goto_swapper[0] == '\0')
2047  {
2048  if (!mutt_str_equal(mutt_buffer_string(&LastDir), c_folder))
2049  {
2050  /* Stores into goto_swapper LastDir, and swaps to `$folder` */
2051  mutt_str_copy(goto_swapper, mutt_buffer_string(&LastDir),
2052  sizeof(goto_swapper));
2054  mutt_buffer_strcpy(&LastDir, c_folder);
2055  }
2056  }
2057  else
2058  {
2060  mutt_buffer_strcpy(&LastDir, goto_swapper);
2061  goto_swapper[0] = '\0';
2062  }
2063  }
2064  }
2065  destroy_state(&state);
2066  mutt_buffer_reset(prefix);
2067  kill_prefix = false;
2068 
2069  if (state.is_mailbox_list)
2070  {
2071  examine_mailboxes(m, menu, &state);
2072  }
2073 #ifdef USE_IMAP
2074  else if (imap_path_probe(mutt_buffer_string(&LastDir), NULL) == MUTT_IMAP)
2075  {
2076  init_state(&state, NULL);
2077  state.imap_browse = true;
2079  browser_sort(&state);
2080  menu->mdata = &state.entry;
2081  }
2082 #endif
2083  else if (examine_directory(m, menu, &state, mutt_buffer_string(&LastDir),
2084  mutt_buffer_string(prefix)) == -1)
2085  {
2086  goto bail;
2087  }
2088  init_menu(&state, menu, m, sbar);
2089  break;
2090 
2091  case OP_MAILBOX_LIST:
2093  break;
2094 
2095  case OP_BROWSER_NEW_FILE:
2097  /* buf comes from the buffer pool, so defaults to size 1024 */
2098  if (mutt_buffer_get_field(_("New file name: "), buf, MUTT_FILE, false,
2099  NULL, NULL, NULL) == 0)
2100  {
2101  mutt_buffer_copy(file, buf);
2102  destroy_state(&state);
2103  goto bail;
2104  }
2105  break;
2106 
2107  case OP_BROWSER_VIEW_FILE:
2108  if (ARRAY_EMPTY(&state.entry))
2109  {
2110  mutt_error(_("No files match the file mask"));
2111  break;
2112  }
2113 
2114 #ifdef USE_IMAP
2115  if (ff->selectable)
2116  {
2117  mutt_buffer_strcpy(file, ff->name);
2118  destroy_state(&state);
2119  goto bail;
2120  }
2121  else
2122 #endif
2123  if (S_ISDIR(ff->mode) ||
2124  (S_ISLNK(ff->mode) && link_is_dir(mutt_buffer_string(&LastDir), ff->name)))
2125  {
2126  mutt_error(_("Can't view a directory"));
2127  break;
2128  }
2129  else
2130  {
2131  char buf2[PATH_MAX];
2132 
2133  mutt_path_concat(buf2, mutt_buffer_string(&LastDir), ff->name, sizeof(buf2));
2134  struct Body *b = mutt_make_file_attach(buf2, NeoMutt->sub);
2135  if (b)
2136  {
2137  mutt_view_attachment(NULL, b, MUTT_VA_REGULAR, NULL, NULL, menu->win);
2138  mutt_body_free(&b);
2140  }
2141  else
2142  mutt_error(_("Error trying to view file"));
2143  }
2144  break;
2145 
2146 #ifdef USE_NNTP
2147  case OP_CATCHUP:
2148  case OP_UNCATCHUP:
2149  {
2150  if (!OptNews)
2151  break;
2152 
2153  struct NntpMboxData *mdata = NULL;
2154 
2156  if (rc < 0)
2157  break;
2158 
2159  if (op == OP_CATCHUP)
2160  mdata = mutt_newsgroup_catchup(m, CurrentNewsSrv, ff->name);
2161  else
2162  mdata = mutt_newsgroup_uncatchup(m, CurrentNewsSrv, ff->name);
2163 
2164  if (mdata)
2165  {
2167  index = menu_get_index(menu) + 1;
2168  if (index < menu->max)
2169  menu_set_index(menu, index);
2170  }
2171  if (rc)
2174  break;
2175  }
2176 
2177  case OP_LOAD_ACTIVE:
2178  {
2179  if (!OptNews)
2180  break;
2181 
2182  struct NntpAccountData *adata = CurrentNewsSrv;
2183 
2184  if (nntp_newsrc_parse(adata) < 0)
2185  break;
2186 
2187  for (size_t i = 0; i < adata->groups_num; i++)
2188  {
2189  struct NntpMboxData *mdata = adata->groups_list[i];
2190  if (mdata)
2191  mdata->deleted = true;
2192  }
2193  nntp_active_fetch(adata, true);
2194  nntp_newsrc_update(adata);
2195  nntp_newsrc_close(adata);
2196 
2197  destroy_state(&state);
2198  if (state.is_mailbox_list)
2199  {
2200  examine_mailboxes(m, menu, &state);
2201  }
2202  else
2203  {
2204  if (examine_directory(m, menu, &state, NULL, NULL) == -1)
2205  break;
2206  }
2207  init_menu(&state, menu, m, sbar);
2208  break;
2209  }
2210 #endif /* USE_NNTP */
2211 
2212 #if defined(USE_IMAP) || defined(USE_NNTP)
2213  case OP_BROWSER_SUBSCRIBE:
2214  case OP_BROWSER_UNSUBSCRIBE:
2215 #endif
2216 #ifdef USE_NNTP
2217  case OP_SUBSCRIBE_PATTERN:
2218  case OP_UNSUBSCRIBE_PATTERN:
2219  {
2220  if (OptNews)
2221  {
2222  struct NntpAccountData *adata = CurrentNewsSrv;
2223  regex_t rx;
2224  memset(&rx, 0, sizeof(rx));
2225  char *s = buf->data;
2226  index = menu_get_index(menu);
2227 
2228  if ((op == OP_SUBSCRIBE_PATTERN) || (op == OP_UNSUBSCRIBE_PATTERN))
2229  {
2230  char tmp2[256];
2231 
2232  mutt_buffer_reset(buf);
2233  if (op == OP_SUBSCRIBE_PATTERN)
2234  snprintf(tmp2, sizeof(tmp2), _("Subscribe pattern: "));
2235  else
2236  snprintf(tmp2, sizeof(tmp2), _("Unsubscribe pattern: "));
2237  /* buf comes from the buffer pool, so defaults to size 1024 */
2238  if ((mutt_buffer_get_field(tmp2, buf, MUTT_PATTERN, false, NULL, NULL, NULL) != 0) ||
2239  mutt_buffer_is_empty(buf))
2240  {
2241  break;
2242  }
2243 
2244  int err = REG_COMP(&rx, s, REG_NOSUB);
2245  if (err != 0)
2246  {
2247  regerror(err, &rx, buf->data, buf->dsize);
2248  regfree(&rx);
2249  mutt_error("%s", mutt_buffer_string(buf));
2250  break;
2251  }
2253  index = 0;
2254  }
2255  else if (ARRAY_EMPTY(&state.entry))
2256  {
2257  mutt_error(_("No newsgroups match the mask"));
2258  break;
2259  }
2260 
2261  int rc = nntp_newsrc_parse(adata);
2262  if (rc < 0)
2263  break;
2264 
2265  ARRAY_FOREACH_FROM(ff, &state.entry, index)
2266  {
2267  if ((op == OP_BROWSER_SUBSCRIBE) || (op == OP_BROWSER_UNSUBSCRIBE) ||
2268  (regexec(&rx, ff->name, 0, NULL, 0) == 0))
2269  {
2270  if ((op == OP_BROWSER_SUBSCRIBE) || (op == OP_SUBSCRIBE_PATTERN))
2271  mutt_newsgroup_subscribe(adata, ff->name);
2272  else
2273  mutt_newsgroup_unsubscribe(adata, ff->name);
2274  }
2275  if ((op == OP_BROWSER_SUBSCRIBE) || (op == OP_BROWSER_UNSUBSCRIBE))
2276  {
2277  if ((index + 1) < menu->max)
2278  menu_set_index(menu, index + 1);
2279  break;
2280  }
2281  }
2282 
2283  if (op == OP_SUBSCRIBE_PATTERN)
2284  {
2285  for (size_t j = 0; adata && (j < adata->groups_num); j++)
2286  {
2287  struct NntpMboxData *mdata = adata->groups_list[j];
2288  if (mdata && mdata->group && !mdata->subscribed)
2289  {
2290  if (regexec(&rx, mdata->group, 0, NULL, 0) == 0)
2291  {
2292  mutt_newsgroup_subscribe(adata, mdata->group);
2293  add_folder(menu, &state, mdata->group, NULL, NULL, NULL, mdata);
2294  }
2295  }
2296  }
2297  init_menu(&state, menu, m, sbar);
2298  }
2299  if (rc > 0)
2301  nntp_newsrc_update(adata);
2302  nntp_clear_cache(adata);
2303  nntp_newsrc_close(adata);
2304  if ((op != OP_BROWSER_SUBSCRIBE) && (op != OP_BROWSER_UNSUBSCRIBE))
2305  regfree(&rx);
2306  }
2307 #ifdef USE_IMAP
2308  else
2309 #endif /* USE_IMAP && USE_NNTP */
2310 #endif /* USE_NNTP */
2311 #ifdef USE_IMAP
2312  {
2313  char tmp2[256];
2314  mutt_str_copy(tmp2, ff->name, sizeof(tmp2));
2315  mutt_expand_path(tmp2, sizeof(tmp2));
2316  imap_subscribe(tmp2, (op == OP_BROWSER_SUBSCRIBE));
2317  }
2318 #endif /* USE_IMAP */
2319  }
2320  }
2321  }
2322 
2323 bail:
2324  mutt_buffer_pool_release(&OldLastDir);
2327  mutt_buffer_pool_release(&prefix);
2328 
2329  simple_dialog_free(&dlg);
2330 
2331  goto_swapper[0] = '\0';
2332 }
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
mode_t mode
Definition: browser.h:55
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:550
bool mutt_mailbox_list(void)
List the mailboxes with new mail.
Definition: mutt_mailbox.c:222
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
static bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
Definition: browser.c:369
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:165
Definition: lib.h:67
static int examine_directory(struct Mailbox *m, struct Menu *menu, struct BrowserState *state, const char *d, const char *prefix)
Get list of all files/newsgroups with mask.
Definition: browser.c:734
static void destroy_state(struct BrowserState *state)
Free the BrowserState.
Definition: browser.c:172
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
#define mutt_error(...)
Definition: logging.h:88
char * desc
Definition: browser.h:63
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:268
int imap_delete_mailbox(struct Mailbox *m, char *path)
Delete a mailbox.
Definition: imap.c:516
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
Definition: newsrc.c:846
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
struct NntpMboxData * mutt_newsgroup_uncatchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Uncatchup newsgroup.
Definition: newsrc.c:1347
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
State of the file/mailbox browser.
Definition: browser.h:91
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:105
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
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:662
String manipulation buffer.
Definition: buffer.h:33
struct NntpMboxData * mutt_newsgroup_subscribe(struct NntpAccountData *adata, char *group)
Subscribe newsgroup.
Definition: newsrc.c:1256
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:583
#define _(a)
Definition: message.h:28
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
struct BrowserStateEntry entry
Definition: browser.h:93
Error occurred examining Mailbox.
Definition: mailbox.h:46
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:54
int imap_mailbox_create(const char *path)
Create a new IMAP mailbox.
Definition: browse.c:384
static int browser_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t.
Definition: browser.c:1202
const char * mutt_path_getcwd(struct Buffer *cwd)
Get the current working directory.
Definition: path.c:563
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:118
static void init_menu(struct BrowserState *state, struct Menu *menu, struct Mailbox *m, struct MuttWindow *sbar)
Set up a new menu.
Definition: browser.c:1047
static void init_lastdir(void)
Initialise the browser directories.
Definition: browser.c:146
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
View using default method.
Definition: mutt_attach.h:43
static int examine_mailboxes(struct Mailbox *m, struct Menu *menu, struct BrowserState *state)
Get list of mailboxes/subscribed newsgroups.
Definition: browser.c:862
#define mutt_perror(...)
Definition: logging.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:60
NNTP-specific Account data -.
Definition: adata.h:36
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
bool subscribed
Definition: mdata.h:41
The body of an email.
Definition: body.h:34
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:105
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:39
#define CSR_RESULT(x)
Definition: set.h:52
char * HomeDir
User&#39;s home directory.
Definition: mutt_globals.h:45
char * folder
Definition: browser.h:96
bool selectable
Definition: browser.h:73
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition: helpers.c:243
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
Sort by the size of the email.
Definition: sort2.h:44
size_t dsize
Length of data.
Definition: buffer.h:37
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:122
int nntp_active_fetch(struct NntpAccountData *adata, bool mark_new)
Fetch list of all newsgroups from server.
Definition: nntp.c:1963
int cs_subset_str_string_set(const struct ConfigSubset *sub, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:408
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
static struct Buffer LastDirBackup
Definition: browser.c:139
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:52
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:48
struct Body * mutt_make_file_attach(const char *path, struct ConfigSubset *sub)
Create a file attachment.
Definition: sendlib.c:1088
char * name
Definition: browser.h:62
char * group
Definition: mdata.h:34
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
size_t mutt_path_realpath(char *buf)
resolve path, unraveling symlinks
Definition: path.c:440
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2402
bool imap
Definition: browser.h:72
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:214
const char * OpStrings[][2]
Definition: opcodes.c:34
void * mdata
Driver specific data.
Definition: mailbox.h:136
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:189
Browser Dialog, mutt_buffer_select_file()
Definition: mutt_window.h:80
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
static int browser_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t.
Definition: browser.c:1172
Browser entry representing a folder/dir.
Definition: browser.h:53
static const struct Mapping FolderNewsHelp[]
Help Bar for the NNTP Mailbox browser dialog.
Definition: browser.c:124
void * mdata
Private data.
Definition: lib.h:155
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:70
size_t mutt_buffer_strcpy_n(struct Buffer *buf, const char *s, size_t len)
Copy a string into a Buffer.
Definition: buffer.c:327
size_t mutt_buffer_addstr_n(struct Buffer *buf, const char *s, size_t len)
Add a string to a Buffer, expanding it if necessary.
Definition: buffer.c:99
char * data
Pointer to data.
Definition: buffer.h:35
unsigned int groups_num
Definition: adata.h:59
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:344
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
Definition: newsrc.c:162
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: question.c:49
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
struct NntpMboxData * mutt_newsgroup_unsubscribe(struct NntpAccountData *adata, char *group)
Unsubscribe newsgroup.
Definition: newsrc.c:1280
static int select_file_search(struct Menu *menu, regex_t *rx, int line)
Menu search callback for matching files - Implements Menu::search() -.
Definition: browser.c:970
int(* tag)(struct Menu *menu, int sel, int act)
Definition: lib.h:130
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:38
NNTP-specific Mailbox data -.
Definition: mdata.h:32
int tagged
Number of tagged entries.
Definition: lib.h:92
#define MUTT_FILE
Do file completion.
Definition: mutt.h:54
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:180
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
char * path
Path.
Definition: url.h:75
int max
Number of entries in the menu.
Definition: lib.h:71
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
#define ARRAY_FOREACH_FROM(elem, head, from)
Iterate from an index to the end.
Definition: array.h:217
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
General file/mailbox browser.
Definition: type.h:44
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: browser.h:37
static void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: browser.c:1021
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1317
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
Log at debug level 1.
Definition: logging.h:40
bool deleted
Definition: mdata.h:44
Sort by the number of unread emails.
Definition: sort2.h:59
void mutt_browser_select_dir(const char *f)
Remember the last directory selected.
Definition: browser.c:1234
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
static int file_tag(struct Menu *menu, int sel, int act)
Tag an entry in the menu - Implements Menu::tag() -.
Definition: browser.c:1152
#define ARRAY_REMOVE(head, elem)
Remove an entry from the array, shifting down the subsequent entries.
Definition: array.h:261
Cached regular expression.
Definition: regex3.h:89
int imap_browse(const char *path, struct BrowserState *state)
IMAP hook into the folder browser.
Definition: browse.c:182
Sort by the folder&#39;s description.
Definition: sort2.h:63
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:50
void ** groups_list
Definition: adata.h:61
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
int imap_mailbox_rename(const char *path)
Rename a mailbox.
Definition: browse.c:437
Mapping between user-readable string and a constant.
Definition: mapping.h:31
static struct Buffer LastDir
Definition: browser.c:138
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:78
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
Sort by number of emails in a folder.
Definition: sort2.h:58
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:128
char * mutt_path_concat(char *d, const char *dir, const char *fname, size_t l)
Join a directory name and a filename.
Definition: path.c:351
bool tagged
Definition: browser.h:78
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int nntp_newsrc_update(struct NntpAccountData *adata)
Update .newsrc file.
Definition: newsrc.c:439
int current
Current entry.
Definition: lib.h:70
char * pattern
printable version
Definition: regex3.h:91
Sort by the date the email was sent.
Definition: sort2.h:43
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:713
struct NntpMboxData * mutt_newsgroup_catchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Catchup newsgroup.
Definition: newsrc.c:1308
bool inferiors
Definition: browser.h:74
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
static const struct Mapping FolderHelp[]
Help Bar for the File/Dir/Mailbox browser dialog.
Definition: browser.c:111
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
void * wdata
Private data.
Definition: mutt_window.h:145
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
bool imap_browse
Definition: browser.h:95
int(* search)(struct Menu *menu, regex_t *rx, int line)
Definition: lib.h:118
void mutt_get_parent_path(const char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition: muttlib.c:1555
bool is_mailbox_list
Definition: browser.h:98
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:44
char delim
Definition: browser.h:70
Sort by the email&#39;s subject.
Definition: sort2.h:46
Log at debug level 3.
Definition: logging.h:42
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:78
static void folder_make_entry(struct Menu *menu, char *buf, size_t buflen, int line)
Format a menu item for the folder browser - Implements Menu::make_entry() -.
Definition: browser.c:986
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
int imap_subscribe(char *path, bool subscribe)
Subscribe to a mailbox.
Definition: imap.c:1286
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
Definition: mutt_attach.c:415
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the caller graph for this function:

◆ mutt_select_file()

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

Let the user select a file.

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

Definition at line 2343 of file browser.c.

2345 {
2346  struct Buffer *f_buf = mutt_buffer_pool_get();
2347 
2348  mutt_buffer_strcpy(f_buf, NONULL(file));
2349  mutt_buffer_select_file(f_buf, flags, m, files, numfiles);
2350  mutt_str_copy(file, mutt_buffer_string(f_buf), filelen);
2351 
2352  mutt_buffer_pool_release(&f_buf);
2353 }
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
void mutt_buffer_select_file(struct Buffer *file, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:1254
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ FolderHelp

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

Help Bar for the File/Dir/Mailbox browser dialog.

Definition at line 111 of file browser.c.

◆ FolderNewsHelp

const 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

Help Bar for the NNTP Mailbox browser dialog.

Definition at line 124 of file browser.c.

◆ LastDir

struct Buffer LastDir = { 0 }
static

Definition at line 138 of file browser.c.

◆ LastDirBackup

struct Buffer LastDirBackup = { 0 }
static

Definition at line 139 of file browser.c.