NeoMutt  2025-12-11-694-ga89709
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.
 
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()

static 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)))
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:213
@ 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:479
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition util.c:857
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition regex.c:614
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:665
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:586
#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:526
char * folder
Folder name.
Definition lib.h:148
struct BrowserEntryArray entry
Array of files / dirs / mailboxes.
Definition lib.h:146
Login details for a remote server.
Definition connaccount.h:53
Browser entry representing a folder/dir.
Definition lib.h:79
bool selectable
Folder can be selected.
Definition lib.h:97
char delim
Path delimiter.
Definition lib.h:94
bool imap
This is an IMAP folder.
Definition lib.h:96
bool has_mailbox
This is a mailbox.
Definition lib.h:99
char * name
Name of file/dir/mailbox.
Definition lib.h:87
bool has_new_mail
true if mailbox has "new mail"
Definition lib.h:90
char * desc
Description of mailbox.
Definition lib.h:88
int msg_count
total number of messages
Definition lib.h:91
bool inferiors
Folder has children.
Definition lib.h:98
int msg_unread
number of unread messages
Definition lib.h:92
A mailbox.
Definition mailbox.h:78
bool has_new
Mailbox has new mail.
Definition mailbox.h:84
int msg_count
Total number of messages.
Definition mailbox.h:87
int msg_unread
Number of unread messages.
Definition mailbox.h:88
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()

static 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:1211
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition command.c:1225
#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:69
Items in an IMAP browser.
Definition private.h:149
bool noselect
Mailbox is not selectable.
Definition private.h:152
bool noinferiors
Mailbox has no children.
Definition private.h:153
char * name
Mailbox name.
Definition private.h:150
char delim
Hierarchy delimiter.
Definition private.h:151
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:
+ 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 196 of file browse.c.

