From: Kevin McCarthy Date: Sat, 8 Dec 2018 23:15:56 +0000 (-0800) Subject: Add $auto_subscribe variable. X-Git-Tag: mutt-1-12-rel~189 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e525bc08ca86c3006f696fb823613c42eb333623;p=mutt Add $auto_subscribe variable. 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 . I've added an opt-in variable $auto_subscribe and a hash table cache to speed up reading headers when the variable is set. --- diff --git a/doc/manual.xml.head b/doc/manual.xml.head index 8a38ee8e..aef594d6 100644 --- a/doc/manual.xml.head +++ b/doc/manual.xml.head @@ -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 lists and subscribe commands in your -.muttrc. +.muttrc. Alternatively or additionally, you can set +$auto_subscribe to automatically +subscribe addresses found in a List-Post header. diff --git a/globals.h b/globals.h index cecb46d6..d71fc779 100644 --- 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); diff --git a/hcache.c b/hcache.c index 0aa05d6a..4f2bac29 100644 --- 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 e5c78961..97bb03eb 100644 --- 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 b5aaa6db..8fc6690d 100644 --- 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 d80facec..c6b5db56 100644 --- 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 0ae55940..c862328d 100644 --- 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; } } diff --git a/protos.h b/protos.h index c4e5a2f9..76d0650b 100644 --- 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 *);