NeoMutt  2020-06-26-250-g349c94
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 "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "browser.h"
#include "mutt_globals.h"
#include "mutt_logging.h"
#include "muttlib.h"
#include "imap/lib.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 60 of file browse.c.

62 {
63  char tmp[PATH_MAX];
64  char relpath[PATH_MAX];
65  struct ConnAccount cac = { { 0 } };
66  char mailbox[1024];
67 
68  if (imap_parse_path(state->folder, &cac, mailbox, sizeof(mailbox)))
69  return;
70 
71  if (state->entrylen + 1 == state->entrymax)
72  {
73  mutt_mem_realloc(&state->entry, sizeof(struct FolderFile) * (state->entrymax += 256));
74  memset(state->entry + state->entrylen, 0,
75  (sizeof(struct FolderFile) * (state->entrymax - state->entrylen)));
76  }
77 
78  /* render superiors as unix-standard ".." */
79  if (isparent)
80  mutt_str_copy(relpath, "../", sizeof(relpath));
81  /* strip current folder from target, to render a relative path */
82  else if (mutt_str_startswith(folder, mailbox))
83  mutt_str_copy(relpath, folder + mutt_str_len(mailbox), sizeof(relpath));
84  else
85  mutt_str_copy(relpath, folder, sizeof(relpath));
86 
87  /* apply filemask filter. This should really be done at menu setup rather
88  * than at scan, since it's so expensive to scan. But that's big changes
89  * to browser.c */
90  if (!mutt_regex_match(C_Mask, relpath))
91  {
92  return;
93  }
94 
95  imap_qualify_path(tmp, sizeof(tmp), &cac, folder);
96  (state->entry)[state->entrylen].name = mutt_str_dup(tmp);
97 
98  /* mark desc with delim in browser if it can have subfolders */
99  if (!isparent && !noinferiors && (strlen(relpath) < sizeof(relpath) - 1))
100  {
101  relpath[strlen(relpath) + 1] = '\0';
102  relpath[strlen(relpath)] = delim;
103  }
104 
105  (state->entry)[state->entrylen].desc = mutt_str_dup(relpath);
106 
107  (state->entry)[state->entrylen].imap = true;
108  /* delimiter at the root is useless. */
109  if (folder[0] == '\0')
110  delim = '\0';
111  (state->entry)[state->entrylen].delim = delim;
112  (state->entry)[state->entrylen].selectable = !noselect;
113  (state->entry)[state->entrylen].inferiors = !noinferiors;
114 
115  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
117  struct MailboxNode *np = NULL;
118  STAILQ_FOREACH(np, &ml, entries)
119  {
120  if (mutt_str_equal(tmp, mailbox_path(np->mailbox)))
121  break;
122  }
123 
124  if (np)
125  {
126  (state->entry)[state->entrylen].has_mailbox = true;
127  (state->entry)[state->entrylen].has_new_mail = np->mailbox->has_new;
128  (state->entry)[state->entrylen].msg_count = np->mailbox->msg_count;
129  (state->entry)[state->entrylen].msg_unread = np->mailbox->msg_unread;
130  }
132 
133  (state->entrylen)++;
134 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:201
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:954
int msg_count
Total number of messages.
Definition: mailbox.h:91
if(!test_colorize_)
Definition: acutest.h:499
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:137
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:618
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:160
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * folder
Definition: browser.h:98
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
unsigned int entrymax
max entry
Definition: browser.h:95
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
Browser entry representing a folder/dir.
Definition: browser.h:57
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:165
#define PATH_MAX
Definition: mutt.h:44
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
Login details for a remote server.
Definition: connaccount.h:51
size_t entrylen
number of real entries
Definition: browser.h:94
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
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:721
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:609
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
List of Mailboxes.
Definition: mailbox.h:150
WHERE struct Regex * C_Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: mutt_globals.h:120
struct FolderFile * entry
Definition: browser.h:93
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:152
+ 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 145 of file browse.c.

147 {
148  struct ImapList list = { 0 };
149  int rc;
150  struct Url *url = url_parse(state->folder);
151 
152  imap_cmd_start(adata, cmd);
153  adata->cmdresult = &list;
154  do
155  {
156  list.name = NULL;
157  rc = imap_cmd_step(adata);
158 
159  if ((rc == IMAP_RES_CONTINUE) && list.name)
160  {
161  /* Let a parent folder never be selectable for navigation */
162  if (isparent)
163  list.noselect = true;
164  /* prune current folder from output */
165  if (isparent || !mutt_str_startswith(url->path, list.name))
166  add_folder(list.delim, list.name, list.noselect, list.noinferiors, state, isparent);
167  }
168  } while (rc == IMAP_RES_CONTINUE);
169  adata->cmdresult = NULL;
170 
171  url_free(&url);
172 
173  return (rc == IMAP_RES_OK) ? 0 : -1;
174 }
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:55
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1076
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
Items in an IMAP browser.
Definition: private.h:147
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:1062
char delim
Definition: private.h:150
char * folder
Definition: browser.h:98
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:165
char * name
Definition: private.h:149
bool noinferiors
Definition: private.h:152
char * path
Path.
Definition: url.h:73
struct ImapList * cmdresult
Definition: private.h:196
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:56
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:60
bool noselect
Definition: private.h:151
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 185 of file browse.c.

186 {
187  struct ImapAccountData *adata = NULL;
188  struct ImapList list = { 0 };
189  struct ConnAccount cac = { { 0 } };
190  char buf[PATH_MAX + 16];
191  char mbox[PATH_MAX];
192  char munged_mbox[PATH_MAX];
193  const char *list_cmd = NULL;
194  int len;
195  int n;
196  char ctmp;
197  bool showparents = false;
198  bool save_lsub;
199 
200  if (imap_parse_path(path, &cac, buf, sizeof(buf)))
201  {
202  mutt_error(_("%s is an invalid IMAP path"), path);
203  return -1;
204  }
205 
206  save_lsub = C_ImapCheckSubscribed;
207  C_ImapCheckSubscribed = false;
208 
209  // Pick first mailbox connected to the same server
210  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
212  struct MailboxNode *np = NULL;
213  STAILQ_FOREACH(np, &ml, entries)
214  {
215  adata = imap_adata_get(np->mailbox);
216  // Pick first mailbox connected on the same server
217  if (imap_account_match(&adata->conn->account, &cac))
218  break;
219  adata = NULL;
220  }
222  if (!adata)
223  goto fail;
224 
226  {
227  /* RFC3348 section 3 states LSUB is unreliable for hierarchy information.
228  * The newer LIST extensions are designed for this. */
230  list_cmd = "LIST (SUBSCRIBED RECURSIVEMATCH)";
231  else
232  list_cmd = "LSUB";
233  }
234  else
235  {
236  list_cmd = "LIST";
237  }
238 
239  mutt_message(_("Getting folder list..."));
240 
241  /* skip check for parents when at the root */
242  if (buf[0] == '\0')
243  {
244  mbox[0] = '\0';
245  n = 0;
246  }
247  else
248  {
249  imap_fix_path(adata->delim, buf, mbox, sizeof(mbox));
250  n = mutt_str_len(mbox);
251  }
252 
253  if (n)
254  {
255  int rc;
256  mutt_debug(LL_DEBUG3, "mbox: %s\n", mbox);
257 
258  /* if our target exists and has inferiors, enter it if we
259  * aren't already going to */
260  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), mbox);
261  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
263  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
264  imap_cmd_start(adata, buf);
265  adata->cmdresult = &list;
266  do
267  {
268  list.name = 0;
269  rc = imap_cmd_step(adata);
270  if ((rc == IMAP_RES_CONTINUE) && list.name)
271  {
272  if (!list.noinferiors && list.name[0] &&
273  (imap_mxcmp(list.name, mbox) == 0) && (n < sizeof(mbox) - 1))
274  {
275  mbox[n++] = list.delim;
276  mbox[n] = '\0';
277  }
278  }
279  } while (rc == IMAP_RES_CONTINUE);
280  adata->cmdresult = NULL;
281 
282  /* if we're descending a folder, mark it as current in browser_state */
283  if (mbox[n - 1] == list.delim)
284  {
285  showparents = true;
286  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
287  state->folder = mutt_str_dup(buf);
288  n--;
289  }
290 
291  /* Find superiors to list
292  * Note: UW-IMAP servers return folder + delimiter when asked to list
293  * folder + delimiter. Cyrus servers don't. So we ask for folder,
294  * and tack on delimiter ourselves.
295  * Further note: UW-IMAP servers return nothing when asked for
296  * NAMESPACES without delimiters at the end. Argh! */
297  for (n--; n >= 0 && mbox[n] != list.delim; n--)
298  ; // do nothing
299 
300  if (n > 0) /* "aaaa/bbbb/" -> "aaaa" */
301  {
302  /* forget the check, it is too delicate (see above). Have we ever
303  * had the parent not exist? */
304  ctmp = mbox[n];
305  mbox[n] = '\0';
306 
307  if (showparents)
308  {
309  mutt_debug(LL_DEBUG3, "adding parent %s\n", mbox);
310  add_folder(list.delim, mbox, true, false, state, true);
311  }
312 
313  /* if our target isn't a folder, we are in our superior */
314  if (!state->folder)
315  {
316  /* store folder with delimiter */
317  mbox[n++] = ctmp;
318  ctmp = mbox[n];
319  mbox[n] = '\0';
320  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
321  state->folder = mutt_str_dup(buf);
322  }
323  mbox[n] = ctmp;
324  }
325  /* "/bbbb/" -> add "/", "aaaa/" -> add "" */
326  else
327  {
328  char relpath[2];
329  /* folder may be "/" */
330  snprintf(relpath, sizeof(relpath), "%c", (n < 0) ? '\0' : adata->delim);
331  if (showparents)
332  add_folder(adata->delim, relpath, true, false, state, true);
333  if (!state->folder)
334  {
335  imap_qualify_path(buf, sizeof(buf), &cac, relpath);
336  state->folder = mutt_str_dup(buf);
337  }
338  }
339  }
340 
341  /* no namespace, no folder: set folder to host only */
342  if (!state->folder)
343  {
344  imap_qualify_path(buf, sizeof(buf), &cac, NULL);
345  state->folder = mutt_str_dup(buf);
346  }
347 
348  mutt_debug(LL_DEBUG3, "Quoting mailbox scan: %s -> ", mbox);
349  snprintf(buf, sizeof(buf), "%s%%", mbox);
350  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), buf);
351  mutt_debug(LL_DEBUG3, "%s\n", munged_mbox);
352  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
354  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
355  if (browse_add_list_result(adata, buf, state, false))
356  goto fail;
357 
358  if (state->entrylen == 0)
359  {
360  mutt_error(_("No such folder"));
361  goto fail;
362  }
363 
365 
366  if (save_lsub)
367  C_ImapCheckSubscribed = true;
368 
369  return 0;
370 
371 fail:
372  if (save_lsub)
373  C_ImapCheckSubscribed = true;
374  return -1;
375 }
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:954
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1076
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define mutt_message(...)
Definition: logging.h:83
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:137
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:618
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:1045
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:160
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define _(a)
Definition: message.h:28
Items in an IMAP browser.
Definition: private.h:147
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1178
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1062
char delim
Definition: private.h:150
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * folder
Definition: browser.h:98
bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: config.c:47
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition: util.c:689
#define PATH_MAX
Definition: mutt.h:44
char * name
Definition: private.h:149
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
bool C_ImapCheckSubscribed
Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.
Definition: config.c:37
ImapCapFlags capabilities
Definition: private.h:185
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
#define IMAP_CAP_LIST_EXTENDED
RFC5258: IMAP4 LIST Command Extensions.
Definition: private.h:138
Login details for a remote server.
Definition: connaccount.h:51
bool noinferiors
Definition: private.h:152
size_t entrylen
number of real entries
Definition: browser.h:94
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
IMAP-specific Account data -.
Definition: private.h:169
int n
Definition: acutest.h:492
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:113
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
#define mutt_error(...)
Definition: logging.h:84
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:145
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
struct ImapList * cmdresult
Definition: private.h:196
List of Mailboxes.
Definition: mailbox.h:150
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:56
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:60
&#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: private.h:192
struct Connection * conn
Definition: private.h:171
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:152
+ 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 385 of file browse.c.