197{
198 struct ImapAccountData *adata = NULL;
199 struct ImapList list = { 0 };
200 struct ConnAccount cac = { { 0 } };
201 char buf[PATH_MAX + 16];
202 char mbox[PATH_MAX] = { 0 };
203 char munged_mbox[PATH_MAX] = { 0 };
204 const char *list_cmd = NULL;
205 int len;
206 int n;
207 bool showparents = false;
208 int rc = -1;
209
210 if (imap_parse_path(path, &cac, buf, sizeof(buf)))
211 {
212 mutt_error(_("%s is an invalid IMAP path"), path);
213 return -1;
214 }
215
216 const bool c_imap_check_subscribed = cs_subset_bool(NeoMutt->sub, "imap_check_subscribed");
217 cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed", false, NULL);
218
219 // Pick first mailbox connected to the same server
220 struct MailboxArray ma = neomutt_mailboxes_get(NeoMutt, MUTT_IMAP);
221 struct Mailbox **mp = NULL;
222 ARRAY_FOREACH(mp, &ma)
223 {
224 adata = imap_adata_get(*mp);
225 // Pick first mailbox connected on the same server
226 if (imap_account_match(&adata->conn->account, &cac))
227 break;
228 adata = NULL;
229 }
230 ARRAY_FREE(&ma); // Clean up the ARRAY, but not the Mailboxes
231
232 if (!adata)
233 goto fail;
234
235 const bool c_imap_list_subscribed = cs_subset_bool(NeoMutt->sub, "imap_list_subscribed");
236 if (c_imap_list_subscribed)
237 {
238 /* RFC3348 section 3 states LSUB is unreliable for hierarchy information.
239 * The newer LIST extensions are designed for this. */
241 list_cmd = "LIST (SUBSCRIBED RECURSIVEMATCH)";
242 else
243 list_cmd = "LSUB";
244 }
245 else
246 {
247 list_cmd = "LIST";
248 }
249
250 mutt_message(_("Getting folder list..."));
251
252 /* skip check for parents when at the root */
253 if (buf[0] == '\0')
254 {
255 mbox[0] = '\0';
256 n = 0;
257 }
258 else
259 {
260 imap_fix_path_with_delim(adata->delim, buf, mbox, sizeof(mbox));
261 n = mutt_str_len(mbox);
262 }
263
264 if (n > 0)
265 {
266 int rc_step;
267 mutt_debug(LL_DEBUG3, "mbox: %s\n", mbox);
268
269 /* if our target exists and has inferiors, enter it if we
270 * aren't already going to */
271 imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), mbox);
272 len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
274 snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
275 imap_cmd_start(adata, buf);
276 adata->cmdresult = &list;
277 do
278 {
279 list.name = 0;
280 rc_step = imap_cmd_step(adata);
281 if ((rc_step == IMAP_RES_CONTINUE) && list.name)
282 {
283 if (!list.noinferiors && list.name[0] &&
284 (imap_mxcmp(list.name, mbox) == 0) && (n < sizeof(mbox) - 1))
285 {
286 mbox[n++] = list.delim;
287 mbox[n] = '\0';
288 }
289 }
290 } while (rc_step == IMAP_RES_CONTINUE);
291 adata->cmdresult = NULL;
292
293 /* if we're descending a folder, mark it as current in browser_state */
294 if (mbox[n - 1] == list.delim)
295 {
296 showparents = true;
297 imap_qualify_path(buf, sizeof(buf), &cac, mbox);
298 state->folder = mutt_str_dup(buf);
299 n--;
300 }
301
302 /* Find superiors to list
303 * Note: UW-IMAP servers return folder + delimiter when asked to list
304 * folder + delimiter. Cyrus servers don't. So we ask for folder,
305 * and tack on delimiter ourselves.
306 * Further note: UW-IMAP servers return nothing when asked for
307 * NAMESPACES without delimiters at the end. Argh! */
308 for (n--; n >= 0 && mbox[n] != list.delim; n--)
309 ; // do nothing
310
311 if (n > 0) /* "aaaa/bbbb/" -> "aaaa" */
312 {
313 /* forget the check, it is too delicate (see above). Have we ever
314 * had the parent not exist? */
315 char ctmp = mbox[n];
316 mbox[n] = '\0';
317
318 if (showparents)
319 {
320 mutt_debug(LL_DEBUG3, "adding parent %s\n", mbox);
321 add_folder(list.delim, mbox, true, false, state, true);
322 }
323
324 /* if our target isn't a folder, we are in our superior */
325 if (!state->folder)
326 {
327 /* store folder with delimiter */
328 mbox[n++] = ctmp;
329 ctmp = mbox[n];
330 mbox[n] = '\0';
331 imap_qualify_path(buf, sizeof(buf), &cac, mbox);
332 state->folder = mutt_str_dup(buf);
333 }
334 mbox[n] = ctmp;
335 }
336 else
337 {
338 /* "/bbbb/" -> add "/", "aaaa/" -> add "" */
339 char relpath[2] = { 0 };
340 /* folder may be "/" */
341 snprintf(relpath, sizeof(relpath), "%c", (n < 0) ? '\0' : adata->delim);
342 if (showparents)
343 add_folder(adata->delim, relpath, true, false, state, true);
344 if (!state->folder)
345 {
346 imap_qualify_path(buf, sizeof(buf), &cac, relpath);
347 state->folder = mutt_str_dup(buf);
348 }
349 }
350 }
351
352 /* no namespace, no folder: set folder to host only */
353 if (!state->folder)
354 {
355 imap_qualify_path(buf, sizeof(buf), &cac, NULL);
356 state->folder = mutt_str_dup(buf);
357 }
358
359 mutt_debug(LL_DEBUG3, "Quoting mailbox scan: %s -> ", mbox);
360 snprintf(buf, sizeof(buf), "%s%%", mbox);
361 imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), buf);
362 mutt_debug(LL_DEBUG3, "%s\n", munged_mbox);
363 len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
365 snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
366 if (browse_add_list_result(adata, buf, state, false))
367 goto fail;
368
369 if (ARRAY_EMPTY(&state->entry))
370 {
371 // L10N: (%s) is the name / path of the folder we were trying to browse
372 mutt_error(_("No such folder: %s"), path);
373 goto fail;
374 }
375
377 rc = 0;
378
379fail:
380 cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed",
381 c_imap_check_subscribed, NULL);
382 return rc;
383}
#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
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:158
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition util.c:550
char * imap_fix_path_with_delim(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition util.c:715
#define IMAP_CAP_LIST_EXTENDED
RFC5258: IMAP4 LIST Command Extensions.
Definition private.h:138
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition util.c:1103
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:968
@ 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)
void * adata
Private data (for Mailbox backends)
Definition account.h:42
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:78
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition adata.h:63
ImapCapFlags capabilities
Capability flags.
Definition adata.h:55
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 393 of file browse.c.

