[git] GPGME - branch, master, updated. gpgme-1.7.1-3-gb8159ea

by Werner Koch cvs at cvs.gnupg.org
Tue Oct 25 17:32:47 CEST 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".

The branch, master has been updated
       via  b8159eadb5636cd9d93ee60c41e75d5978927870 (commit)
      from  26cbba3c9cb04a68b95f3a6000ac9bd93fe76dd7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit b8159eadb5636cd9d93ee60c41e75d5978927870
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Oct 25 17:27:49 2016 +0200

    core: New API functions gpgme_set_sender, gpgme_get_sender.
    
    * src/context.h (struct gpgme_context): Add field 'sender'.
    * src/gpgme.c: Include mbox-util.h.
    (gpgme_release): Free SENDER.
    (gpgme_set_sender): New.
    (gpgme_get_sender): New.
    * src/gpgme.def, src/libgpgme.vers: Add new functions.
    
    * src/engine-gpg.c (append_args_from_sender): New.
    (gpg_encrypt_sign, gpg_sign): Call append_args_from_sender.
    (gpg_verify): Add arg CTX.  Call append_args_from_sender/
    * src/engine-gpgsm.c (gpgsm_verify): Add dummy arg CTX.
    * src/engine-uiserver.c (uiserver_verify): Ditto.
    * src/engine.c (_gpgme_engine_op_verify): Add arg CTX.
    * src/verify.c (verify_start): Pass CTX to engine function.
    
    * tests/gpg/t-verify.c (main): Add some checks for new functions.
    * tests/run-sign.c (main): Add option --sender.
    * tests/run-verify.c (main): Ditto.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index f5d7ce0..38f38d6 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,12 @@ Noteworthy changes in version 1.7.2 (unreleased)
 ------------------------------------------------
 
 
+ * Interface changes relative to the 1.7.1 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gpgme_set_sender                NEW.
+ gpgme_get_sender                NEW.
+
+
 Noteworthy changes in version 1.7.1 (2016-10-18)
 ------------------------------------------------
 
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index cc59888..9fae9aa 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -186,6 +186,7 @@ Context Attributes
 
 * Protocol Selection::            Selecting the protocol used by a context.
 * Crypto Engine::                 Configuring the crypto engine.
+* Setting the Sender::            How to tell the engine the sender.
 * ASCII Armor::                   Requesting @acronym{ASCII} armored output.
 * Text Mode::                     Choosing canonical text mode.
 * Offline Mode::                  Choosing offline mode.
@@ -2366,6 +2367,7 @@ started.  In fact, these references are accessed through the
 @menu
 * Protocol Selection::            Selecting the protocol used by a context.
 * Crypto Engine::                 Configuring the crypto engine.
+* Setting the Sender::            How to tell the engine the sender.
 * ASCII Armor::                   Requesting @acronym{ASCII} armored output.
 * Text Mode::                     Choosing canonical text mode.
 * Offline Mode::                  Choosing offline mode.
@@ -2448,6 +2450,47 @@ successful, or an eror code on failure.
 @end deftypefun
 
 
+ at node Setting the Sender
+ at subsection How to tell the engine the sender.
+ at cindex context, sender
+ at cindex sender
+ at cindex From:
+
+Some engines can make use of the sender’s address, for example to
+figure out the best user id in certain trust models.  For verification
+and signing of mails, it is thus suggested to let the engine know the
+sender ("From:") address.  @acronym{GPGME} provides two functions to
+accomplish that.  Note that the esoteric use of multiple "From:"
+addresses is not supported.
+
+ at deftypefun gpgme_error_t gpgme_set_sender @
+      (@w{gpgme_ctx_t @var{ctx}}, @
+       @w{int @var{address}})
+
+The function @code{gpgme_set_sender} specifies the sender address for
+use in sign and verify operations.  @var{address} is expected to be
+the ``addr-spec'' part of an address but my also be a complete mailbox
+address, in which case this function extracts the ``addr-spec'' from
+it.  Using @code{NULL} for @var{address} clears the sender address.
+
+The function returns 0 on success or an error code on failure.  The
+most likely failure is that no valid ``addr-spec'' was found in
+ at var{address}.
+
+ at end deftypefun
+
+ at deftypefun @w{const char *} gpgme_get_sender @
+      (@w{gpgme_ctx_t @var{ctx}})
+
+The function @code{gpgme_get_sender} returns the current sender
+address from the context, or NULL if none was set.  The returned
+value is valid as long as the @var{ctx} is valid and
+ at code{gpgme_set_sender} has not been called again.
+
+ at end deftypefun
+
+
+
 @c FIXME: Unfortunately, using @acronym here breaks texi2dvi.
 @node ASCII Armor
 @subsection @acronym{ASCII} Armor
