core: Extend gpgme_user_id_t with 'address'.
authorWerner Koch <wk@gnupg.org>
Tue, 23 Aug 2016 04:48:50 +0000 (06:48 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 23 Aug 2016 04:48:50 +0000 (06:48 +0200)
* src/mbox-util.c, src/mbox-util.h: Adjust for use in gpgme.
* src/Makefile.am (main_sources): Add mbox-util.
* src/key.c (_gpgme_key_append_name): Set 'address' field of uid.
(gpgme_key_unref): Free it.

Signed-off-by: Werner Koch <wk@gnupg.org>
src/Makefile.am
src/gpgme.h.in
src/key.c
src/mbox-util.c
src/mbox-util.h

index 6691540..d541f87 100644 (file)
@@ -76,6 +76,7 @@ endif
 main_sources =                                                         \
        util.h conversion.c b64dec.c get-env.c context.h ops.h          \
        parsetlv.c parsetlv.h                                           \
+       mbox-util.c mbox-util.h                                         \
        data.h data.c data-fd.c data-stream.c data-mem.c data-user.c    \
        data-compat.c data-identify.c                                   \
        signers.c sig-notation.c                                        \
index 40f5442..49cea77 100644 (file)
@@ -801,6 +801,12 @@ struct _gpgme_user_id
 
   /* Internal to GPGME, do not use.  */
   gpgme_key_sig_t _last_keysig;
+
+  /* The mail address (addr-spec from RFC5322) of the UID string.
+   * This is general the same as the EMAIL part of this struct but
+   * might be slightly different.  IF no mail address is available
+   * NULL is stored.  */
+  char *address;
 };
 typedef struct _gpgme_user_id *gpgme_user_id_t;
 
index de97102..f642501 100644 (file)
--- a/src/key.c
+++ b/src/key.c
@@ -31,6 +31,8 @@
 #include "ops.h"
 #include "sema.h"
 #include "debug.h"
+#include "mbox-util.h"
+
 
 \f
 /* Protects all reference counters in keys.  All other accesses to a
@@ -233,6 +235,14 @@ _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert)
     parse_user_id (uid->uid, &uid->name, &uid->email,
                   &uid->comment, dst);
 
+  uid->address = _gpgme_mailbox_from_userid (uid->uid);
+  if (uid->address && uid->email && !strcmp (uid->address, uid->email))
+    {
+      /* The ADDRESS is the same as EMAIL: Save some space.  */
+      free (uid->address);
+      uid->address = uid->email;
+    }
+
   if (!key->uids)
     key->uids = uid;
   if (key->_last_uid)
@@ -363,6 +373,8 @@ gpgme_key_unref (gpgme_key_t key)
           free (keysig);
          keysig = next_keysig;
         }
+      if (uid->address && uid->address != uid->email)
+        free (uid->address);
       free (uid);
       uid = next_uid;
     }
index c451198..83c8b5e 100644 (file)
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <config.h>
+/* NB: This code has been taken from GnuPG.  Please keep it in sync
+ * with GnuPG.  */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
 
-#include "util.h"
 #include "mbox-util.h"
 
+/* Lowercase all ASCII characters in STRING.  */
+static char *
+ascii_strlwr (char *string)
+{
+  char *p;
+
+  for (p = string; *p; p++ )
+    if (!(*p & ~0x7f) && *p >= 'A' && *p <= 'Z')
+      *p |= 0x20;
+
+  return string;
+}
+
 
 static int
 string_count_chr (const char *string, int c)
@@ -117,7 +135,7 @@ has_dotdot_after_at (const char *string)
    Note that we can't do an utf-8 encoding checking here because in
    keygen.c this function is called with the native encoding and
    native to utf-8 encoding is only done later.  */
-int
+static int
 has_invalid_email_chars (const void *buffer, size_t length)
 {
   const unsigned char *s = buffer;
@@ -143,7 +161,7 @@ has_invalid_email_chars (const void *buffer, size_t length)
 
 /* Same as is_valid_mailbox (see below) but operates on non-nul
    terminated buffer.  */
-int
+static int
 is_valid_mailbox_mem (const void *name_arg, size_t namelen)
 {
   const char *name = name_arg;
@@ -162,7 +180,7 @@ is_valid_mailbox_mem (const void *name_arg, size_t namelen)
 /* Check whether NAME represents a valid mailbox according to
    RFC822. Returns true if so. */
 int
-is_valid_mailbox (const char *name)
+_gpgme_is_valid_mailbox (const char *name)
 {
   return name? is_valid_mailbox_mem (name, strlen (name)) : 0;
 }
@@ -173,7 +191,7 @@ is_valid_mailbox (const char *name)
    lowercase.  Caller must free the result.  Returns NULL if no valid
    mailbox was found (or we are out of memory). */
 char *
-mailbox_from_userid (const char *userid)
+_gpgme_mailbox_from_userid (const char *userid)
 {
   const char *s, *s_end;
   size_t len;
@@ -188,7 +206,7 @@ mailbox_from_userid (const char *userid)
       if (s_end && s_end > s)
         {
           len = s_end - s;
-          result = xtrymalloc (len + 1);
+          result = malloc (len + 1);
           if (!result)
             return NULL; /* Ooops - out of core.  */
           strncpy (result, s, len);
@@ -202,7 +220,7 @@ mailbox_from_userid (const char *userid)
               || string_has_ctrl_or_space (result)
               || has_dotdot_after_at (result))
             {
-              xfree (result);
+              free (result);
               result = NULL;
               errno = EINVAL;
             }
@@ -210,14 +228,14 @@ mailbox_from_userid (const char *userid)
       else
         errno = EINVAL;
     }
-  else if (is_valid_mailbox (userid))
+  else if (_gpgme_is_valid_mailbox (userid))
     {
       /* The entire user id is a mailbox.  Return that one.  Note that
          this fallback method has some restrictions on the valid
          syntax of the mailbox.  However, those who want weird
          addresses should know about it and use the regular <...>
          syntax.  */
-      result = xtrystrdup (userid);
+      result = strdup (userid);
     }
   else
     errno = EINVAL;
@@ -226,14 +244,14 @@ mailbox_from_userid (const char *userid)
 }
 
 
-/* Check whether UID is a valid standard user id of the form
-     "Heinrich Heine <heinrichh@duesseldorf.de>"
-   and return true if this is the case. */
-int
-is_valid_user_id (const char *uid)
-{
-  if (!uid || !*uid)
-    return 0;
+/* /\* Check whether UID is a valid standard user id of the form */
+/*      "Heinrich Heine <heinrichh@duesseldorf.de>" */
+/*    and return true if this is the case. *\/ */
+/* int */
+/* is_valid_user_id (const char *uid) */
+/* { */
+/*   if (!uid || !*uid) */
+/*     return 0; */
 
-  return 1;
-}
+/*   return 1; */
+/* } */
index 9c7271f..3195a4d 100644 (file)
 #ifndef GNUPG_COMMON_MBOX_UTIL_H
 #define GNUPG_COMMON_MBOX_UTIL_H
 
-int has_invalid_email_chars (const void *buffer, size_t length);
-int is_valid_mailbox (const char *name);
-int is_valid_mailbox_mem (const void *buffer, size_t length);
-char *mailbox_from_userid (const char *userid);
-int is_valid_user_id (const char *uid);
+/* int has_invalid_email_chars (const void *buffer, size_t length); */
+int _gpgme_is_valid_mailbox (const char *name);
+/* int _gpgme_is_valid_mailbox_mem (const void *buffer, size_t length); */
+char *_gpgme_mailbox_from_userid (const char *userid);
+/* int is_valid_user_id (const char *uid); */
 
 
 #endif /*GNUPG_COMMON_MBOX_UTIL_H*/