386 {
387  struct ImapAccountData *adata = NULL;
388  struct ImapMboxData *mdata = NULL;
389  char name[1024];
390  short n;
391 
392  if (imap_adata_find(path, &adata, &mdata) < 0)
393  {
394  mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
395  goto err;
396  }
397 
398  /* append a delimiter if necessary */
399  mutt_str_copy(name, mdata->real_name, sizeof(name));
400  n = mutt_str_len(name);
401  if (n && (n < sizeof(name) - 1) && (name[n - 1] != adata->delim))
402  {
403  name[n++] = adata->delim;
404  name[n] = '\0';
405  }
406 
407  if (mutt_get_field(_("Create mailbox: "), name, sizeof(name), MUTT_FILE) < 0)
408  goto err;
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 }
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:226
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:128
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1446
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: private.h:218
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:424
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:220
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
IMAP-specific Account data -.
Definition: private.h:169
Log at debug level 1.
Definition: logging.h:40
int n
Definition: acutest.h:492
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:721
IMAP-specific Mailbox data -.
Definition: private.h:216
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ 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) < 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 }
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:226
#define mutt_message(...)
Definition: logging.h:83
int imap_rename_mailbox(struct ImapAccountData *adata, char *oldname, const char *newname)
Rename a mailbox.
Definition: imap.c:465
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:128
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1446
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define PATH_MAX
Definition: mutt.h:44
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: private.h:218
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:220
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
IMAP-specific Account data -.
Definition: private.h:169
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:906
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:820
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:721
IMAP-specific Mailbox data -.
Definition: private.h:216
char * buf
Definition: private.h:189
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function: