Remove most of the hooks
authorPierre Habouzit <madcoder@debian.org>
Sun, 18 Nov 2007 11:01:10 +0000 (12:01 +0100)
committerPierre Habouzit <madcoder@debian.org>
Sun, 18 Nov 2007 11:01:10 +0000 (12:01 +0100)
* migrate the crypt-hook to lua.
* hard-code compress-hooks for now.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
crypt.cpkg
hook.c
init.c
init.h
lib-mx/compress.c
lib-mx/mx.c
protos.h

index 10a33b2..0dded60 100644 (file)
@@ -3400,6 +3400,23 @@ crypt_ask_for_key(const char *tag, int abilities, int app, int *forced_valid)
     }
 }
 
+static char *crypt_hook(address_t *adr)
+{
+    char *res = NULL;
+    lua_State *L = luaM_getruntime();
+    lua_getglobal(L, "mod_core");             /* push mod_core        1 */
+    lua_getfield(L, -1, "crypt_hook");        /* push folder_hook()   2 */
+    if (lua_isfunction(L, -1)) {
+        lua_pushstring(L, adr->mailbox);
+        if (!lua_pcall(L, 1, 1, 0)) {
+            res = m_strdup(lua_tostring(L, -1));
+        }
+        lua_pop(L, 1);
+    }
+    lua_pop(L, 2);
+    return res;
+}
+
 /* This routine attempts to find the keyids of the recipients of a
    message.  It returns NULL if any of the keys can not be found.  */
 static char *find_keys(ENVELOPE *env, unsigned int app)
@@ -3422,10 +3439,10 @@ static char *find_keys(ENVELOPE *env, unsigned int app)
     while ((addr = address_list_pop(&lst))) {
         char buf[STRING];
         int forced_valid = 0;
-        const char *keyID;
+        char *keyID;
         cryptkey_t *key = NULL;
 
-        if ((keyID = mutt_crypt_hook(addr))) {
+        if ((keyID = crypt_hook(addr))) {
             int r;
 
             snprintf(buf, sizeof(buf), _("Use keyID = \"%s\" for %s?"), keyID,
@@ -3436,6 +3453,7 @@ static char *find_keys(ENVELOPE *env, unsigned int app)
                 address_list_wipe(&lst);
                 address_list_wipe(&addr);
                 buffer_delete(&keylist);
+                p_delete(&keyID);
                 return NULL;
             }
 
@@ -3452,6 +3470,7 @@ static char *find_keys(ENVELOPE *env, unsigned int app)
                 }
             }
         }
