NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
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 "adata.h"
#include "browser.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. More...
 
static int browse_add_list_result (struct ImapAccountData *adata, const char *cmd, struct BrowserState *state, bool isparent)
 Add entries to the folder browser. More...
 
int imap_browse (const char *path, struct BrowserState *state)
 IMAP hook into the folder browser. More...
 
int imap_mailbox_create (const char *path)
 Create a new IMAP mailbox. More...
 
int imap_mailbox_rename (const char *path)
 Rename a mailbox. More...
 

Detailed Description

GUI select an IMAP mailbox from a list.

Authors
  • Brandon Long
  • Brendan Cully

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 62 of file browse.c.

64 {
65  char tmp[PATH_MAX];
66  char relpath[PATH_MAX];
67  struct ConnAccount cac = { { 0 } };
68  char mailbox[1024];
69  struct FolderFile ff = { 0 };
70 
71  if (imap_parse_path(state->folder, &cac, mailbox, sizeof(mailbox)))
72  return;
73 
74  /* render superiors as unix-standard ".." */
75  if (isparent)
76  mutt_str_copy(relpath, "../", sizeof(relpath));
77  /* strip current folder from target, to render a relative path */
78  else if (mutt_str_startswith(folder, mailbox))
79  mutt_str_copy(relpath, folder + mutt_str_len(mailbox), sizeof(relpath));
80  else
81  mutt_str_copy(relpath, folder, sizeof(relpath));
82 
83  /* apply filemask filter. This should really be done at menu setup rather
84  * than at scan, since it's so expensive to scan. But that's big changes
85  * to browser.c */
86  const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
87  if (!mutt_regex_match(c_mask, relpath))
88  {
89  return;
90  }
91 
92  imap_qualify_path(tmp, sizeof(tmp), &cac, folder);
93  ff.name = mutt_str_dup(tmp);
94 
95  /* mark desc with delim in browser if it can have subfolders */
96  if (!isparent && !noinferiors && (strlen(relpath) < sizeof(relpath) - 1))
97  {
98  relpath[strlen(relpath) + 1] = '\0';
99  relpath[strlen(relpath)] = delim;
100  }
101 
102  ff.desc = mutt_str_dup(relpath);
103  ff.imap = true;
104 
105  /* delimiter at the root is useless. */
106  if (folder[0] == '\0')
107  delim = '\0';
108  ff.delim = delim;
109  ff.selectable = !noselect;
110  ff.inferiors = !noinferiors;
111 
112  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
114  struct MailboxNode *np = NULL;
115  STAILQ_FOREACH(np, &ml, entries)
116  {
117  if (mutt_str_equal(tmp, mailbox_path(np->mailbox)))
118  break;
119  }
120 
121  if (np)
122  {
123  ff.has_mailbox = true;
124  ff.has_new_mail = np->mailbox->has_new;
125  ff.msg_count = np->mailbox->msg_count;
126  ff.msg_unread = np->mailbox->msg_unread;
127  }
129 
130  ARRAY_ADD(&state->entry, ff);
131 }
int msg_unread
number of unread messages
Definition: browser.h:67
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:823
bool has_mailbox
Definition: browser.h:76
int msg_count
Total number of messages.
Definition: mailbox.h:91
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
char * desc
Definition: browser.h:63
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:141
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:483
Match any Mailbox type.
Definition: mailbox.h:45
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:164
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
struct BrowserStateEntry entry
Definition: browser.h:93
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * folder
Definition: browser.h:96
bool selectable
Definition: browser.h:73
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition: helpers.c:243
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
char * name
Definition: browser.h:62
bool imap
Definition: browser.h:72
Browser entry representing a folder/dir.
Definition: browser.h:53
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
#define PATH_MAX
Definition: mutt.h:40
int msg_count
total number of messages
Definition: browser.h:66
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
Login details for a remote server.
Definition: connaccount.h:51
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
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:749
Cached regular expression.
Definition: regex3.h:89
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:613
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition: array.h:152
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
List of Mailboxes.
Definition: mailbox.h:156
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
bool inferiors
Definition: browser.h:74
char delim
Definition: browser.h:70
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:158
bool has_new_mail
true if mailbox has "new mail"
Definition: browser.h:65
+ 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 state,
bool  isparent 
)
static

Add entries to the folder browser.

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

Definition at line 142 of file browse.c.

