[PATCH 2/4] notmuch-reply: respect users.other_name in From
authorShea Levy <shea@shealevy.com>
Tue, 9 Aug 2016 20:55:16 +0000 (16:55 +2000)
committerW. Trevor King <wking@tremily.us>
Sat, 20 Aug 2016 23:22:22 +0000 (16:22 -0700)
90/02b5bb20fff90757715070c134e45355ea7289 [new file with mode: 0644]

diff --git a/90/02b5bb20fff90757715070c134e45355ea7289 b/90/02b5bb20fff90757715070c134e45355ea7289
new file mode 100644 (file)
index 0000000..a02ab8f
--- /dev/null
@@ -0,0 +1,414 @@
+Return-Path: <shea@shealevy.com>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by arlo.cworth.org (Postfix) with ESMTP id 048916DE091B\r
+ for <notmuch@notmuchmail.org>; Tue,  9 Aug 2016 14:05:53 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at cworth.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.006\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.006 tagged_above=-999 required=5\r
+ tests=[AWL=-0.006, RCVD_IN_DNSWL_NONE=-0.0001] autolearn=disabled\r
+Received: from arlo.cworth.org ([127.0.0.1])\r
+ by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id DnX_K33TDuaw for <notmuch@notmuchmail.org>;\r
+ Tue,  9 Aug 2016 14:05:45 -0700 (PDT)\r
+Received: from smtprelay.hostedemail.com (smtprelay0047.hostedemail.com\r
+ [216.40.44.47])\r
+ by arlo.cworth.org (Postfix) with ESMTPS id DE8A86DE0362\r
+ for <notmuch@notmuchmail.org>; Tue,  9 Aug 2016 14:05:44 -0700 (PDT)\r
+Received: from smtprelay.hostedemail.com (10.5.19.251.rfc1918.com\r
+ [10.5.19.251])\r
+ by smtpgrave03.hostedemail.com (Postfix) with ESMTP id 69C1128F2FB\r
+ for <notmuch@notmuchmail.org>; Tue,  9 Aug 2016 20:56:42 +0000 (UTC)\r
+Received: from filter.hostedemail.com (unknown [216.40.38.60])\r
+ by smtprelay01.hostedemail.com (Postfix) with ESMTP id 19F2C23421\r
+ for <notmuch@notmuchmail.org>; Tue,  9 Aug 2016 20:56:41 +0000 (UTC)\r
+X-Session-Marker: 7368656140736865616C6576792E636F6D\r
+X-Spam-Summary: 10, 1, 0, , d41d8cd98f00b204, shea@shealevy.com, :,\r
+ RULES_HIT:1:41:69:355:379:541:800:960:966:973:988:989:1260:1321:1345:1359:1381:1437:1730:1747:1777:1792:2196:2198:2199:2200:2393:2559:2562:2639:2693:2731:2737:2898:3138:3139:3140:3141:3142:3354:3608:3865:3866:3867:3868:3870:3871:3872:3874:4250:4321:4385:4605:5007:6119:6248:6261:7903:7904:7974:8660:8957:9010:10848:11026:11473:11658:11914:12043:12291:12294:12296:12438:12517:12519:12555:12683:13148:13230:14110:14394:21063:21080:21324:21433:30003:30022:30029:30034:30051:30054:30070, 0, RBL:none, CacheIP:none, Bayesian:0.5, 0.5, 0.5, Netcheck:none,\r
+ DomainCache:0, MSF:not bulk, SPF:fn, MSBL:0, DNSBL:none, Custom_rules:0:1:0,\r
+ LFtime:18, LUA_SUMMARY:none\r
+X-HE-Tag: loaf36_1d227d9b5a82d\r
+X-Filterd-Recvd-Size: 14326\r
+Received: from shlevy-laptop.local.tld (unknown [184.209.6.164])\r
+ (Authenticated sender: shea@shealevy.com)\r
+ by omf08.hostedemail.com (Postfix) with ESMTPA\r
+ for <notmuch@notmuchmail.org>; Tue,  9 Aug 2016 20:56:39 +0000 (UTC)\r
+From: Shea Levy <shea@shealevy.com>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH 2/4] notmuch-reply: respect users.other_name in From\r
+Date: Tue,  9 Aug 2016 16:55:16 -0400\r
+Message-Id: <1470776118-5070-3-git-send-email-shea@shealevy.com>\r
+X-Mailer: git-send-email 2.7.4\r
+In-Reply-To: <1470776118-5070-1-git-send-email-shea@shealevy.com>\r
+References: <1470776118-5070-1-git-send-email-shea@shealevy.com>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.20\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Tue, 09 Aug 2016 21:05:53 -0000\r
+\r
+---\r
+ notmuch-reply.c | 129 ++++++++++++++++++++++++++++++++++++++++----------------\r
+ 1 file changed, 92 insertions(+), 37 deletions(-)\r
+\r
+diff --git a/notmuch-reply.c b/notmuch-reply.c\r
+index 4951373..1c205f9 100644\r
+--- a/notmuch-reply.c\r
++++ b/notmuch-reply.c\r
+@@ -118,25 +118,41 @@ match_address (const char *str, const char *address, address_match_t mode)\r
+ }\r
\r
+ /* Match given string against user's configured "primary" and "other"\r
+- * addresses according to mode. */\r
++ * addresses according to mode.\r
++ *\r
++ * If 'user_from_name' is non-NULL and the address is found,\r
++ * *user_from_name is set to the corresponding name.\r
++ */\r
+ static const char *\r
+-address_match (const char *str, notmuch_config_t *config, address_match_t mode)\r
++address_match (const char *str, notmuch_config_t *config, const char **user_from_name, address_match_t mode)\r
+ {\r
+     const char *primary;\r
+     const char **other;\r
+-    size_t i, other_len;\r
++    const char **other_name;\r
++    size_t i, other_len, other_name_len;\r
\r
+     if (!str || *str == '\0')\r
+       return NULL;\r
\r
+     primary = notmuch_config_get_user_primary_email (config);\r
+-    if (match_address (str, primary, mode))\r
++    if (match_address (str, primary, mode)) {\r
++      if (user_from_name != NULL)\r
++          *user_from_name = notmuch_config_get_user_name (config);\r
+       return primary;\r
++    }\r
\r
+     other = notmuch_config_get_user_other_email (config, &other_len);\r
+     for (i = 0; i < other_len; i++) {\r
+-      if (match_address (str, other[i], mode))\r
++      if (match_address (str, other[i], mode)) {\r
++          if (user_from_name != NULL) {\r
++              other_name = notmuch_config_get_user_other_name (config, &other_name_len);\r
++              if (i < other_name_len)\r
++                  *user_from_name = other_name[i];\r
++              else\r
++                  *user_from_name = NULL;\r
++          }\r
+           return other[i];\r
++      }\r
+     }\r
\r
+     return NULL;\r
+@@ -144,28 +160,41 @@ address_match (const char *str, notmuch_config_t *config, address_match_t mode)\r
\r
+ /* Does the given string contain an address configured as one of the\r
+  * user's "primary" or "other" addresses. If so, return the matching\r
+- * address, NULL otherwise. */\r
++ * address, NULL otherwise.\r
++ *\r
++ * If 'user_from_name' is non-NULL and the address is the user's,\r
++ * *user_from_name is set to the corresponding name.\r
++ */\r
+ static const char *\r
+-user_address_in_string (const char *str, notmuch_config_t *config)\r
++user_address_in_string (const char *str, notmuch_config_t *config, const char **user_from_name)\r
+ {\r
+-    return address_match (str, config, USER_ADDRESS_IN_STRING);\r
++    return address_match (str, config, user_from_name, USER_ADDRESS_IN_STRING);\r
+ }\r
\r
+ /* Do any of the addresses configured as one of the user's "primary"\r
+  * or "other" addresses contain the given string. If so, return the\r
+- * matching address, NULL otherwise. */\r
++ * matching address, NULL otherwise.\r
++ *\r
++ * If 'user_from_name' is non-NULL and the address is the user's,\r
++ * *user_from_name is set to the corresponding name.\r
++ */\r
+ static const char *\r
+-string_in_user_address (const char *str, notmuch_config_t *config)\r
++string_in_user_address (const char *str, notmuch_config_t *config, const char **user_from_name)\r
+ {\r
+-    return address_match (str, config, STRING_IN_USER_ADDRESS);\r
++    return address_match (str, config, user_from_name, STRING_IN_USER_ADDRESS);\r
+ }\r
\r
+ /* Is the given address configured as one of the user's "primary" or\r
+- * "other" addresses. */\r
++ * "other" addresses.\r
++ *\r
++ * If 'user_from_name' is non-NULL and the address is the user's,\r
++ * *user_from_name is set to the corresponding name.\r
++ *\r
++ */\r
+ static notmuch_bool_t\r
+-address_is_users (const char *address, notmuch_config_t *config)\r
++address_is_users (const char *address, notmuch_config_t *config, const char **user_from_name)\r
+ {\r
+-    return address_match (address, config, STRING_IS_USER_ADDRESS) != NULL;\r
++    return address_match (address, config, user_from_name, STRING_IS_USER_ADDRESS) != NULL;\r
+ }\r
\r
+ /* Scan addresses in 'list'.\r
+@@ -178,6 +207,9 @@ address_is_users (const char *address, notmuch_config_t *config)\r
+  * be set to the first address encountered in 'list' that is the\r
+  * user's address.\r
+  *\r
++ * If 'user_from_name' is non-NULL and *user_from is set by this call,\r
++ * *user_from_name will be set to the name corresponding to *user_from.\r
++ *\r
+  * Return the number of addresses added to 'message'. (If 'message' is\r
+  * NULL, the function returns 0 by definition.)\r
+  */\r
+@@ -186,7 +218,8 @@ scan_address_list (InternetAddressList *list,\r
+                  notmuch_config_t *config,\r
+                  GMimeMessage *message,\r
+                  GMimeRecipientType type,\r
+-                 const char **user_from)\r
++                 const char **user_from,\r
++                 const char **user_from_name)\r
+ {\r
+     InternetAddress *address;\r
+     int i;\r
+@@ -203,7 +236,7 @@ scan_address_list (InternetAddressList *list,\r
+           if (group_list == NULL)\r
+               continue;\r
\r
+-          n += scan_address_list (group_list, config, message, type, user_from);\r
++          n += scan_address_list (group_list, config, message, type, user_from, user_from_name);\r
+       } else {\r
+           InternetAddressMailbox *mailbox;\r
+           const char *name;\r
+@@ -214,7 +247,7 @@ scan_address_list (InternetAddressList *list,\r
+           name = internet_address_get_name (address);\r
+           addr = internet_address_mailbox_get_addr (mailbox);\r
\r
+-          if (address_is_users (addr, config)) {\r
++          if (address_is_users (addr, config, user_from_name)) {\r
+               if (user_from && *user_from == NULL)\r
+                   *user_from = addr;\r
+           } else if (message) {\r
+@@ -238,7 +271,8 @@ scan_address_string (const char *recipients,\r
+                    notmuch_config_t *config,\r
+                    GMimeMessage *message,\r
+                    GMimeRecipientType type,\r
+-                   const char **user_from)\r
++                   const char **user_from,\r
++                   const char **user_from_name)\r
+ {\r
+     InternetAddressList *list;\r
\r
+@@ -249,7 +283,7 @@ scan_address_string (const char *recipients,\r
+     if (list == NULL)\r
+       return 0;\r
\r
+-    return scan_address_list (list, config, message, type, user_from);\r
++    return scan_address_list (list, config, message, type, user_from, user_from_name);\r
+ }\r
\r
+ /* Does the address in the Reply-To header of 'message' already appear\r
+@@ -300,6 +334,10 @@ reply_to_header_is_redundant (notmuch_message_t *message)\r
+  * (typically this would be reply-to-sender, but also handles reply to\r
+  * user's own message in a sensible way).\r
+  *\r
++ * If 'from_name' is non-NULL and any of the user's addresses were found\r
++ * in these headers and the user specified an alternate name for that\r
++ * address, it will be set to the corresponding value.\r
++ *\r
+  * If any of the user's addresses were found in these headers, the\r
+  * first of these returned, otherwise NULL is returned.\r
+  */\r
+@@ -307,7 +345,8 @@ static const char *\r
+ add_recipients_from_message (GMimeMessage *reply,\r
+                            notmuch_config_t *config,\r
+                            notmuch_message_t *message,\r
+-                           notmuch_bool_t reply_all)\r
++                           notmuch_bool_t reply_all,\r
++                           const char **from_name)\r
+ {\r
+     struct {\r
+       const char *header;\r
+@@ -349,7 +388,7 @@ add_recipients_from_message (GMimeMessage *reply,\r
+                                                    reply_to_map[i].fallback);\r
\r
+       n += scan_address_string (recipients, config, reply,\r
+-                                reply_to_map[i].recipient_type, &from_addr);\r
++                                reply_to_map[i].recipient_type, &from_addr, from_name);\r
\r
+       if (!reply_all && n) {\r
+           /* Stop adding new recipients in reply-to-sender mode if\r
+@@ -375,10 +414,13 @@ add_recipients_from_message (GMimeMessage *reply,\r
+  * Look for the user's address in " for <email@add.res>" in the\r
+  * received headers.\r
+  *\r
++ * If 'user_from_name' is non-NULL and the address is found,\r
++ * *user_from_name is set to the corresponding name.\r
++ *\r
+  * Return the address that was found, if any, and NULL otherwise.\r
+  */\r
+ static const char *\r
+-guess_from_in_received_for (notmuch_config_t *config, const char *received)\r
++guess_from_in_received_for (notmuch_config_t *config, const char *received, const char **user_from_name)\r
+ {\r
+     const char *ptr;\r
\r
+@@ -386,7 +428,7 @@ guess_from_in_received_for (notmuch_config_t *config, const char *received)\r
+     if (! ptr)\r
+       return NULL;\r
\r
+-    return user_address_in_string (ptr, config);\r
++    return user_address_in_string (ptr, config, user_from_name);\r
+ }\r
\r
+ /*\r
+@@ -399,10 +441,13 @@ guess_from_in_received_for (notmuch_config_t *config, const char *received)\r
+  * - and then assume that the first whitespace delimited token that\r
+  * follows is the receiving system in this step of the receive chain.\r
+  *\r
++ * If 'user_from_name' is non-NULL and the address is found,\r
++ * *user_from_name is set to the corresponding name.\r
++ *\r
+  * Return the address that was found, if any, and NULL otherwise.\r
+  */\r
+ static const char *\r
+-guess_from_in_received_by (notmuch_config_t *config, const char *received)\r
++guess_from_in_received_by (notmuch_config_t *config, const char *received, const char **user_from_name)\r
+ {\r
+     const char *addr;\r
+     const char *by = received;\r
+@@ -440,7 +485,7 @@ guess_from_in_received_by (notmuch_config_t *config, const char *received)\r
+            */\r
+           *(tld - 1) = '.';\r
\r
+-          addr = string_in_user_address (domain, config);\r
++          addr = string_in_user_address (domain, config, user_from_name);\r
+           if (addr) {\r
+               free (mta);\r
+               return addr;\r
+@@ -460,11 +505,15 @@ guess_from_in_received_by (notmuch_config_t *config, const char *received)\r
+  * The Received: header is special in our get_header function and is\r
+  * always concatenated.\r
+  *\r
++ * If 'user_from_name' is non-NULL and the address is found,\r
++ * *user_from_name is set to the corresponding name.\r
++ *\r
+  * Return the address that was found, if any, and NULL otherwise.\r
+  */\r
+ static const char *\r
+ guess_from_in_received_headers (notmuch_config_t *config,\r
+-                              notmuch_message_t *message)\r
++                              notmuch_message_t *message,\r
++                              const char **user_from_name)\r
+ {\r
+     const char *received, *addr;\r
+     char *sanitized;\r
+@@ -477,9 +526,9 @@ guess_from_in_received_headers (notmuch_config_t *config,\r
+     if (! sanitized)\r
+       return NULL;\r
\r
+-    addr = guess_from_in_received_for (config, sanitized);\r
++    addr = guess_from_in_received_for (config, sanitized, user_from_name);\r
+     if (! addr)\r
+-      addr = guess_from_in_received_by (config, sanitized);\r
++      addr = guess_from_in_received_by (config, sanitized, user_from_name);\r
\r
+     talloc_free (sanitized);\r
\r
+@@ -491,10 +540,13 @@ guess_from_in_received_headers (notmuch_config_t *config,\r
+  * headers: Envelope-To, X-Original-To, and Delivered-To (searched in\r
+  * that order).\r
+  *\r
++ * If 'user_from_name' is non-NULL and the address is found,\r
++ * *user_from_name is set to the corresponding name.\r
++ *\r
+  * Return the address that was found, if any, and NULL otherwise.\r
+  */\r
+ static const char *\r
+-get_from_in_to_headers (notmuch_config_t *config, notmuch_message_t *message)\r
++get_from_in_to_headers (notmuch_config_t *config, notmuch_message_t *message, const char **user_from_name)\r
+ {\r
+     size_t i;\r
+     const char *tohdr, *addr;\r
+@@ -508,7 +560,7 @@ get_from_in_to_headers (notmuch_config_t *config, notmuch_message_t *message)\r
+       tohdr = notmuch_message_get_header (message, to_headers[i]);\r
\r
+       /* Note: tohdr potentially contains a list of email addresses. */\r
+-      addr = user_address_in_string (tohdr, config);\r
++      addr = user_address_in_string (tohdr, config, user_from_name);\r
+       if (addr)\r
+           return addr;\r
+     }\r
+@@ -523,7 +575,7 @@ create_reply_message(void *ctx,\r
+                    notmuch_bool_t reply_all)\r
+ {\r
+     const char *subject, *from_addr = NULL;\r
+-    const char *in_reply_to, *orig_references, *references;\r
++    const char *in_reply_to, *orig_references, *references, *from_name;\r
\r
+     /* The 1 means we want headers in a "pretty" order. */\r
+     GMimeMessage *reply = g_mime_message_new (1);\r
+@@ -540,7 +592,7 @@ create_reply_message(void *ctx,\r
+     }\r
\r
+     from_addr = add_recipients_from_message (reply, config,\r
+-                                           message, reply_all);\r
++                                           message, reply_all, &from_name);\r
\r
+     /*\r
+      * Sadly, there is no standard way to find out to which email\r
+@@ -555,7 +607,7 @@ create_reply_message(void *ctx,\r
+      * Delivered-To: headers.\r
+      */\r
+     if (from_addr == NULL)\r
+-      from_addr = get_from_in_to_headers (config, message);\r
++      from_addr = get_from_in_to_headers (config, message, &from_name);\r
\r
+     /*\r
+      * Check for a (for <email@add.res>) clause in Received: headers,\r
+@@ -563,14 +615,17 @@ create_reply_message(void *ctx,\r
+      * of Received: headers\r
+      */\r
+     if (from_addr == NULL)\r
+-      from_addr = guess_from_in_received_headers (config, message);\r
++      from_addr = guess_from_in_received_headers (config, message, &from_name);\r
\r
+     /* Default to user's primary address. */\r
+-    if (from_addr == NULL)\r
++    if (from_addr == NULL) {\r
+       from_addr = notmuch_config_get_user_primary_email (config);\r
++      from_name = notmuch_config_get_user_name (config);\r
++    } else if (from_name == NULL || from_name[0] == '\0')\r
++      from_name = notmuch_config_get_user_name (config);\r
\r
+     from_addr = talloc_asprintf (ctx, "%s <%s>",\r
+-                               notmuch_config_get_user_name (config),\r
++                               from_name,\r
+                                from_addr);\r
+     g_mime_object_set_header (GMIME_OBJECT (reply),\r
+                             "From", from_addr);\r
+@@ -751,7 +806,7 @@ notmuch_reply_format_headers_only(void *ctx,\r
+       g_mime_object_set_header (GMIME_OBJECT (reply),\r
+                                 "References", references);\r
\r
+-      (void)add_recipients_from_message (reply, config, message, reply_all);\r
++      (void)add_recipients_from_message (reply, config, message, reply_all, NULL);\r
\r
+       reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));\r
+       printf ("%s", reply_headers);\r
+-- \r
+2.7.4\r
+\r