+        p_delete(&keyID);
 
         if (!key) {
             key = crypt_getkeybyaddr(addr, KEYFLAG_CANENCRYPT, app, &forced_valid);
diff --git a/hook.c b/hook.c
index 37eda9e..efda902 100644 (file)
--- a/hook.c
+++ b/hook.c
@@ -37,247 +37,21 @@ DO_SLIST(hook_t, hook, hook_delete);
 static hook_t *Hooks = NULL;
 static unsigned long current_hook_type = 0;
 
-int mutt_parse_hook (BUFFER * buf __attribute__ ((unused)), BUFFER * s,
-                     unsigned long data, BUFFER * err)
-{
-  hook_t *ptr;
-  BUFFER command, pattern;
-  int rc, neg = 0;
-  regex_t *rx = NULL;
-  pattern_t *pat = NULL;
-  char path[_POSIX_PATH_MAX];
-
-  p_clear(&pattern, 1);
-  p_clear(&command, 1);
-
-  if (*s->dptr == '!') {
-    s->dptr = vskipspaces(s->dptr + 1);
-    neg = 1;
-  }
-
-  mutt_extract_token (&pattern, s, 0);
-
-  if (!MoreArgs (s)) {
-    m_strcpy(err->data, err->dsize, _("too few arguments"));
-    goto error;
-  }
-
-  mutt_extract_token(&command, s, (data & (M_FOLDERHOOK | M_SENDHOOK |
-                                           M_SEND2HOOK | M_REPLYHOOK)) ?
-                     M_TOKEN_SPACE : 0);
-
-  if (!command.data) {
-    m_strcpy(err->data, err->dsize, _("too few arguments"));
-    goto error;
-  }
-
-  if (MoreArgs (s)) {
-    m_strcpy(err->data, err->dsize, _("too many arguments"));
-    goto error;
-  }
-
-  if (data & (M_FOLDERHOOK | M_MBOXHOOK)) {
-    _mutt_expand_path (path, sizeof (path), pattern.data, 1);
-    p_delete(&pattern.data);
-    p_clear(&pattern, 1);
-    pattern.data = m_strdup(path);
-  }
-  else if (data & (M_APPENDHOOK | M_OPENHOOK | M_CLOSEHOOK)) {
-    if (mutt_test_compress_command (command.data)) {
-      m_strcpy(err->data, err->dsize, _("bad formatted command string"));
-      return (-1);
-    }
-  }
-  else if (DefaultHook && !(data & M_CRYPTHOOK))
-  {
-    char tmp[HUGE_STRING];
-
-    m_strcpy(tmp, sizeof(tmp), pattern.data);
-    mutt_check_simple (tmp, sizeof (tmp), DefaultHook);
-    p_delete(&pattern.data);
-    p_clear(&pattern, 1);
-    pattern.data = m_strdup(tmp);
-  }
-
-  if (data & (M_MBOXHOOK | M_SAVEHOOK | M_FCCHOOK)) {
-    m_strcpy(path, sizeof(path), command.data);
-    mutt_expand_path (path, sizeof (path));
-    p_delete(&command.data);
-    p_clear(&command, 1);
-    command.data = m_strdup(path);
-  }
-
-  /* check to make sure that a matching hook doesn't already exist */
-  for (ptr = Hooks; ptr; ptr = ptr->next) {
-    if (ptr->type == (int)data &&
-        ptr->rx.neg == neg && !m_strcmp(pattern.data, ptr->rx.pattern)) {
-      if (data & (M_FOLDERHOOK | M_SENDHOOK | M_SEND2HOOK | M_MESSAGEHOOK |
-           M_REPLYHOOK))
-      {
-        /* these hooks allow multiple commands with the same
-         * pattern, so if we've already seen this pattern/command pair, just
-         * ignore it instead of creating a duplicate */
-        if (!m_strcmp(ptr->command, command.data)) {
-          p_delete(&command.data);
-          p_delete(&pattern.data);
-          return 0;
-        }
-      } else {
-        /* other hooks only allow one command per pattern, so update the
-         * entry with the new command.  this currently does not change the
-         * order of execution of the hooks, which i think is desirable since
-         * a common action to perform is to change the default (.) entry
-         * based upon some other information. */
-        p_delete(&ptr->command);
-        ptr->command = command.data;
-        p_delete(&pattern.data);
-        return 0;
-      }
-    }
-    if (!ptr->next)
-      break;
-  }
-
-  if (data & (M_SENDHOOK | M_SEND2HOOK | M_SAVEHOOK | M_FCCHOOK |
-              M_MESSAGEHOOK | M_REPLYHOOK))
-  {
-    if ((pat =
-         mutt_pattern_comp (pattern.data,
-                            (data & (M_SENDHOOK | M_SEND2HOOK | M_FCCHOOK)) ?
-                            0 : M_FULL_MSG, err)) == NULL)
-      goto error;
-  } else {
-    rx = p_new(regex_t, 1);
-    if ((rc = REGCOMP(rx, NONULL(pattern.data),
-                  ((data & M_CRYPTHOOK) ? REG_ICASE : 0))) != 0)
-    {
-      regerror (rc, rx, err->data, err->dsize);
-      regfree (rx);
-      p_delete(&rx);
-      goto error;
-    }
-  }
-
-  if (ptr) {
-    ptr->next = p_new(hook_t, 1);
-    ptr = ptr->next;
-  } else {
-    Hooks = ptr = p_new(hook_t, 1);
-  }
-  ptr->type = data;
-  ptr->command = command.data;
-  ptr->pattern = pat;
-  ptr->rx.pattern = pattern.data;
-  ptr->rx.rx = rx;
-  ptr->rx.neg = neg;
-  return 0;
-
-error:
-  p_delete(&pattern.data);
-  p_delete(&command.data);
-  return (-1);
-}
-
 /* Deletes all hooks of type ``type'', or all defined hooks if ``type'' is 0 */
-static void delete_hooks (long type)
-{
-    hook_t **l = &Hooks;
-
-    while (*l) {
-        if ((*l)->type == type) {
-            hook_t *tmp = hook_list_pop(l);
-            hook_delete(&tmp);
-        } else {
-            l = &(*l)->next;
-        }
-    }
-}
-
-int mutt_parse_unhook (BUFFER * buf, BUFFER * s, unsigned long data __attribute__ ((unused)),
-                       BUFFER * err)
-{
-  while (MoreArgs (s)) {
-    mutt_extract_token (buf, s, 0);
-    if (m_strcmp("*", buf->data) == 0) {
-      if (current_hook_type) {
-        snprintf (err->data, err->dsize,
-                  _("unhook: Can't do unhook * from within a hook."));
-        return -1;
-      }
-      hook_list_wipe(&Hooks);
-    } else {
-      unsigned long type = mutt_get_hook_type (buf->data);
-
-      if (!type) {
-        snprintf (err->data, err->dsize,
-                  _("unhook: unknown hook type: %s"), buf->data);
-        return (-1);
-      }
-      if (current_hook_type == type) {
-        snprintf (err->data, err->dsize,
-                  _("unhook: Can't delete a %s from within a %s."), buf->data,
-                  buf->data);
-        return -1;
-      }
-      delete_hooks (type);
-    }
-  }
-  return 0;
-}
-
 void mutt_folder_hook (char *path)
 {
-  hook_t *tmp = Hooks;
-  BUFFER err, token;
-  char buf[STRING];
-
-  current_hook_type = M_FOLDERHOOK;
-
-  err.data = buf;
-  err.dsize = sizeof (buf);
-  p_clear(&token, 1);
-  for (; tmp; tmp = tmp->next) {
-    if (!tmp->command)
-      continue;
-
-    if (tmp->type & M_FOLDERHOOK) {
-      if ((regexec (tmp->rx.rx, path, 0, NULL, 0) == 0) ^ tmp->rx.neg) {
-        if (mutt_parse_rc_line (tmp->command, &token, &err) == -1) {
-          mutt_error ("%s", err.data);
-          mutt_sleep (1);       /* pause a moment to let the user see the error */
-        }
-      }
-    }
-  }
-  p_delete(&token.data);
-
-  current_hook_type = 0;
-
-    {
-        lua_State *L = luaM_getruntime();
-        lua_getfield(L, LUA_GLOBALSINDEX, "mod_core");
-        lua_getfield(L, -1, "folder_hook");
-        lua_remove(L, -2);
-        if (lua_isfunction(L, -1)) {
-            lua_pushstring(L, LastFolder);
-            lua_pushstring(L, CurrentFolder);
-            lua_pcall(L, 2, 0, 0);
-        } else {
-            lua_pop(L, 1);
+    lua_State *L = luaM_getruntime();
+    lua_getglobal(L, "mod_core");             /* push mod_core        1 */
+    lua_getfield(L, -1, "folder_hook");       /* push folder_hook()   2 */
+    if (lua_isfunction(L, -1)) {
+        lua_pushstring(L, LastFolder);
+        lua_pushstring(L, CurrentFolder);
+        if (lua_pcall(L, 2, 0, 0)) {
+            lua_pop(L, 3);
+            return;
         }
     }
-}
-
-char *mutt_find_hook (int type, const char *pat)
-{
-  hook_t *tmp = Hooks;
-
-  for (; tmp; tmp = tmp->next)
-    if (tmp->type & type) {
-      if (regexec (tmp->rx.rx, pat, 0, NULL, 0) == 0)
-        return (tmp->command);
-    }
-  return (NULL);
+    lua_pop(L, 2);
 }
 
 void mutt_message_hook (CONTEXT * ctx, HEADER * hdr, int type)
@@ -306,74 +80,33 @@ void mutt_message_hook (CONTEXT * ctx, HEADER * hdr, int type)
   current_hook_type = 0;
 }
 
-static int
-mutt_addr_hook (char *path, ssize_t pathlen, unsigned long type, CONTEXT * ctx,
-                HEADER * hdr)
-{
-  hook_t *hook;
-
-  /* determine if a matching hook exists */
-  for (hook = Hooks; hook; hook = hook->next) {
-    if (!hook->command)
-      continue;
-
-    if (hook->type & type)
-      if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.neg) {
-        mutt_make_string (path, pathlen, hook->command, ctx, hdr);
-        return 0;
-      }
-  }
-
-  return -1;
-}
-
 void mutt_default_save (char *path, ssize_t pathlen, HEADER * hdr)
 {
-  *path = 0;
-  if (mutt_addr_hook (path, pathlen, M_SAVEHOOK, Context, hdr) != 0) {
-    char tmp[_POSIX_PATH_MAX];
-    address_t *adr;
-    ENVELOPE *env = hdr->env;
-    int fromMe = mutt_addr_is_user (env->from);
-
-    if (!fromMe && env->reply_to && env->reply_to->mailbox)
-      adr = env->reply_to;
-    else if (!fromMe && env->from && env->from->mailbox)
-      adr = env->from;
-    else if (env->to && env->to->mailbox)
-      adr = env->to;
-    else if (env->cc && env->cc->mailbox)
-      adr = env->cc;
-    else
-      adr = NULL;
-    if (adr) {
-      mutt_safe_path (tmp, sizeof (tmp), adr);
-      snprintf (path, pathlen, "=%s", tmp);
-    }
+  char tmp[_POSIX_PATH_MAX];
+  address_t *adr;
+  ENVELOPE *env = hdr->env;
+  int fromMe = mutt_addr_is_user (env->from);
+
+  if (!fromMe && env->reply_to && env->reply_to->mailbox)
+    adr = env->reply_to;
+  else if (!fromMe && env->from && env->from->mailbox)
+    adr = env->from;
+  else if (env->to && env->to->mailbox)
+    adr = env->to;
+  else if (env->cc && env->cc->mailbox)
+    adr = env->cc;
+  else
+    adr = NULL;
+  if (adr) {
+    mutt_safe_path (tmp, sizeof (tmp), adr);
+    snprintf (path, pathlen, "=%s", tmp);
+  } else {
+    *path = 0;
   }
 }
 
 void mutt_select_fcc (char *path, ssize_t pathlen, HEADER * hdr)
 {
-    if (mutt_addr_hook (path, pathlen, M_FCCHOOK, NULL, hdr) != 0) {
-        m_strcpy(path, pathlen, NONULL(MAlias.record));
-    }
-    mutt_pretty_mailbox (path);
-}
-
-static const char *_mutt_string_hook (const char *match, int hook)
-{
-  hook_t *tmp = Hooks;
-
-  for (; tmp; tmp = tmp->next) {
-    if ((tmp->type & hook)
-    && ((match && regexec(tmp->rx.rx, match, 0, NULL, 0) == 0) ^ tmp->rx.neg))
-      return (tmp->command);
-  }
-  return (NULL);
-}
-
-const char *mutt_crypt_hook (address_t * adr)
-{
-  return _mutt_string_hook (adr->mailbox, M_CRYPTHOOK);
+    m_strcpy(path, pathlen, NONULL(MAlias.record));
+    mutt_pretty_mailbox(path);
 }
diff --git a/init.c b/init.c
index 323d5ac..9b9346e 100644 (file)
--- a/init.c
+++ b/init.c
@@ -1767,13 +1767,3 @@ void mutt_init (int skip_sys_rc, string_list_t * commands)
   }
 }
 
