]> granicus.if.org Git - neomutt/commitdiff
IMAP folder creation and deletion. From Brendan Cully.
authorThomas Roessler <roessler@does-not-exist.org>
Mon, 22 Nov 1999 16:01:39 +0000 (16:01 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Mon, 22 Nov 1999 16:01:39 +0000 (16:01 +0000)
12 files changed:
OPS
browser.c
functions.h
imap/BUGS
imap/README
imap/TODO
imap/imap.c
imap/imap.h
imap/imap_private.h
imap/message.c
imap/util.c
pgppubring.c

diff --git a/OPS b/OPS
index f9821e97c167c1bb90b99a9a827e2b0ab828561e..88390c82e9b94d673c8af973ed953281c19ace89 100644 (file)
--- a/OPS
+++ b/OPS
@@ -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"
index 14c1089bd6d88d862245dc1803c6cef302355050..0973ebaeed925b0a256f20aef1c4d53a3efc2357 100644 (file)
--- a/browser.c
+++ b/browser.c
@@ -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:
index 5bac5774ef37d023bc64e9734cd357a01e69b087..816745472d088f6e59ef3beae5ff2d5b6785f972 100644 (file)
@@ -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" },
index d5f1799800c4ab83359f3b70b65384f47a56be24..c74b50f93681e7258ad4a1cd54ff310cafcb2e4d 100644 (file)
--- a/imap/BUGS
+++ b/imap/BUGS
@@ -1,5 +1,16 @@
 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
index c91c9571da74c321b479645f1ecf1727ec0e6553..b45706ad5a7df297faa538053598871c1f6b6704 100644 (file)
@@ -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)
index 4b87e3280fdb3e0a36a6a5dc56d8653b31c99a9d..3d2f3e2f158b471c88be34fb327c4f16d9336c49 100644 (file)
--- a/imap/TODO
+++ b/imap/TODO
@@ -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
index 03d1699f39d3e512afec6383974df39c9b7ac513..959d32f0004fdc4d4f9b3f663d485ec408af3ca7 100644 (file)
@@ -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);
       }
index 978fe4bd50f6ac67fb21b2147888e5416bf675df..fd41112dee6c648113d91afbffa6cb0d019db838 100644 (file)
 #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);
index 62b7a58cad7eb57b86e226684828a19fe30b8752..b61e9d08d814ce944b78a814418551575a4faf40 100644 (file)
@@ -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);
index 1b7c16c10687873420faf38c499ed8449dd5b0a9..408bbcf8f835328dfb24868c53d03dc763ec2de9 100644 (file)
@@ -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 */
index b02dde961ad90942b5f04eb0868615106c3ee338..6bc5d42332e10d0bb9a15e43421c1fc9c6b2ac0c 100644 (file)
@@ -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;
index d60331e45eda5ecbcec809db27f11a6631b53467..3f6a62dc06baed42f1722dadfab4a1d2b39d9166 100644 (file)
@@ -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;
 }