NeoMutt  2025-12-11-1059-g2f5469
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
browse.c File Reference

GUI select an IMAP mailbox from a list. More...

#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "private.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 "lib.h"
#include "browser/lib.h"
#include "editor/lib.h"
#include "history/lib.h"
#include "adata.h"
#include "mdata.h"
#include "mutt_logging.h"
#include "muttlib.h"
Include dependency graph for browse.c:

Go to the source code of this file.

Functions

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.
static int browse_add_list_result (struct ImapAccountData *adata, const char *cmd, struct BrowserState *bstate, bool isparent)
 Add entries to the folder browser.
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.
int imap_browse (const char *path, struct BrowserState *state)
 IMAP hook into the folder browser.
int imap_mailbox_create (const char *path)
 Create a new IMAP mailbox.
int imap_mailbox_rename (const char *path)
 Rename a mailbox.

Detailed Description

GUI select an IMAP mailbox from a list.

Authors
  • Brandon Long
  • Brendan Cully
  • Richard Russon
  • Mehdi Abaakouk
  • Pietro Cerutti
  • Ian Zimmerman
  • Naveen Nathan

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 browse.c.

Function Documentation

◆ add_folder()

void add_folder ( char delim,
char * folder,
bool noselect,
bool noinferiors,
struct BrowserState * state,
bool isparent )
static

Format and add an IMAP folder to the browser.

Parameters
delimPath delimiter
folderName of the folder
noselecttrue if item isn't selectable
noinferiorstrue if item has no children
stateBrowser state to add to
isparenttrue if item represents the parent folder

The folder parameter should already be 'unmunged' via imap_unmunge_mbox_name().

Definition at line 68 of file browse.c.

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}
#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_FREE(head)
Release all memory.
Definition array.h:209
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition helpers.c:217
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:217
@ MUTT_MAILBOX_ANY
Match any Mailbox type.
Definition mailbox.h:41
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
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
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
struct MailboxArray neomutt_mailboxes_get(struct NeoMutt *n, enum MailboxType type)
Get an Array of matching Mailboxes.
Definition neomutt.c:607
char * folder
Folder name.
Definition lib.h:151
struct BrowserEntryArray entry
Array of files / dirs / mailboxes.
Definition lib.h:149
Login details for a remote server.
Definition connaccount.h:59
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
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
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ browse_add_list_result()

int browse_add_list_result ( struct ImapAccountData * adata,
const char * cmd,
struct BrowserState * bstate,
bool isparent )
static

Add entries to the folder browser.

Parameters
adataImap Account data
cmdCommand string from server
bstateBrowser state to add to
isparentIs this a shortcut for the parent directory?
Return values
0Success
-1Failure

Definition at line 154 of file browse.c.

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}
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_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
#define IMAP_RES_OK
<tag> OK ...
Definition private.h:54
#define IMAP_RES_CONTINUE
* ...
Definition private.h:55
struct ImapList * cmdresult
Resuls of complicated commands.
Definition adata.h:70
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
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:247
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition url.c:124
Here is the call graph for this function:
Here is the caller graph for this function:

◆ browse_build_list_cmd()

void browse_build_list_cmd ( struct Buffer * buf,
const char * list_cmd,
const char * mbox,
bool extended )
static

Build a LIST command for a mailbox.

Parameters
bufBuffer for the command
list_cmdLIST command to use, e.g. "LSUB"
mboxMunged mailbox name
extendedtrue if the server supports LIST-EXTENDED

Definition at line 194 of file browse.c.

196{
197 buf_printf(buf, "%s \"\" %s", list_cmd, mbox);
198 if (extended)
199 buf_addstr(buf, " RETURN (CHILDREN)");
200}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:168
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:233
Here is the call graph for this function:
Here is the caller graph for this function:

◆ imap_browse()

int imap_browse ( const char * path,
struct BrowserState * state )

IMAP hook into the folder browser.

Parameters
pathCurrent folder
stateBrowserState to populate
Return values
0Success
-1Failure

Fill out browser_state, given a current folder to browse

Definition at line 211 of file browse.c.

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}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
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 const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:99
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:49
#define mutt_error(...)
Definition logging2.h:94
#define mutt_message(...)
Definition logging2.h:93
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition adata.c:162
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition util.c:556
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
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
@ LL_DEBUG3
Log at debug level 3.
Definition logging2.h:47
#define _(a)
Definition message.h:28
void mutt_clear_error(void)
Clear the message line (bottom line of screen).
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
String manipulation buffer.
Definition buffer.h:37
struct ConnAccount account
Account details: username, password, etc.
Definition connection.h:49
IMAP-specific Account data -.
Definition adata.h:40
char delim
Path delimiter.
Definition adata.h:79
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
struct Connection * conn
Connection to IMAP server.
Definition adata.h:41
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:
Here is the caller graph for this function:

◆ imap_mailbox_create()

int imap_mailbox_create ( const char * path)

Create a new IMAP mailbox.

Parameters
pathMailbox to create
Return values
0Success
-1Failure

Prompt for a new mailbox name, and try to create it

Definition at line 408 of file browse.c.

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}
const struct CompleteOps CompleteMailboxOps
Auto-Completion of Files / Mailboxes.
Definition complete.c:159
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_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
@ MUTT_COMP_NONE
No flags are set.
Definition wdata.h:46
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
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free() -.
Definition mdata.c:40
@ HC_MAILBOX
Mailboxes.
Definition lib.h:62
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition util.c:73
int imap_create_mailbox(struct ImapAccountData *adata, const char *mailbox)
Create a new mailbox.
Definition imap.c:542
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
void mutt_sleep(short s)
Sleep for a while.
Definition muttlib.c:795
Input for the file completion function.
Definition curs_lib.h:39
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
void * mdata
Driver specific data.
Definition mailbox.h:134
Here is the call graph for this function:
Here is the caller graph for this function:

◆ imap_mailbox_rename()

int imap_mailbox_rename ( const char * path)

Rename a mailbox.

Parameters
pathMailbox to rename
Return values
0Success
-1Failure

The user will be prompted for a new name.

Definition at line 463 of file browse.c.

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}
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
size_t dsize
Length of data.
Definition buffer.h:40
char * data
Pointer to data.
Definition buffer.h:38
char * buf
Command buffer.
Definition adata.h:61
char * name
Mailbox name.
Definition mdata.h:41
Here is the call graph for this function:
Here is the caller graph for this function: