NeoMutt  2024-11-14-34-g5aaf0d
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 "mutt.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 69 of file browse.c.

71{
72 char tmp[PATH_MAX] = { 0 };
73 char relpath[PATH_MAX] = { 0 };
74 struct ConnAccount cac = { { 0 } };
75 char mailbox[1024] = { 0 };
76 struct FolderFile ff = { 0 };
77
78 if (imap_parse_path(state->folder, &cac, mailbox, sizeof(mailbox)))
79 return;
80
81 if (isparent)
82 {
83 /* render superiors as unix-standard ".." */
84 mutt_str_copy(relpath, "../", sizeof(relpath));
85 }
86 else if (mutt_str_startswith(folder, mailbox))
87 {
88 /* strip current folder from target, to render a relative path */
89 mutt_str_copy(relpath, folder + mutt_str_len(mailbox), sizeof(relpath));
90 }
91 else
92 {
93 mutt_str_copy(relpath, folder, sizeof(relpath));
94 }
95
96 /* apply filemask filter. This should really be done at menu setup rather
97 * than at scan, since it's so expensive to scan. But that's big changes
98 * to browser.c */
99 const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
100 if (!mutt_regex_match(c_mask, relpath))
101 {
102 return;
103 }
104
105 imap_qualify_path(tmp, sizeof(tmp), &cac, folder);
106 ff.name = mutt_str_dup(tmp);
107
108 /* mark desc with delim in browser if it can have subfolders */
109 if (!isparent && !noinferiors && (strlen(relpath) < sizeof(relpath) - 1))
110 {
111 relpath[strlen(relpath) + 1] = '\0';
112 relpath[strlen(relpath)] = delim;
113 }
114
115 ff.desc = mutt_str_dup(relpath);
116 ff.imap = true;
117
118 /* delimiter at the root is useless. */
119 if (folder[0] == '\0')
120 delim = '\0';
121 ff.delim = delim;
122 ff.selectable = !noselect;
123 ff.inferiors = !noinferiors;
124
125 struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
127 struct MailboxNode *np = NULL;
128 STAILQ_FOREACH(np, &ml, entries)
129 {
130 if (mutt_str_equal(tmp, mailbox_path(np->mailbox)))
131 break;
132 }
133
134 if (np)
135 {
136 ff.has_mailbox = true;
137 ff.has_new_mail = np->mailbox->has_new;
138 ff.msg_count = np->mailbox->msg_count;
139 ff.msg_unread = np->mailbox->msg_unread;
140 }
142
143 ARRAY_ADD(&state->entry, ff);
144}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition: array.h:156
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:223
@ MUTT_MAILBOX_ANY
Match any Mailbox type.
Definition: mailbox.h:42
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:478
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:856
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:253
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:496
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:581
#define PATH_MAX
Definition: mutt.h:42
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:168
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:191
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
char * folder
Folder name.
Definition: lib.h:146
struct BrowserEntryArray entry
Array of files / dirs / mailboxes.
Definition: lib.h:144
Login details for a remote server.
Definition: connaccount.h:53
Browser entry representing a folder/dir.
Definition: lib.h:77
bool selectable
Folder can be selected.
Definition: lib.h:95
char delim
Path delimiter.
Definition: lib.h:92
bool imap
This is an IMAP folder.
Definition: lib.h:94
bool has_mailbox
This is a mailbox.
Definition: lib.h:97
char * name
Name of file/dir/mailbox.
Definition: lib.h:85
bool has_new_mail
true if mailbox has "new mail"
Definition: lib.h:88
char * desc
Description of mailbox.
Definition: lib.h:86
int msg_count
total number of messages
Definition: lib.h:89
bool inferiors
Folder has children.
Definition: lib.h:96
int msg_unread
number of unread messages
Definition: lib.h:90
List of Mailboxes.
Definition: mailbox.h:166
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:167
bool has_new
Mailbox has new mail.
Definition: mailbox.h:85
int msg_count
Total number of messages.
Definition: mailbox.h:88
int msg_unread
Number of unread messages.
Definition: mailbox.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
Cached regular expression.
Definition: regex3.h:86
+ 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 155 of file browse.c.

157{
158 struct ImapList list = { 0 };
159 int rc;
160 struct Url *url = url_parse(bstate->folder);
161 if (!url)
162 return -1;
163
164 imap_cmd_start(adata, cmd);
165 adata->cmdresult = &list;
166 do
167 {
168 list.name = NULL;
169 rc = imap_cmd_step(adata);
170
171 if ((rc == IMAP_RES_CONTINUE) && list.name)
172 {
173 /* Let a parent folder never be selectable for navigation */
174 if (isparent)
175 list.noselect = true;
176 /* prune current folder from output */
177 if (isparent || !mutt_str_startswith(url->path, list.name))
178 add_folder(list.delim, list.name, list.noselect, list.noinferiors, bstate, isparent);
179 }
180 } while (rc == IMAP_RES_CONTINUE);
181 adata->cmdresult = NULL;
182
183 url_free(&url);
184
185 return (rc == IMAP_RES_OK) ? 0 : -1;
186}
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:69
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1115
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1129
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:55
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:56
struct ImapList * cmdresult
Definition: adata.h:66
Items in an IMAP browser.
Definition: private.h:149
bool noselect
Definition: private.h:152
bool noinferiors
Definition: private.h:153
char * name
Definition: private.h:150
char delim
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 197 of file browse.c.

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

395{
396 struct ImapAccountData *adata = NULL;
397 struct ImapMboxData *mdata = NULL;
398 struct Buffer *name = buf_pool_get();
399 int rc = -1;
400
401 if (imap_adata_find(path, &adata, &mdata) < 0)
402 {
403 mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
404 goto done;
405 }
406
407 /* append a delimiter if necessary */
408 const size_t n = buf_strcpy(name, mdata->real_name);
409 if ((n != 0) && (name->data[n - 1] != adata->delim))
410 {
411 buf_addch(name, adata->delim);
412 }
413
414 struct FileCompletionData cdata = { false, NULL, NULL, NULL };
415 if (mw_get_field(_("Create mailbox: "), name, MUTT_COMP_NO_FLAGS, HC_MAILBOX,
416 &CompleteMailboxOps, &cdata) != 0)
417 {
418 goto done;
419 }
420
421 if (buf_is_empty(name))
422 {
423 mutt_error(_("Mailbox must have a name"));
424 goto done;
425 }
426
427 if (imap_create_mailbox(adata, buf_string(name)) < 0)
428 goto done;
429
430 imap_mdata_free((void *) &mdata);
431 mutt_message(_("Mailbox created"));
432 mutt_sleep(0);
433 rc = 0;
434
435done:
436 imap_mdata_free((void *) &mdata);
437 buf_pool_release(&name);
438 return rc;
439}
const struct CompleteOps CompleteMailboxOps
Auto-Completion of Files / Mailboxes.
Definition: complete.c:160
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
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
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:274
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:60
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:436
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:843
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
String manipulation buffer.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:37
Input for the file completion function.
Definition: curs_lib.h:40
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:132
+ 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 449 of file browse.c.

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