NeoMutt  2024-04-16-36-g75b6fb
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:218
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:474
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:816
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:654
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:490
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:575
#define PATH_MAX
Definition: mutt.h:42
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:163
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:186
#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:147
struct BrowserEntryArray entry
Array of files / dirs / mailboxes.
Definition: lib.h:145
Login details for a remote server.
Definition: connaccount.h:53
Browser entry representing a folder/dir.
Definition: lib.h:78
bool selectable
Folder can be selected.
Definition: lib.h:96
char delim
Path delimiter.
Definition: lib.h:93
bool imap
This is an IMAP folder.
Definition: lib.h:95
bool has_mailbox
This is a mailbox.
Definition: lib.h:98
char * name
Name of file/dir/mailbox.
Definition: lib.h:86
bool has_new_mail
true if mailbox has "new mail"
Definition: lib.h:89
char * desc
Description of mailbox.
Definition: lib.h:87
int msg_count
total number of messages
Definition: lib.h:90
bool inferiors
Folder has children.
Definition: lib.h:97
int msg_unread
number of unread messages
Definition: lib.h:91
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:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
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 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 char ctmp;
209 bool showparents = false;
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(adata->delim, buf, mbox, sizeof(mbox));
262 n = mutt_str_len(mbox);
263 }
264
265 if (n)
266 {
267 int rc;
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 = imap_cmd_step(adata);
282 if ((rc == 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 == 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 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
379 cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed",
380 c_imap_check_subscribed, NULL);
381 return 0;
382
383fail:
384 cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed",
385 c_imap_check_subscribed, NULL);
386 return -1;
387}
#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:48
@ 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:545
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:679
#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:1054
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:921
@ 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 397 of file browse.c.

398{
399 struct ImapAccountData *adata = NULL;
400 struct ImapMboxData *mdata = NULL;
401 struct Buffer *name = buf_pool_get();
402 int rc = -1;
403
404 if (imap_adata_find(path, &adata, &mdata) < 0)
405 {
406 mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
407 goto done;
408 }
409
410 /* append a delimiter if necessary */
411 const size_t n = buf_strcpy(name, mdata->real_name);
412 if ((n != 0) && (name->data[n - 1] != adata->delim))
413 {
414 buf_addch(name, adata->delim);
415 }
416
417 struct FileCompletionData cdata = { false, NULL, NULL, NULL };
418 if (mw_get_field(_("Create mailbox: "), name, MUTT_COMP_NO_FLAGS, HC_MAILBOX,
419 &CompleteMailboxOps, &cdata) != 0)
420 {
421 goto done;
422 }
423
424 if (buf_is_empty(name))
425 {
426 mutt_error(_("Mailbox must have a name"));
427 goto done;
428 }
429
430 if (imap_create_mailbox(adata, buf_string(name)) < 0)
431 goto done;
432
433 imap_mdata_free((void *) &mdata);
434 mutt_message(_("Mailbox created"));
435 mutt_sleep(0);
436 rc = 0;
437
438done:
439 imap_mdata_free((void *) &mdata);
440 buf_pool_release(&name);
441 return rc;
442}
const struct CompleteOps CompleteMailboxOps
Auto-Completion of Files / Mailboxes.
Definition: complete.c:162
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:290
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:394
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:39
@ HC_MAILBOX
Mailboxes.
Definition: lib.h:57
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:878
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 452 of file browse.c.

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