diff --git a/src/context.h b/src/context.h
index 4b12c3b..f6c1ad1 100644
--- a/src/context.h
+++ b/src/context.h
@@ -119,16 +119,18 @@ struct gpgme_context
   /* Number of certs to be included.  */
   unsigned int include_certs;
 
-  /* The number of keys in signers.  */
+  /* The actual number of keys in SIGNERS, the allocated size of the
+   * array, and the array with the signing keys.  */
   unsigned int signers_len;
-
-  /* Size of the following array.  */
   unsigned int signers_size;
   gpgme_key_t *signers;
 
   /* The signature notations for this context.  */
   gpgme_sig_notation_t sig_notations;
 
+  /* The sender's addr-spec or NULL.  */
+  char *sender;
+
   /* The locale for the pinentry.  */
   char *lc_ctype;
   char *lc_messages;
diff --git a/src/engine-backend.h b/src/engine-backend.h
index ccab0e3..e02c715 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -111,7 +111,8 @@ struct engine_ops
 			 gpgme_ctx_t ctx /* FIXME */);
   gpgme_error_t (*trustlist) (void *engine, const char *pattern);
   gpgme_error_t (*verify) (void *engine, gpgme_data_t sig,
-			   gpgme_data_t signed_text, gpgme_data_t plaintext);
+			   gpgme_data_t signed_text, gpgme_data_t plaintext,
+                           gpgme_ctx_t ctx);
   gpgme_error_t  (*getauditlog) (void *engine, gpgme_data_t output,
                                  unsigned int flags);
   gpgme_error_t  (*opassuan_transact) (void *engine,
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 4415c94..cb52dea 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -1646,6 +1646,23 @@ append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
 
 
 static gpgme_error_t
+append_args_from_sender (engine_gpg_t gpg, gpgme_ctx_t ctx)
+{
+  gpgme_error_t err;
+
+  if (ctx->sender && have_gpg_version (gpg, "2.1.15"))
+    {
+      err = add_arg (gpg, "--sender");
+      if (!err)
+        err = add_arg (gpg, ctx->sender);
+    }
+  else
+    err = 0;
+  return err;
+}
+
+
+static gpgme_error_t
 append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
 {
   gpgme_error_t err = 0;
@@ -1893,6 +1910,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
     err = append_args_from_signers (gpg, ctx);
 
   if (!err)
+    err = append_args_from_sender (gpg, ctx);
+
+  if (!err)
     err = append_args_from_sig_notations (gpg, ctx);
 
   /* Tell the gpg object about the data.  */
@@ -2794,6 +2814,8 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
   if (!err)
     err = append_args_from_signers (gpg, ctx);
   if (!err)
+    err = append_args_from_sender (gpg, ctx);
+  if (!err)
     err = append_args_from_sig_notations (gpg, ctx);
 
   if (gpgme_data_get_file_name (in))
@@ -2845,12 +2867,15 @@ gpg_trustlist (void *engine, const char *pattern)
 
 static gpgme_error_t
 gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
-	    gpgme_data_t plaintext)
+	    gpgme_data_t plaintext, gpgme_ctx_t ctx)
 {
   engine_gpg_t gpg = engine;
-  gpgme_error_t err = 0;
+  gpgme_error_t err;
 
-  if (plaintext)
+  err = append_args_from_sender (gpg, ctx);
+  if (err)
+    ;
+  else if (plaintext)
     {
       /* Normal or cleartext signature.  */
       err = add_arg (gpg, "--output");
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index e7e2a20..0ce4a6d 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -1901,11 +1901,13 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
 
 static gpgme_error_t
 gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
-	      gpgme_data_t plaintext)
+	      gpgme_data_t plaintext, gpgme_ctx_t ctx)
 {
   engine_gpgsm_t gpgsm = engine;
   gpgme_error_t err;
 
+  (void)ctx;
+
   if (!gpgsm)
     return gpg_error (GPG_ERR_INV_VALUE);
 
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index 63e77de..76fa4d7 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -1243,13 +1243,16 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
 /* FIXME: Missing a way to specify --silent.  */
 static gpgme_error_t
 uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
-	      gpgme_data_t plaintext)
+                 gpgme_data_t plaintext, gpgme_ctx_t ctx)
 {
   engine_uiserver_t uiserver = engine;
   gpgme_error_t err;
   const char *protocol;
   char *cmd;
 
+  (void)ctx; /* FIXME: We should to add a --sender option to the
+              * UISever protocol.  */
+
   if (!uiserver)
     return gpg_error (GPG_ERR_INV_VALUE);
   if (uiserver->protocol == GPGME_PROTOCOL_DEFAULT)
@@ -1395,6 +1398,6 @@ struct engine_ops _gpgme_engine_ops_uiserver =
     uiserver_cancel,
     NULL,		/* cancel_op */
     NULL,               /* passwd */
-    NULL,                /* set_pinentry_mode */
+    NULL,               /* set_pinentry_mode */
     NULL                /* opspawn */
   };
diff --git a/src/engine.c b/src/engine.c
index a1173a0..f5dfe51 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -902,7 +902,8 @@ _gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
 
 gpgme_error_t
 _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
-			 gpgme_data_t signed_text, gpgme_data_t plaintext)
+			 gpgme_data_t signed_text, gpgme_data_t plaintext,
+                         gpgme_ctx_t ctx)
 {
   if (!engine)
     return gpg_error (GPG_ERR_INV_VALUE);
@@ -910,7 +911,8 @@ _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
   if (!engine->ops->verify)
     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
 
-  return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext);
+  return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext,
+                                 ctx);
 }
 
 
diff --git a/src/engine.h b/src/engine.h
index 4ce2bed..2999ab6 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -152,7 +152,8 @@ gpgme_error_t _gpgme_engine_op_trustlist (engine_t engine,
 					  const char *pattern);
 gpgme_error_t _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
 				       gpgme_data_t signed_text,
-				       gpgme_data_t plaintext);
+				       gpgme_data_t plaintext,
+                                       gpgme_ctx_t ctx);
 
 gpgme_error_t _gpgme_engine_op_getauditlog (engine_t engine,
                                             gpgme_data_t output,
diff --git a/src/gpgme.c b/src/gpgme.c
index d59f808..6d0dbff 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -38,6 +38,7 @@
 #include "debug.h"
 #include "priv-io.h"
 #include "sys-util.h"
+#include "mbox-util.h"
 
 

 /* The default locale.  */
@@ -275,12 +276,10 @@ gpgme_release (gpgme_ctx_t ctx)
   _gpgme_release_result (ctx);
   _gpgme_signers_clear (ctx);
   _gpgme_sig_notation_clear (ctx);
-  if (ctx->signers)
-    free (ctx->signers);
-  if (ctx->lc_ctype)
-    free (ctx->lc_ctype);
-  if (ctx->lc_messages)
-    free (ctx->lc_messages);
+  free (ctx->sender);
+  free (ctx->signers);
+  free (ctx->lc_ctype);
+  free (ctx->lc_messages);
   _gpgme_engine_info_release (ctx->engine_info);
   ctx->engine_info = NULL;
   DESTROY_LOCK (ctx->lock);
@@ -459,6 +458,42 @@ gpgme_get_protocol_name (gpgme_protocol_t protocol)
     }
 }
 
+
+/* Store the sender's address in the context.  ADDRESS is addr-spec of
+ * mailbox but my also be a complete mailbox, in which case this
+ * function extracts the addr-spec from it.  Returns 0 on success or
+ * an error code if no valid addr-spec could be extracted from
+ * ADDRESS.  */
+gpgme_error_t
+gpgme_set_sender (gpgme_ctx_t ctx, const char *address)
+{
+  char *p = NULL;
+
+  TRACE_BEG1 (DEBUG_CTX, "gpgme_set_sender", ctx, "sender='%s'",
+              address?address:"(null)");
+
+  if (!ctx || (address && !(p = _gpgme_mailbox_from_userid (address))))
+    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+  free (ctx->sender);
+  ctx->sender = p;
+  return TRACE_ERR (0);
+}
+
+
+/* Return the sender's address (addr-spec part) from the context or
+ * NULL if none was set.  The returned value is valid as long as the
+ * CTX is valid and gpgme_set_sender has not been used.  */
+const char *
+gpgme_get_sender (gpgme_ctx_t ctx)
+{
+  TRACE1 (DEBUG_CTX, "gpgme_get_sender", ctx, "sender='%s'",
+          ctx?ctx->sender:"");
+
+  return ctx->sender;
+}
+
+
 /* Enable or disable the use of an ascii armor for all output.  */
 void
 gpgme_set_armor (gpgme_ctx_t ctx, int use_armor)
diff --git a/src/gpgme.def b/src/gpgme.def
index c94c960..d633df5 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -246,5 +246,8 @@ EXPORTS
 
     gpgme_addrspec_from_uid               @186
 
+    gpgme_set_sender                      @187
+    gpgme_get_sender                      @188
+
 ; END
 
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 5c914ae..94ef51d 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1161,6 +1161,12 @@ gpgme_error_t gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
 /* Get the sig notations for this context.  */
 gpgme_sig_notation_t gpgme_sig_notation_get (gpgme_ctx_t ctx);
 
+/* Store a sender address in the context.  */
+gpgme_error_t gpgme_set_sender (gpgme_ctx_t ctx, const char *address);
+
+/* Get the sender address from the context.  */
+const char *gpgme_get_sender (gpgme_ctx_t ctx);
+
 
 

 /*
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index d3962db..42f00d5 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -119,6 +119,9 @@ GPGME_1.1 {
     gpgme_op_interact;
 
     gpgme_addrspec_from_uid;
+
+    gpgme_set_sender;
+    gpgme_get_sender;
 };
 
 
diff --git a/src/verify.c b/src/verify.c
index eb1cc10..faa8deb 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -1104,7 +1104,8 @@ verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t sig,
   if (!sig)
     return gpg_error (GPG_ERR_NO_DATA);
 
-  return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext);
+  return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext,
+                                  ctx);
 }
 
 
diff --git a/tests/gpg/t-verify.c b/tests/gpg/t-verify.c
index 9842d3a..f955cc9 100644
--- a/tests/gpg/t-verify.c
+++ b/tests/gpg/t-verify.c
@@ -209,6 +209,7 @@ main (int argc, char *argv[])
   gpgme_error_t err;
   gpgme_data_t sig, text;
   gpgme_verify_result_t result;
+  const char *s;
 
   (void)argc;
   (void)argv;
@@ -270,6 +271,54 @@ main (int argc, char *argv[])
       exit (1);
     }
 
+  /* Checking that set/get_sernder works.  */
+  err = gpgme_set_sender (ctx, "foo at example.org");
+  fail_if_err (err);
+  s = gpgme_get_sender (ctx);
+  if (!s || strcmp (s, "foo at example.org"))
+    {
+      fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n",
+               __FILE__, __LINE__);
+      exit (1);
+    }
+
+  err = gpgme_set_sender (ctx, "<bar at example.org>");
+  fail_if_err (err);
+  s = gpgme_get_sender (ctx);
+  if (!s || strcmp (s, "bar at example.org"))
+    {
+      fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n",
+               __FILE__, __LINE__);
+      exit (1);
+    }
+
+  err = gpgme_set_sender (ctx, "Foo bar (comment) <foo at example.org>");
+  fail_if_err (err);
+  s = gpgme_get_sender (ctx);
+  if (!s || strcmp (s, "foo at example.org"))
+    {
+      fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n",
+               __FILE__, __LINE__);
+      exit (1);
+    }
+
+  err = gpgme_set_sender (ctx, "foo");
+  if (gpgme_err_code (err) != GPG_ERR_INV_VALUE)
+    {
+      fprintf (stderr, "%s:%i: gpgme_set_sender didn't detect bogus address\n",
+               __FILE__, __LINE__);
+      exit (1);
+    }
+  /* (the former address should still be there.)  */
+  s = gpgme_get_sender (ctx);
+  if (!s || strcmp (s, "foo at example.org"))
+    {
+      fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n",
+               __FILE__, __LINE__);
+      exit (1);
+    }
+
+
   gpgme_data_release (sig);
   gpgme_data_release (text);
   gpgme_release (ctx);
