NeoMutt  2025-12-11-435-g4ac674
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
Browser Function API

Prototype for a Browser Function. More...

Functions

static int op_browser_new_file (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Select a new file in this directory - Implements browser_function_t -.
 
static int op_browser_subscribe (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Subscribe to current mbox (IMAP/NNTP only) - Implements browser_function_t -.
 
static int op_browser_tell (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Display the currently selected file's name - Implements browser_function_t -.
 
static int op_browser_toggle_lsub (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Toggle view all/subscribed mailboxes (IMAP only) - Implements browser_function_t -.
 
static int op_browser_view_file (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 View file - Implements browser_function_t -.
 
static int op_catchup (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Mark all articles in newsgroup as read - Implements browser_function_t -.
 
static int op_change_directory (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Change directories - Implements browser_function_t -.
 
static int op_create_mailbox (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Create a new mailbox (IMAP only) - Implements browser_function_t -.
 
static int op_delete_mailbox (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Delete the current mailbox (IMAP only) - Implements browser_function_t -.
 
static int op_enter_mask (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Enter a file mask - Implements browser_function_t -.
 
static int op_exit (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Exit this menu - Implements browser_function_t -.
 
static int op_generic_select_entry (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Select the current entry - Implements browser_function_t -.
 
static int op_load_active (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Load list of all newsgroups from NNTP server - Implements browser_function_t -.
 
static int op_mailbox_list (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 List mailboxes with new mail - Implements browser_function_t -.
 
static int op_rename_mailbox (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Rename the current mailbox (IMAP only) - Implements browser_function_t -.
 
static int op_sort (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Sort messages - Implements browser_function_t -.
 
static int op_subscribe_pattern (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Subscribe to newsgroups matching a pattern - Implements browser_function_t -.
 
static int op_toggle_mailboxes (struct BrowserPrivateData *priv, const struct KeyEvent *event)
 Toggle whether to browse mailboxes or all files - Implements browser_function_t -.
 

Detailed Description

Prototype for a Browser Function.

Parameters
privPrivate Browser data
eventEvent to process
Return values
enumFunctionRetval
Precondition
priv is not NULL
event is not NULL

Function Documentation

◆ op_browser_new_file()

static int op_browser_new_file ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Select a new file in this directory - Implements browser_function_t -.

Definition at line 167 of file functions.c.

168{
169 struct Buffer *buf = buf_pool_get();
170 buf_printf(buf, "%s/", buf_string(&LastDir));
171
172 struct FileCompletionData cdata = { false, priv->mailbox, NULL, NULL, NULL };
173 const int rc = mw_get_field(_("New file name: "), buf, MUTT_COMP_NO_FLAGS,
174 HC_FILE, &CompleteMailboxOps, &cdata);
175 if (rc != 0)
176 {
177 buf_pool_release(&buf);
178 return FR_NO_ACTION;
179 }
180
181 buf_copy(priv->file, buf);
182 buf_pool_release(&buf);
183 priv->done = true;
184 return FR_DONE;
185}
const struct CompleteOps CompleteMailboxOps
Auto-Completion of Files / Mailboxes.
Definition complete.c:159
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition buffer.c:601
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
@ FR_DONE
Exit the Dialog.
Definition dispatcher.h:36
@ FR_NO_ACTION
Valid function - no action performed.
Definition dispatcher.h:38
struct Buffer LastDir
Browser: previous selected directory.
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition wdata.h:42
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
Definition window.c:270
@ HC_FILE
Files.
Definition lib.h:58
#define _(a)
Definition message.h:28
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
bool done
Should we close the Dialog?
struct Mailbox * mailbox
Mailbox.
struct Buffer * file
Buffer for the result.
String manipulation buffer.
Definition buffer.h:36
Input for the file completion function.
Definition curs_lib.h:39
+ Here is the call graph for this function:

◆ op_browser_subscribe()

static int op_browser_subscribe ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Subscribe to current mbox (IMAP/NNTP only) - Implements browser_function_t -.

This function handles:

  • OP_BROWSER_SUBSCRIBE
  • OP_BROWSER_UNSUBSCRIBE

Definition at line 194 of file functions.c.

195{
196 const int op = event->op;
197
198 if (OptNews)
199 {
201 int index = menu_get_index(priv->menu);
202
203 if (ARRAY_EMPTY(&priv->state.entry))
204 {
205 mutt_error(_("No newsgroups match the mask"));
206 return FR_ERROR;
207 }
208
209 int rc = nntp_newsrc_parse(adata);
210 if (rc < 0)
211 return FR_ERROR;
212
213 struct FolderFile *ff = ARRAY_GET(&priv->state.entry, index);
214 if (op == OP_BROWSER_SUBSCRIBE)
215 mutt_newsgroup_subscribe(adata, ff->name);
216 else
218
219 menu_set_index(priv->menu, index + 1);
220
221 if (rc > 0)
223 nntp_newsrc_update(adata);
224 nntp_clear_cache(adata);
225 nntp_newsrc_close(adata);
226 }
227 else
228 {
229 if (ARRAY_EMPTY(&priv->state.entry))
230 {
231 mutt_error(_("There are no mailboxes"));
232 return FR_ERROR;
233 }
234
235 struct Buffer *buf = buf_pool_get();
236 int index = menu_get_index(priv->menu);
237 struct FolderFile *ff = ARRAY_GET(&priv->state.entry, index);
238 buf_strcpy(buf, ff->name);
239 expand_path(buf, false);
240 imap_subscribe(buf_string(buf), (op == OP_BROWSER_SUBSCRIBE));
241 buf_pool_release(&buf);
242 }
243 return FR_SUCCESS;
244}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
#define ARRAY_GET(head, idx)
Return the element at index.
Definition array.h:109
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
@ FR_SUCCESS
Valid function - successfully performed.
Definition dispatcher.h:40
@ FR_ERROR
Valid function - error occurred.
Definition dispatcher.h:39
bool OptNews
(pseudo) used to change reader mode
Definition globals.c:53
#define mutt_error(...)
Definition logging2.h:94
int imap_subscribe(const char *path, bool subscribe)
Subscribe to a mailbox.
Definition imap.c:1405
#define MENU_REDRAW_FULL
Redraw everything.
Definition lib.h:60
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition menu.c:188
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition menu.c:164
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition menu.c:178
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:121
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
Definition newsrc.c:840
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
Definition newsrc.c:163
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition newsrc.c:119
int nntp_newsrc_update(struct NntpAccountData *adata)
Update .newsrc file.
Definition newsrc.c:442
struct NntpMboxData * mutt_newsgroup_subscribe(struct NntpAccountData *adata, char *group)
Subscribe newsgroup.
Definition newsrc.c:1174
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition nntp.c:74
struct NntpMboxData * mutt_newsgroup_unsubscribe(struct NntpAccountData *adata, char *group)
Unsubscribe newsgroup.
Definition newsrc.c:1198
void * adata
Private data (for Mailbox backends)
Definition account.h:42
struct Menu * menu
Menu.
struct BrowserState state
State containing list of files/dir/mailboxes.
struct BrowserEntryArray entry
Array of files / dirs / mailboxes.
Definition lib.h:146
Browser entry representing a folder/dir.
Definition lib.h:79
char * name
Name of file/dir/mailbox.
Definition lib.h:87
NNTP-specific Account data -.
Definition adata.h:36
+ Here is the call graph for this function:

◆ op_browser_tell()

static int op_browser_tell ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Display the currently selected file's name - Implements browser_function_t -.

Definition at line 249 of file functions.c.

250{
251 int index = menu_get_index(priv->menu);
252 if (ARRAY_EMPTY(&priv->state.entry))
253 return FR_ERROR;
254
255 mutt_message("%s", ARRAY_GET(&priv->state.entry, index)->name);
256 return FR_SUCCESS;
257}
#define mutt_message(...)
Definition logging2.h:93
+ Here is the call graph for this function:

◆ op_browser_toggle_lsub()

static int op_browser_toggle_lsub ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Toggle view all/subscribed mailboxes (IMAP only) - Implements browser_function_t -.

Definition at line 262 of file functions.c.

263{
264 bool_str_toggle(NeoMutt->sub, "imap_list_subscribed", NULL);
265
266 mutt_unget_op(OP_CHECK_NEW);
267 return FR_SUCCESS;
268}
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition bool.c:229
void mutt_unget_op(int op)
Return an operation to the input buffer.
Definition get.c:133
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:

◆ op_browser_view_file()

static int op_browser_view_file ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

View file - Implements browser_function_t -.

Definition at line 273 of file functions.c.

274{
275 if (ARRAY_EMPTY(&priv->state.entry))
276 {
277 mutt_error(_("No files match the file mask"));
278 return FR_ERROR;
279 }
280
281 int index = menu_get_index(priv->menu);
282 struct FolderFile *ff = ARRAY_GET(&priv->state.entry, index);
283 if (ff->selectable)
284 {
285 buf_strcpy(priv->file, ff->name);
286 priv->done = true;
287 return FR_DONE;
288 }
289 else if (S_ISDIR(ff->mode) ||
290 (S_ISLNK(ff->mode) && link_is_dir(buf_string(&LastDir), ff->name)))
291 {
292 mutt_error(_("Can't view a directory"));
293 return FR_ERROR;
294 }
295 else
296 {
297 struct Buffer *path = buf_pool_get();
299 struct Body *b = mutt_make_file_attach(buf_string(path), NeoMutt->sub);
300 if (b)
301 {
302 mutt_view_attachment(NULL, b, MUTT_VA_REGULAR, NULL, NULL, priv->menu->win);
303 mutt_body_free(&b);
305 }
306 else
307 {
308 mutt_error(_("Error trying to view file"));
309 }
310 buf_pool_release(&path);
311 }
312 return FR_ERROR;
313}
size_t buf_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition buffer.c:509
bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition body.c:58
int mutt_view_attachment(FILE *fp, struct Body *b, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
@ MUTT_VA_REGULAR
View using default method.
Definition mutt_attach.h:44
struct Body * mutt_make_file_attach(const char *path, struct ConfigSubset *sub)
Create a file attachment.
Definition sendlib.c:606
The body of an email.
Definition body.h:36
bool selectable
Folder can be selected.
Definition lib.h:97
mode_t mode
File permissions.
Definition lib.h:80
struct MuttWindow * win
Window holding the Menu.
Definition lib.h:88
+ Here is the call graph for this function:

◆ op_catchup()

static int op_catchup ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Mark all articles in newsgroup as read - Implements browser_function_t -.

Definition at line 318 of file functions.c.

319{
320 if (!OptNews)
321 return FR_NOT_IMPL;
322
323 struct NntpMboxData *mdata = NULL;
324
326 if (rc < 0)
327 return FR_ERROR;
328
329 int index = menu_get_index(priv->menu);
330 struct FolderFile *ff = ARRAY_GET(&priv->state.entry, index);
331 if (event->op == OP_CATCHUP)
333 else
335
336 if (mdata)
337 {
339 index = menu_get_index(priv->menu) + 1;
340 if (index < priv->menu->max)
341 menu_set_index(priv->menu, index);
342 }
343
344 if (rc != 0)
346
348 return FR_ERROR;
349}
@ FR_NOT_IMPL
Invalid function - feature not enabled.
Definition dispatcher.h:37
#define MENU_REDRAW_INDEX
Redraw the index.
Definition lib.h:57
struct NntpMboxData * mutt_newsgroup_catchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Catchup newsgroup.
Definition newsrc.c:1225
struct NntpMboxData * mutt_newsgroup_uncatchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Uncatchup newsgroup.
Definition newsrc.c:1264
int op
Function opcode, e.g. OP_HELP.
Definition get.h:52
void * mdata
Driver specific data.
Definition mailbox.h:131
NNTP-specific Mailbox data -.
Definition mdata.h:34
+ Here is the call graph for this function:

◆ op_change_directory()

static int op_change_directory ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Change directories - Implements browser_function_t -.

This function handles:

  • OP_GOTO_PARENT
  • OP_CHANGE_DIRECTORY

Definition at line 358 of file functions.c.

359{
360 if (OptNews)
361 return FR_NOT_IMPL;
362
363 struct Buffer *buf = buf_pool_get();
364 buf_copy(buf, &LastDir);
365 if (!priv->state.imap_browse)
366 {
367 /* add '/' at the end of the directory name if not already there */
368 size_t len = buf_len(buf);
369 if ((len > 0) && (buf_string(&LastDir)[len - 1] != '/'))
370 buf_addch(buf, '/');
371 }
372
373 const int op = event->op;
374 if (op == OP_CHANGE_DIRECTORY)
375 {
376 struct FileCompletionData cdata = { false, priv->mailbox, NULL, NULL, NULL };
377 int rc = mw_get_field(_("Chdir to: "), buf, MUTT_COMP_NO_FLAGS, HC_FILE,
378 &CompleteMailboxOps, &cdata);
379 if ((rc != 0) && buf_is_empty(buf))
380 {
381 buf_pool_release(&buf);
382 return FR_NO_ACTION;
383 }
384 }
385 else if (op == OP_GOTO_PARENT)
386 {
387 mutt_get_parent_path(buf_string(buf), buf->data, buf->dsize);
388 }
389
390 if (!buf_is_empty(buf))
391 {
392 priv->state.is_mailbox_list = false;
393 expand_path(buf, false);
394 if (imap_path_probe(buf_string(buf), NULL) == MUTT_IMAP)
395 {
396 buf_copy(&LastDir, buf);
397 destroy_state(&priv->state);
398 init_state(&priv->state);
399 priv->state.imap_browse = true;
401 browser_sort(&priv->state);
402 browser_highlight_default(&priv->state, priv->menu);
403 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
404 }
405 else
406 {
407 if (buf_string(buf)[0] != '/')
408 {
409 /* in case dir is relative, make it relative to LastDir,
410 * not current working dir */
411 struct Buffer *tmp = buf_pool_get();
413 buf_copy(buf, tmp);
414 buf_pool_release(&tmp);
415 }
416 /* Resolve path from <chdir>
417 * Avoids buildup such as /a/b/../../c
418 * Symlinks are always unraveled to keep code simple */
419 if (mutt_path_realpath(buf) == 0)
420 {
421 buf_pool_release(&buf);
422 return FR_ERROR;
423 }
424
425 struct stat st = { 0 };
426 if (stat(buf_string(buf), &st) == 0)
427 {
428 if (S_ISDIR(st.st_mode))
429 {
430 destroy_state(&priv->state);
431 if (examine_directory(priv->mailbox, priv->menu, &priv->state,
432 buf_string(buf), buf_string(priv->prefix)) == 0)
433 {
434 buf_copy(&LastDir, buf);
435 }
436 else
437 {
438 mutt_error(_("Error scanning directory"));
439 if (examine_directory(priv->mailbox, priv->menu, &priv->state,
440 buf_string(&LastDir), buf_string(priv->prefix)) == -1)
441 {
442 priv->done = true;
443 return FR_ERROR;
444 }
445 }
446 browser_highlight_default(&priv->state, priv->menu);
447 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
448 }
449 else
450 {
451 mutt_error(_("%s is not a directory"), buf_string(buf));
452 }
453 }
454 else
455 {
456 mutt_perror("%s", buf_string(buf));
457 }
458 }
459 }
460 buf_pool_release(&buf);
461 return FR_ERROR;
462}
int imap_browse(const char *path, struct BrowserState *state)
IMAP hook into the folder browser.
Definition browse.c:196
void destroy_state(struct BrowserState *state)
Free the BrowserState.
Definition functions.c:150
void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition sort.c:186
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition buffer.c:491
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:241
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:49
int examine_directory(struct Mailbox *m, struct Menu *menu, struct BrowserState *state, const char *dirname, const char *prefix)
Get list of all files/newsgroups with mask.
void init_menu(struct BrowserState *state, struct Menu *menu, struct Mailbox *m, struct MuttWindow *sbar)
Set up a new menu.
void init_state(struct BrowserState *state)
Initialise a browser state.
void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
#define mutt_perror(...)
Definition logging2.h:95
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox?
Definition imap.c:2543
size_t mutt_path_realpath(struct Buffer *path)
Resolve path, unraveling symlinks.
Definition path.c:377
void mutt_get_parent_path(const char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition muttlib.c:866
struct Buffer * prefix
Folder prefix string.
struct MuttWindow * sbar
Status Bar.
bool is_mailbox_list
Viewing mailboxes.
Definition lib.h:149
bool imap_browse
IMAP folder.
Definition lib.h:147
size_t dsize
Length of data.
Definition buffer.h:39
char * data
Pointer to data.
Definition buffer.h:37
+ Here is the call graph for this function:

◆ op_create_mailbox()

static int op_create_mailbox ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Create a new mailbox (IMAP only) - Implements browser_function_t -.

Definition at line 467 of file functions.c.

468{
469 if (!priv->state.imap_browse)
470 {
471 mutt_error(_("Create is only supported for IMAP mailboxes"));
472 return FR_ERROR;
473 }
474
476 return FR_ERROR;
477
478 /* TODO: find a way to detect if the new folder would appear in
479 * this window, and insert it without starting over. */
480 destroy_state(&priv->state);
481 init_state(&priv->state);
482 priv->state.imap_browse = true;
484 browser_sort(&priv->state);
485 browser_highlight_default(&priv->state, priv->menu);
486 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
487
488 return FR_SUCCESS;
489}
int imap_mailbox_create(const char *path)
Create a new IMAP mailbox.
Definition browse.c:393
+ Here is the call graph for this function:

◆ op_delete_mailbox()

static int op_delete_mailbox ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Delete the current mailbox (IMAP only) - Implements browser_function_t -.

Definition at line 494 of file functions.c.

495{
496 int index = menu_get_index(priv->menu);
497 struct FolderFile *ff = ARRAY_GET(&priv->state.entry, index);
498 if (!ff->imap)
499 {
500 mutt_error(_("Delete is only supported for IMAP mailboxes"));
501 return FR_ERROR;
502 }
503
504 char msg[128] = { 0 };
505
506 // TODO(sileht): It could be better to select INBOX instead. But I
507 // don't want to manipulate Mailboxes/mailbox->account here for now.
508 // Let's just protect neomutt against crash for now. #1417
509 if (mutt_str_equal(mailbox_path(priv->mailbox), ff->name))
510 {
511 mutt_error(_("Can't delete currently selected mailbox"));
512 return FR_ERROR;
513 }
514
515 snprintf(msg, sizeof(msg), _("Really delete mailbox \"%s\"?"), ff->name);
516 if (query_yesorno(msg, MUTT_NO) != MUTT_YES)
517 {
518 mutt_message(_("Mailbox not deleted"));
519 return FR_NO_ACTION;
520 }
521
522 if (imap_delete_mailbox(priv->mailbox, ff->name) != 0)
523 {
524 mutt_error(_("Mailbox deletion failed"));
525 return FR_ERROR;
526 }
527
528 /* free the mailbox from the browser */
529 FREE(&ff->name);
530 FREE(&ff->desc);
531 /* and move all other entries up */
532 ARRAY_REMOVE(&priv->state.entry, ff);
533 mutt_message(_("Mailbox deleted"));
534 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
535
536 return FR_SUCCESS;
537}
#define ARRAY_REMOVE(head, elem)
Remove an entry from the array, shifting down the subsequent entries.
Definition array.h:355
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:213
int imap_delete_mailbox(struct Mailbox *m, char *path)
Delete a mailbox.
Definition imap.c:611
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:662
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition quad.h:38
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition quad.h:39
enum QuadOption query_yesorno(const char *prompt, enum QuadOption def)
Ask the user a Yes/No question.
Definition question.c:326
bool imap
This is an IMAP folder.
Definition lib.h:96
char * desc
Description of mailbox.
Definition lib.h:88
+ Here is the call graph for this function:

◆ op_enter_mask()

static int op_enter_mask ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Enter a file mask - Implements browser_function_t -.

Definition at line 542 of file functions.c.

543{
544 const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
545 struct Buffer *buf = buf_pool_get();
546 buf_strcpy(buf, c_mask ? c_mask->pattern : NULL);
547 if (mw_get_field(_("File Mask: "), buf, MUTT_COMP_NO_FLAGS, HC_OTHER, NULL, NULL) != 0)
548 {
549 buf_pool_release(&buf);
550 return FR_NO_ACTION;
551 }
552
553 buf_fix_dptr(buf);
554
555 priv->state.is_mailbox_list = false;
556 /* assume that the user wants to see everything */
557 if (buf_is_empty(buf))
558 buf_strcpy(buf, ".");
559
560 struct Buffer *errmsg = buf_pool_get();
561 int rc = cs_subset_str_string_set(NeoMutt->sub, "mask", buf_string(buf), errmsg);
562 buf_pool_release(&buf);
563 if (CSR_RESULT(rc) != CSR_SUCCESS)
564 {
565 if (!buf_is_empty(errmsg))
566 {
567 mutt_error("%s", buf_string(errmsg));
568 buf_pool_release(&errmsg);
569 }
570 return FR_ERROR;
571 }
572 buf_pool_release(&errmsg);
573
574 destroy_state(&priv->state);
575 if (priv->state.imap_browse)
576 {
577 init_state(&priv->state);
578 priv->state.imap_browse = true;
580 browser_sort(&priv->state);
581 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
582 }
583 else if (examine_directory(priv->mailbox, priv->menu, &priv->state,
584 buf_string(&LastDir), NULL) == 0)
585 {
586 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
587 }
588 else
589 {
590 mutt_error(_("Error scanning directory"));
591 priv->done = true;
592 return FR_ERROR;
593 }
594 priv->kill_prefix = false;
595 if (ARRAY_EMPTY(&priv->state.entry))
596 {
597 mutt_error(_("No files match the file mask"));
598 return FR_ERROR;
599 }
600 return FR_SUCCESS;
601}
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition buffer.c:182
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition helpers.c:217
#define CSR_RESULT(x)
Extract the result code from CSR_* flags.
Definition set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition set.h:33
@ HC_OTHER
Miscellaneous strings.
Definition lib.h:60
bool kill_prefix
Prefix is in use.
Cached regular expression.
Definition regex3.h:85
char * pattern
printable version
Definition regex3.h:86
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:392
+ Here is the call graph for this function:

◆ op_exit()

static int op_exit ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Exit this menu - Implements browser_function_t -.

Definition at line 606 of file functions.c.

607{
608 if (priv->multiple)
609 {
610 char **tfiles = NULL;
611
612 if (priv->menu->tag_prefix && (priv->menu->num_tagged != 0))
613 {
614 *priv->numfiles = priv->menu->num_tagged;
615 tfiles = MUTT_MEM_CALLOC(*priv->numfiles, char *);
616 size_t j = 0;
617 struct FolderFile *ff = NULL;
618 ARRAY_FOREACH(ff, &priv->state.entry)
619 {
620 if (ff->tagged)
621 {
622 struct Buffer *buf = buf_pool_get();
624 expand_path(buf, false);
625 tfiles[j++] = buf_strdup(buf);
626 buf_pool_release(&buf);
627 }
628 }
629 *priv->files = tfiles;
630 }
631 else if (!buf_is_empty(priv->file)) /* no tagged entries. return selected entry */
632 {
633 *priv->numfiles = 1;
634 tfiles = MUTT_MEM_CALLOC(*priv->numfiles, char *);
635 expand_path(priv->file, false);
636 tfiles[0] = buf_strdup(priv->file);
637 *priv->files = tfiles;
638 }
639 }
640
641 priv->done = true;
642 return FR_DONE;
643}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
char *** files
Array of selected files.
int * numfiles
Number of selected files.
bool multiple
Allow multiple selections.
bool tagged
Folder is tagged.
Definition lib.h:103
int num_tagged
Number of tagged entries.
Definition lib.h:95
bool tag_prefix
User has pressed <tag-prefix>
Definition lib.h:86
+ Here is the call graph for this function:

◆ op_generic_select_entry()

static int op_generic_select_entry ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Select the current entry - Implements browser_function_t -.

This function handles:

  • OP_DESCEND_DIRECTORY
  • OP_GENERIC_SELECT_ENTRY

Definition at line 652 of file functions.c.

653{
654 if (ARRAY_EMPTY(&priv->state.entry))
655 {
656 mutt_warning(_("No files match the file mask"));
657 return FR_ERROR;
658 }
659
660 const int op = event->op;
661 int index = menu_get_index(priv->menu);
662 struct FolderFile *ff = ARRAY_GET(&priv->state.entry, index);
663 if ((priv->menu->tag_prefix) && (op == OP_GENERIC_SELECT_ENTRY))
664 {
665 // Do nothing
666 }
667 else if (S_ISDIR(ff->mode) ||
668 (S_ISLNK(ff->mode) && link_is_dir(buf_string(&LastDir), ff->name)) || ff->inferiors)
669 {
670 /* make sure this isn't a MH or maildir mailbox */
671 struct Buffer *buf = buf_pool_get();
672 if (priv->state.is_mailbox_list)
673 {
674 buf_strcpy(buf, ff->name);
675 expand_path(buf, false);
676 }
677 else if (priv->state.imap_browse)
678 {
679 buf_strcpy(buf, ff->name);
680 }
681 else
682 {
684 }
685
686 enum MailboxType type = mx_path_probe(buf_string(buf));
687 buf_pool_release(&buf);
688
689 if ((op == OP_DESCEND_DIRECTORY) || (type == MUTT_MAILBOX_ERROR) ||
690 (type == MUTT_UNKNOWN) || ff->inferiors)
691 {
692 /* save the old directory */
694
695 if (mutt_str_equal(ff->name, ".."))
696 {
697 size_t lastdirlen = buf_len(&LastDir);
698 if ((lastdirlen > 1) && mutt_str_equal("..", buf_string(&LastDir) + lastdirlen - 2))
699 {
700 buf_addstr(&LastDir, "/..");
701 }
702 else
703 {
704 char *p = NULL;
705 if (lastdirlen > 1)
706 p = strrchr(LastDir.data + 1, '/');
707
708 if (p)
709 {
710 *p = '\0';
712 }
713 else
714 {
715 if (buf_string(&LastDir)[0] == '/')
716 buf_strcpy(&LastDir, "/");
717 else
718 buf_addstr(&LastDir, "/..");
719 }
720 }
721 }
722 else if (priv->state.is_mailbox_list)
723 {
724 buf_strcpy(&LastDir, ff->name);
725 expand_path(&LastDir, false);
726 }
727 else if (priv->state.imap_browse)
728 {
729 buf_strcpy(&LastDir, ff->name);
730 /* tack on delimiter here */
731
732 /* special case "" needs no delimiter */
733 struct Url *url = url_parse(ff->name);
734 if (url && url->path && (ff->delim != '\0'))
735 {
736 buf_addch(&LastDir, ff->delim);
737 }
738 url_free(&url);
739 }
740 else
741 {
742 struct Buffer *tmp = buf_pool_get();
744 buf_copy(&LastDir, tmp);
745 buf_pool_release(&tmp);
746 }
747
748 destroy_state(&priv->state);
749 if (priv->kill_prefix)
750 {
751 buf_reset(priv->prefix);
752 priv->kill_prefix = false;
753 }
754 priv->state.is_mailbox_list = false;
755 if (priv->state.imap_browse)
756 {
757 init_state(&priv->state);
758 priv->state.imap_browse = true;
760 browser_sort(&priv->state);
761 }
762 else
763 {
764 if (examine_directory(priv->mailbox, priv->menu, &priv->state,
765 buf_string(&LastDir), buf_string(priv->prefix)) == -1)
766 {
767 /* try to restore the old values */
769 if (examine_directory(priv->mailbox, priv->menu, &priv->state,
770 buf_string(&LastDir), buf_string(priv->prefix)) == -1)
771 {
773 priv->done = true;
774 return FR_DONE;
775 }
776 }
777 /* resolve paths navigated from GUI */
778 if (mutt_path_realpath(&LastDir) == 0)
779 return FR_ERROR;
780 }
781
782 browser_highlight_default(&priv->state, priv->menu);
783 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
784 priv->goto_swapper[0] = '\0';
785 return FR_SUCCESS;
786 }
787 }
788 else if (op == OP_DESCEND_DIRECTORY)
789 {
790 mutt_error(_("%s is not a directory"), ARRAY_GET(&priv->state.entry, index)->name);
791 return FR_ERROR;
792 }
793
794 if (priv->state.is_mailbox_list || OptNews)
795 {
796 buf_strcpy(priv->file, ff->name);
797 expand_path(priv->file, false);
798 }
799 else if (priv->state.imap_browse)
800 {
801 buf_strcpy(priv->file, ff->name);
802 }
803 else
804 {
806 }
807
808 return op_exit(priv, event);
809}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
MailboxType
Supported mailbox formats.
Definition mailbox.h:40
@ MUTT_MAILBOX_ERROR
Error occurred examining Mailbox.
Definition mailbox.h:42
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition mailbox.h:43
static int op_exit(struct AliasMenuData *mdata, const struct KeyEvent *event)
exit this menu - Implements alias_function_t -
Definition functions.c:234
#define mutt_warning(...)
Definition logging2.h:92
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition mx.c:1323
struct Buffer * old_last_dir
Previous to last dir.
char goto_swapper[PATH_MAX]
Saved path after <goto-folder>
char delim
Path delimiter.
Definition lib.h:94
bool inferiors
Folder has children.
Definition lib.h:98
char * home_dir
User's home directory.
Definition neomutt.h:56
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition url.h:69
char * path
Path.
Definition url.h:75
struct Url * url_parse(const char *src)
Fill in Url.
Definition url.c:239
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition url.c:124
+ Here is the call graph for this function:

◆ op_load_active()

static int op_load_active ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Load list of all newsgroups from NNTP server - Implements browser_function_t -.

Definition at line 814 of file functions.c.

815{
816 if (!OptNews)
817 return FR_NOT_IMPL;
818
820
821 if (nntp_newsrc_parse(adata) < 0)
822 return FR_ERROR;
823
824 for (size_t i = 0; i < adata->groups_num; i++)
825 {
826 struct NntpMboxData *mdata = adata->groups_list[i];
827 if (mdata)
828 mdata->deleted = true;
829 }
833
834 destroy_state(&priv->state);
835 if (priv->state.is_mailbox_list)
836 {
837 examine_mailboxes(priv->mailbox, priv->menu, &priv->state);
838 }
839 else
840 {
841 if (examine_directory(priv->mailbox, priv->menu, &priv->state, NULL, NULL) == -1)
842 return FR_ERROR;
843 }
844 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
845 return FR_SUCCESS;
846}
int examine_mailboxes(struct Mailbox *m, struct Menu *menu, struct BrowserState *state)
Get list of mailboxes/subscribed newsgroups.
int nntp_active_fetch(struct NntpAccountData *adata, bool mark_new)
Fetch list of all newsgroups from server.
Definition nntp.c:2034
struct NntpMboxData ** groups_list
List of newsgroups.
Definition adata.h:60
bool deleted
Newsgroup is deleted.
Definition mdata.h:45
struct NntpAccountData * adata
Account data.
Definition mdata.h:48
+ Here is the call graph for this function:

◆ op_mailbox_list()

static int op_mailbox_list ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

List mailboxes with new mail - Implements browser_function_t -.

Definition at line 851 of file functions.c.

852{
854 return FR_SUCCESS;
855}
bool mutt_mailbox_list(void)
Show a message with the list of mailboxes with new mail.
+ Here is the call graph for this function:

◆ op_rename_mailbox()

static int op_rename_mailbox ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Rename the current mailbox (IMAP only) - Implements browser_function_t -.

Definition at line 860 of file functions.c.

861{
862 int index = menu_get_index(priv->menu);
863 struct FolderFile *ff = ARRAY_GET(&priv->state.entry, index);
864 if (!ff->imap)
865 {
866 mutt_error(_("Rename is only supported for IMAP mailboxes"));
867 return FR_ERROR;
868 }
869
870 if (imap_mailbox_rename(ff->name) < 0)
871 return FR_ERROR;
872
873 destroy_state(&priv->state);
874 init_state(&priv->state);
875 priv->state.imap_browse = true;
877 browser_sort(&priv->state);
878 browser_highlight_default(&priv->state, priv->menu);
879 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
880
881 return FR_SUCCESS;
882}
int imap_mailbox_rename(const char *path)
Rename a mailbox.
Definition browse.c:448
+ Here is the call graph for this function:

◆ op_sort()

static int op_sort ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Sort messages - Implements browser_function_t -.

This function handles:

  • OP_SORT
  • OP_SORT_REVERSE

Definition at line 891 of file functions.c.

892{
893 bool resort = true;
894 int sort = -1;
895 const int op = event->op;
896 int reverse = (op == OP_SORT_REVERSE);
897
898 switch (mw_multi_choice((reverse) ?
899 /* L10N: The highlighted letters must match the "Sort" options */
900 _("Reverse sort by (d)ate, (a)lpha, si(z)e, d(e)scription, (c)ount, ne(w) count, or do(n)'t sort?") :
901 /* L10N: The highlighted letters must match the "Reverse Sort" options */
902 _("Sort by (d)ate, (a)lpha, si(z)e, d(e)scription, (c)ount, ne(w) count, or do(n)'t sort?"),
903 /* L10N: These must match the highlighted letters from "Sort" and "Reverse Sort" */
904 _("dazecwn")))
905 {
906 case -1: /* abort */
907 resort = false;
908 break;
909
910 case 1: /* (d)ate */
911 sort = BROWSER_SORT_DATE;
912 break;
913
914 case 2: /* (a)lpha */
915 sort = BROWSER_SORT_ALPHA;
916 break;
917
918 case 3: /* si(z)e */
919 sort = BROWSER_SORT_SIZE;
920 break;
921
922 case 4: /* d(e)scription */
923 sort = BROWSER_SORT_DESC;
924 break;
925
926 case 5: /* (c)ount */
927 sort = BROWSER_SORT_COUNT;
928 break;
929
930 case 6: /* ne(w) count */
931 sort = BROWSER_SORT_NEW;
932 break;
933
934 case 7: /* do(n)'t sort */
936 break;
937 }
938
939 if (!resort)
940 return FR_NO_ACTION;
941
942 sort |= reverse ? SORT_REVERSE : 0;
943 cs_subset_str_native_set(NeoMutt->sub, "browser_sort", sort, NULL);
944 browser_sort(&priv->state);
945 browser_highlight_default(&priv->state, priv->menu);
947 return FR_SUCCESS;
948}
@ BROWSER_SORT_ALPHA
Sort by name.
Definition sort.h:31
@ BROWSER_SORT_UNSORTED
Sort into the raw order.
Definition sort.h:37
@ BROWSER_SORT_COUNT
Sort by total message count.
Definition sort.h:32
@ BROWSER_SORT_DATE
Sort by date.
Definition sort.h:33
@ BROWSER_SORT_NEW
Sort by count of new messages.
Definition sort.h:35
@ BROWSER_SORT_SIZE
Sort by size.
Definition sort.h:36
@ BROWSER_SORT_DESC
Sort by description.
Definition sort.h:34
#define SORT_REVERSE
Reverse the order of the sort.
Definition sort.h:40
int mw_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question -.
Definition question.c:62
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:303
+ Here is the call graph for this function:

◆ op_subscribe_pattern()

static int op_subscribe_pattern ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Subscribe to newsgroups matching a pattern - Implements browser_function_t -.

This function handles:

  • OP_SUBSCRIBE_PATTERN
  • OP_UNSUBSCRIBE_PATTERN

Definition at line 957 of file functions.c.

958{
959 if (!OptNews)
960 return FR_NOT_IMPL;
961
963 regex_t rx = { 0 };
964 int index = menu_get_index(priv->menu);
965
966 char tmp2[256] = { 0 };
967
968 const int op = event->op;
969 struct Buffer *buf = buf_pool_get();
970 if (op == OP_SUBSCRIBE_PATTERN)
971 snprintf(tmp2, sizeof(tmp2), _("Subscribe pattern: "));
972 else
973 snprintf(tmp2, sizeof(tmp2), _("Unsubscribe pattern: "));
974 /* buf comes from the buffer pool, so defaults to size 1024 */
975 if ((mw_get_field(tmp2, buf, MUTT_COMP_NO_FLAGS, HC_PATTERN, &CompletePatternOps, NULL) != 0) ||
976 buf_is_empty(buf))
977 {
978 buf_pool_release(&buf);
979 return FR_NO_ACTION;
980 }
981
982 int err = REG_COMP(&rx, buf->data, REG_NOSUB);
983 if (err != 0)
984 {
985 regerror(err, &rx, buf->data, buf->dsize);
986 regfree(&rx);
987 mutt_error("%s", buf_string(buf));
988 buf_pool_release(&buf);
989 return FR_ERROR;
990 }
992 index = 0;
993 buf_pool_release(&buf);
994
995 int rc = nntp_newsrc_parse(adata);
996 if (rc < 0)
997 return FR_ERROR;
998
999 struct FolderFile *ff = NULL;
1000 ARRAY_FOREACH_FROM(ff, &priv->state.entry, index)
1001 {
1002 if (regexec(&rx, ff->name, 0, NULL, 0) == 0)
1003 {
1004 if (op == OP_SUBSCRIBE_PATTERN)
1005 mutt_newsgroup_subscribe(adata, ff->name);
1006 else
1007 mutt_newsgroup_unsubscribe(adata, ff->name);
1008 }
1009 }
1010
1011 if (op == OP_SUBSCRIBE_PATTERN)
1012 {
1013 for (size_t j = 0; j < adata->groups_num; j++)
1014 {
1015 struct NntpMboxData *mdata = adata->groups_list[j];
1016 if (mdata && mdata->group && !mdata->subscribed)
1017 {
1018 if (regexec(&rx, mdata->group, 0, NULL, 0) == 0)
1019 {
1021 browser_add_folder(priv->menu, &priv->state, mdata->group, NULL, NULL, NULL, mdata);
1022 }
1023 }
1024 }
1025 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
1026 }
1027 if (rc > 0)
1032 regfree(&rx);
1033 return FR_SUCCESS;
1034}
#define ARRAY_FOREACH_FROM(elem, head, from)
Iterate from an index to the end.
Definition array.h:235
void browser_add_folder(const struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *st, struct Mailbox *m, void *data)
Add a folder to the browser list.
@ HC_PATTERN
Patterns.
Definition lib.h:59
const struct CompleteOps CompletePatternOps
Auto-Completion of Patterns.
Definition complete.c:98
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition regex3.h:49
unsigned int groups_num
Number of newsgroups.
Definition adata.h:58
+ Here is the call graph for this function:

◆ op_toggle_mailboxes()

static int op_toggle_mailboxes ( struct BrowserPrivateData * priv,
const struct KeyEvent * event )
static

Toggle whether to browse mailboxes or all files - Implements browser_function_t -.

This function handles:

  • OP_CHECK_NEW
  • OP_TOGGLE_MAILBOXES

Definition at line 1043 of file functions.c.

1044{
1045 if (priv->state.is_mailbox_list)
1046 {
1048 }
1049
1050 const int op = event->op;
1051 if (op == OP_TOGGLE_MAILBOXES)
1052 {
1054 }
1055
1056 if (op == OP_BROWSER_GOTO_FOLDER)
1057 {
1058 /* When in mailboxes mode, disables this feature */
1059 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
1060 if (c_folder)
1061 {
1062 mutt_debug(LL_DEBUG3, "= hit! Folder: %s, LastDir: %s\n", c_folder,
1064 if (priv->goto_swapper[0] == '\0')
1065 {
1066 if (!mutt_str_equal(buf_string(&LastDir), c_folder))
1067 {
1068 /* Stores into goto_swapper LastDir, and swaps to `$folder` */
1069 mutt_str_copy(priv->goto_swapper, buf_string(&LastDir), sizeof(priv->goto_swapper));
1071 buf_strcpy(&LastDir, c_folder);
1072 }
1073 }
1074 else
1075 {
1078 priv->goto_swapper[0] = '\0';
1079 }
1080 }
1081 }
1082 destroy_state(&priv->state);
1083 buf_reset(priv->prefix);
1084 priv->kill_prefix = false;
1085
1086 if (priv->state.is_mailbox_list)
1087 {
1088 examine_mailboxes(priv->mailbox, priv->menu, &priv->state);
1089 }
1090 else if (imap_path_probe(buf_string(&LastDir), NULL) == MUTT_IMAP)
1091 {
1092 init_state(&priv->state);
1093 priv->state.imap_browse = true;
1095 browser_sort(&priv->state);
1096 }
1097 else if (examine_directory(priv->mailbox, priv->menu, &priv->state,
1098 buf_string(&LastDir), buf_string(priv->prefix)) == -1)
1099 {
1100 priv->done = true;
1101 return FR_ERROR;
1102 }
1103 init_menu(&priv->state, priv->menu, priv->mailbox, priv->sbar);
1104 if (priv->state.is_mailbox_list)
1106 return FR_ERROR;
1107}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
struct Buffer LastDirBackup
Browser: backup copy of the current directory.
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
@ LL_DEBUG3
Log at debug level 3.
Definition logging2.h:47
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:583
int last_selected_mailbox
Index of last selected Mailbox.
+ Here is the call graph for this function: