]> granicus.if.org Git - mutt/commitdiff
Add $auto_subscribe variable.
authorKevin McCarthy <kevin@8t8.us>
Sat, 8 Dec 2018 23:15:56 +0000 (15:15 -0800)
committerKevin McCarthy <kevin@8t8.us>
Sat, 8 Dec 2018 23:15:56 +0000 (15:15 -0800)
When set, it automatically subscribes to mailing lists found in
List-Post headers.

This commit is based on Michael Elkins's patch from the thread
<https://marc.info/?l=mutt-users&m=127076105423565&w=2>.

I've added an opt-in variable $auto_subscribe and a hash table cache
to speed up reading headers when the variable is set.

doc/manual.xml.head
globals.h
hcache.c
init.c
init.h
mutt.h
parse.c
protos.h

index 8a38ee8e3cded42b81f5add8349a1900719dbaad..aef594d64910bb2c4aad83716d127822745e49c6 100644 (file)
@@ -6205,7 +6205,9 @@ not have to be a mailing list, but that is what it is most often used
 for), and what lists you are subscribed to.  This is accomplished
 through the use of the <link linkend="lists"><command>lists</command>
 and <command>subscribe</command></link> commands in your
-<literal>.muttrc</literal>.
+<literal>.muttrc</literal>.  Alternatively or additionally, you can set
+<link linkend="auto-subscribe">$auto_subscribe</link> to automatically
+subscribe addresses found in a <literal>List-Post</literal> header.
 </para>
 
 <para>
index cecb46d619e5356de34187b0afc633067edc89e3..d71fc779bc4992000a3e75d764650750e352cfd8 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -170,6 +170,7 @@ WHERE const char *ReleaseDate;
 
 WHERE HASH *Groups;
 WHERE HASH *ReverseAlias;
+WHERE HASH *AutoSubscribeCache;
 
 WHERE LIST *AutoViewList INITVAL(0);
 WHERE LIST *AlternativeOrderList INITVAL(0);
index 0aa05d6a3a52eac0a669ea818edfa9abe9eedcfb..4f2bac29e8766b0a0deb34a3492f339120243e9f 100644 (file)
--- a/hcache.c
+++ b/hcache.c
@@ -552,6 +552,9 @@ restore_envelope(ENVELOPE * e, const unsigned char *d, int *off, int convert)
   restore_address(&e->mail_followup_to, d, off, convert);
 
   restore_char(&e->list_post, d, off, convert);
+  if (option (OPTAUTOSUBSCRIBE))
+    mutt_auto_subscribe (e->list_post);
+
   restore_char(&e->subject, d, off, convert);
   restore_int((unsigned int *) (&real_subj_off), d, off);
 
diff --git a/init.c b/init.c
index e5c78961cbe4148897d5837beb6f9396e1aaaf65..97bb03eb7deaa711a4f88da7013cebecad5a3c46 100644 (file)
--- a/init.c
+++ b/init.c
@@ -1377,6 +1377,7 @@ static int parse_unattachments (BUFFER *buf, BUFFER *s, unsigned long data, BUFF
 
 static int parse_unlists (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
 {
+  hash_destroy (&AutoSubscribeCache, NULL);
   do
   {
     mutt_extract_token (buf, s, 0);
@@ -1425,6 +1426,7 @@ static int parse_subscribe (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *
 
 static int parse_unsubscribe (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
 {
+  hash_destroy (&AutoSubscribeCache, NULL);
   do
   {
     mutt_extract_token (buf, s, 0);
diff --git a/init.h b/init.h
index b5aaa6dbde780e27ac99eb35e2b37e33aebc8dee..8fc6690dbceb5e7b6c7f6dab4b4c7e3a8992aa0f 100644 (file)
--- a/init.h
+++ b/init.h
@@ -302,6 +302,15 @@ struct option_t MuttVars[] = {
   ** will use your locale environment, so there is no need to set
   ** this except to override that default.
   */
+  { "auto_subscribe",  DT_BOOL, R_NONE, OPTAUTOSUBSCRIBE, 0 },
+  /*
+  ** .pp
+  ** When \fIset\fP, Mutt assumes the presence of a List-Post header
+  ** means the recipient is subscribed to the list.  Unless the mailing list
+  ** is in the ``unsubscribe'' or ``unlist'' lists, it will be added
+  ** to the ``$subscribe'' list.  Parsing and checking these things slows
+  ** header reading down, so this option is disabled by default.
+  */
   { "auto_tag",                DT_BOOL, R_NONE, OPTAUTOTAG, 0 },
   /*
   ** .pp
diff --git a/mutt.h b/mutt.h
index d80facec0a0607418d7b520a279f525e173cc413..c6b5db5671381543b680c8f52c0a281636dbd0aa 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -363,6 +363,7 @@ enum
   OPTASKCC,
   OPTATTACHSPLIT,
   OPTAUTOEDIT,
+  OPTAUTOSUBSCRIBE,
   OPTAUTOTAG,
   OPTBEEP,
   OPTBEEPNEW,
diff --git a/parse.c b/parse.c
index 0ae559401bcb2d5c4435bd60980b16a0fe55873f..c862328d39e0e57be45b7238691c60ed0ecebe12 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -976,6 +976,41 @@ void mutt_parse_mime_message (CONTEXT *ctx, HEADER *cur)
   cur->attach_valid = 0;
 }
 
+void mutt_auto_subscribe (const char *mailto)
+{
+  ENVELOPE *lpenv;
+
+  if (!AutoSubscribeCache)
+    AutoSubscribeCache = hash_create (200, MUTT_HASH_STRCASECMP | MUTT_HASH_STRDUP_KEYS);
+
+  if (!mailto || hash_find (AutoSubscribeCache, mailto))
+    return;
+
+  hash_insert (AutoSubscribeCache, mailto, AutoSubscribeCache);
+
+  lpenv = mutt_new_envelope (); /* parsed envelope from the List-Post mailto: URL */
+
+  if ((url_parse_mailto (lpenv, NULL, mailto) != -1) &&
+      lpenv->to && lpenv->to->mailbox &&
+      !mutt_match_rx_list (lpenv->to->mailbox, SubscribedLists) &&
+      !mutt_match_rx_list (lpenv->to->mailbox, UnMailLists) &&
+      !mutt_match_rx_list (lpenv->to->mailbox, UnSubscribedLists))
+  {
+    BUFFER err;
+    char errbuf[STRING];
+
+    memset (&err, 0, sizeof(err));
+    err.data = errbuf;
+    err.dsize = sizeof(errbuf);
+
+    /* mutt_add_to_rx_list() detects duplicates, so it is safe to
+     * try to add here without any checks. */
+    mutt_add_to_rx_list (&MailLists, lpenv->to->mailbox, REG_ICASE, &err);
+    mutt_add_to_rx_list (&SubscribedLists, lpenv->to->mailbox, REG_ICASE, &err);
+  }
+  mutt_free_envelope (&lpenv);
+}
+
 int mutt_parse_rfc822_line (ENVELOPE *e, HEADER *hdr, char *line, char *p, short user_hdrs, short weed,
                            short do_2047, LIST **lastp)
 {
@@ -1120,6 +1155,8 @@ int mutt_parse_rfc822_line (ENVELOPE *e, HEADER *hdr, char *line, char *p, short
          {
            FREE (&e->list_post);
            e->list_post = mutt_substrdup (beg, end);
+            if (option (OPTAUTOSUBSCRIBE))
+              mutt_auto_subscribe (e->list_post);
            break;
          }
        }
index c4e5a2f9ee0bb69418476ef8a21adbaef9b1c828..76d0650b8ba2d4f1e7e8552c0e4be41af031ff4d 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -163,6 +163,7 @@ void mutt_buffer_adv_mktemp (BUFFER *);
 void mutt_adv_mktemp (char *, size_t);
 void mutt_alias_menu (char *, size_t, ALIAS *);
 void mutt_allow_interrupt (int);
+void mutt_auto_subscribe (const char *);
 void mutt_block_signals (void);
 void mutt_block_signals_system (void);
 int mutt_body_handler (BODY *, STATE *);