144 {
145  struct ImapList list = { 0 };
146  int rc;
147  struct Url *url = url_parse(state->folder);
148 
149  imap_cmd_start(adata, cmd);
150  adata->cmdresult = &list;
151  do
152  {
153  list.name = NULL;
154  rc = imap_cmd_step(adata);
155 
156  if ((rc == IMAP_RES_CONTINUE) && list.name)
157  {
158  /* Let a parent folder never be selectable for navigation */
159  if (isparent)
160  list.noselect = true;
161  /* prune current folder from output */
162  if (isparent || !mutt_str_startswith(url->path, list.name))
163  add_folder(list.delim, list.name, list.noselect, list.noinferiors, state, isparent);
164  }
165  } while (rc == IMAP_RES_CONTINUE);
166  adata->cmdresult = NULL;
167 
168  url_free(&url);
169 
170  return (rc == IMAP_RES_OK) ? 0 : -1;
171 }
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:56
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1079
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
Items in an IMAP browser.
Definition: private.h:148
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1065
char delim
Definition: private.h:151
char * folder
Definition: browser.h:96
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
char * name
Definition: private.h:150
bool noinferiors
Definition: private.h:153
char * path
Path.
Definition: url.h:75
struct ImapList * cmdresult
Definition: adata.h:66
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
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:62
bool noselect
Definition: private.h:152
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ 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 182 of file browse.c.