394{
395 struct ImapAccountData *adata = NULL;
396 struct ImapMboxData *mdata = NULL;
397 struct Buffer *name = buf_pool_get();
398 int rc = -1;
399
400 if (imap_adata_find(path, &adata, &mdata) < 0)
401 {
402 mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
403 goto done;
404 }
405
406 /* append a delimiter if necessary */
407 const size_t n = buf_strcpy(name, mdata->real_name);
408 if ((n != 0) && (buf_at(name, n - 1) != adata->delim))
409 {
410 buf_addch(name, adata->delim);
411 }
412
413 struct FileCompletionData cdata = { false, NULL, NULL, NULL, NULL };
414 if (mw_get_field(_("Create mailbox: "), name, MUTT_COMP_NO_FLAGS, HC_MAILBOX,
415 &CompleteMailboxOps, &cdata) != 0)
416 {
417 goto done;
418 }
419
420 if (buf_is_empty(name))
421 {
422 mutt_error(_("Mailbox must have a name"));
423 goto done;
424 }
425
426 if (imap_create_mailbox(adata, buf_string(name)) < 0)
427 goto done;
428
429 imap_mdata_free((void *) &mdata);
430 mutt_message(_("Mailbox created"));
431 mutt_sleep(0);
432 rc = 0;
433
434done:
435 imap_mdata_free((void *) &mdata);
436 buf_pool_release(&name);
437 return rc;
438}
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:291
char buf_at(const struct Buffer *buf, size_t offset)
Return the character at the given offset.
Definition buffer.c:668
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:241
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
#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:463
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:61
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition util.c:72
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:787
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
String manipulation buffer.
Definition buffer.h:36
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:131
+ 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 448 of file browse.c.

449{
450 struct ImapAccountData *adata = NULL;
451 struct ImapMboxData *mdata = NULL;
452 struct Buffer *buf = NULL;
453 struct Buffer *newname = NULL;
454 int rc = -1;
455
456 if (imap_adata_find(path, &adata, &mdata) < 0)
457 {
458 mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
459 goto done;
460 }
461
462 if (mdata->real_name[0] == '\0')
463 {
464 mutt_error(_("Can't rename root folder"));
465 goto done;
466 }
467
468 buf = buf_pool_get();
469 newname = buf_pool_get();
470
471 buf_printf(buf, _("Rename mailbox %s to: "), mdata->name);
472 buf_strcpy(newname, mdata->name);
473
474 struct FileCompletionData cdata = { false, NULL, NULL, NULL, NULL };
476 &CompleteMailboxOps, &cdata) != 0)
477 {
478 goto done;
479 }
480
481 if (buf_is_empty(newname))
482 {
483 mutt_error(_("Mailbox must have a name"));
484 goto done;
485 }
486
487 imap_fix_path_with_delim(adata->delim, buf_string(newname), buf->data, buf->dsize);
488
489 if (imap_rename_mailbox(adata, mdata->name, buf_string(buf)) < 0)
490 {
491 mutt_error(_("Rename failed: %s"), imap_get_qualifier(adata->buf));
492 goto done;
493 }
494
495 mutt_message(_("Mailbox renamed"));
496 mutt_sleep(0);
497 rc = 0;
498
499done:
500 imap_mdata_free((void *) &mdata);
501 buf_pool_release(&buf);
502 buf_pool_release(&newname);
503
504 return rc;
505}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition util.c:809
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:39
char * data
Pointer to data.
Definition buffer.h:37
char * buf
Command buffer.
Definition adata.h:60
char * name
Mailbox name.
Definition mdata.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function: