From 48a272550aceeceb75585a73c8cc4e3b0b70de8a Mon Sep 17 00:00:00 2001 From: Brendan Cully Date: Thu, 17 Feb 2005 03:33:00 +0000 Subject: [PATCH] New function: rename-mailbox (bound to 'r' by default). The lack of a rename-mailbox command for IMAP finally got too annoying. It's a bit of a cut-and-paste job, but I've put my dreams of cleaning up the IMAP codebase on hold. Gotta grow up some time. --- OPS | 1 + browser.c | 23 ++++++++++++++++++++- doc/manual.sgml.head | 6 ++++-- functions.h | 1 + imap/browse.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ imap/imap.c | 31 +++++++++++++++++++++------- imap/imap.h | 1 + imap/imap_private.h | 1 + 8 files changed, 103 insertions(+), 10 deletions(-) diff --git a/OPS b/OPS index f090fb2c7..0844487f8 100644 --- a/OPS +++ b/OPS @@ -144,6 +144,7 @@ OP_QUIT "save changes to mailbox and quit" OP_RECALL_MESSAGE "recall a postponed message" OP_REDRAW "clear and redraw the screen" OP_REFORMAT_WINCH "{internal}" +OP_RENAME_MAILBOX "rename the current mailbox (IMAP only)" OP_REPLY "reply to a message" OP_RESEND "use the current message as a template for a new one" OP_SAVE "save message/attachment to a file" diff --git a/browser.c b/browser.c index d38f76893..108efd4ea 100644 --- a/browser.c +++ b/browser.c @@ -875,7 +875,28 @@ void _mutt_select_file (char *f, size_t flen, int flags, char ***files, int *num } break; - case OP_DELETE_MAILBOX: + case OP_RENAME_MAILBOX: + if (!state.entry[menu->current].imap) + mutt_error (_("Rename is only supported for IMAP mailboxes")); + else + { + int nentry = menu->current; + + if (imap_mailbox_rename (state.entry[nentry].name) >= 0) { + destroy_state (&state); + init_state (&state, NULL); + state.imap_browse = 1; + imap_browse (LastDir, &state); + menu->data = state.entry; + menu->current = 0; + menu->top = 0; + init_menu (&state, menu, title, sizeof (title), buffy); + MAYBE_REDRAW (menu->redraw); + } + } + break; + + case OP_DELETE_MAILBOX: if (!state.entry[menu->current].imap) mutt_error (_("Delete is only supported for IMAP mailboxes")); else diff --git a/doc/manual.sgml.head b/doc/manual.sgml.head index a974537ec..c8e65f997 100644 --- a/doc/manual.sgml.head +++ b/doc/manual.sgml.head @@ -2461,8 +2461,10 @@ following differences: will choose to descend into the subfolder view. If you wish to view the messages in that folder, you must use view-file instead (bound to space by default). -You can delete mailboxes with the delete-mailbox - command (bound to d by default. You may also +You can create, delete and rename mailboxes with the + create-mailbox, delete-mailbox, and + rename-mailbox commands (default bindings: C, + d and r, respectively). You may also subscribe and unsubscribe to mailboxes (normally these are bound to s and u, respectively). diff --git a/functions.h b/functions.h index d1a7ca105..47181cc76 100644 --- a/functions.h +++ b/functions.h @@ -350,6 +350,7 @@ struct binding_t OpBrowser[] = { #ifdef USE_IMAP { "create-mailbox", OP_CREATE_MAILBOX, "C" }, { "delete-mailbox", OP_DELETE_MAILBOX, "d" }, + { "rename-mailbox", OP_RENAME_MAILBOX, "r" }, { "subscribe", OP_BROWSER_SUBSCRIBE, "s" }, { "unsubscribe", OP_BROWSER_UNSUBSCRIBE, "u" }, { "toggle-subscribed", OP_BROWSER_TOGGLE_LSUB, "T" }, diff --git a/imap/browse.c b/imap/browse.c index 760870e68..f2b01f4da 100644 --- a/imap/browse.c +++ b/imap/browse.c @@ -302,6 +302,55 @@ int imap_mailbox_create (const char* folder) return -1; } +int imap_mailbox_rename(const char* mailbox) +{ + IMAP_DATA* idata; + IMAP_MBOX mx; + char buf[LONG_STRING]; + char newname[SHORT_STRING]; + + if (imap_parse_path (mailbox, &mx) < 0) + { + dprint (1, (debugfile, "imap_mailbox_rename: Bad source mailbox %s\n", + mailbox)); + return -1; + } + + if (!(idata = imap_conn_find (&mx.account, M_IMAP_CONN_NONEW))) + { + dprint (1, (debugfile, "imap_mailbox_rename: Couldn't find open connection to %s", mx.account.host)); + goto fail; + } + + snprintf(buf, sizeof (buf), _("Rename mailbox %s to: "), mx.mbox); + + if (mutt_get_field (buf, newname, sizeof (newname), M_FILE) < 0) + goto fail; + + if (!mutt_strlen (newname)) + { + mutt_error (_("Mailbox must have a name.")); + mutt_sleep (1); + goto fail; + } + + if (imap_rename_mailbox (idata, &mx, newname) < 0) { + mutt_error (_("Rename failed: %s"), imap_get_qualifier (idata->cmd.buf)); + mutt_sleep (1); + goto fail; + } + + mutt_message (_("Mailbox renamed.")); + mutt_sleep (0); + + FREE (&mx.mbox); + return 0; + + fail: + FREE (&mx.mbox); + return -1; +} + static int browse_add_list_result (IMAP_DATA* idata, const char* cmd, struct browser_state* state, short isparent) { diff --git a/imap/imap.c b/imap/imap.c index 675edab28..fde8b9a6c 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -108,20 +108,37 @@ int imap_create_mailbox (IMAP_DATA* idata, char* mailbox) return 0; } +int imap_rename_mailbox (IMAP_DATA* idata, IMAP_MBOX* mx, const char* newname) +{ + char oldmbox[LONG_STRING]; + char newmbox[LONG_STRING]; + char buf[LONG_STRING]; + + imap_munge_mbox_name (oldmbox, sizeof (oldmbox), mx->mbox); + imap_munge_mbox_name (newmbox, sizeof (newmbox), newname); + + snprintf (buf, sizeof (buf), "RENAME %s %s", oldmbox, newmbox); + + if (imap_exec (idata, buf, 0) != 0) + return -1; + + return 0; +} + int imap_delete_mailbox (CONTEXT* ctx, IMAP_MBOX mx) { char buf[LONG_STRING], mbox[LONG_STRING]; IMAP_DATA *idata; if (!ctx || !ctx->data) { - if (!(idata = imap_conn_find (&mx.account, - option (OPTIMAPPASSIVE) ? M_IMAP_CONN_NONEW : 0))) - { - FREE (&mx.mbox); - return -1; - } + if (!(idata = imap_conn_find (&mx.account, + option (OPTIMAPPASSIVE) ? M_IMAP_CONN_NONEW : 0))) + { + FREE (&mx.mbox); + return -1; + } } else { - idata = ctx->data; + idata = ctx->data; } imap_munge_mbox_name (mbox, sizeof (mbox), mx.mbox); diff --git a/imap/imap.h b/imap/imap.h index ae42ff2f8..9ac7a95e6 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -50,6 +50,7 @@ void imap_disallow_reopen (CONTEXT *ctx); /* browse.c */ int imap_browse (char* path, struct browser_state* state); int imap_mailbox_create (const char* folder); +int imap_mailbox_rename (const char* mailbox); /* message.c */ int imap_append_message (CONTEXT* ctx, MESSAGE* msg); diff --git a/imap/imap_private.h b/imap/imap_private.h index 056fbcfc2..848326bc6 100644 --- a/imap/imap_private.h +++ b/imap/imap_private.h @@ -194,6 +194,7 @@ typedef struct /* -- private IMAP functions -- */ /* imap.c */ int imap_create_mailbox (IMAP_DATA* idata, char* mailbox); +int imap_rename_mailbox (IMAP_DATA* idata, IMAP_MBOX* mx, const char* newname); int imap_make_msg_set (IMAP_DATA* idata, BUFFER* buf, int flag, int changed); int imap_open_connection (IMAP_DATA* idata); IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags); -- 2.50.1