183 {
184  struct ImapAccountData *adata = NULL;
185  struct ImapList list = { 0 };
186  struct ConnAccount cac = { { 0 } };
187  char buf[PATH_MAX + 16];
188  char mbox[PATH_MAX];
189  char munged_mbox[PATH_MAX];
190  const char *list_cmd = NULL;
191  int len;
192  int n;
193  char ctmp;
194  bool showparents = false;
195 
196  if (imap_parse_path(path, &cac, buf, sizeof(buf)))
197  {
198  mutt_error(_("%s is an invalid IMAP path"), path);
199  return -1;
200  }
201 
202  const bool c_imap_check_subscribed =
203  cs_subset_bool(NeoMutt->sub, "imap_check_subscribed");
204  cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed", false, NULL);
205 
206  // Pick first mailbox connected to the same server
207  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
209  struct MailboxNode *np = NULL;
210  STAILQ_FOREACH(np, &ml, entries)
211  {
212  adata = imap_adata_get(np->mailbox);
213  // Pick first mailbox connected on the same server
214  if (imap_account_match(&adata->conn->account, &cac))
215  break;
216  adata = NULL;
217  }
219  if (!adata)
220  goto fail;
221 
222  const bool c_imap_list_subscribed =
223  cs_subset_bool(NeoMutt->sub, "imap_list_subscribed");
224  if (c_imap_list_subscribed)
225  {
226  /* RFC3348 section 3 states LSUB is unreliable for hierarchy information.
227  * The newer LIST extensions are designed for this. */
229  list_cmd = "LIST (SUBSCRIBED RECURSIVEMATCH)";
230  else
231  list_cmd = "LSUB";
232  }
233  else
234  {
235  list_cmd = "LIST";
236  }
237 
238  mutt_message(_("Getting folder list..."));
239 
240  /* skip check for parents when at the root */
241  if (buf[0] == '\0')
242  {
243  mbox[0] = '\0';
244  n = 0;
245  }
246  else
247  {
248  imap_fix_path(adata->delim, buf, mbox, sizeof(mbox));
249  n = mutt_str_len(mbox);
250  }
251 
252  if (n)
253  {
254  int rc;
255  mutt_debug(LL_DEBUG3, "mbox: %s\n", mbox);
256 
257  /* if our target exists and has inferiors, enter it if we
258  * aren't already going to */
259  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), mbox);
260  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
262  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
263  imap_cmd_start(adata, buf);
264  adata->cmdresult = &list;
265  do
266  {
267  list.name = 0;
268  rc = imap_cmd_step(adata);
269  if ((rc == IMAP_RES_CONTINUE) && list.name)
270  {
271  if (!list.noinferiors && list.name[0] &&
272  (imap_mxcmp(list.name, mbox) == 0) && (n < sizeof(mbox) - 1))
273  {
274  mbox[n++] = list.delim;
275  mbox[n] = '\0';
276  }
277  }
278  } while (rc == IMAP_RES_CONTINUE);
279  adata->cmdresult = NULL;
280 
281  /* if we're descending a folder, mark it as current in browser_state */
282  if (mbox[n - 1] == list.delim)
283  {
284  showparents = true;
285  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
286  state->folder = mutt_str_dup(buf);
287  n--;
288  }
289 
290  /* Find superiors to list
291  * Note: UW-IMAP servers return folder + delimiter when asked to list
292  * folder + delimiter. Cyrus servers don't. So we ask for folder,
293  * and tack on delimiter ourselves.
294  * Further note: UW-IMAP servers return nothing when asked for
295  * NAMESPACES without delimiters at the end. Argh! */
296  for (n--; n >= 0 && mbox[n] != list.delim; n--)
297  ; // do nothing
298 
299  if (n > 0) /* "aaaa/bbbb/" -> "aaaa" */
300  {
301  /* forget the check, it is too delicate (see above). Have we ever
302  * had the parent not exist? */
303  ctmp = mbox[n];
304  mbox[n] = '\0';
305 
306  if (showparents)
307  {
308  mutt_debug(LL_DEBUG3, "adding parent %s\n", mbox);
309  add_folder(list.delim, mbox, true, false, state, true);
310  }
311 
312  /* if our target isn't a folder, we are in our superior */
313  if (!state->folder)
314  {
315  /* store folder with delimiter */
316  mbox[n++] = ctmp;
317  ctmp = mbox[n];
318  mbox[n] = '\0';
319  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
320  state->folder = mutt_str_dup(buf);
321  }
322  mbox[n] = ctmp;
323  }
324  /* "/bbbb/" -> add "/", "aaaa/" -> add "" */
325  else
326  {
327  char relpath[2];
328  /* folder may be "/" */
329  snprintf(relpath, sizeof(relpath), "%c", (n < 0) ? '\0' : adata->delim);
330  if (showparents)
331  add_folder(adata->delim, relpath, true, false, state, true);
332  if (!state->folder)
333  {
334  imap_qualify_path(buf, sizeof(buf), &cac, relpath);
335  state->folder = mutt_str_dup(buf);
336  }
337  }
338  }
339 
340  /* no namespace, no folder: set folder to host only */
341  if (!state->folder)
342  {
343  imap_qualify_path(buf, sizeof(buf), &cac, NULL);
344  state->folder = mutt_str_dup(buf);
345  }
346 
347  mutt_debug(LL_DEBUG3, "Quoting mailbox scan: %s -> ", mbox);
348  snprintf(buf, sizeof(buf), "%s%%", mbox);
349  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), buf);
350  mutt_debug(LL_DEBUG3, "%s\n", munged_mbox);
351  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
353  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
354  if (browse_add_list_result(adata, buf, state, false))
355  goto fail;
356 
357  if (ARRAY_EMPTY(&state->entry))
358  {
359  // L10N: (%s) is the name / path of the folder we were trying to browse
360  mutt_error(_("No such folder: %s"), path);
361  goto fail;
362  }
363 
365 
366  cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed",
367  c_imap_check_subscribed, NULL);
368  return 0;
369 
370 fail:
371  cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed",
372  c_imap_check_subscribed, NULL);
373  return -1;
374 }
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:823
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1079
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:141
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:483
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:914
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:164
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
struct BrowserStateEntry entry
Definition: browser.h:93
Items in an IMAP browser.
Definition: private.h:148
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1049
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1065
char delim
Definition: private.h:151
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * folder
Definition: browser.h:96
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:305
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
char delim
Definition: adata.h:75
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition: util.c:554
#define PATH_MAX
Definition: mutt.h:40
char * name
Definition: private.h:150
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:70
ImapCapFlags capabilities
Definition: adata.h:55
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define IMAP_CAP_LIST_EXTENDED
RFC5258: IMAP4 LIST Command Extensions.
Definition: private.h:139
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Login details for a remote server.
Definition: connaccount.h:51
bool noinferiors
Definition: private.h:153
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
IMAP-specific Account data -.
Definition: adata.h:39
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:687
static int browse_add_list_result(struct ImapAccountData *adata, const char *cmd, struct BrowserState *state, bool isparent)
Add entries to the folder browser.
Definition: browse.c:142
#define mutt_message(...)
Definition: logging.h:87
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
struct ImapList * cmdresult
Definition: adata.h:66
List of Mailboxes.
Definition: mailbox.h:156
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
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:62
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
Log at debug level 3.
Definition: logging.h:42
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: adata.h:62
struct Connection * conn
Definition: adata.h:41
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:158
+ 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 384 of file browse.c.

