NeoMutt  2025-12-11-1059-g2f5469
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
browse.c
Go to the documentation of this file.
1
28
34
35#include "config.h"
36#include <limits.h>
37#include <stdbool.h>
38#include <stdio.h>
39#include <string.h>
40#include "private.h"
41#include "mutt/lib.h"
42#include "config/lib.h"
43#include "email/lib.h"
44#include "core/lib.h"
45#include "conn/lib.h"
46#include "gui/lib.h"
47#include "lib.h"
48#include "browser/lib.h"
49#include "editor/lib.h"
50#include "history/lib.h"
51#include "adata.h"
52#include "mdata.h"
53#include "mutt_logging.h"
54#include "muttlib.h"
55
68static void add_folder(char delim, char *folder, bool noselect, bool noinferiors,
69 struct BrowserState *state, bool isparent)
70{
71 char tmp[PATH_MAX] = { 0 };
72 char relpath[PATH_MAX] = { 0 };
73 struct ConnAccount cac = { { 0 } };
74 char mailbox[1024] = { 0 };
75 struct FolderFile ff = { 0 };
76
77 if (imap_parse_path(state->folder, &cac, mailbox, sizeof(mailbox)) != 0)
78 return;
79
80 if (isparent)
81 {
82 /* render superiors as unix-standard ".." */
83 mutt_str_copy(relpath, "../", sizeof(relpath));
84 }
85 else if (mutt_str_startswith(folder, mailbox))
86 {
87 /* strip current folder from target, to render a relative path */
88 mutt_str_copy(relpath, folder + mutt_str_len(mailbox), sizeof(relpath));
89 }
90 else
91 {
92 mutt_str_copy(relpath, folder, sizeof(relpath));
93 }
94
95 /* apply filemask filter. This should really be done at menu setup rather
96 * than at scan, since it's so expensive to scan. But that's big changes
97 * to browser.c */
98 const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
99 if (!mutt_regex_match(c_mask, relpath))
100 {
101 return;
102 }
103
104 imap_qualify_path(tmp, sizeof(tmp), &cac, folder);
105 ff.name = mutt_str_dup(tmp);
106
107 /* mark desc with delim in browser if it can have subfolders */
108 if (!isparent && !noinferiors && (strlen(relpath) < sizeof(relpath) - 1))
109 {
110 relpath[strlen(relpath) + 1] = '\0';
111 relpath[strlen(relpath)] = delim;
112 }
113
114 ff.desc = mutt_str_dup(relpath);
115 ff.imap = true;
116
117 /* delimiter at the root is useless. */
118 if (folder[0] == '\0')
119 delim = '\0';
120 ff.delim = delim;
121 ff.selectable = !noselect;
122 ff.inferiors = !noinferiors;
123
124 struct MailboxArray ma = neomutt_mailboxes_get(NeoMutt, MUTT_MAILBOX_ANY);
125 struct Mailbox **mp = NULL;
126 ARRAY_FOREACH(mp, &ma)
127 {
128 struct Mailbox *m = *mp;
129
130 if (mutt_str_equal(tmp, mailbox_path(m)))
131 {
132 ff.has_mailbox = true;
133 ff.has_new_mail = m->has_new;
134 ff.msg_count = m->msg_count;
135 ff.msg_unread = m->msg_unread;
136 break;
137 }
138 }
139
140 ARRAY_FREE(&ma); // Clean up the ARRAY, but not the Mailboxes
141
142 ARRAY_ADD(&state->entry, ff);
143}
144
154static int browse_add_list_result(struct ImapAccountData *adata, const char *cmd,
155 struct BrowserState *bstate, bool isparent)
156{
157 struct ImapList list = { 0 };
158 int rc;
159 struct Url *url = url_parse(bstate->folder);
160 if (!url)
161 return -1;
162
163 imap_cmd_start(adata, cmd);
164 adata->cmdresult = &list;
165 do
166 {
167 list.name = NULL;
168 rc = imap_cmd_step(adata);
169
170 if ((rc == IMAP_RES_CONTINUE) && list.name)
171 {
172 /* Let a parent folder never be selectable for navigation */
173 if (isparent)
174 list.noselect = true;
175 /* prune current folder from output */
176 if (isparent || !mutt_str_startswith(url->path, list.name))
177 add_folder(list.delim, list.name, list.noselect, list.noinferiors, bstate, isparent);
178 }
179 } while (rc == IMAP_RES_CONTINUE);
180 adata->cmdresult = NULL;
181
182 url_free(&url);
183
184 return (rc == IMAP_RES_OK) ? 0 : -1;
185}
186
194static void browse_build_list_cmd(struct Buffer *buf, const char *list_cmd,
195 const char *mbox, bool extended)
196{
197 buf_printf(buf, "%s \"\" %s", list_cmd, mbox);
198 if (extended)
199 buf_addstr(buf, " RETURN (CHILDREN)");
200}
201
211int imap_browse(const char *path, struct BrowserState *state)
212{
213 struct ImapAccountData *adata = NULL;
214 struct ImapList list = { 0 };
215 struct ConnAccount cac = { { 0 } };
216 char buf[PATH_MAX + 16] = { 0 };
217 char mbox[PATH_MAX] = { 0 };
218 char munged_mbox[PATH_MAX] = { 0 };
219 const char *list_cmd = NULL;
220 struct Buffer *cmd = NULL;
221 int n;
222 bool showparents = false;
223 int rc = -1;
224
225 if (imap_parse_path(path, &cac, buf, sizeof(buf)) != 0)
226 {
227 mutt_error(_("%s is an invalid IMAP path"), path);
228 return -1;
229 }
230
231 const bool c_imap_check_subscribed = cs_subset_bool(NeoMutt->sub, "imap_check_subscribed");
232 cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed", false, NULL);
233
234 // Pick first mailbox connected to the same server
235 struct MailboxArray ma = neomutt_mailboxes_get(NeoMutt, MUTT_IMAP);
236 struct Mailbox **mp = NULL;
237 ARRAY_FOREACH(mp, &ma)
238 {
239 adata = imap_adata_get(*mp);
240 // Pick first mailbox connected on the same server
241 if (imap_account_match(&adata->conn->account, &cac))
242 break;
243 adata = NULL;
244 }
245 ARRAY_FREE(&ma); // Clean up the ARRAY, but not the Mailboxes
246
247 if (!adata)
248 goto fail;
249
250 const bool c_imap_list_subscribed = cs_subset_bool(NeoMutt->sub, "imap_list_subscribed");
251 if (c_imap_list_subscribed)
252 {
253 /* RFC3348 section 3 states LSUB is unreliable for hierarchy information.
254 * The newer LIST extensions are designed for this. */
256 list_cmd = "LIST (SUBSCRIBED RECURSIVEMATCH)";
257 else
258 list_cmd = "LSUB";
259 }
260 else
261 {
262 list_cmd = "LIST";
263 }
264
265 mutt_message(_("Getting folder list..."));
266
267 cmd = buf_pool_get();
268
269 /* skip check for parents when at the root */
270 if (buf[0] == '\0')
271 {
272 mbox[0] = '\0';
273 n = 0;
274 }
275 else
276 {
277 imap_fix_path_with_delim(adata->delim, buf, mbox, sizeof(mbox));
278 n = mutt_str_len(mbox);
279 }
280
281 if (n > 0)
282 {
283 int rc_step;
284 mutt_debug(LL_DEBUG3, "mbox: %s\n", mbox);
285
286 /* if our target exists and has inferiors, enter it if we
287 * aren't already going to */
288 imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), mbox);
289 browse_build_list_cmd(cmd, list_cmd, munged_mbox,
291 imap_cmd_start(adata, buf_string(cmd));
292 adata->cmdresult = &list;
293 do
294 {
295 list.name = 0;
296 rc_step = imap_cmd_step(adata);
297 if ((rc_step == IMAP_RES_CONTINUE) && list.name)
298 {
299 if (!list.noinferiors && list.name[0] &&
300 (imap_mxcmp(list.name, mbox) == 0) && (n < sizeof(mbox) - 1))
301 {
302 mbox[n++] = list.delim;
303 mbox[n] = '\0';
304 }
305 }
306 } while (rc_step == IMAP_RES_CONTINUE);
307 adata->cmdresult = NULL;
308
309 /* if we're descending a folder, mark it as current in browser_state */
310 if (mbox[n - 1] == list.delim)
311 {
312 showparents = true;
313 imap_qualify_path(buf, sizeof(buf), &cac, mbox);
314 state->folder = mutt_str_dup(buf);
315 n--;
316 }
317
318 /* Find superiors to list
319 * Note: UW-IMAP servers return folder + delimiter when asked to list
320 * folder + delimiter. Cyrus servers don't. So we ask for folder,
321 * and tack on delimiter ourselves.
322 * Further note: UW-IMAP servers return nothing when asked for
323 * NAMESPACES without delimiters at the end. Argh! */
324 for (n--; n >= 0 && mbox[n] != list.delim; n--)
325 ; // do nothing
326
327 if (n > 0) /* "aaaa/bbbb/" -> "aaaa" */
328 {
329 /* forget the check, it is too delicate (see above). Have we ever
330 * had the parent not exist? */
331 char ctmp = mbox[n];
332 mbox[n] = '\0';
333
334 if (showparents)
335 {
336 mutt_debug(LL_DEBUG3, "adding parent %s\n", mbox);
337 add_folder(list.delim, mbox, true, false, state, true);
338 }
339
340 /* if our target isn't a folder, we are in our superior */
341 if (!state->folder)
342 {
343 /* store folder with delimiter */
344 mbox[n++] = ctmp;
345 ctmp = mbox[n];
346 mbox[n] = '\0';
347 imap_qualify_path(buf, sizeof(buf), &cac, mbox);
348 state->folder = mutt_str_dup(buf);
349 }
350 mbox[n] = ctmp;
351 }
352 else
353 {
354 /* "/bbbb/" -> add "/", "aaaa/" -> add "" */
355 char relpath[2] = { 0 };
356 /* folder may be "/" */
357 snprintf(relpath, sizeof(relpath), "%c", (n < 0) ? '\0' : adata->delim);
358 if (showparents)
359 add_folder(adata->delim, relpath, true, false, state, true);
360 if (!state->folder)
361 {
362 imap_qualify_path(buf, sizeof(buf), &cac, relpath);
363 state->folder = mutt_str_dup(buf);
364 }
365 }
366 }
367
368 /* no namespace, no folder: set folder to host only */
369 if (!state->folder)
370 {
371 imap_qualify_path(buf, sizeof(buf), &cac, NULL);
372 state->folder = mutt_str_dup(buf);
373 }
374
375 mutt_debug(LL_DEBUG3, "Quoting mailbox scan: %s -> ", mbox);
376 snprintf(buf, sizeof(buf), "%s%%", mbox);
377 imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), buf);
378 mutt_debug(LL_DEBUG3, "%s\n", munged_mbox);
379 browse_build_list_cmd(cmd, list_cmd, munged_mbox, adata->capabilities & IMAP_CAP_LIST_EXTENDED);
380 if (browse_add_list_result(adata, buf_string(cmd), state, false))
381 goto fail;
382
383 if (ARRAY_EMPTY(&state->entry))
384 {
385 // L10N: (%s) is the name / path of the folder we were trying to browse
386 mutt_error(_("No such folder: %s"), path);
387 goto fail;
388 }
389
391 rc = 0;
392
393fail:
394 buf_pool_release(&cmd);
395 cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed",
396 c_imap_check_subscribed, NULL);
397 return rc;
398}
399
408int imap_mailbox_create(const char *path)
409{
410 struct ImapAccountData *adata = NULL;
411 struct ImapMboxData *mdata = NULL;
412 struct Buffer *name = buf_pool_get();
413 int rc = -1;
414
415 if (imap_adata_find(path, &adata, &mdata) < 0)
416 {
417 mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
418 goto done;
419 }
420
421 /* append a delimiter if necessary */
422 const size_t n = buf_strcpy(name, mdata->real_name);
423 if ((n != 0) && (buf_at(name, n - 1) != adata->delim))
424 {
425 buf_addch(name, adata->delim);
426 }
427
428 struct FileCompletionData cdata = { false, NULL, NULL, NULL, NULL };
429 if (mw_get_field(_("Create mailbox: "), name, MUTT_COMP_NONE, HC_MAILBOX,
430 &CompleteMailboxOps, &cdata) != 0)
431 {
432 goto done;
433 }
434
435 if (buf_is_empty(name))
436 {
437 mutt_error(_("Mailbox must have a name"));
438 goto done;
439 }
440
441 if (imap_create_mailbox(adata, buf_string(name)) < 0)
442 goto done;
443
444 imap_mdata_free((void *) &mdata);
445 mutt_message(_("Mailbox created"));
446 mutt_sleep(0);
447 rc = 0;
448
449done:
450 imap_mdata_free((void *) &mdata);
451 buf_pool_release(&name);
452 return rc;
453}
454
463int imap_mailbox_rename(const char *path)
464{
465 struct ImapAccountData *adata = NULL;
466 struct ImapMboxData *mdata = NULL;
467 struct Buffer *buf = NULL;
468 struct Buffer *newname = NULL;
469 int rc = -1;
470
471 if (imap_adata_find(path, &adata, &mdata) < 0)
472 {
473 mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
474 goto done;
475 }
476
477 if (mdata->real_name[0] == '\0')
478 {
479 mutt_error(_("Can't rename root folder"));
480 goto done;
481 }
482
483 buf = buf_pool_get();
484 newname = buf_pool_get();
485
486 buf_printf(buf, _("Rename mailbox %s to: "), mdata->name);
487 buf_strcpy(newname, mdata->name);
488
489 struct FileCompletionData cdata = { false, NULL, NULL, NULL, NULL };
491 &CompleteMailboxOps, &cdata) != 0)
492 {
493 goto done;
494 }
495
496 if (buf_is_empty(newname))
497 {
498 mutt_error(_("Mailbox must have a name"));
499 goto done;
500 }
501
502 imap_fix_path_with_delim(adata->delim, buf_string(newname), buf->data, buf->dsize);
503
504 if (imap_rename_mailbox(adata, mdata->name, buf_string(buf)) < 0)
505 {
506 mutt_error(_("Rename failed: %s"), imap_get_qualifier(adata->buf));
507 goto done;
508 }
509
510 mutt_message(_("Mailbox renamed"));
511 mutt_sleep(0);
512 rc = 0;
513
514done:
515 imap_mdata_free((void *) &mdata);
516 buf_pool_release(&buf);
517 buf_pool_release(&newname);
518
519 return rc;
520}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
int imap_browse(const char *path, struct BrowserState *state)
IMAP hook into the folder browser.
Definition browse.c:211
static int browse_add_list_result(struct ImapAccountData *adata, const char *cmd, struct BrowserState *bstate, bool isparent)
Add entries to the folder browser.
Definition browse.c:154
static void browse_build_list_cmd(struct Buffer *buf, const char *list_cmd, const char *mbox, bool extended)
Build a LIST command for a mailbox.
Definition browse.c:194
static void add_folder(char delim, char *folder, bool noselect, bool noinferiors, struct BrowserState *state, bool isparent)
Format and add an IMAP folder to the browser.
Definition browse.c:68
int imap_mailbox_create(const char *path)
Create a new IMAP mailbox.
Definition browse.c:408
int imap_mailbox_rename(const char *path)
Rename a mailbox.
Definition browse.c:463
const struct CompleteOps CompleteMailboxOps
Auto-Completion of Files / Mailboxes.
Definition complete.c:159
Select a Mailbox from a list.
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:168
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:298
char buf_at(const struct Buffer *buf, size_t offset)
Return the character at the given offset.
Definition buffer.c:674
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:248
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:233
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:99
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition helpers.c:217
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
Convenience wrapper for the config headers.
Connection Library.
Convenience wrapper for the core headers.
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:217
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:49
@ MUTT_MAILBOX_ANY
Match any Mailbox type.
Definition mailbox.h:41
Edit a string.
@ MUTT_COMP_NONE
No flags are set.
Definition wdata.h:46
Structs that make up an email.
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:502
#define mutt_error(...)
Definition logging2.h:94
#define mutt_message(...)
Definition logging2.h:93
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free() -.
Definition mdata.c:40
Convenience wrapper for the gui headers.
Read/write command history from/to a file.
@ HC_MAILBOX
Mailboxes.
Definition lib.h:62
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition adata.c:162
Imap-specific Account data.
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition command.c:1219
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition command.c:1233
IMAP network mailbox.
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition util.c:485
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition util.c:556
Imap-specific Mailbox data.
Shared constants/structs that are private to IMAP.
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition util.c:862
#define IMAP_RES_OK
<tag> OK ...
Definition private.h:54
char * imap_fix_path_with_delim(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition util.c:720
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition util.c:73
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition util.c:1108
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition util.c:973
@ IMAP_CAP_LIST_EXTENDED
RFC5258: IMAP4 LIST Command Extensions.
Definition private.h:152
#define IMAP_RES_CONTINUE
* ...
Definition private.h:55
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition util.c:814
int imap_rename_mailbox(struct ImapAccountData *adata, char *oldname, const char *newname)
Rename a mailbox.
Definition imap.c:584
int imap_create_mailbox(struct ImapAccountData *adata, const char *mailbox)
Create a new mailbox.
Definition imap.c:542
@ LL_DEBUG3
Log at debug level 3.
Definition logging2.h:47
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
Convenience wrapper for the library headers.
#define _(a)
Definition message.h:28
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture().
Definition regex.c:621
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition string.c:234
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
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:587
#define PATH_MAX
Definition mutt.h:49
void mutt_clear_error(void)
Clear the message line (bottom line of screen).
NeoMutt Logging.
void mutt_sleep(short s)
Sleep for a while.
Definition muttlib.c:795
Some miscellaneous functions.
struct MailboxArray neomutt_mailboxes_get(struct NeoMutt *n, enum MailboxType type)
Get an Array of matching Mailboxes.
Definition neomutt.c:607
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
void * adata
Private data (for Mailbox backends).
Definition account.h:42
State of the file/mailbox browser.
Definition lib.h:148
char * folder
Folder name.
Definition lib.h:151
struct BrowserEntryArray entry
Array of files / dirs / mailboxes.
Definition lib.h:149
String manipulation buffer.
Definition buffer.h:37
size_t dsize
Length of data.
Definition buffer.h:40
char * data
Pointer to data.
Definition buffer.h:38
Login details for a remote server.
Definition connaccount.h:59
struct ConnAccount account
Account details: username, password, etc.
Definition connection.h:49
Input for the file completion function.
Definition curs_lib.h:39
Browser entry representing a folder/dir.
Definition lib.h:82
bool selectable
Folder can be selected.
Definition lib.h:100
char delim
Path delimiter.
Definition lib.h:97
bool imap
This is an IMAP folder.
Definition lib.h:99
bool has_mailbox
This is a mailbox.
Definition lib.h:102
char * name
Name of file/dir/mailbox.
Definition lib.h:90
bool has_new_mail
true if mailbox has "new mail"
Definition lib.h:93
char * desc
Description of mailbox.
Definition lib.h:91
int msg_count
total number of messages
Definition lib.h:94
bool inferiors
Folder has children.
Definition lib.h:101
int msg_unread
number of unread messages
Definition lib.h:95
IMAP-specific Account data -.
Definition adata.h:40
char delim
Path delimiter.
Definition adata.h:79
struct ImapList * cmdresult
Resuls of complicated commands.
Definition adata.h:70
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition adata.h:64
ImapCapFlags capabilities
Capability flags.
Definition adata.h:56
char * buf
Command buffer.
Definition adata.h:61
struct Connection * conn
Connection to IMAP server.
Definition adata.h:41
Items in an IMAP browser.
Definition private.h:165
bool noselect
Mailbox is not selectable.
Definition private.h:168
bool noinferiors
Mailbox has no children.
Definition private.h:169
char * name
Mailbox name.
Definition private.h:166
char delim
Hierarchy delimiter.
Definition private.h:167
IMAP-specific Mailbox data -.
Definition mdata.h:40
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition mdata.h:43
char * name
Mailbox name.
Definition mdata.h:41
A mailbox.
Definition mailbox.h:81
bool has_new
Mailbox has new mail.
Definition mailbox.h:87
int msg_count
Total number of messages.
Definition mailbox.h:90
void * mdata
Driver specific data.
Definition mailbox.h:134
int msg_unread
Number of unread messages.
Definition mailbox.h:91
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
Cached regular expression.
Definition regex3.h:85
A parsed URL proto://user:password@host:port/path?a=1&b=2.
Definition url.h:69
char * path
Path.
Definition url.h:75
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
struct Url * url_parse(const char *src)
Fill in Url.
Definition url.c:247
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition url.c:124