-int mutt_get_hook_type (const char *name)
-{
-  struct command_t *c;
-
-  for (c = Commands; c->name; c++)
-    if (c->func == mutt_parse_hook && ascii_strcasecmp (c->name, name) == 0)
-      return c->data;
-  return 0;
-}
-
diff --git a/init.h b/init.h
index 7f6bcb9..feedd18 100644 (file)
--- a/init.h
+++ b/init.h
@@ -210,7 +210,7 @@ struct option_t MuttVars[] = {
    ** checking each file to see if it has already been looked at.  If it's
    ** \fIunset\fP, no check for new mail is performed while the mailbox is open.
    */
-  {"collapse_unread", DT_BOOL, OPTCOLLAPSEUNREAD, "yes" },
+  {"collapse_unread", DT_BOOL, OPTCOLLAPSEUNREAD, "no" },
   /*
    ** .pp
    ** When \fIunset\fP, Madmutt will not collapse a thread if it contains any
@@ -2023,24 +2023,9 @@ struct command_t Commands[] = {
     {"bind",                mutt_parse_bind,       0},
     {"color",               mutt_parse_color,      0},
     {"exec",                mutt_parse_exec,       0},
-    {"append-hook",         mutt_parse_hook,       M_APPENDHOOK},
-    {"close-hook",          mutt_parse_hook,       M_CLOSEHOOK},
-    {"crypt-hook",          mutt_parse_hook,       M_CRYPTHOOK},
-    {"fcc-hook",            mutt_parse_hook,       M_FCCHOOK},
-    {"fcc-save-hook",       mutt_parse_hook,       M_FCCHOOK|M_SAVEHOOK},
-    {"folder-hook",         mutt_parse_hook,       M_FOLDERHOOK},
-    {"mbox-hook",           mutt_parse_hook,       M_MBOXHOOK},
-    {"message-hook",        mutt_parse_hook,       M_MESSAGEHOOK},
-    {"open-hook",           mutt_parse_hook,       M_OPENHOOK},
-    {"pgp-hook",            mutt_parse_hook,       M_CRYPTHOOK},
-    {"reply-hook",          mutt_parse_hook,       M_REPLYHOOK},
-    {"save-hook",           mutt_parse_hook,       M_SAVEHOOK},
-    {"send2-hook",          mutt_parse_hook,       M_SEND2HOOK},
-    {"send-hook",           mutt_parse_hook,       M_SENDHOOK},
     {"macro",               mutt_parse_macro,      0},
     {"push",                mutt_parse_push,       0},
     {"uncolor",             mutt_parse_uncolor,    0},
-    {"unhook",              mutt_parse_unhook,     0},
     {"alias",               parse_alias,           0},
     {"attachments",         parse_attachments,     0 },
     {"my_hdr",              parse_my_hdr,          0},
index 22fe01e..67f72bc 100644 (file)
@@ -65,9 +65,24 @@ static int is_new (const char *path)
 
 static const char *find_compress_hook (int type, const char *path)
 {
-  const char *c = mutt_find_hook (type, path);
-
-  return (!c || !*c) ? NULL : c;
+  int len = strlen(path);
+  if (len > 3 && !strcmp(path + len - 3, ".gz")) {
+      switch (type) {
+        case M_OPENHOOK:   return "gzip -cd %f > %t";
+        case M_CLOSEHOOK:  return "gzip -cd %t > %f";
+        case M_APPENDHOOK: return "gzip -cd %t >> %f";
+        default: return NULL;
+      }
+  }
+  if (len > 4 && !strcmp(path + len - 4, ".bz2")) {
+      switch (type) {
+        case M_OPENHOOK:   return "bzip2 -cd %f > %t";
+        case M_CLOSEHOOK:  return "bzip2 -cd %t > %f";
+        case M_APPENDHOOK: return "bzip2 -cd %t >> %f";
+        default: return NULL;
+      }
+  }
+  return NULL;
 }
 
 int mutt_can_read_compressed (const char *path)
index 6e84b10..ba1cc3c 100644 (file)
@@ -600,14 +600,8 @@ static int _mx_close_mailbox (CONTEXT * ctx, int *index_hint)
   if (read_msgs && quadoption (OPT_MOVE) != M_NO) {
     char *p;
 
-    if ((p = mutt_find_hook (M_MBOXHOOK, ctx->path))) {
-      isSpool = 1;
-      m_strcpy(mbox, sizeof(mbox), p);
-    }
-    else {
-      m_strcpy(mbox, sizeof(mbox), NONULL(Inbox));
-      isSpool = mutt_is_spool (ctx->path) && !mutt_is_spool (mbox);
-    }
+    m_strcpy(mbox, sizeof(mbox), NONULL(Inbox));
+    isSpool = mutt_is_spool (ctx->path) && !mutt_is_spool (mbox);
     mutt_expand_path (mbox, sizeof (mbox));
 
     if (isSpool) {
index ce22711..037e3fe 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -37,10 +37,8 @@ int mutt_cmp_header (const HEADER*, const HEADER*);
 ssize_t _mutt_expand_path(char *, ssize_t, const char *, int);
 #define mutt_expand_path(s, n) _mutt_expand_path((s), (n), (s), 0)
 
-char *mutt_find_hook (int, const char *);
 char *mutt_get_body_charset (char *, ssize_t, BODY *);
 const char *mutt_get_name (address_t *);
-const char *mutt_crypt_hook (address_t *);
 char *mutt_make_date (char *, ssize_t);
 
 const char *mutt_make_version(void);
@@ -104,7 +102,6 @@ int mutt_fetch_recips (ENVELOPE * out, ENVELOPE * in, int flags);
 int mutt_prepare_template (FILE *, CONTEXT *, HEADER *, HEADER *, short);
 int mutt_resend_message (FILE *, CONTEXT *, HEADER *);
 
-int mutt_get_hook_type (const char *);
 int mutt_get_postponed (CONTEXT *, HEADER *, HEADER **, char *, ssize_t);
 int mutt_invoke_mta (address_t *, address_t *, address_t *, address_t *, const char *,
                      int);
@@ -114,11 +111,9 @@ int mutt_lookup_mime_type (BODY *, const char *);
 int mutt_num_postponed (int);
 int mutt_parse_bind (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_exec (BUFFER *, BUFFER *, unsigned long, BUFFER *);
-int mutt_parse_hook (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_macro (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_push (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_rc_line (const char *, BUFFER *, BUFFER *);
-int mutt_parse_unhook (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int _mutt_save_message (HEADER *, CONTEXT *, int, int, int);
 int mutt_save_message (HEADER *, int, int, int, int *);
 int mutt_search_command (int, int);