385 {
386  struct ImapAccountData *adata = NULL;
387  struct ImapMboxData *mdata = NULL;
388  char name[1024];
389 
390  if (imap_adata_find(path, &adata, &mdata) < 0)
391  {
392  mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
393  goto err;
394  }
395 
396  /* append a delimiter if necessary */
397  const size_t n = mutt_str_copy(name, mdata->real_name, sizeof(name));
398  if (n && (n < sizeof(name) - 1) && (name[n - 1] != adata->delim))
399  {
400  name[n] = adata->delim;
401  name[n + 1] = '\0';
402  }
403 
404  if (mutt_get_field(_("Create mailbox: "), name, sizeof(name), MUTT_FILE,
405  false, NULL, NULL) < 0)
406  {
407  goto err;
408  }
409 
410  if (mutt_str_len(name) == 0)
411  {
412  mutt_error(_("Mailbox must have a name"));
413  goto err;
414  }
415 
416  if (imap_create_mailbox(adata, name) < 0)
417  goto err;
418 
419  imap_mdata_free((void *) &mdata);
420  mutt_message(_("Mailbox created"));
421  mutt_sleep(0);
422  return 0;
423 
424 err:
425  imap_mdata_free((void *) &mdata);
426  return -1;
427 }
#define mutt_error(...)
Definition: logging.h:88
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:40
#define _(a)
Definition: message.h:28
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:72
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1461
char delim
Definition: adata.h:75
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: mdata.h:40
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:448
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
#define MUTT_FILE
Do file completion.
Definition: mutt.h:54
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: mdata.h:42
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
IMAP-specific Account data -.
Definition: adata.h:39
Log at debug level 1.
Definition: logging.h:40
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:749
IMAP-specific Mailbox data -.
Definition: mdata.h:38
#define mutt_message(...)
Definition: logging.h:87
+ 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 437 of file browse.c.

438 {
439  struct ImapAccountData *adata = NULL;
440  struct ImapMboxData *mdata = NULL;
441  char buf[PATH_MAX];
442  char newname[PATH_MAX];
443 
444  if (imap_adata_find(path, &adata, &mdata) < 0)
445  {
446  mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
447  return -1;
448  }
449 
450  if (mdata->real_name[0] == '\0')
451  {
452  mutt_error(_("Can't rename root folder"));
453  goto err;
454  }
455 
456  snprintf(buf, sizeof(buf), _("Rename mailbox %s to: "), mdata->name);
457  mutt_str_copy(newname, mdata->name, sizeof(newname));
458 
459  if (mutt_get_field(buf, newname, sizeof(newname), MUTT_FILE, false, NULL, NULL) < 0)
460  goto err;
461 
462  if (mutt_str_len(newname) == 0)
463  {
464  mutt_error(_("Mailbox must have a name"));
465  goto err;
466  }
467 
468  imap_fix_path(adata->delim, newname, buf, sizeof(buf));
469 
470  if (imap_rename_mailbox(adata, mdata->name, buf) < 0)
471  {
472  mutt_error(_("Rename failed: %s"), imap_get_qualifier(adata->buf));
473  goto err;
474  }
475 
476  mutt_message(_("Mailbox renamed"));
477  mutt_sleep(0);
478  return 0;
479 
480 err:
481  imap_mdata_free((void *) &mdata);
482  return -1;
483 }
#define mutt_error(...)
Definition: logging.h:88
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:40
int imap_rename_mailbox(struct ImapAccountData *adata, char *oldname, const char *newname)
Rename a mailbox.
Definition: imap.c:489
#define _(a)
Definition: message.h:28
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:72
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1461
char delim
Definition: adata.h:75
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: mdata.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
#define MUTT_FILE
Do file completion.
Definition: mutt.h:54
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: mdata.h:42
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
IMAP-specific Account data -.
Definition: adata.h:39
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:775
Log at debug level 1.
Definition: logging.h:40
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:687
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:749
IMAP-specific Mailbox data -.
Definition: mdata.h:38
char * buf
Definition: adata.h:59
#define mutt_message(...)
Definition: logging.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function: