]> granicus.if.org Git - neomutt/commitdiff
reorg: idna -> address, envelope
authorRichard Russon <rich@flatcap.org>
Sat, 30 Dec 2017 15:30:39 +0000 (15:30 +0000)
committerRichard Russon <rich@flatcap.org>
Sun, 31 Dec 2017 00:40:13 +0000 (00:40 +0000)
address.c
address.h
envelope.c
envelope.h
mutt_address.c
mutt_idna.c
mutt_idna.h

index 194b459e5d5aec51cddb4357d6912ea7d17cd734..fbf25076261d37f031e35ee7777d5e13a17eeaa6 100644 (file)
--- a/address.c
+++ b/address.c
  * | mutt_addr_cmp_strict()       | Strictly compare two Address lists
  * | mutt_addr_copy()             | Copy the real address
  * | mutt_addr_copy_list()        | Copy a list of addresses
+ * | mutt_addr_for_display()      | Convert an Address for display purposes
  * | mutt_addr_free()             | Free a list of Addresses
  * | mutt_addr_has_recips()       | Count the number of Addresses with valid recipients
+ * | mutt_addr_is_intl()          | Does the Address have IDN components
+ * | mutt_addr_is_local()         | Does the Address have NO IDN components
+ * | mutt_addr_mbox_to_udomain()  | Split a mailbox name into user and domain
  * | mutt_addr_new()              | Create a new Address
  * | mutt_addr_parse_list()       | Parse a list of email addresses
  * | mutt_addr_parse_list2()      | Parse a list of email addresses
  * | mutt_addr_qualify()          | Expand local names in an Address list using a hostname
  * | mutt_addr_remove_from_list() | Remove an Address from a list
  * | mutt_addr_search()           | Search for an e-mail address in a list
+ * | mutt_addr_set_intl()         | Mark an Address as having IDN components
+ * | mutt_addr_set_local()        | Mark an Address as having NO IDN components
  * | mutt_addr_valid_msgid()      | Is this a valid Message ID?
  */
 
@@ -932,3 +938,106 @@ bool mutt_addr_search(struct Address *a, struct Address *lst)
   }
   return false;
 }
+
+/**
+ * mutt_addr_is_intl - Does the Address have IDN components
+ * @param a Address to check
+ * @retval true Address contains IDN components
+ */
+bool mutt_addr_is_intl(struct Address *a)
+{
+  return (a->intl_checked && a->is_intl);
+}
+
+/**
+ * mutt_addr_is_local - Does the Address have NO IDN components
+ * @param a Address to check
+ * @retval true Address contains NO IDN components
+ */
+bool mutt_addr_is_local(struct Address *a)
+{
+  return (a->intl_checked && !a->is_intl);
+}
+
+/**
+ * mutt_addr_mbox_to_udomain - Split a mailbox name into user and domain
+ * @param[in]  mbox   Mailbox name to split
+ * @param[out] user   User
+ * @param[out] domain Domain
+ * @retval 0  Success
+ * @retval -1 Error
+ */
+int mutt_addr_mbox_to_udomain(const char *mbox, char **user, char **domain)
+{
+  static char *buf = NULL;
+  char *p = NULL;
+
+  mutt_str_replace(&buf, mbox);
+  if (!buf)
+    return -1;
+
+  p = strchr(buf, '@');
+  if (!p || !p[1])
+    return -1;
+  *p = '\0';
+  *user = buf;
+  *domain = p + 1;
+  return 0;
+}
+
+/**
+ * mutt_addr_set_intl - Mark an Address as having IDN components
+ * @param a            Address to modify
+ * @param intl_mailbox Email address with IDN components
+ */
+void mutt_addr_set_intl(struct Address *a, char *intl_mailbox)
+{
+  FREE(&a->mailbox);
+  a->mailbox = intl_mailbox;
+  a->intl_checked = true;
+  a->is_intl = true;
+}
+
+/**
+ * mutt_addr_set_local - Mark an Address as having NO IDN components
+ * @param a             Address
+ * @param local_mailbox Email address with NO IDN components
+ */
+void mutt_addr_set_local(struct Address *a, char *local_mailbox)
+{
+  FREE(&a->mailbox);
+  a->mailbox = local_mailbox;
+  a->intl_checked = true;
+  a->is_intl = false;
+}
+
+/**
+ * mutt_addr_for_display - Convert an Address for display purposes
+ * @param a Address to convert
+ * @retval ptr Address to display
+ *
+ * @warning This function may return a static pointer.  It must not be freed by
+ * the caller.  Later calls may overwrite the returned pointer.
+ */
+const char *mutt_addr_for_display(struct Address *a)
+{
+  char *user = NULL, *domain = NULL;
+  static char *buf = NULL;
+  char *local_mailbox = NULL;
+
+  FREE(&buf);
+
+  if (!a->mailbox || mutt_addr_is_local(a))
+    return a->mailbox;
+
+  if (mutt_addr_mbox_to_udomain(a->mailbox, &user, &domain) == -1)
+    return a->mailbox;
+
+  local_mailbox = mutt_idna_intl_to_local(user, domain, MI_MAY_BE_IRREVERSIBLE);
+  if (!local_mailbox)
+    return a->mailbox;
+
+  mutt_str_replace(&buf, local_mailbox);
+  FREE(&local_mailbox);
+  return buf;
+}
index 67f62e0da205298715cd62115654f81d4495a2cc..03d6afe5715a857e88cbddb4f4d370b403d5f587 100644 (file)
--- a/address.h
+++ b/address.h
@@ -24,6 +24,7 @@
 #define _MUTT_ADDRESS_H
 
 #include <stdbool.h>
+#include <stddef.h>
 
 /**
  * struct Address - An email address
@@ -63,14 +64,20 @@ bool            mutt_addr_cmp_strict(const struct Address *a, const struct Addre
 bool            mutt_addr_cmp(struct Address *a, struct Address *b);
 struct Address *mutt_addr_copy_list(struct Address *addr, bool prune);
 struct Address *mutt_addr_copy(struct Address *addr);
+const char *    mutt_addr_for_display(struct Address *a);
 void            mutt_addr_free(struct Address **p);
 int             mutt_addr_has_recips(struct Address *a);
+bool            mutt_addr_is_intl(struct Address *a);
+bool            mutt_addr_is_local(struct Address *a);
+int             mutt_addr_mbox_to_udomain(const char *mbox, char **user, char **domain);
 struct Address *mutt_addr_new(void);
 struct Address *mutt_addr_parse_list2(struct Address *p, const char *s);
 struct Address *mutt_addr_parse_list(struct Address *top, const char *s);
 void            mutt_addr_qualify(struct Address *addr, const char *host);
 int             mutt_addr_remove_from_list(struct Address **a, const char *mailbox);
 bool            mutt_addr_search(struct Address *a, struct Address *lst);
+void            mutt_addr_set_intl(struct Address *a, char *intl_mailbox);
+void            mutt_addr_set_local(struct Address *a, char *local_mailbox);
 bool            mutt_addr_valid_msgid(const char *msgid);
 
 #endif /* _MUTT_ADDRESS_H */
index 112a661e827c007b89b75bde039bcdb920c25c1e..e8b21d69f61fb26d4d96b7c0aa2f1ce55413ffb2 100644 (file)
@@ -31,6 +31,8 @@
  * | mutt_env_free()       | Free an Envelope
  * | mutt_env_merge()      | Merge the headers of two Envelopes
  * | mutt_env_new()        | Create a new Envelope
+ * | mutt_env_to_intl()    | Convert an Envelope's Address fields to Punycode format
+ * | mutt_env_to_local()   | Convert an Envelope's Address fields to local format
  */
 
 #include "config.h"
@@ -41,6 +43,7 @@
 #include "mutt/string2.h"
 #include "envelope.h"
 #include "address.h"
+#include "mutt_idna.h"
 
 /**
  * mutt_env_new - Create a new Envelope
@@ -196,3 +199,59 @@ bool mutt_env_cmp_strict(const struct Envelope *e1, const struct Envelope *e2)
       return false;
   }
 }
+
+/**
+ * mutt_env_to_local - Convert an Envelope's Address fields to local format
+ * @param e Envelope to modify
+ *
+ * Run mutt_addrlist_to_local() on each of the Address fields in the Envelope.
+ */
+void mutt_env_to_local(struct Envelope *e)
+{
+  mutt_addrlist_to_local(e->return_path);
+  mutt_addrlist_to_local(e->from);
+  mutt_addrlist_to_local(e->to);
+  mutt_addrlist_to_local(e->cc);
+  mutt_addrlist_to_local(e->bcc);
+  mutt_addrlist_to_local(e->reply_to);
+  mutt_addrlist_to_local(e->mail_followup_to);
+}
+
+/* Note that `a' in the `env->a' expression is macro argument, not
+ * "real" name of an `env' compound member.  Real name will be substituted
+ * by preprocessor at the macro-expansion time.
+ * Note that #a escapes and double quotes the argument.
+ */
+#define H_TO_INTL(a)                                                           \
+  if (mutt_addrlist_to_intl(env->a, err) && !e)                                \
+  {                                                                            \
+    if (tag)                                                                   \
+      *tag = #a;                                                               \
+    e = 1;                                                                     \
+    err = NULL;                                                                \
+  }
+
+/**
+ * mutt_env_to_intl - Convert an Envelope's Address fields to Punycode format
+ * @param[in]  env Envelope to modify
+ * @param[out] tag Name of the failed field
+ * @param[out] err Failed address
+ * @retval 0 Success, all addresses converted
+ * @retval 1 Error, tag and err will be set
+ *
+ * Run mutt_addrlist_to_intl() on each of the Address fields in the Envelope.
+ */
+int mutt_env_to_intl(struct Envelope *env, char **tag, char **err)
+{
+  int e = 0;
+  H_TO_INTL(return_path);
+  H_TO_INTL(from);
+  H_TO_INTL(to);
+  H_TO_INTL(cc);
+  H_TO_INTL(bcc);
+  H_TO_INTL(reply_to);
+  H_TO_INTL(mail_followup_to);
+  return e;
+}
+
+#undef H_TO_INTL
index ff11ceba28b135becf2e2d4f8971af2085e5f014..4e4df32cbb705ea4eb157db9395854f2effc7cc0 100644 (file)
@@ -68,5 +68,7 @@ bool             mutt_env_cmp_strict(const struct Envelope *e1, const struct Env
 void             mutt_env_free(struct Envelope **p);
 void             mutt_env_merge(struct Envelope *base, struct Envelope **extra);
 struct Envelope *mutt_env_new(void);
+int              mutt_env_to_intl(struct Envelope *env, char **tag, char **err);
+void             mutt_env_to_local(struct Envelope *e);
 
 #endif /* _MUTT_ENVELOPE_H */
index 0be18f79efdd040c76b89418c7c415ce8d49c1d7..948800b8679489ca66e01ee1d44a199b27a611c1 100644 (file)
 #include "address.h"
 #include "mutt_idna.h"
 
+/**
+ * mutt_addrlist_to_intl - Convert an Address list to Punycode
+ * @param[in]  a   Address list to modify
+ * @param[out] err Pointer for failed addresses
+ * @retval 0  Success, all addresses converted
+ * @retval -1 Error, err will be set to the failed address
+ */
+int mutt_addrlist_to_intl(struct Address *a, char **err)
+{
+  char *user = NULL, *domain = NULL;
+  char *intl_mailbox = NULL;
+  int rc = 0;
+
+  if (err)
+    *err = NULL;
+
+  for (; a; a = a->next)
+  {
+    if (!a->mailbox || mutt_addr_is_intl(a))
+      continue;
+
+    if (mutt_addr_mbox_to_udomain(a->mailbox, &user, &domain) == -1)
+      continue;
+
+    intl_mailbox = mutt_idna_local_to_intl(user, domain);
+    if (!intl_mailbox)
+    {
+      rc = -1;
+      if (err && !*err)
+        *err = mutt_str_strdup(a->mailbox);
+      continue;
+    }
+
+    mutt_addr_set_intl(a, intl_mailbox);
+  }
+
+  return rc;
+}
+
+/**
+ * mutt_addrlist_to_local - Convert an Address list from Punycode
+ * @param a Address list to modify
+ * @retval 0 Always
+ */
+int mutt_addrlist_to_local(struct Address *a)
+{
+  char *user = NULL, *domain = NULL;
+  char *local_mailbox = NULL;
+
+  for (; a; a = a->next)
+  {
+    if (!a->mailbox || mutt_addr_is_local(a))
+      continue;
+
+    if (mutt_addr_mbox_to_udomain(a->mailbox, &user, &domain) == -1)
+      continue;
+
+    local_mailbox = mutt_idna_intl_to_local(user, domain, 0);
+    if (local_mailbox)
+      mutt_addr_set_local(a, local_mailbox);
+  }
+
+  return 0;
+}
+
 void rfc822_write_address_single(char *buf, size_t buflen, struct Address *addr, int display)
 {
   size_t len;
index bc50072789361392c743b6d78a5f532235c76117..4a56bf6e54bc378ceec9f0f9bfa94c918a8c0480 100644 (file)
@@ -85,50 +85,6 @@ static bool check_idn(char *domain)
 }
 #endif /* HAVE_LIBIDN */
 
-static int mbox_to_udomain(const char *mbx, char **user, char **domain)
-{
-  static char *buf = NULL;
-  char *p = NULL;
-
-  mutt_str_replace(&buf, mbx);
-  if (!buf)
-    return -1;
-
-  p = strchr(buf, '@');
-  if (!p || !p[1])
-    return -1;
-  *p = '\0';
-  *user = buf;
-  *domain = p + 1;
-  return 0;
-}
-
-static int addr_is_local(struct Address *a)
-{
-  return (a->intl_checked && !a->is_intl);
-}
-
-static int addr_is_intl(struct Address *a)
-{
-  return (a->intl_checked && a->is_intl);
-}
-
-static void set_local_mailbox(struct Address *a, char *local_mailbox)
-{
-  FREE(&a->mailbox);
-  a->mailbox = local_mailbox;
-  a->intl_checked = true;
-  a->is_intl = false;
-}
-
-static void set_intl_mailbox(struct Address *a, char *intl_mailbox)
-{
-  FREE(&a->mailbox);
-  a->mailbox = intl_mailbox;
-  a->intl_checked = true;
-  a->is_intl = true;
-}
-
 char *mutt_idna_intl_to_local(char *orig_user, char *orig_domain, int flags)
 {
   char *local_user = NULL, *local_domain = NULL, *mailbox = NULL;
@@ -265,127 +221,3 @@ cleanup:
 
   return mailbox;
 }
-
-/* higher level functions */
-
-int mutt_addrlist_to_intl(struct Address *a, char **err)
-{
-  char *user = NULL, *domain = NULL;
-  char *intl_mailbox = NULL;
-  int rc = 0;
-
-  if (err)
-    *err = NULL;
-
-  for (; a; a = a->next)
-  {
-    if (!a->mailbox || addr_is_intl(a))
-      continue;
-
-    if (mbox_to_udomain(a->mailbox, &user, &domain) == -1)
-      continue;
-
-    intl_mailbox = mutt_idna_local_to_intl(user, domain);
-    if (!intl_mailbox)
-    {
-      rc = -1;
-      if (err && !*err)
-        *err = mutt_str_strdup(a->mailbox);
-      continue;
-    }
-
-    set_intl_mailbox(a, intl_mailbox);
-  }
-
-  return rc;
-}
-
-int mutt_addrlist_to_local(struct Address *a)
-{
-  char *user = NULL, *domain = NULL;
-  char *local_mailbox = NULL;
-
-  for (; a; a = a->next)
-  {
-    if (!a->mailbox || addr_is_local(a))
-      continue;
-
-    if (mbox_to_udomain(a->mailbox, &user, &domain) == -1)
-      continue;
-
-    local_mailbox = mutt_idna_intl_to_local(user, domain, 0);
-    if (local_mailbox)
-      set_local_mailbox(a, local_mailbox);
-  }
-
-  return 0;
-}
-
-/**
- * mutt_addr_for_display - convert just for displaying purposes
- */
-const char *mutt_addr_for_display(struct Address *a)
-{
-  char *user = NULL, *domain = NULL;
-  static char *buf = NULL;
-  char *local_mailbox = NULL;
-
-  FREE(&buf);
-
-  if (!a->mailbox || addr_is_local(a))
-    return a->mailbox;
-
-  if (mbox_to_udomain(a->mailbox, &user, &domain) == -1)
-    return a->mailbox;
-
-  local_mailbox = mutt_idna_intl_to_local(user, domain, MI_MAY_BE_IRREVERSIBLE);
-  if (!local_mailbox)
-    return a->mailbox;
-
-  mutt_str_replace(&buf, local_mailbox);
-  FREE(&local_mailbox);
-  return buf;
-}
-
-/**
- * mutt_env_to_local - Convert an Envelope structure
- */
-void mutt_env_to_local(struct Envelope *e)
-{
-  mutt_addrlist_to_local(e->return_path);
-  mutt_addrlist_to_local(e->from);
-  mutt_addrlist_to_local(e->to);
-  mutt_addrlist_to_local(e->cc);
-  mutt_addrlist_to_local(e->bcc);
-  mutt_addrlist_to_local(e->reply_to);
-  mutt_addrlist_to_local(e->mail_followup_to);
-}
-
-/* Note that `a' in the `env->a' expression is macro argument, not
- * "real" name of an `env' compound member.  Real name will be substituted
- * by preprocessor at the macro-expansion time.
- * Note that #a escapes and double quotes the argument.
- */
-#define H_TO_INTL(a)                                                           \
-  if (mutt_addrlist_to_intl(env->a, err) && !e)                                \
-  {                                                                            \
-    if (tag)                                                                   \
-      *tag = #a;                                                               \
-    e = 1;                                                                     \
-    err = NULL;                                                                \
-  }
-
-int mutt_env_to_intl(struct Envelope *env, char **tag, char **err)
-{
-  int e = 0;
-  H_TO_INTL(return_path);
-  H_TO_INTL(from);
-  H_TO_INTL(to);
-  H_TO_INTL(cc);
-  H_TO_INTL(bcc);
-  H_TO_INTL(reply_to);
-  H_TO_INTL(mail_followup_to);
-  return e;
-}
-
-#undef H_TO_INTL
index 26c89d90c935a2b4f4673fbb5317e833bd0c33e0..b7d520a233773fa24a996fe4843b1a15cf3c1b0a 100644 (file)
@@ -36,9 +36,6 @@ char *mutt_idna_local_to_intl(char *user, char *domain);
 int mutt_addrlist_to_intl(struct Address *a, char **err);
 int mutt_addrlist_to_local(struct Address *a);
 
-void mutt_env_to_local(struct Envelope *e);
-int mutt_env_to_intl(struct Envelope *env, char **tag, char **err);
-
 const char *mutt_addr_for_display(struct Address *a);
 
 #endif /* _MUTT_IDNA_H */