[PATCH] Implement more export options (clean, no-export-attributes)

Daniele Ricci daniele.athome at gmail.com
Sat Jan 25 13:18:16 CET 2014


 * src/engine-gpg.c: add_to_last_arg() is used to append more data to
   the last added argument, namely export-clean and
   no-export-attributes
 * src/export.c: handle the relevant export mode flags
 * src/gpgme.h.in: added more export mode flags
 * tests/run-export.c: added test cases for the new export modes and
   fixed some other constant names
 * doc/gpgme.texi: document new export mode flags

Signed-off-by: Daniele Ricci <daniele.athome at gmail.com>
---
 doc/gpgme.texi     |  6 ++++++
 src/engine-gpg.c   | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/export.c       |  8 +++++--
 src/gpgme.h.in     |  2 ++
 tests/run-export.c | 26 ++++++++++++++++++----
 5 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 3f31492..1aabbea 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -3547,6 +3547,12 @@ If this bit is set, the smallest possible key is exported.  For OpenPGP
 keys it removes all signatures except for the latest self-signatures.
 For X.509 keys it has no effect.
 
+ at item GPGME_EXPORT_MODE_CLEAN
+If this bit is set, key is exported with only usable signatures. More
+specifically, it will exclude all signatures from unusable user IDs and
+all unusable signatures, including signatures from keys not present on
+the keyring. This is currently only allowed for OpenPGP keys.
+
 
 @end table
 
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 2f59bb9..c0e1b77 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -261,6 +261,46 @@ add_arg (engine_gpg_t gpg, const char *arg)
 
 
 static gpgme_error_t
+add_to_last_arg (engine_gpg_t gpg, const char *arg)
+{
+  struct arg_and_data_s *a;
+  struct arg_and_data_s *prev;
+
+  assert (gpg);
+  assert (arg);
+
+  /* Iterate to the last argument. */
+  a = prev = gpg->arglist;
+  while (a)
+    {
+      if (!a->next)
+        break;
+
+      prev = a;
+      a = a->next;
+    }
+
+  /* This function can be used only after the first call to add_arg. */
+  if (!a)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  a = realloc (a, sizeof *a + strlen (a->arg) + strlen (arg));
+  if (!a)
+    return gpg_error_from_syserror ();
+
+  strcat (a->arg, arg);
+
+  if (prev)
+    prev->next = a;
+
+  *gpg->argtail = a;
+  gpg->argtail = &a->next;
+
+  return 0;
+}
+
+
+static gpgme_error_t
 add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
 {
   struct arg_and_data_s *a;
@@ -973,6 +1013,7 @@ build_argv (engine_gpg_t gpg)
 
   gpg->argv = argv;
   gpg->fd_data_map = fd_data_map;
+
   return 0;
 }
 
@@ -1762,11 +1803,27 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
   gpgme_error_t err = 0;
 
   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
-                |GPGME_EXPORT_MODE_MINIMAL)))
+                |GPGME_EXPORT_MODE_MINIMAL
+                |GPGME_EXPORT_MODE_CLEAN
+                |GPGME_EXPORT_MODE_NO_ATTRIBUTES)))
     return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
-  if ((mode & GPGME_EXPORT_MODE_MINIMAL))
-    err = add_arg (gpg, "--export-options=export-minimal");
+  if ((mode & GPGME_EXPORT_MODE_MINIMAL) |
+      (mode & GPGME_EXPORT_MODE_CLEAN) |
+      (mode & GPGME_EXPORT_MODE_NO_ATTRIBUTES))
+    {
+      err = add_arg(gpg, "--export-options=");
+
+      if (!err && (mode & GPGME_EXPORT_MODE_MINIMAL))
+        err = add_to_last_arg(gpg, "export-minimal,");
+
+      if (!err && (mode & GPGME_EXPORT_MODE_CLEAN))
+        err = add_to_last_arg(gpg, "export-clean,");
+
+      if (!err && (mode & GPGME_EXPORT_MODE_NO_ATTRIBUTES))
+        err = add_to_last_arg(gpg, "no-export-attributes,");
+
+    }
 
   if (err)
     ;
diff --git a/src/export.c b/src/export.c
index 81a23b0..9151087 100644
--- a/src/export.c
+++ b/src/export.c
@@ -45,7 +45,9 @@ export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
   gpgme_error_t err;
 
   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
-                |GPGME_EXPORT_MODE_MINIMAL)))
+                |GPGME_EXPORT_MODE_MINIMAL
+                |GPGME_EXPORT_MODE_CLEAN
+                |GPGME_EXPORT_MODE_NO_ATTRIBUTES)))
     return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */
 
 
@@ -116,7 +118,9 @@ export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],
   gpgme_error_t err;
 
   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
-                |GPGME_EXPORT_MODE_MINIMAL)))
+                |GPGME_EXPORT_MODE_MINIMAL
+                |GPGME_EXPORT_MODE_CLEAN
+                |GPGME_EXPORT_MODE_NO_ATTRIBUTES)))
     return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */
 
   if ((mode & GPGME_EXPORT_MODE_EXTERN))
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 5c4de6b..551ed60 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -388,6 +388,8 @@ gpgme_pinentry_mode_t;
 /* The available export mode flags.  */
 #define GPGME_EXPORT_MODE_EXTERN                2
 #define GPGME_EXPORT_MODE_MINIMAL               4
+#define GPGME_EXPORT_MODE_CLEAN                 8
+#define GPGME_EXPORT_MODE_NO_ATTRIBUTES         16
 
 typedef unsigned int gpgme_export_mode_t;
 
diff --git a/tests/run-export.c b/tests/run-export.c
index 4333208..b0e0771 100644
--- a/tests/run-export.c
+++ b/tests/run-export.c
@@ -43,6 +43,9 @@ show_usage (int ex)
   fputs ("usage: " PGM " [options] USERIDS\n\n"
          "Options:\n"
          "  --verbose        run in verbose mode\n"
+         "  --clean          remove any unusable user IDs and signatures\n"
+         "  --minimal        remove all signatures except self-signatures\n"
+         "  --no-attributes  do not include any user attribute\n"
          "  --extern         send keys to the keyserver (TAKE CARE!)\n"
          , stderr);
   exit (ex);
@@ -81,7 +84,22 @@ main (int argc, char **argv)
         }
       else if (!strcmp (*argv, "--extern"))
         {
-          mode |= GPGME_KEYLIST_MODE_EXTERN;
+          mode |= GPGME_EXPORT_MODE_EXTERN;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--clean"))
+        {
+          mode |= GPGME_EXPORT_MODE_CLEAN;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--minimal"))
+        {
+          mode |= GPGME_EXPORT_MODE_MINIMAL;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--no-attributes"))
+        {
+          mode |= GPGME_EXPORT_MODE_NO_ATTRIBUTES;
           argc--; argv++;
         }
       else if (!strncmp (*argv, "--", 2))
@@ -131,7 +149,7 @@ main (int argc, char **argv)
     }
 
   /* Now for the actual export.  */
-  if ((mode & GPGME_KEYLIST_MODE_EXTERN))
+  if ((mode & GPGME_EXPORT_MODE_EXTERN))
     printf ("sending keys to keyserver\n");
 
   err = gpgme_data_new (&out);
@@ -139,11 +157,11 @@ main (int argc, char **argv)
 
   gpgme_set_armor (ctx, 1);
   err = gpgme_op_export_keys (ctx, keyarray, mode,
-                              (mode & GPGME_KEYLIST_MODE_EXTERN)? NULL:out);
+                              (mode & GPGME_EXPORT_MODE_EXTERN)? NULL:out);
   fail_if_err (err);
 
   fflush (NULL);
-  if (!(mode & GPGME_KEYLIST_MODE_EXTERN))
+  if (!(mode & GPGME_EXPORT_MODE_EXTERN))
     {
       fputs ("Begin Result:\n", stdout);
       print_data (out);
-- 
1.8.5.2




More information about the Gnupg-devel mailing list