diff --git a/tests/run-sign.c b/tests/run-sign.c
index 70853ed..f790cb6 100644
--- a/tests/run-sign.c
+++ b/tests/run-sign.c
@@ -83,6 +83,7 @@ show_usage (int ex)
          "  --uiserver       use the UI server\n"
          "  --loopback       use a loopback pinentry\n"
          "  --key NAME       use key NAME for signing\n"
+         "  --sender MBOX    use MBOX as sender address\n"
          , stderr);
   exit (ex);
 }
@@ -101,6 +102,7 @@ main (int argc, char **argv)
   gpgme_sign_result_t result;
   int print_status = 0;
   int use_loopback = 0;
+  const char *sender = NULL;
 
   if (argc)
     { argc--; argv++; }
@@ -148,6 +150,14 @@ main (int argc, char **argv)
           key_string = *argv;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--sender"))
+        {
+          argc--; argv++;
+          if (!argc)
+            show_usage (1);
+          sender = *argv;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--loopback"))
         {
           use_loopback = 1;
@@ -192,6 +202,12 @@ main (int argc, char **argv)
       gpgme_key_unref (akey);
     }
 
+  if (sender)
+    {
+      err = gpgme_set_sender (ctx, sender);
+      fail_if_err (err);
+    }
+
   err = gpgme_data_new_from_file (&in, *argv, 1);
   if (err)
     {
diff --git a/tests/run-verify.c b/tests/run-verify.c
index ebc20d9..22242c0 100644
--- a/tests/run-verify.c
+++ b/tests/run-verify.c
@@ -221,6 +221,7 @@ show_usage (int ex)
          "  --status         print status lines from the backend\n"
          "  --openpgp        use the OpenPGP protocol (default)\n"
          "  --cms            use the CMS protocol\n"
+         "  --sender MBOX    use MBOX as sender address\n"
          , stderr);
   exit (ex);
 }
@@ -239,6 +240,7 @@ main (int argc, char **argv)
   gpgme_data_t msg = NULL;
   gpgme_verify_result_t result;
   int print_status = 0;
+  const char *sender = NULL;
 
   if (argc)
     { argc--; argv++; }
@@ -273,6 +275,14 @@ main (int argc, char **argv)
           protocol = GPGME_PROTOCOL_CMS;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--sender"))
+        {
+          argc--; argv++;
+          if (!argc)
+            show_usage (1);
+          sender = *argv;
+          argc--; argv++;
+        }
       else if (!strncmp (*argv, "--", 2))
         show_usage (1);
 
@@ -313,6 +323,12 @@ main (int argc, char **argv)
     }
   /* gpgme_set_ctx_flag (ctx, "raw-description", "1"); */
 
+  if (sender)
+    {
+      err = gpgme_set_sender (ctx, sender);
+      fail_if_err (err);
+    }
+
   err = gpgme_data_new_from_stream (&sig, fp_sig);
   if (err)
     {

-----------------------------------------------------------------------

Summary of changes:
 NEWS                  |  6 ++++++
 doc/gpgme.texi        | 43 +++++++++++++++++++++++++++++++++++++++++++
 src/context.h         |  8 +++++---
 src/engine-backend.h  |  3 ++-
 src/engine-gpg.c      | 31 ++++++++++++++++++++++++++++---
 src/engine-gpgsm.c    |  4 +++-
 src/engine-uiserver.c |  7 +++++--
 src/engine.c          |  6 ++++--
 src/engine.h          |  3 ++-
 src/gpgme.c           | 47 +++++++++++++++++++++++++++++++++++++++++------
 src/gpgme.def         |  3 +++
 src/gpgme.h.in        |  6 ++++++
 src/libgpgme.vers     |  3 +++
 src/verify.c          |  3 ++-
 tests/gpg/t-verify.c  | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/run-sign.c      | 16 ++++++++++++++++
 tests/run-verify.c    | 16 ++++++++++++++++
 17 files changed, 234 insertions(+), 20 deletions(-)


hooks/post-receive
-- 
GnuPG Made Easy
http://git.gnupg.org




More information about the Gnupg-commits mailing list