Commit 995c71b0 authored by Thomas Roessler's avatar Thomas Roessler

IMAP folder creation and deletion. From Brendan Cully.

parent 8c16ab2b
......@@ -6,9 +6,9 @@ OP_BOUNCE_MESSAGE "remail a message to another user"
OP_BROWSER_NEW_FILE "select a new file in this directory"
OP_BROWSER_VIEW_FILE "view file"
OP_BROWSER_TELL "display the currently selected file's name"
OP_BROWSER_SUBSCRIBE "subscribe to current mailbox (IMAP Only)"
OP_BROWSER_UNSUBSCRIBE "unsubscribe to current mailbox (IMAP Only)"
OP_BROWSER_TOGGLE_LSUB "toggle view all/subscribed mailboxes (IMAP Only)"
OP_BROWSER_SUBSCRIBE "subscribe to current mailbox (IMAP only)"
OP_BROWSER_UNSUBSCRIBE "unsubscribe to current mailbox (IMAP only)"
OP_BROWSER_TOGGLE_LSUB "toggle view all/subscribed mailboxes (IMAP only)"
OP_CHANGE_DIRECTORY "change directories"
OP_CHECK_NEW "check mailboxes for new mail"
OP_COMPOSE_ATTACH_FILE "attach a file(s) to this message"
......@@ -47,6 +47,7 @@ OP_CURRENT_TOP "move entry to top of screen"
OP_DECODE_COPY "make decoded (text/plain) copy"
OP_DECODE_SAVE "make decoded copy (text/plain) and delete"
OP_DELETE "delete the current entry"
OP_DELETE_MAILBOX "delete the current mailbox (IMAP only)"
OP_DELETE_SUBTHREAD "delete all messages in subthread"
OP_DELETE_THREAD "delete all messages in thread"
OP_DISPLAY_ADDRESS "display full address of sender"
......@@ -112,6 +113,7 @@ OP_MAIN_TAG_PATTERN "tag messages matching a pattern"
OP_MAIN_UNDELETE_PATTERN "undelete messages matching a pattern"
OP_MAIN_UNTAG_PATTERN "untag messages matching a pattern"
OP_MIDDLE_PAGE "move to the middle of the page"
OP_NEW_MAILBOX "create a new mailbox (IMAP only)"
OP_NEXT_ENTRY "move to the next entry"
OP_NEXT_LINE "scroll down one line"
OP_NEXT_PAGE "move to the next page"
......
......@@ -337,6 +337,9 @@ static void init_state (struct browser_state *state, MUTTMENU *menu)
state->entrymax = 256;
state->entry = (struct folder_file *) safe_malloc (sizeof (struct folder_file) * state->entrymax);
memset (state->entry, 0, sizeof (struct folder_file) * state->entrymax);
#ifdef USE_IMAP
state->imap_browse = 0;
#endif
if (menu)
menu->data = state->entry;
}
......@@ -596,7 +599,8 @@ void _mutt_select_file (char *f, size_t flen, int buffy,
if (multiple)
menu->tag = file_tag;
menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_FOLDER, FolderHelp);
menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_FOLDER,
FolderHelp);
init_menu (&state, menu, title, sizeof (title), buffy);
......@@ -793,6 +797,45 @@ void _mutt_select_file (char *f, size_t flen, int buffy,
}
mutt_ungetch (0, OP_CHECK_NEW);
break;
case OP_NEW_MAILBOX:
mutt_error (_("Creating mailboxes is not yet supported."));
break;
case OP_DELETE_MAILBOX:
if (!mx_is_imap (state.entry[menu->current].name))
mutt_error (_("Delete is only supported for IMAP mailboxes"));
else
{
char msg[LONG_STRING];
char* mbox;
int nentry = menu->current;
imap_parse_path (state.entry[nentry].name, NULL, 0, NULL,
NULL, &mbox);
snprintf (msg, sizeof (msg), _("Really delete mailbox \"%s\"?"),
mbox);
if (mutt_yesorno (msg, M_NO) == M_YES)
{
if (!imap_delete_mailbox (Context, mbox))
{
/* free the mailbox from the browser */
safe_free ((void **) &((state.entry)[nentry].name));
safe_free ((void **) &((state.entry)[nentry].desc));
/* and move all other entries up */
if (nentry+1 < state.entrylen)
memmove (state.entry + nentry, state.entry + nentry + 1,
sizeof (struct folder_file) * (state.entrylen - (nentry+1)));
state.entrylen--;
mutt_message _("Mailbox deleted.");
init_menu (&state, menu, title, sizeof (title), buffy);
MAYBE_REDRAW (menu->redraw);
}
}
else
mutt_message _("Mailbox not deleted.");
}
break;
#endif
case OP_CHANGE_DIRECTORY:
......
......@@ -327,6 +327,8 @@ struct binding_t OpBrowser[] = {
{ "toggle-mailboxes", OP_TOGGLE_MAILBOXES, "\t" },
{ "view-file", OP_BROWSER_VIEW_FILE, " " },
#ifdef USE_IMAP
{ "new-mailbox", OP_NEW_MAILBOX, "n" },
{ "delete-mailbox", OP_DELETE_MAILBOX, "d" },
{ "subscribe", OP_BROWSER_SUBSCRIBE, "s" },
{ "unsubscribe", OP_BROWSER_UNSUBSCRIBE, "u" },
{ "toggle-subscribed", OP_BROWSER_TOGGLE_LSUB, "T" },
......
In no particular order:
* Mutt doesn't detect when a mailbox has only been opened read-only
(because, say, another process has it open), so it lets you store
changes that it can't commit.
--> just pick up the [READ-ONLY] in the tagged response, set mutt's flag
* ~h searches download the entire folder, setting everything to \Seen in
the process.
--> Use SEARCH? or at least try to use .PEEK when doing scans. I've been
thinking of going to always PEEK anyway, but then you'd have to store
updates for every message you touched. Maybe a config option?
* No checks are performed on long commands to make sure that they are
still correct after they've been made to fit in their buffers.
Tagged message sets can exceed the fixed space we've allocated for
......@@ -40,4 +51,4 @@ In no particular order:
* The mutt_pretty routines don't work well when the delimiter isn't '/'.
Brendan Cully <brendan@kublai.com>
Updated 19991102
Updated 19991110
......@@ -25,3 +25,4 @@ New features vs. the stable distribution:
* Use an IMAP path as your Maildir (set folder='')
* Preserve message keywords
* Preserve deleted messages if you don't choose to expunge them
* Delete mailboxes (from the browser)
......@@ -27,6 +27,12 @@ IMAP enhancements, by priority:
PRIORITY: [** ]
* See if we can't add more info to the IMAP browser than just name (without
incurring too much overhead). eg which folders contain new mail, size,
number of messages.
PRIORITY: [** ]
[ -- speed -- ]
* Persistent caching of data. I think the nicest way to do this is to store
local copies like IMAP does, with an invisible control message at the top,
......@@ -44,6 +50,12 @@ IMAP enhancements, by priority:
PRIORITY: [* ]
* Instead of testing for the existence of a mailbox for APPEND, just append
and create/retry on failure. This is only a small bandwidth savings, but
it should be easy.
PRIORITY: [* ]
[ -- new features -- ]
* Implement the received folder on IMAP, now that COPY is done
......@@ -60,4 +72,4 @@ IMAP enhancements, by priority:
PRIORITY: [** ]
Brendan Cully <brendan@kublai.com>
Updated: 19990911
Updated: 19991119
......@@ -42,6 +42,37 @@ static char* imap_get_flags (LIST** hflags, char* s);
static int imap_check_acl (IMAP_DATA *idata);
static int imap_check_capabilities (IMAP_DATA *idata);
int imap_create_mailbox (CONTEXT* ctx, char* mailbox)
{
char buf[LONG_STRING], mbox[LONG_STRING];
imap_quote_string (mbox, sizeof (mbox), mailbox);
snprintf (buf, sizeof (buf), "CREATE %s", mbox);
if (imap_exec (buf, sizeof (buf), CTX_DATA, buf, 0) != 0)
{
imap_error ("imap_create_mailbox()", buf);
return -1;
}
return 0;
}
int imap_delete_mailbox (CONTEXT* ctx, char* mailbox)
{
char buf[LONG_STRING], mbox[LONG_STRING];
imap_quote_string (mbox, sizeof (mbox), mailbox);
snprintf (buf, sizeof (buf), "DELETE %s", mbox);
if (imap_exec (buf, sizeof (buf), CTX_DATA, buf, 0) != 0)
{
imap_error ("imap_delete_mailbox", buf);
return -1;
}
return 0;
}
void imap_set_logout (CONTEXT *ctx)
{
if (CTX_DATA)
......@@ -712,21 +743,6 @@ int imap_select_mailbox (CONTEXT* ctx, const char* path)
return imap_open_mailbox (ctx);
}
int imap_create_mailbox (IMAP_DATA* idata, char* mailbox)
{
char buf[LONG_STRING], mbox[LONG_STRING];
imap_quote_string (mbox, sizeof (mbox), mailbox);
snprintf (buf, sizeof (buf), "CREATE %s", mbox);
if (imap_exec (buf, sizeof (buf), idata, buf, 0) != 0)
{
imap_error ("imap_create_mailbox()", buf);
return (-1);
}
return 0;
}
int imap_open_mailbox_append (CONTEXT *ctx)
{
CONNECTION *conn;
......@@ -798,7 +814,7 @@ int imap_open_mailbox_append (CONTEXT *ctx)
{
return (-1);
}
if (imap_create_mailbox (idata, mailbox) < 0)
if (imap_create_mailbox (ctx, mailbox) < 0)
{
return (-1);
}
......
......@@ -22,8 +22,11 @@
#include "browser.h"
#include "mailbox.h"
/* imap.c */
int imap_check_mailbox (CONTEXT *ctx, int *index_hint);
int imap_create_mailbox (CONTEXT* idata, char* mailbox);
int imap_close_connection (CONTEXT *ctx);
int imap_delete_mailbox (CONTEXT* idata, char* mailbox);
int imap_open_mailbox (CONTEXT *ctx);
int imap_open_mailbox_append (CONTEXT *ctx);
int imap_select_mailbox (CONTEXT *ctx, const char* path);
......
......@@ -149,7 +149,6 @@ typedef struct
/* -- private IMAP functions -- */
/* imap.c */
int imap_create_mailbox (IMAP_DATA* idata, char* mailbox);
int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag,
int changed);
int imap_open_connection (IMAP_DATA* idata, CONNECTION* conn);
......
......@@ -580,7 +580,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
mutt_clear_error ();
return -1;
}
if (imap_create_mailbox (CTX_DATA, mbox) < 0)
if (imap_create_mailbox (ctx, mbox) < 0)
return -1;
}
/* try again */
......
......@@ -128,19 +128,23 @@ int imap_parse_path (char* path, char* host, size_t hlen, int* port,
char *pt;
/* set default port */
*port = 0;
if (port)
*port = 0;
if (socktype)
*socktype = M_NEW_SOCKET;
pc = path;
if (*pc != '{')
return -1;
pc++;
n = 0;
while (*pc && *pc != '}' && *pc != ':' && *pc != '/' && (n < hlen-1))
host[n++] = *pc++;
host[n] = 0;
/* catch NULL hosts */
if (!*host)
/* skip over the entire host, but copy in only what we have room for */
for (n = 0; *pc && *pc != '}' && *pc != ':' && *pc != '/'; pc++)
if (n+1 < hlen)
host[n++] = *pc;
if (hlen)
host[n] = 0;
/* catch NULL hosts, unless we're deliberately not parsing them */
if (hlen && !*host)
{
dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path));
return -1;
......@@ -157,8 +161,9 @@ int imap_parse_path (char* path, char* host, size_t hlen, int* port,
return -1;
c = *pc;
*pc = '\0';
*port = atoi (pt);
if (!port)
if (port)
*port = atoi (pt);
if (port && !*port)
{
dprint (1, (debugfile, "imap_parse_path: bad port in %s\n", path));
return -1;
......@@ -178,7 +183,7 @@ int imap_parse_path (char* path, char* host, size_t hlen, int* port,
{
if (socktype)
*socktype = M_NEW_SSL_SOCKET;
if (!*port)
if (port && !*port)
*port = IMAP_SSL_PORT;
} else
#endif
......@@ -187,7 +192,7 @@ int imap_parse_path (char* path, char* host, size_t hlen, int* port,
}
pc++;
if (!*port)
if (port && !*port)
*port = IMAP_PORT;
*mbox = pc;
......
......@@ -133,7 +133,7 @@ int main (int argc, char * const argv[])
snprintf (kring, sizeof (kring), "%s/pubring.%s", pgppath, version == 2 ? "pgp" : "pkr");
}
pgpring_find_candidates (kring, argv + optind, argc - optind);
pgpring_find_candidates (kring, (const char**) argv + optind, argc - optind);
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment