[Pkg-gnupg-commit] [gnupg2] 165/166: more bugfix patches from upstream

Daniel Kahn Gillmor dkg at fifthhorseman.net
Thu Mar 16 22:33:21 UTC 2017


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch experimental
in repository gnupg2.

commit 320b9c132335e0437c28775b247d612fb8cb427e
Author: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
Date:   Thu Mar 16 12:46:55 2017 -0400

    more bugfix patches from upstream
---
 ...r-SSH-robustly-handling-scdaemon-s-errors.patch |   82 +
 .../0026-scd-Fix-API-of-select_file-_path.patch    |  266 ++
 debian/patches/0027-scd-Clean-up-old-code.patch    | 1355 +++++++++
 .../0028-scd-More-cleanup-of-old-code.patch        |  102 +
 ...d-Fix-compiler-warnings-for-app-openpgp.c.patch |   45 +
 ...x-attempt-to-double-free-an-UID-structure.patch |   59 +
 ...scm-Fix-creation-of-temporary-directories.patch |   38 +
 ...nize-temporary-and-socket-directory-handl.patch |  376 +++
 .../patches/0033-scd-Close-THE_EVENT-handle.patch  |   29 +
 .../0034-tools-More-portable-for-openpty-use.patch |   58 +
 .../0035-common-Fix-warning-for-portability.patch  |   26 +
 ...-agent-Fix-get_client_pid-for-portability.patch |  177 ++
 debian/patches/0037-agent-Add-include-files.patch  |   27 +
 .../0038-agent-Resolve-conflict-of-util.h.patch    |  263 ++
 ...ts-Avoid-overflowing-signed-32-bit-time_t.patch |   56 +
 .../patches/0040-Remove-I-option-to-common.patch   | 3130 ++++++++++++++++++++
 debian/patches/0041-More-change-for-common.patch   |   69 +
 debian/patches/0042-tools-Removal-of-Icommon.patch |   39 +
 ...allow-the-user-to-revoke-the-last-valid-U.patch |  119 +
 ...044-gpgscm-Use-system-strlwr-if-available.patch |   51 +
 ...-doc-Add-a-note-to-the-trust-model-direct.patch |   75 +
 ...not-put-a-keyserver-into-a-new-dirmngr.co.patch |   54 +
 ...10-Move-more-flags-into-the-flag-bitfield.patch |  728 +++++
 .../0048-tests-Rework-environment-setup.patch      |  227 ++
 ...he-tests-for-the-Python-bindings-of-GPGME.patch |  141 +
 ...tdout-before-printing-stats-with-check-si.patch |   37 +
 ...-in-README-how-to-create-run-user-directo.patch |   47 +
 ...Python-tests-if-the-bindings-are-not-buil.patch |   63 +
 .../0053-tests-Fix-running-python-condition.patch  |   33 +
 .../patches/0054-g10-Remove-unused-function.patch  |  120 +
 .../patches/0055-g10-Fix-check-of-serialno.patch   |   25 +
 ...Remove-disable-tools-configuration-option.patch |   62 +
 ...the-tools-that-the-tests-are-going-to-use.patch |   44 +
 ...-Fix-using-tools-from-the-build-directory.patch |   59 +
 ...ent-g10-Remove-redundant-SERIALNO-request.patch |  234 ++
 debian/patches/series                              |   35 +
 36 files changed, 8351 insertions(+)

diff --git a/debian/patches/0025-agent-For-SSH-robustly-handling-scdaemon-s-errors.patch b/debian/patches/0025-agent-For-SSH-robustly-handling-scdaemon-s-errors.patch
new file mode 100644
index 0000000..20e299a
--- /dev/null
+++ b/debian/patches/0025-agent-For-SSH-robustly-handling-scdaemon-s-errors.patch
@@ -0,0 +1,82 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Mon, 6 Mar 2017 10:26:11 +0900
+Subject: agent: For SSH, robustly handling scdaemon's errors.
+
+* agent/command-ssh.c (card_key_list): Return 0 when
+agent_card_serialno returns an error.
+(ssh_handler_request_identities): Handle errors for card listing
+and proceed to other cases.
+--
+
+GnuPG-bug-id: 2980
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 4ce4f2f683a17be3ddb93729f3f25014a97934ad)
+---
+ agent/command-ssh.c | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index 79b8f85..3ab41cf 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -2393,13 +2393,12 @@ card_key_list (ctrl_t ctrl, char **r_serialno, strlist_t *result)
+   err = agent_card_serialno (ctrl, r_serialno, NULL);
+   if (err)
+     {
+-      if (gpg_err_code (err) == GPG_ERR_ENODEV)
+-        return 0;               /* Nothing available.  */
+-
+-      if (opt.verbose)
++      if (gpg_err_code (err) != GPG_ERR_ENODEV && opt.verbose)
+         log_info (_("error getting serial number of card: %s\n"),
+                   gpg_strerror (err));
+-      return err;
++
++      /* Nothing available.  */
++      return 0;
+     }
+ 
+   err = agent_card_cardlist (ctrl, result);
+@@ -2568,7 +2567,6 @@ ssh_handler_request_identities (ctrl_t ctrl,
+   gpg_error_t err;
+   int ret;
+   ssh_control_file_t cf = NULL;
+-  char *cardsn;
+   gpg_error_t ret_err;
+ 
+   (void)request;
+@@ -2601,21 +2599,21 @@ ssh_handler_request_identities (ctrl_t ctrl,
+           if (opt.verbose)
+             log_info (_("error getting list of cards: %s\n"),
+                       gpg_strerror (err));
+-          goto out;
++          goto scd_out;
+         }
+ 
+       for (sl = card_list; sl; sl = sl->next)
+         {
+           char *serialno0;
++          char *cardsn;
++
+           err = agent_card_serialno (ctrl, &serialno0, sl->d);
+           if (err)
+             {
+               if (opt.verbose)
+                 log_info (_("error getting serial number of card: %s\n"),
+                           gpg_strerror (err));
+-              xfree (serialno);
+-              free_strlist (card_list);
+-              goto out;
++              continue;
+             }
+ 
+           xfree (serialno0);
+@@ -2640,6 +2638,7 @@ ssh_handler_request_identities (ctrl_t ctrl,
+       free_strlist (card_list);
+     }
+ 
++ scd_out:
+   /* Then look at all the registered and non-disabled keys. */
+   err = open_control_file (&cf, 0);
+   if (err)
diff --git a/debian/patches/0026-scd-Fix-API-of-select_file-_path.patch b/debian/patches/0026-scd-Fix-API-of-select_file-_path.patch
new file mode 100644
index 0000000..20472f9
--- /dev/null
+++ b/debian/patches/0026-scd-Fix-API-of-select_file-_path.patch
@@ -0,0 +1,266 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Mon, 6 Mar 2017 13:39:46 +0900
+Subject: scd: Fix API of select_file/_path.
+
+* scd/iso7816.c (iso7816_select_file, iso7816_select_path): Remove
+unused arguments.
+* scd/app-dinsig.c (do_readcert): Follow the change.
+* scd/app-help.c (app_help_read_length_of_cert): Likewise.
+* scd/app-nks.c (keygripstr_from_pk_file, do_readcert, do_readkey)
+(switch_application): Likewise.
+* scd/app-p15.c (select_and_read_binary, select_ef_by_path)
+(micardo_mse, app_select_p15): Likewise.
+* scd/app.c (app_new_register): Likewise.
+
+--
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 0703de01c8fbc417a99ecf8e950fc306b8c8ac9c)
+---
+ scd/app-dinsig.c |  2 +-
+ scd/app-help.c   |  2 +-
+ scd/app-nks.c    |  8 ++++----
+ scd/app-p15.c    | 15 +++++++--------
+ scd/app.c        |  4 ++--
+ scd/iso7816.c    | 34 +++++++---------------------------
+ scd/iso7816.h    |  8 +++-----
+ 7 files changed, 25 insertions(+), 48 deletions(-)
+
+diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c
+index 99e4f00..5d65845 100644
+--- a/scd/app-dinsig.c
++++ b/scd/app-dinsig.c
+@@ -193,7 +193,7 @@ do_readcert (app_t app, const char *certid,
+   /* Read the entire file.  fixme: This could be optimized by first
+      reading the header to figure out how long the certificate
+      actually is. */
+-  err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
++  err = iso7816_select_file (app->slot, fid, 0);
+   if (err)
+     {
+       log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
+diff --git a/scd/app-help.c b/scd/app-help.c
+index 1cc86b1..85bcc66 100644
+--- a/scd/app-help.c
++++ b/scd/app-help.c
+@@ -106,7 +106,7 @@ app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff)
+   int class, tag, constructed, ndef;
+   size_t resultlen, objlen, hdrlen;
+ 
+-  err = iso7816_select_file (slot, fid, 0, NULL, NULL);
++  err = iso7816_select_file (slot, fid, 0);
+   if (err)
+     {
+       log_info ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
+diff --git a/scd/app-nks.c b/scd/app-nks.c
+index 4442a10..98dd588 100644
+--- a/scd/app-nks.c
++++ b/scd/app-nks.c
+@@ -151,7 +151,7 @@ keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr)
+   int i;
+   int offset[2] = { 0, 0 };
+ 
+-  err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
++  err = iso7816_select_file (app->slot, fid, 0);
+   if (err)
+     return err;
+   err = iso7816_read_record (app->slot, 1, 1, 0, &buffer[0], &buflen[0]);
+@@ -528,7 +528,7 @@ do_readcert (app_t app, const char *certid,
+   /* Read the entire file.  fixme: This could be optimized by first
+      reading the header to figure out how long the certificate
+      actually is. */
+-  err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
++  err = iso7816_select_file (app->slot, fid, 0);
+   if (err)
+     {
+       log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
+@@ -636,7 +636,7 @@ do_readkey (app_t app, int advanced, const char *keyid,
+     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ 
+   /* Access the KEYD file which is always in the master directory.  */
+-  err = iso7816_select_path (app->slot, path, DIM (path), NULL, NULL);
++  err = iso7816_select_path (app->slot, path, DIM (path));
+   if (err)
+     return err;
+   /* Due to the above select we need to re-select our application.  */
+@@ -1354,7 +1354,7 @@ switch_application (app_t app, int enable_sigg)
+ 
+       app->app_local->sigg_msig_checked = 1;
+       app->app_local->sigg_is_msig = 1;
+-      err = iso7816_select_file (app->slot, 0x5349, 0, NULL, NULL);
++      err = iso7816_select_file (app->slot, 0x5349, 0);
+       if (!err)
+         err = iso7816_read_record (app->slot, 1, 1, 0, &buffer, &buflen);
+       if (!err)
+diff --git a/scd/app-p15.c b/scd/app-p15.c
+index 3def55b..db8c38e 100644
+--- a/scd/app-p15.c
++++ b/scd/app-p15.c
+@@ -409,7 +409,7 @@ select_and_read_binary (int slot, unsigned short efid, const char *efid_desc,
+ {
+   gpg_error_t err;
+ 
+-  err = iso7816_select_file (slot, efid, 0, NULL, NULL);
++  err = iso7816_select_file (slot, efid, 0);
+   if (err)
+     {
+       log_error ("error selecting %s (0x%04X): %s\n",
+@@ -443,7 +443,7 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen)
+ 
+   if (app->app_local->direct_path_selection)
+     {
+-      err = iso7816_select_path (app->slot, path+1, pathlen-1, NULL, NULL);
++      err = iso7816_select_path (app->slot, path+1, pathlen-1);
+       if (err)
+         {
+           log_error ("error selecting path ");
+@@ -461,8 +461,7 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen)
+          supported by the card. */
+       for (i=0; i < pathlen; i++)
+         {
+-          err = iso7816_select_file (app->slot, path[i],
+-                                     !(i+1 == pathlen), NULL, NULL);
++          err = iso7816_select_file (app->slot, path[i], !(i+1 == pathlen));
+           if (err)
+             {
+               log_error ("error selecting part %d from path ", i);
+@@ -2761,7 +2760,7 @@ micardo_mse (app_t app, unsigned short fid)
+   unsigned char msebuf[10];
+ 
+   /* Read the KeyD file containing extra information on keys. */
+-  err = iso7816_select_file (app->slot, 0x0013, 0, NULL, NULL);
++  err = iso7816_select_file (app->slot, 0x0013, 0);
+   if (err)
+     {
+       log_error ("error reading EF_keyD: %s\n", gpg_strerror (err));
+@@ -3301,7 +3300,7 @@ app_select_p15 (app_t app)
+          Using the 2f02 just works. */
+       unsigned short path[1] = { 0x2f00 };
+ 
+-      rc = iso7816_select_path (app->slot, path, 1, NULL, NULL);
++      rc = iso7816_select_path (app->slot, path, 1);
+       if (!rc)
+         {
+           direct = 1;
+@@ -3309,14 +3308,14 @@ app_select_p15 (app_t app)
+           if (def_home_df)
+             {
+               path[0] = def_home_df;
+-              rc = iso7816_select_path (app->slot, path, 1, NULL, NULL);
++              rc = iso7816_select_path (app->slot, path, 1);
+             }
+         }
+     }
+   if (rc)
+     { /* Still not found:  Try the default DF. */
+       def_home_df = 0x5015;
+-      rc = iso7816_select_file (slot, def_home_df, 1, NULL, NULL);
++      rc = iso7816_select_file (slot, def_home_df, 1);
+     }
+   if (!rc)
+     {
+diff --git a/scd/app.c b/scd/app.c
+index 1d81631..e1c4e10 100644
+--- a/scd/app.c
++++ b/scd/app.c
+@@ -208,9 +208,9 @@ app_new_register (int slot, ctrl_t ctrl, const char *name,
+      We skip this if the undefined application has been requested. */
+   if (!want_undefined)
+     {
+-      err = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL);
++      err = iso7816_select_file (slot, 0x3F00, 1);
+       if (!err)
+-        err = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL);
++        err = iso7816_select_file (slot, 0x2F02, 0);
+       if (!err)
+         err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
+       if (!err)
+diff --git a/scd/iso7816.c b/scd/iso7816.c
+index 6cfa6b6..8f79698 100644
+--- a/scd/iso7816.c
++++ b/scd/iso7816.c
+@@ -138,8 +138,7 @@ iso7816_select_application (int slot, const char *aid, size_t aidlen,
+ 
+ 
+ gpg_error_t
+-iso7816_select_file (int slot, int tag, int is_dir,
+-                     unsigned char **result, size_t *resultlen)
++iso7816_select_file (int slot, int tag, int is_dir)
+ {
+   int sw, p0, p1;
+   unsigned char tagbuf[2];
+@@ -147,41 +146,22 @@ iso7816_select_file (int slot, int tag, int is_dir,
+   tagbuf[0] = (tag >> 8) & 0xff;
+   tagbuf[1] = tag & 0xff;
+ 
+-  if (result || resultlen)
+-    {
+-      *result = NULL;
+-      *resultlen = 0;
+-      return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+-    }
+-  else
+-    {
+-      p0 = (tag == 0x3F00)? 0: is_dir? 1:2;
+-      p1 = 0x0c; /* No FC return. */
+-      sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE,
+-                             p0, p1, 2, (char*)tagbuf );
+-      return map_sw (sw);
+-    }
+-
+-  return 0;
++  p0 = (tag == 0x3F00)? 0: is_dir? 1:2;
++  p1 = 0x0c; /* No FC return. */
++  sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE,
++                         p0, p1, 2, (char*)tagbuf );
++  return map_sw (sw);
+ }
+ 
+ 
+ /* Do a select file command with a direct path. */
+ gpg_error_t
+-iso7816_select_path (int slot, const unsigned short *path, size_t pathlen,
+-                     unsigned char **result, size_t *resultlen)
++iso7816_select_path (int slot, const unsigned short *path, size_t pathlen)
+ {
+   int sw, p0, p1;
+   unsigned char buffer[100];
+   int buflen;
+ 
+-  if (result || resultlen)
+-    {
+-      *result = NULL;
+-      *resultlen = 0;
+-      return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+-    }
+-
+   if (pathlen/2 >= sizeof buffer)
+     return gpg_error (GPG_ERR_TOO_LARGE);
+ 
+diff --git a/scd/iso7816.h b/scd/iso7816.h
+index bcef473..4c71bbd 100644
+--- a/scd/iso7816.h
++++ b/scd/iso7816.h
+@@ -51,11 +51,9 @@ gpg_error_t iso7816_map_sw (int sw);
+ gpg_error_t iso7816_select_application (int slot,
+                                         const char *aid, size_t aidlen,
+                                         unsigned int flags);
+-gpg_error_t iso7816_select_file (int slot, int tag, int is_dir,
+-                                 unsigned char **result, size_t *resultlen);
++gpg_error_t iso7816_select_file (int slot, int tag, int is_dir);
+ gpg_error_t iso7816_select_path (int slot,
+-                                 const unsigned short *path, size_t pathlen,
+-                                 unsigned char **result, size_t *resultlen);
++                                 const unsigned short *path, size_t pathlen);
+ gpg_error_t iso7816_list_directory (int slot, int list_dirs,
+                                     unsigned char **result, size_t *resultlen);
+ gpg_error_t iso7816_apdu_direct (int slot,
+@@ -71,7 +69,7 @@ gpg_error_t iso7816_change_reference_data (int slot, int chvno,
+                                const char *oldchv, size_t oldchvlen,
+                                const char *newchv, size_t newchvlen);
+ gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno,
+-					      int is_exchange,
++                                              int is_exchange,
+                                               pininfo_t *pininfo);
+ gpg_error_t iso7816_reset_retry_counter (int slot, int chvno,
+                                          const char *newchv, size_t newchvlen);
diff --git a/debian/patches/0027-scd-Clean-up-old-code.patch b/debian/patches/0027-scd-Clean-up-old-code.patch
new file mode 100644
index 0000000..d631456
--- /dev/null
+++ b/debian/patches/0027-scd-Clean-up-old-code.patch
@@ -0,0 +1,1355 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Mon, 6 Mar 2017 14:18:06 +0900
+Subject: scd: Clean up old code.
+
+* scd/apdu.c (CT_init, CT_data, CT_close): Remove.
+(ct_error_string, ct_activate_card, close_ct_reader, reset_ct_reader)
+(ct_get_status, ct_send_apdu, open_ct_reader): Remove.
+(new_reader_slot) [NEED_PCSC_WRAPPER]: Remove fd and pid handling.
+(writen, readn): Remove.
+(pcsc_get_status, pcsc_send_apdu, control_pcsc, close_pcsc_reader)
+(reset_pcsc_reader, open_pcsc_reader): Only DIRECT version.
+(apdu_open_one_reader): Remove CT_api handling.
+(apdu_get_status_internal, send_le): Fix to stop warnings.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit cb6337329d3c858c695a7e56e2fc31d9d50ca3fe)
+---
+ scd/apdu.c | 1167 ++----------------------------------------------------------
+ 1 file changed, 22 insertions(+), 1145 deletions(-)
+
+diff --git a/scd/apdu.c b/scd/apdu.c
+index 9df1572..c8ce684 100644
+--- a/scd/apdu.c
++++ b/scd/apdu.c
+@@ -73,16 +73,6 @@ struct dev_list {
+   int idx_max;
+ };
+ 
+-/* Due to conflicting use of threading libraries we usually can't link
+-   against libpcsclite if we are using Pth.  Instead we use a wrapper
+-   program.  Note that with nPth there is no need for a wrapper. */
+-#ifdef USE_PTH  /* Right, plain old Pth.  */
+-#if !defined(HAVE_W32_SYSTEM) && !defined(__CYGWIN__)
+-#define NEED_PCSC_WRAPPER 1
+-#endif
+-#endif
+-
+-
+ #define MAX_READER 4 /* Number of readers we support concurrently. */
+ 
+ 
+@@ -129,11 +119,6 @@ struct reader_table_s {
+     pcsc_dword_t modify_ioctl;
+     int pinmin;
+     int pinmax;
+-#ifdef NEED_PCSC_WRAPPER
+-    int req_fd;
+-    int rsp_fd;
+-    pid_t pid;
+-#endif /*NEED_PCSC_WRAPPER*/
+   } pcsc;
+ #ifdef USE_G10CODE_RAPDU
+   struct {
+@@ -165,14 +150,6 @@ static npth_mutex_t reader_table_lock;
+ #endif
+ 
+ 
+-/* ct API function pointer. */
+-static char (* DLSTDCALL CT_init) (unsigned short ctn, unsigned short Pn);
+-static char (* DLSTDCALL CT_data) (unsigned short ctn, unsigned char *dad,
+-                                   unsigned char *sad, unsigned short lc,
+-                                   unsigned char *cmd, unsigned short *lr,
+-                                   unsigned char *rsp);
+-static char (* DLSTDCALL CT_close) (unsigned short ctn);
+-
+ /* PC/SC constants and function pointer. */
+ #define PCSC_SCOPE_USER      0
+ #define PCSC_SCOPE_TERMINAL  1
+@@ -472,11 +449,6 @@ new_reader_slot (void)
+   reader_table[reader].is_spr532 = 0;
+   reader_table[reader].pinpad_varlen_supported = 0;
+   reader_table[reader].require_get_status = 1;
+-#ifdef NEED_PCSC_WRAPPER
+-  reader_table[reader].pcsc.req_fd = -1;
+-  reader_table[reader].pcsc.rsp_fd = -1;
+-  reader_table[reader].pcsc.pid = (pid_t)(-1);
+-#endif
+   reader_table[reader].pcsc.verify_ioctl = 0;
+   reader_table[reader].pcsc.modify_ioctl = 0;
+   reader_table[reader].pcsc.pinmin = -1;
+@@ -562,268 +534,11 @@ apdu_strerror (int rc)
+       return "unknown status error";
+     }
+ }
+-
+-
+-

+-/*
+-       ct API Interface
+- */
+-
+-static const char *
+-ct_error_string (long err)
+-{
+-  switch (err)
+-    {
+-    case 0: return "okay";
+-    case -1: return "invalid data";
+-    case -8: return "ct error";
+-    case -10: return "transmission error";
+-    case -11: return "memory allocation error";
+-    case -128: return "HTSI error";
+-    default: return "unknown CT-API error";
+-    }
+-}
+-
+-
+-/* Wait for the card in SLOT and activate it.  Return a status word
+-   error or 0 on success. */
+-static int
+-ct_activate_card (int slot)
+-{
+-  int rc;
+-  unsigned char dad[1], sad[1], cmd[11], buf[256];
+-  unsigned short buflen;
+-
+-  /* Check whether card has been inserted. */
+-  dad[0] = 1;     /* Destination address: CT. */
+-  sad[0] = 2;     /* Source address: Host. */
+-
+-  cmd[0] = 0x20;  /* Class byte. */
+-  cmd[1] = 0x13;  /* Request status. */
+-  cmd[2] = 0x00;  /* From kernel. */
+-  cmd[3] = 0x80;  /* Return card's DO. */
+-  cmd[4] = 0x00;
+-
+-  buflen = DIM(buf);
+-
+-  rc = CT_data (slot, dad, sad, 5, cmd, &buflen, buf);
+-  if (rc || buflen < 2 || buf[buflen-2] != 0x90)
+-    {
+-      log_error ("ct_activate_card: can't get status of reader %d: %s\n",
+-                 slot, ct_error_string (rc));
+-      return SW_HOST_CARD_IO_ERROR;
+-    }
+-
+-  /* Connected, now activate the card. */
+-  dad[0] = 1;    /* Destination address: CT. */
+-  sad[0] = 2;    /* Source address: Host. */
+-
+-  cmd[0] = 0x20;  /* Class byte. */
+-  cmd[1] = 0x12;  /* Request ICC. */
+-  cmd[2] = 0x01;  /* From first interface. */
+-  cmd[3] = 0x01;  /* Return card's ATR. */
+-  cmd[4] = 0x00;
+-
+-  buflen = DIM(buf);
+-
+-  rc = CT_data (slot, dad, sad, 5, cmd, &buflen, buf);
+-  if (rc || buflen < 2 || buf[buflen-2] != 0x90)
+-    {
+-      log_error ("ct_activate_card(%d): activation failed: %s\n",
+-                 slot, ct_error_string (rc));
+-      if (!rc)
+-        log_printhex ("  received data:", buf, buflen);
+-      return SW_HOST_CARD_IO_ERROR;
+-    }
+-
+-  /* Store the type and the ATR. */
+-  if (buflen - 2 > DIM (reader_table[0].atr))
+-    {
+-      log_error ("ct_activate_card(%d): ATR too long\n", slot);
+-      return SW_HOST_CARD_IO_ERROR;
+-    }
+-
+-  memcpy (reader_table[slot].atr, buf, buflen - 2);
+-  reader_table[slot].atrlen = buflen - 2;
+-  return 0;
+-}
+-
+-
+-static int
+-close_ct_reader (int slot)
+-{
+-  CT_close (slot);
+-  return 0;
+-}
+-
+-static int
+-reset_ct_reader (int slot)
+-{
+-  /* FIXME: Check is this is sufficient do do a reset. */
+-  return ct_activate_card (slot);
+-}
+-
+-
+-static int
+-ct_get_status (int slot, unsigned int *status, int on_wire)
+-{
+-  (void)slot;
+-  (void)on_wire;
+-  /* The status we returned is wrong but we don't care because ctAPI
+-     is not anymore required.  */
+-  *status = APDU_CARD_USABLE|APDU_CARD_PRESENT|APDU_CARD_ACTIVE;
+-  return 0;
+-}
+-
+-/* Actually send the APDU of length APDULEN to SLOT and return a
+-   maximum of *BUFLEN data in BUFFER, the actual returned size will be
+-   set to BUFLEN.  Returns: CT API error code. */
+-static int
+-ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
+-              unsigned char *buffer, size_t *buflen, pininfo_t *pininfo)
+-{
+-  int rc;
+-  unsigned char dad[1], sad[1];
+-  unsigned short ctbuflen;
+-
+-  (void)pininfo;
+-
+-  /* If we don't have an ATR, we need to reset the reader first. */
+-  if (!reader_table[slot].atrlen
+-      && (rc = reset_ct_reader (slot)))
+-    return rc;
+-
+-  dad[0] = 0;     /* Destination address: Card. */
+-  sad[0] = 2;     /* Source address: Host. */
+-  ctbuflen = *buflen;
+-  if (DBG_CARD_IO)
+-    log_printhex ("  CT_data:", apdu, apdulen);
+-  rc = CT_data (slot, dad, sad, apdulen, apdu, &ctbuflen, buffer);
+-  *buflen = ctbuflen;
+-
+-  return rc? SW_HOST_CARD_IO_ERROR: 0;
+-}
+-
+-
+-
+-/* Open a reader and return an internal handle for it.  PORT is a
+-   non-negative value with the port number of the reader. USB readers
+-   do have port numbers starting at 32769. */
+-static int
+-open_ct_reader (int port)
+-{
+-  int rc, reader;
+-
+-  if (port < 0 || port > 0xffff)
+-    {
+-      log_error ("open_ct_reader: invalid port %d requested\n", port);
+-      return -1;
+-    }
+-  reader = new_reader_slot ();
+-  if (reader == -1)
+-    return reader;
+-  reader_table[reader].port = port;
+-
+-  rc = CT_init (reader, (unsigned short)port);
+-  if (rc)
+-    {
+-      log_error ("apdu_open_ct_reader failed on port %d: %s\n",
+-                 port, ct_error_string (rc));
+-      reader_table[reader].used = 0;
+-      unlock_slot (reader);
+-      return -1;
+-    }
+-
+-  /* Only try to activate the card. */
+-  rc = ct_activate_card (reader);
+-  if (rc)
+-    {
+-      reader_table[reader].atrlen = 0;
+-      rc = 0;
+-    }
+-
+-  reader_table[reader].close_reader = close_ct_reader;
+-  reader_table[reader].reset_reader = reset_ct_reader;
+-  reader_table[reader].get_status_reader = ct_get_status;
+-  reader_table[reader].send_apdu_reader = ct_send_apdu;
+-  reader_table[reader].check_pinpad = NULL;
+-  reader_table[reader].dump_status_reader = NULL;
+-  reader_table[reader].pinpad_verify = NULL;
+-  reader_table[reader].pinpad_modify = NULL;
+-
+-  dump_reader_status (reader);
+-  unlock_slot (reader);
+-  return reader;
+-}
+-
+ 

+ /*
+        PC/SC Interface
+  */
+ 
+-#ifdef NEED_PCSC_WRAPPER
+-static int
+-writen (int fd, const void *buf, size_t nbytes)
+-{
+-  size_t nleft = nbytes;
+-  int nwritten;
+-
+-/*   log_printhex (" writen:", buf, nbytes); */
+-
+-  while (nleft > 0)
+-    {
+-#ifdef USE_NPTH
+-      nwritten = npth_write (fd, buf, nleft);
+-#else
+-      nwritten = write (fd, buf, nleft);
+-#endif
+-      if (nwritten < 0 && errno == EINTR)
+-        continue;
+-      if (nwritten < 0)
+-        return -1;
+-      nleft -= nwritten;
+-      buf = (const char*)buf + nwritten;
+-    }
+-  return 0;
+-}
+-
+-/* Read up to BUFLEN bytes from FD and return the number of bytes
+-   actually read in NREAD.  Returns -1 on error or 0 on success. */
+-static int
+-readn (int fd, void *buf, size_t buflen, size_t *nread)
+-{
+-  size_t nleft = buflen;
+-  int n;
+-/*   void *orig_buf = buf; */
+-
+-  while (nleft > 0)
+-    {
+-#ifdef USE_NPTH
+-# ifdef HAVE_W32_SYSTEM
+-#  error Cannot use npth_read here because it expects a system HANDLE.
+-# endif
+-      n = npth_read (fd, buf, nleft);
+-#else
+-      n = read (fd, buf, nleft);
+-#endif
+-      if (n < 0 && errno == EINTR)
+-        continue;
+-      if (n < 0)
+-        return -1; /* read error. */
+-      if (!n)
+-        break; /* EOF */
+-      nleft -= n;
+-      buf = (char*)buf + n;
+-    }
+-  if (nread)
+-    *nread = buflen - nleft;
+-
+-/*   log_printhex ("  readn:", orig_buf, *nread); */
+-
+-  return 0;
+-}
+-#endif /*NEED_PCSC_WRAPPER*/
+-
+ static const char *
+ pcsc_error_string (long err)
+ {
+@@ -928,9 +643,8 @@ dump_pcsc_reader_status (int slot)
+ }
+ 
+ 
+-#ifndef NEED_PCSC_WRAPPER
+ static int
+-pcsc_get_status_direct (int slot, unsigned int *status, int on_wire)
++pcsc_get_status (int slot, unsigned int *status, int on_wire)
+ {
+   long err;
+   struct pcsc_readerstate_s rdrstates[1];
+@@ -989,136 +703,15 @@ pcsc_get_status_direct (int slot, unsigned int *status, int on_wire)
+ 
+   return 0;
+ }
+-#endif /*!NEED_PCSC_WRAPPER*/
+-
+-
+-#ifdef NEED_PCSC_WRAPPER
+-static int
+-pcsc_get_status_wrapped (int slot, unsigned int *status, int on_wire)
+-{
+-  long err;
+-  reader_table_t slotp;
+-  size_t len, full_len;
+-  int i, n;
+-  unsigned char msgbuf[9];
+-  unsigned char buffer[16];
+-  int sw = SW_HOST_CARD_IO_ERROR;
+-
+-  (void)on_wire;
+-  slotp = reader_table + slot;
+-
+-  if (slotp->pcsc.req_fd == -1
+-      || slotp->pcsc.rsp_fd == -1
+-      || slotp->pcsc.pid == (pid_t)(-1) )
+-    {
+-      log_error ("pcsc_get_status: pcsc-wrapper not running\n");
+-      return sw;
+-    }
+-
+-  msgbuf[0] = 0x04; /* STATUS command. */
+-  len = 0;
+-  msgbuf[1] = (len >> 24);
+-  msgbuf[2] = (len >> 16);
+-  msgbuf[3] = (len >>  8);
+-  msgbuf[4] = (len      );
+-  if ( writen (slotp->pcsc.req_fd, msgbuf, 5) )
+-    {
+-      log_error ("error sending PC/SC STATUS request: %s\n",
+-                 strerror (errno));
+-      goto command_failed;
+-    }
+-
+-  /* Read the response. */
+-  if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
+-    {
+-      log_error ("error receiving PC/SC STATUS response: %s\n",
+-                 i? strerror (errno) : "premature EOF");
+-      goto command_failed;
+-    }
+-  len = buf_to_size_t (msgbuf+1);
+-  if (msgbuf[0] != 0x81 || len < 4)
+-    {
+-      log_error ("invalid response header from PC/SC received\n");
+-      goto command_failed;
+-    }
+-  len -= 4; /* Already read the error code. */
+-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+-  if (err)
+-    {
+-      log_error ("pcsc_status failed: %s (0x%lx)\n",
+-                 pcsc_error_string (err), err);
+-      /* This is a proper error code, so return immediately.  */
+-      return pcsc_error_to_sw (err);
+-    }
+-
+-  full_len = len;
+-
+-  /* The current version returns 3 words but we allow also for old
+-     versions returning only 2 words. */
+-  n = 12 < len ? 12 : len;
+-  if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len))
+-      || (len != 8 && len != 12))
+-    {
+-      log_error ("error receiving PC/SC STATUS response: %s\n",
+-                 i? strerror (errno) : "premature EOF");
+-      goto command_failed;
+-    }
+-
+-  slotp->is_t0 = (len == 12 && !!(buffer[11] & PCSC_PROTOCOL_T0));
+-
+-
+-  full_len -= len;
+-  /* Newer versions of the wrapper might send more status bytes.
+-     Read them. */
+-  while (full_len)
+-    {
+-      unsigned char dummybuf[128];
+-
+-      n = full_len < DIM (dummybuf) ? full_len : DIM (dummybuf);
+-      if ((i=readn (slotp->pcsc.rsp_fd, dummybuf, n, &len)) || len != n)
+-        {
+-          log_error ("error receiving PC/SC TRANSMIT response: %s\n",
+-                     i? strerror (errno) : "premature EOF");
+-          goto command_failed;
+-        }
+-      full_len -= n;
+-    }
+-
+-  /* We are lucky: The wrapper already returns the data in the
+-     required format. */
+-  *status = buffer[3];
+-  return 0;
+-
+- command_failed:
+-  close (slotp->pcsc.req_fd);
+-  close (slotp->pcsc.rsp_fd);
+-  slotp->pcsc.req_fd = -1;
+-  slotp->pcsc.rsp_fd = -1;
+-  if (slotp->pcsc.pid != -1)
+-    kill (slotp->pcsc.pid, SIGTERM);
+-  slotp->pcsc.pid = (pid_t)(-1);
+-  slotp->used = 0;
+-  return sw;
+-}
+-#endif /*NEED_PCSC_WRAPPER*/
+ 
+ 
++/* Send the APDU of length APDULEN to SLOT and return a maximum of
++   *BUFLEN data in BUFFER, the actual returned size will be stored at
++   BUFLEN.  Returns: A status word. */
+ static int
+-pcsc_get_status (int slot, unsigned int *status, int on_wire)
+-{
+-#ifdef NEED_PCSC_WRAPPER
+-  return pcsc_get_status_wrapped (slot, status, on_wire);
+-#else
+-  return pcsc_get_status_direct (slot, status, on_wire);
+-#endif
+-}
+-
+-
+-#ifndef NEED_PCSC_WRAPPER
+-static int
+-pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen,
+-                       unsigned char *buffer, size_t *buflen,
+-                       pininfo_t *pininfo)
++pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
++                unsigned char *buffer, size_t *buflen,
++                pininfo_t *pininfo)
+ {
+   long err;
+   struct pcsc_io_request_s send_pci;
+@@ -1149,270 +742,6 @@ pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen,
+ 
+   return pcsc_error_to_sw (err);
+ }
+-#endif /*!NEED_PCSC_WRAPPER*/
+-
+-
+-#ifdef NEED_PCSC_WRAPPER
+-static int
+-pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen,
+-                        unsigned char *buffer, size_t *buflen,
+-                        pininfo_t *pininfo)
+-{
+-  long err;
+-  reader_table_t slotp;
+-  size_t len, full_len;
+-  int i, n;
+-  unsigned char msgbuf[9];
+-  int sw = SW_HOST_CARD_IO_ERROR;
+-
+-  (void)pininfo;
+-
+-  if (!reader_table[slot].atrlen
+-      && (err = reset_pcsc_reader (slot)))
+-    return err;
+-
+-  if (DBG_CARD_IO)
+-    log_printhex ("  PCSC_data:", apdu, apdulen);
+-
+-  slotp = reader_table + slot;
+-
+-  if (slotp->pcsc.req_fd == -1
+-      || slotp->pcsc.rsp_fd == -1
+-      || slotp->pcsc.pid == (pid_t)(-1) )
+-    {
+-      log_error ("pcsc_send_apdu: pcsc-wrapper not running\n");
+-      return sw;
+-    }
+-
+-  msgbuf[0] = 0x03; /* TRANSMIT command. */
+-  len = apdulen;
+-  msgbuf[1] = (len >> 24);
+-  msgbuf[2] = (len >> 16);
+-  msgbuf[3] = (len >>  8);
+-  msgbuf[4] = (len      );
+-  if ( writen (slotp->pcsc.req_fd, msgbuf, 5)
+-       || writen (slotp->pcsc.req_fd, apdu, len))
+-    {
+-      log_error ("error sending PC/SC TRANSMIT request: %s\n",
+-                 strerror (errno));
+-      goto command_failed;
+-    }
+-
+-  /* Read the response. */
+-  if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
+-    {
+-      log_error ("error receiving PC/SC TRANSMIT response: %s\n",
+-                 i? strerror (errno) : "premature EOF");
+-      goto command_failed;
+-    }
+-  len = buf_to_size_t (msgbuf+1);
+-  if (msgbuf[0] != 0x81 || len < 4)
+-    {
+-      log_error ("invalid response header from PC/SC received\n");
+-      goto command_failed;
+-    }
+-  len -= 4; /* Already read the error code. */
+-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+-  if (err)
+-    {
+-      log_error ("pcsc_transmit failed: %s (0x%lx)\n",
+-                 pcsc_error_string (err), err);
+-      return pcsc_error_to_sw (err);
+-    }
+-
+-   full_len = len;
+-
+-   n = *buflen < len ? *buflen : len;
+-   if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n)
+-     {
+-       log_error ("error receiving PC/SC TRANSMIT response: %s\n",
+-                  i? strerror (errno) : "premature EOF");
+-       goto command_failed;
+-     }
+-   *buflen = n;
+-
+-   full_len -= len;
+-   if (full_len)
+-     {
+-       log_error ("pcsc_send_apdu: provided buffer too short - truncated\n");
+-       err = SW_HOST_INV_VALUE;
+-     }
+-   /* We need to read any rest of the response, to keep the
+-      protocol running.  */
+-   while (full_len)
+-     {
+-       unsigned char dummybuf[128];
+-
+-       n = full_len < DIM (dummybuf) ? full_len : DIM (dummybuf);
+-       if ((i=readn (slotp->pcsc.rsp_fd, dummybuf, n, &len)) || len != n)
+-         {
+-           log_error ("error receiving PC/SC TRANSMIT response: %s\n",
+-                      i? strerror (errno) : "premature EOF");
+-           goto command_failed;
+-         }
+-       full_len -= n;
+-     }
+-
+-   return err;
+-
+- command_failed:
+-  close (slotp->pcsc.req_fd);
+-  close (slotp->pcsc.rsp_fd);
+-  slotp->pcsc.req_fd = -1;
+-  slotp->pcsc.rsp_fd = -1;
+-  if (slotp->pcsc.pid != -1)
+-    kill (slotp->pcsc.pid, SIGTERM);
+-  slotp->pcsc.pid = (pid_t)(-1);
+-  slotp->used = 0;
+-  return sw;
+-}
+-#endif /*NEED_PCSC_WRAPPER*/
+-
+-
+-/* Send the APDU of length APDULEN to SLOT and return a maximum of
+-   *BUFLEN data in BUFFER, the actual returned size will be stored at
+-   BUFLEN.  Returns: A status word. */
+-static int
+-pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
+-                unsigned char *buffer, size_t *buflen,
+-                pininfo_t *pininfo)
+-{
+-#ifdef NEED_PCSC_WRAPPER
+-  return pcsc_send_apdu_wrapped (slot, apdu, apdulen, buffer, buflen, pininfo);
+-#else
+-  return pcsc_send_apdu_direct (slot, apdu, apdulen, buffer, buflen, pininfo);
+-#endif
+-}
+-
+-
+-#ifndef NEED_PCSC_WRAPPER
+-static int
+-control_pcsc_direct (int slot, pcsc_dword_t ioctl_code,
+-                     const unsigned char *cntlbuf, size_t len,
+-                     unsigned char *buffer, pcsc_dword_t *buflen)
+-{
+-  long err;
+-
+-  err = pcsc_control (reader_table[slot].pcsc.card, ioctl_code,
+-                      cntlbuf, len, buffer, buflen? *buflen:0, buflen);
+-  if (err)
+-    {
+-      log_error ("pcsc_control failed: %s (0x%lx)\n",
+-                 pcsc_error_string (err), err);
+-      return pcsc_error_to_sw (err);
+-    }
+-
+-  return 0;
+-}
+-#endif /*!NEED_PCSC_WRAPPER*/
+-
+-
+-#ifdef NEED_PCSC_WRAPPER
+-static int
+-control_pcsc_wrapped (int slot, pcsc_dword_t ioctl_code,
+-                      const unsigned char *cntlbuf, size_t len,
+-                      unsigned char *buffer, pcsc_dword_t *buflen)
+-{
+-  long err = PCSC_E_NOT_TRANSACTED;
+-  reader_table_t slotp;
+-  unsigned char msgbuf[9];
+-  int i, n;
+-  size_t full_len;
+-
+-  slotp = reader_table + slot;
+-
+-  msgbuf[0] = 0x06; /* CONTROL command. */
+-  msgbuf[1] = ((len + 4) >> 24);
+-  msgbuf[2] = ((len + 4) >> 16);
+-  msgbuf[3] = ((len + 4) >>  8);
+-  msgbuf[4] = ((len + 4)      );
+-  msgbuf[5] = (ioctl_code >> 24);
+-  msgbuf[6] = (ioctl_code >> 16);
+-  msgbuf[7] = (ioctl_code >>  8);
+-  msgbuf[8] = (ioctl_code      );
+-  if ( writen (slotp->pcsc.req_fd, msgbuf, 9)
+-       || writen (slotp->pcsc.req_fd, cntlbuf, len))
+-    {
+-      log_error ("error sending PC/SC CONTROL request: %s\n",
+-                 strerror (errno));
+-      goto command_failed;
+-    }
+-
+-  /* Read the response. */
+-  if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
+-    {
+-      log_error ("error receiving PC/SC CONTROL response: %s\n",
+-                 i? strerror (errno) : "premature EOF");
+-      goto command_failed;
+-    }
+-  len = buf32_to_size_t (msgbuf+1);
+-  if (msgbuf[0] != 0x81 || len < 4)
+-    {
+-      log_error ("invalid response header from PC/SC received\n");
+-      goto command_failed;
+-    }
+-  len -= 4; /* Already read the error code. */
+-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+-  if (err)
+-    {
+-      log_error ("pcsc_control failed: %s (0x%lx)\n",
+-                 pcsc_error_string (err), err);
+-      return pcsc_error_to_sw (err);
+-    }
+-
+-  full_len = len;
+-
+-  if (buflen)
+-    n = *buflen < len ? *buflen : len;
+-  else
+-    n = 0;
+-  if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n)
+-    {
+-      log_error ("error receiving PC/SC CONTROL response: %s\n",
+-                 i? strerror (errno) : "premature EOF");
+-      goto command_failed;
+-    }
+-  if (buflen)
+-    *buflen = n;
+-
+-  full_len -= len;
+-  if (full_len)
+-    {
+-      log_error ("pcsc_send_apdu: provided buffer too short - truncated\n");
+-      err = PCSC_E_INVALID_VALUE;
+-    }
+-  /* We need to read any rest of the response, to keep the
+-     protocol running.  */
+-  while (full_len)
+-    {
+-      unsigned char dummybuf[128];
+-
+-      n = full_len < DIM (dummybuf) ? full_len : DIM (dummybuf);
+-      if ((i=readn (slotp->pcsc.rsp_fd, dummybuf, n, &len)) || len != n)
+-        {
+-          log_error ("error receiving PC/SC CONTROL response: %s\n",
+-                     i? strerror (errno) : "premature EOF");
+-          goto command_failed;
+-        }
+-      full_len -= n;
+-    }
+-
+-  if (!err)
+-    return 0;
+-
+- command_failed:
+-  close (slotp->pcsc.req_fd);
+-  close (slotp->pcsc.rsp_fd);
+-  slotp->pcsc.req_fd = -1;
+-  slotp->pcsc.rsp_fd = -1;
+-  if (slotp->pcsc.pid != -1)
+-    kill (slotp->pcsc.pid, SIGTERM);
+-  slotp->pcsc.pid = (pid_t)(-1);
+-  slotp->used = 0;
+-  return pcsc_error_to_sw (err);
+-}
+-#endif /*NEED_PCSC_WRAPPER*/
+-
+ 
+ 
+ /* Do some control with the value of IOCTL_CODE to the card inserted
+@@ -1425,106 +754,30 @@ control_pcsc (int slot, pcsc_dword_t ioctl_code,
+               const unsigned char *cntlbuf, size_t len,
+               unsigned char *buffer, pcsc_dword_t *buflen)
+ {
+-#ifdef NEED_PCSC_WRAPPER
+-  return control_pcsc_wrapped (slot, ioctl_code, cntlbuf, len, buffer, buflen);
+-#else
+-  return control_pcsc_direct (slot, ioctl_code, cntlbuf, len, buffer, buflen);
+-#endif
+-}
+-
+-
+-#ifndef NEED_PCSC_WRAPPER
+-static int
+-close_pcsc_reader_direct (int slot)
+-{
+-  pcsc_release_context (reader_table[slot].pcsc.context);
+-  return 0;
+-}
+-#endif /*!NEED_PCSC_WRAPPER*/
+-
+-
+-#ifdef NEED_PCSC_WRAPPER
+-static int
+-close_pcsc_reader_wrapped (int slot)
+-{
+   long err;
+-  reader_table_t slotp;
+-  size_t len;
+-  int i;
+-  unsigned char msgbuf[9];
+-
+-  slotp = reader_table + slot;
+ 
+-  if (slotp->pcsc.req_fd == -1
+-      || slotp->pcsc.rsp_fd == -1
+-      || slotp->pcsc.pid == (pid_t)(-1) )
+-    {
+-      log_error ("close_pcsc_reader: pcsc-wrapper not running\n");
+-      return 0;
+-    }
+-
+-  msgbuf[0] = 0x02; /* CLOSE command. */
+-  len = 0;
+-  msgbuf[1] = (len >> 24);
+-  msgbuf[2] = (len >> 16);
+-  msgbuf[3] = (len >>  8);
+-  msgbuf[4] = (len      );
+-  if ( writen (slotp->pcsc.req_fd, msgbuf, 5) )
+-    {
+-      log_error ("error sending PC/SC CLOSE request: %s\n",
+-                 strerror (errno));
+-      goto command_failed;
+-    }
+-
+-  /* Read the response. */
+-  if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
+-    {
+-      log_error ("error receiving PC/SC CLOSE response: %s\n",
+-                 i? strerror (errno) : "premature EOF");
+-      goto command_failed;
+-    }
+-  len = buf32_to_size_t (msgbuf+1);
+-  if (msgbuf[0] != 0x81 || len < 4)
++  err = pcsc_control (reader_table[slot].pcsc.card, ioctl_code,
++                      cntlbuf, len, buffer, buflen? *buflen:0, buflen);
++  if (err)
+     {
+-      log_error ("invalid response header from PC/SC received\n");
+-      goto command_failed;
++      log_error ("pcsc_control failed: %s (0x%lx)\n",
++                 pcsc_error_string (err), err);
++      return pcsc_error_to_sw (err);
+     }
+-  len -= 4; /* Already read the error code. */
+-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+-  if (err)
+-    log_error ("pcsc_close failed: %s (0x%lx)\n",
+-               pcsc_error_string (err), err);
+ 
+-  /* We will close the wrapper in any case - errors are merely
+-     informational. */
+-
+- command_failed:
+-  close (slotp->pcsc.req_fd);
+-  close (slotp->pcsc.rsp_fd);
+-  slotp->pcsc.req_fd = -1;
+-  slotp->pcsc.rsp_fd = -1;
+-  if (slotp->pcsc.pid != -1)
+-    kill (slotp->pcsc.pid, SIGTERM);
+-  slotp->pcsc.pid = (pid_t)(-1);
+-  slotp->used = 0;
+   return 0;
+ }
+-#endif /*NEED_PCSC_WRAPPER*/
+ 
+ 
+ static int
+ close_pcsc_reader (int slot)
+ {
+-#ifdef NEED_PCSC_WRAPPER
+-  return close_pcsc_reader_wrapped (slot);
+-#else
+-  return close_pcsc_reader_direct (slot);
+-#endif
++  pcsc_release_context (reader_table[slot].pcsc.context);
++  return 0;
+ }
+ 
+ 
+ /* Connect a PC/SC card.  */
+-#ifndef NEED_PCSC_WRAPPER
+ static int
+ connect_pcsc_card (int slot)
+ {
+@@ -1580,12 +833,8 @@ connect_pcsc_card (int slot)
+   dump_reader_status (slot);
+   return pcsc_error_to_sw (err);
+ }
+-#endif /*!NEED_PCSC_WRAPPER*/
+ 
+ 
+-/* Disconnect a PC/SC card.  Note that this succeeds even if the card
+-   is not connected.  */
+-#ifndef NEED_PCSC_WRAPPER
+ static int
+ disconnect_pcsc_card (int slot)
+ {
+@@ -1606,12 +855,12 @@ disconnect_pcsc_card (int slot)
+   reader_table[slot].pcsc.card = 0;
+   return 0;
+ }
+-#endif /*!NEED_PCSC_WRAPPER*/
+ 
+ 
+-#ifndef NEED_PCSC_WRAPPER
++/* Send an PC/SC reset command and return a status word on error or 0
++   on success. */
+ static int
+-reset_pcsc_reader_direct (int slot)
++reset_pcsc_reader (int slot)
+ {
+   int sw;
+ 
+@@ -1621,122 +870,6 @@ reset_pcsc_reader_direct (int slot)
+ 
+   return sw;
+ }
+-#endif /*NEED_PCSC_WRAPPER*/
+-
+-
+-#ifdef NEED_PCSC_WRAPPER
+-static int
+-reset_pcsc_reader_wrapped (int slot)
+-{
+-  long err;
+-  reader_table_t slotp;
+-  size_t len;
+-  int i, n;
+-  unsigned char msgbuf[9];
+-  unsigned int dummy_status;
+-  int sw = SW_HOST_CARD_IO_ERROR;
+-
+-  slotp = reader_table + slot;
+-
+-  if (slotp->pcsc.req_fd == -1
+-      || slotp->pcsc.rsp_fd == -1
+-      || slotp->pcsc.pid == (pid_t)(-1) )
+-    {
+-      log_error ("pcsc_get_status: pcsc-wrapper not running\n");
+-      return sw;
+-    }
+-
+-  msgbuf[0] = 0x05; /* RESET command. */
+-  len = 0;
+-  msgbuf[1] = (len >> 24);
+-  msgbuf[2] = (len >> 16);
+-  msgbuf[3] = (len >>  8);
+-  msgbuf[4] = (len      );
+-  if ( writen (slotp->pcsc.req_fd, msgbuf, 5) )
+-    {
+-      log_error ("error sending PC/SC RESET request: %s\n",
+-                 strerror (errno));
+-      goto command_failed;
+-    }
+-
+-  /* Read the response. */
+-  if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
+-    {
+-      log_error ("error receiving PC/SC RESET response: %s\n",
+-                 i? strerror (errno) : "premature EOF");
+-      goto command_failed;
+-    }
+-  len = buf32_to_size_t (msgbuf+1);
+-  if (msgbuf[0] != 0x81 || len < 4)
+-    {
+-      log_error ("invalid response header from PC/SC received\n");
+-      goto command_failed;
+-    }
+-  len -= 4; /* Already read the error code. */
+-  if (len > DIM (slotp->atr))
+-    {
+-      log_error ("PC/SC returned a too large ATR (len=%lx)\n",
+-                 (unsigned long)len);
+-      sw = SW_HOST_GENERAL_ERROR;
+-      goto command_failed;
+-    }
+-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+-  if (err)
+-    {
+-      log_error ("PC/SC RESET failed: %s (0x%lx)\n",
+-                 pcsc_error_string (err), err);
+-      /* If the error code is no smart card, we should not considere
+-         this a major error and close the wrapper.  */
+-      sw = pcsc_error_to_sw (err);
+-      if (err == PCSC_E_NO_SMARTCARD)
+-        return sw;
+-      goto command_failed;
+-    }
+-
+-  /* The open function may return a zero for the ATR length to
+-     indicate that no card is present.  */
+-  n = len;
+-  if (n)
+-    {
+-      if ((i=readn (slotp->pcsc.rsp_fd, slotp->atr, n, &len)) || len != n)
+-        {
+-          log_error ("error receiving PC/SC RESET response: %s\n",
+-                     i? strerror (errno) : "premature EOF");
+-          goto command_failed;
+-        }
+-    }
+-  slotp->atrlen = len;
+-
+-  /* Read the status so that IS_T0 will be set. */
+-  pcsc_get_status (slot, &dummy_status, 1);
+-
+-  return 0;
+-
+- command_failed:
+-  close (slotp->pcsc.req_fd);
+-  close (slotp->pcsc.rsp_fd);
+-  slotp->pcsc.req_fd = -1;
+-  slotp->pcsc.rsp_fd = -1;
+-  if (slotp->pcsc.pid != -1)
+-    kill (slotp->pcsc.pid, SIGTERM);
+-  slotp->pcsc.pid = (pid_t)(-1);
+-  slotp->used = 0;
+-  return sw;
+-}
+-#endif /* !NEED_PCSC_WRAPPER */
+-
+-
+-/* Send an PC/SC reset command and return a status word on error or 0
+-   on success. */
+-static int
+-reset_pcsc_reader (int slot)
+-{
+-#ifdef NEED_PCSC_WRAPPER
+-  return reset_pcsc_reader_wrapped (slot);
+-#else
+-  return reset_pcsc_reader_direct (slot);
+-#endif
+-}
+ 
+ 
+ /* Examine reader specific parameters and initialize.  This is mostly
+@@ -1894,9 +1027,8 @@ pcsc_vendor_specific_init (int slot)
+ 
+ /* Open the PC/SC reader without using the wrapper.  Returns -1 on
+    error or a slot number for the reader.  */
+-#ifndef NEED_PCSC_WRAPPER
+ static int
+-open_pcsc_reader_direct (const char *portstr)
++open_pcsc_reader (const char *portstr)
+ {
+   long err;
+   int slot;
+@@ -1996,229 +1128,6 @@ open_pcsc_reader_direct (const char *portstr)
+   unlock_slot (slot);
+   return slot;
+ }
+-#endif /*!NEED_PCSC_WRAPPER */
+-
+-
+-/* Open the PC/SC reader using the pcsc_wrapper program.  This is
+-   needed to cope with different thread models and other peculiarities
+-   of libpcsclite. */
+-#ifdef NEED_PCSC_WRAPPER
+-static int
+-open_pcsc_reader_wrapped (const char *portstr)
+-{
+-  int slot;
+-  reader_table_t slotp;
+-  int fd, rp[2], wp[2];
+-  int n, i;
+-  pid_t pid;
+-  size_t len;
+-  unsigned char msgbuf[9];
+-  int err;
+-  unsigned int dummy_status;
+-
+-  /* Note that we use the constant and not the function because this
+-     code won't be used under Windows.  */
+-  const char *wrapperpgm = GNUPG_LIBEXECDIR "/gnupg-pcsc-wrapper";
+-
+-  if (access (wrapperpgm, X_OK))
+-    {
+-      log_error ("can't run PC/SC access module '%s': %s\n",
+-                 wrapperpgm, strerror (errno));
+-      return -1;
+-    }
+-
+-  slot = new_reader_slot ();
+-  if (slot == -1)
+-    return -1;
+-  slotp = reader_table + slot;
+-
+-  /* Fire up the PC/SCc wrapper.  We don't use any fork/exec code from
+-     the common directy but implement it directly so that this file
+-     may still be source copied. */
+-
+-  if (pipe (rp) == -1)
+-    {
+-      log_error ("error creating a pipe: %s\n", strerror (errno));
+-      slotp->used = 0;
+-      unlock_slot (slot);
+-      return -1;
+-    }
+-  if (pipe (wp) == -1)
+-    {
+-      log_error ("error creating a pipe: %s\n", strerror (errno));
+-      close (rp[0]);
+-      close (rp[1]);
+-      slotp->used = 0;
+-      unlock_slot (slot);
+-      return -1;
+-    }
+-
+-  pid = fork ();
+-  if (pid == -1)
+-    {
+-      log_error ("error forking process: %s\n", strerror (errno));
+-      close (rp[0]);
+-      close (rp[1]);
+-      close (wp[0]);
+-      close (wp[1]);
+-      slotp->used = 0;
+-      unlock_slot (slot);
+-      return -1;
+-    }
+-  slotp->pcsc.pid = pid;
+-
+-  if (!pid)
+-    { /*
+-         === Child ===
+-       */
+-
+-      /* Double fork. */
+-      pid = fork ();
+-      if (pid == -1)
+-        _exit (31);
+-      if (pid)
+-        _exit (0); /* Immediate exit this parent, so that the child
+-                      gets cleaned up by the init process. */
+-
+-      /* Connect our pipes. */
+-      if (wp[0] != 0 && dup2 (wp[0], 0) == -1)
+-        log_fatal ("dup2 stdin failed: %s\n", strerror (errno));
+-      if (rp[1] != 1 && dup2 (rp[1], 1) == -1)
+-        log_fatal ("dup2 stdout failed: %s\n", strerror (errno));
+-
+-      /* Send stderr to the bit bucket. */
+-      fd = open ("/dev/null", O_WRONLY);
+-      if (fd == -1)
+-        log_fatal ("can't open '/dev/null': %s", strerror (errno));
+-      if (fd != 2 && dup2 (fd, 2) == -1)
+-        log_fatal ("dup2 stderr failed: %s\n", strerror (errno));
+-
+-      /* Close all other files. */
+-      close_all_fds (3, NULL);
+-
+-      execl (wrapperpgm,
+-             "pcsc-wrapper",
+-             "--",
+-             "1", /* API version */
+-             opt.pcsc_driver, /* Name of the PC/SC library. */
+-              NULL);
+-      _exit (31);
+-    }
+-
+-  /*
+-     === Parent ===
+-   */
+-  close (wp[0]);
+-  close (rp[1]);
+-  slotp->pcsc.req_fd = wp[1];
+-  slotp->pcsc.rsp_fd = rp[0];
+-
+-  /* Wait for the intermediate child to terminate. */
+-#ifdef USE_NPTH
+-#define WAIT npth_waitpid
+-#else
+-#define WAIT waitpid
+-#endif
+-  while ( (i=WAIT (pid, NULL, 0)) == -1 && errno == EINTR)
+-    ;
+-#undef WAIT
+-
+-  /* Now send the open request. */
+-  msgbuf[0] = 0x01; /* OPEN command. */
+-  len = portstr? strlen (portstr):0;
+-  msgbuf[1] = (len >> 24);
+-  msgbuf[2] = (len >> 16);
+-  msgbuf[3] = (len >>  8);
+-  msgbuf[4] = (len      );
+-  if ( writen (slotp->pcsc.req_fd, msgbuf, 5)
+-       || (portstr && writen (slotp->pcsc.req_fd, portstr, len)))
+-    {
+-      log_error ("error sending PC/SC OPEN request: %s\n",
+-                 strerror (errno));
+-      goto command_failed;
+-    }
+-  /* Read the response. */
+-  if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
+-    {
+-      log_error ("error receiving PC/SC OPEN response: %s\n",
+-                 i? strerror (errno) : "premature EOF");
+-      goto command_failed;
+-    }
+-  len = buf32_to_size_t (msgbuf+1);
+-  if (msgbuf[0] != 0x81 || len < 4)
+-    {
+-      log_error ("invalid response header from PC/SC received\n");
+-      goto command_failed;
+-    }
+-  len -= 4; /* Already read the error code. */
+-  if (len > DIM (slotp->atr))
+-    {
+-      log_error ("PC/SC returned a too large ATR (len=%lx)\n",
+-                 (unsigned long)len);
+-      goto command_failed;
+-    }
+-  err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
+-  if (err)
+-    {
+-      log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err));
+-      goto command_failed;
+-    }
+-
+-  /* The open request may return a zero for the ATR length to
+-     indicate that no card is present.  */
+-  n = len;
+-  if (n)
+-    {
+-      if ((i=readn (slotp->pcsc.rsp_fd, slotp->atr, n, &len)) || len != n)
+-        {
+-          log_error ("error receiving PC/SC OPEN response: %s\n",
+-                     i? strerror (errno) : "premature EOF");
+-          goto command_failed;
+-        }
+-    }
+-  slotp->atrlen = len;
+-
+-  reader_table[slot].close_reader = close_pcsc_reader;
+-  reader_table[slot].reset_reader = reset_pcsc_reader;
+-  reader_table[slot].get_status_reader = pcsc_get_status;
+-  reader_table[slot].send_apdu_reader = pcsc_send_apdu;
+-  reader_table[slot].dump_status_reader = dump_pcsc_reader_status;
+-
+-  pcsc_vendor_specific_init (slot);
+-
+-  /* Read the status so that IS_T0 will be set. */
+-  pcsc_get_status (slot, &dummy_status, 1);
+-
+-  dump_reader_status (slot);
+-  unlock_slot (slot);
+-  return slot;
+-
+- command_failed:
+-  close (slotp->pcsc.req_fd);
+-  close (slotp->pcsc.rsp_fd);
+-  slotp->pcsc.req_fd = -1;
+-  slotp->pcsc.rsp_fd = -1;
+-  if (slotp->pcsc.pid != -1)
+-    kill (slotp->pcsc.pid, SIGTERM);
+-  slotp->pcsc.pid = (pid_t)(-1);
+-  slotp->used = 0;
+-  unlock_slot (slot);
+-  /* There is no way to return SW. */
+-  return -1;
+-
+-}
+-#endif /*NEED_PCSC_WRAPPER*/
+-
+-
+-static int
+-open_pcsc_reader (const char *portstr)
+-{
+-#ifdef NEED_PCSC_WRAPPER
+-  return open_pcsc_reader_wrapped (portstr);
+-#else
+-  return open_pcsc_reader_direct (portstr);
+-#endif
+-}
+ 
+ 
+ /* Check whether the reader supports the ISO command code COMMAND
+@@ -2998,45 +1907,15 @@ apdu_dev_list_finish (struct dev_list *dl)
+ static int
+ apdu_open_one_reader (const char *portstr)
+ {
+-  static int pcsc_api_loaded, ct_api_loaded;
++  static int pcsc_api_loaded;
+   int slot;
+ 
+   if (DBG_READER)
+     log_debug ("enter: apdu_open_reader: portstr=%s\n", portstr);
+ 
+-  if (opt.ctapi_driver && *opt.ctapi_driver)
+-    {
+-      int port = portstr? atoi (portstr) : 32768;
+-
+-      if (!ct_api_loaded)
+-        {
+-          void *handle;
+-
+-          handle = dlopen (opt.ctapi_driver, RTLD_LAZY);
+-          if (!handle)
+-            {
+-              log_error ("apdu_open_reader: failed to open driver: %s\n",
+-                         dlerror ());
+-              return -1;
+-            }
+-          CT_init = dlsym (handle, "CT_init");
+-          CT_data = dlsym (handle, "CT_data");
+-          CT_close = dlsym (handle, "CT_close");
+-          if (!CT_init || !CT_data || !CT_close)
+-            {
+-              log_error ("apdu_open_reader: invalid CT-API driver\n");
+-              dlclose (handle);
+-              return -1;
+-            }
+-          ct_api_loaded = 1;
+-        }
+-      return open_ct_reader (port);
+-    }
+-
+-  /* No ctAPI configured, so lets try the PC/SC API */
++  /* Lets try the PC/SC API */
+   if (!pcsc_api_loaded)
+     {
+-#ifndef NEED_PCSC_WRAPPER
+       void *handle;
+ 
+       handle = dlopen (opt.pcsc_driver, RTLD_LAZY);
+@@ -3115,7 +1994,6 @@ apdu_open_one_reader (const char *portstr)
+           dlclose (handle);
+           return -1;
+         }
+-#endif /*!NEED_PCSC_WRAPPER*/
+       pcsc_api_loaded = 1;
+     }
+ 
+@@ -3569,7 +2447,7 @@ static int
+ apdu_get_status_internal (int slot, int hang, unsigned int *status, int on_wire)
+ {
+   int sw;
+-  unsigned int s;
++  unsigned int s = 0;
+ 
+   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
+     return SW_HOST_NO_DRIVER;
+@@ -3935,7 +2813,6 @@ send_le (int slot, int class, int ins, int p0, int p1,
+     {
+       xfree (apdu_buffer);
+       apdu_buffer = NULL;
+-      apdu_buffer_size = 0;
+     }
+ 
+   /* Store away the returned data but strip the statusword. */
diff --git a/debian/patches/0028-scd-More-cleanup-of-old-code.patch b/debian/patches/0028-scd-More-cleanup-of-old-code.patch
new file mode 100644
index 0000000..8405cc3
--- /dev/null
+++ b/debian/patches/0028-scd-More-cleanup-of-old-code.patch
@@ -0,0 +1,102 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Mon, 6 Mar 2017 14:59:02 +0900
+Subject: scd: More cleanup of old code.
+
+* scd/app-dinsig.c (do_sign): Remove assignment to HASHALGO.
+* scd/app-p15.c (parse_keyusage_flags): Remove assign to MASK.
+(read_ef_aodf): Likewise.
+(read_ef_cdf): Change the control to parse_error.
+* scd/app-sc-hsm.c (parse_keyusage_flags): Remove assign to MASK.
+(read_ef_prkd): Remove assign to S.
+(read_ef_prkd): Check if PRKDF is not null.
+(read_ef_cd): Likewise for CDF.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 9bf39ed75ddbd35908bcd0996f55325ff801619a)
+---
+ scd/app-dinsig.c | 1 -
+ scd/app-p15.c    | 4 +---
+ scd/app-sc-hsm.c | 8 ++++----
+ 3 files changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c
+index 5d65845..f7ecc4b 100644
+--- a/scd/app-dinsig.c
++++ b/scd/app-dinsig.c
+@@ -456,7 +456,6 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
+           /* Fixme: This is a kludge.  A better solution is not to use
+              SHA1 as default but use an autodetection.  However this
+              needs changes in all app-*.c */
+-          hashalgo = GCRY_MD_SHA256;
+           datalen  = indatalen;
+         }
+       else
+diff --git a/scd/app-p15.c b/scd/app-p15.c
+index db8c38e..4072fb7 100644
+--- a/scd/app-p15.c
++++ b/scd/app-p15.c
+@@ -752,7 +752,6 @@ parse_keyusage_flags (const unsigned char *der, size_t derlen,
+       else
+         {
+           bits &= ~mask;
+-          mask = 0;
+         }
+     }
+   else
+@@ -1388,7 +1387,7 @@ read_ef_cdf (app_t app, unsigned short fid, cdf_object_t *result)
+       if (class != CLASS_UNIVERSAL || tag != TAG_SEQUENCE)
+         {
+           errstr = "unsupported reference type";
+-          continue;
++          goto parse_error;
+         }
+       nn = objlen;
+ 
+@@ -1801,7 +1800,6 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
+             else
+               {
+                 bits &= ~mask;
+-                mask = 0;
+               }
+           }
+         if ((bits & 0x80))
+diff --git a/scd/app-sc-hsm.c b/scd/app-sc-hsm.c
+index c582734..dddc8dc 100644
+--- a/scd/app-sc-hsm.c
++++ b/scd/app-sc-hsm.c
+@@ -414,7 +414,6 @@ parse_keyusage_flags (const unsigned char *der, size_t derlen,
+       else
+         {
+           bits &= ~mask;
+-          mask = 0;
+         }
+     }
+   else
+@@ -827,7 +826,6 @@ read_ef_prkd (app_t app, unsigned short fid, prkdf_object_t *prkdresult,
+   if (prkdf->usageflags.non_repudiation)
+     {
+       log_printf ("%snon_repudiation", s);
+-      s = ",";
+     }
+   log_printf ("\n");
+ 
+@@ -891,7 +889,8 @@ read_ef_prkd (app_t app, unsigned short fid, prkdf_object_t *prkdresult,
+     }
+   else
+     {
+-      prkdf->next = *prkdresult;
++      if (prkdf)
++        prkdf->next = *prkdresult;
+       *prkdresult = prkdf;
+       if (cdf)
+         {
+@@ -1112,7 +1111,8 @@ read_ef_cd (app_t app, unsigned short fid, cdf_object_t *result)
+     }
+   else
+     {
+-      cdf->next = *result;
++      if (cdf)
++        cdf->next = *result;
+       *result = cdf;
+     }
+   return err;
diff --git a/debian/patches/0029-scd-Fix-compiler-warnings-for-app-openpgp.c.patch b/debian/patches/0029-scd-Fix-compiler-warnings-for-app-openpgp.c.patch
new file mode 100644
index 0000000..d333e65
--- /dev/null
+++ b/debian/patches/0029-scd-Fix-compiler-warnings-for-app-openpgp.c.patch
@@ -0,0 +1,45 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Mon, 6 Mar 2017 15:14:18 +0900
+Subject: scd: Fix compiler warnings for app-openpgp.c.
+
+* scd/app-openpgp.c (retrieve_key_material): Remove touching I.
+(do_change_pin): Make sure going to leave if PINVALUE == 0.
+(rsa_writekey): Emit simpler log.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit e6ca015ae182a6dbb0466441efc17c99683e9375)
+---
+ scd/app-openpgp.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
+index 5e75d4b..af81dce 100644
+--- a/scd/app-openpgp.c
++++ b/scd/app-openpgp.c
+@@ -1280,7 +1280,6 @@ retrieve_key_material (FILE *fp, const char *hexkeyid,
+ 
+       if ( strcmp (fields[0], "pkd") )
+         continue; /* Not a key data record.  */
+-      i = 0; /* Avoid erroneous compiler warning. */
+       if ( nfields < 4 || (i = atoi (fields[1])) < 0 || i > 1
+            || (!i && m_new) || (i && e_new))
+         {
+@@ -2652,7 +2651,7 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *chvnostr,
+       rc = pincb (pincb_arg, set_resetcode? _("|RN|New Reset Code") :
+                   chvno == 3? _("|AN|New Admin PIN") : _("|N|New PIN"),
+                   &pinvalue);
+-      if (rc)
++      if (rc || pinvalue == NULL)
+         {
+           log_error (_("error getting new PIN: %s\n"), gpg_strerror (rc));
+           goto leave;
+@@ -3352,8 +3351,7 @@ rsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
+   maxbits = app->app_local->keyattr[keyno].rsa.n_bits;
+   nbits = rsa_n? count_bits (rsa_n, rsa_n_len) : 0;
+   if (opt.verbose)
+-    log_info ("RSA modulus size is %u bits (%u bytes)\n",
+-              nbits, (unsigned int)rsa_n_len);
++    log_info ("RSA modulus size is %u bits\n", nbits);
+   if (nbits && nbits != maxbits
+       && app->app_local->extcap.algo_attr_change)
+     {
diff --git a/debian/patches/0030-gpg-Fix-attempt-to-double-free-an-UID-structure.patch b/debian/patches/0030-gpg-Fix-attempt-to-double-free-an-UID-structure.patch
new file mode 100644
index 0000000..5a43f24
--- /dev/null
+++ b/debian/patches/0030-gpg-Fix-attempt-to-double-free-an-UID-structure.patch
@@ -0,0 +1,59 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Sun, 5 Mar 2017 23:24:15 +0100
+Subject: gpg: Fix attempt to double free an UID structure.
+
+* g10/getkey.c (get_best_pubkey_byname): Set released .UID to NULL.
+--
+
+Phil Pennock reported an assertion failure when doing
+
+  % gpg --auto-key-locate dane --locate-keys someone
+  gpg: Ohhhh jeeee: Assertion "uid->ref > 0" in \
+         free_user_id failed (free-packet.c:310)
+
+on his keyring.  This patch is not tested but a good guess.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 4a130bbc2c2f4be6e8c6357512a943f435ade28f)
+---
+ g10/getkey.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/g10/getkey.c b/g10/getkey.c
+index 163ab80..be7367f 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -1592,8 +1592,10 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
+   if (is_valid_mailbox (name) && ctx)
+     {
+       /* Rank results and return only the most relevant key.  */
+-      struct pubkey_cmp_cookie best = { 0 }, new;
+-      KBNODE new_keyblock;
++      struct pubkey_cmp_cookie best = { 0 };
++      struct pubkey_cmp_cookie new;
++      kbnode_t new_keyblock;
++
+       while (getkey_next (ctx, &new.key, &new_keyblock) == 0)
+         {
+           int diff = pubkey_cmp (ctrl, name, &best, &new, new_keyblock);
+@@ -1610,17 +1612,20 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
+               /* Old key is better.  */
+               release_public_key_parts (&new.key);
+               free_user_id (new.uid);
++              new.uid = NULL;
+             }
+           else
+             {
+               /* A tie.  Keep the old key.  */
+               release_public_key_parts (&new.key);
+               free_user_id (new.uid);
++              new.uid = NULL;
+             }
+         }
+       getkey_end (ctx);
+       ctx = NULL;
+       free_user_id (best.uid);
++      best.uid = NULL;
+ 
+       if (best.valid)
+         {
diff --git a/debian/patches/0031-gpgscm-Fix-creation-of-temporary-directories.patch b/debian/patches/0031-gpgscm-Fix-creation-of-temporary-directories.patch
new file mode 100644
index 0000000..b6e40d6
--- /dev/null
+++ b/debian/patches/0031-gpgscm-Fix-creation-of-temporary-directories.patch
@@ -0,0 +1,38 @@
+From: Justus Winter <justus at g10code.com>
+Date: Mon, 6 Mar 2017 17:14:58 +0100
+Subject: gpgscm: Fix creation of temporary directories.
+
+* tests/gpgscm/ffi.c (do_mkdtemp): Use a larger buffer for the
+template.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 171e4314ebd3ff74af3dcdc8bd68e1100e8910ea)
+---
+ tests/gpgscm/ffi.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c
+index 42facee..34e573f 100644
+--- a/tests/gpgscm/ffi.c
++++ b/tests/gpgscm/ffi.c
+@@ -26,6 +26,7 @@
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <gpg-error.h>
++#include <limits.h>
+ #include <stdarg.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+@@ -345,7 +346,11 @@ do_mkdtemp (scheme *sc, pointer args)
+ {
+   FFI_PROLOG ();
+   char *template;
+-  char buffer[128];
++#ifdef PATH_MAX
++  char buffer[PATH_MAX];
++#else
++  char buffer[1024];
++#endif
+   char *name;
+   FFI_ARG_OR_RETURN (sc, char *, template, string, args);
+   FFI_ARGS_DONE_OR_RETURN (sc, args);
diff --git a/debian/patches/0032-tests-Harmonize-temporary-and-socket-directory-handl.patch b/debian/patches/0032-tests-Harmonize-temporary-and-socket-directory-handl.patch
new file mode 100644
index 0000000..ce67604
--- /dev/null
+++ b/debian/patches/0032-tests-Harmonize-temporary-and-socket-directory-handl.patch
@@ -0,0 +1,376 @@
+From: Justus Winter <justus at g10code.com>
+Date: Mon, 6 Mar 2017 17:16:41 +0100
+Subject: tests: Harmonize temporary and socket directory handling.
+
+* tests/gpgscm/tests.scm (mkdtemp): Do not magically obey the
+environment variable 'TMP', make sure to always return an absolute
+path.
+* tests/gpgme/Makefile.am (TMP): Drop variable.
+(TESTS_ENVIRONMENT): Drop 'TMP'.
+* tests/gpgme/gpgme-defs.scm (create-gpgmehome): Start the agent.  Do
+not create private key store, the agent does that for us.
+* tests/gpgsm/Makefile.am (TMP): Drop variable.
+(TESTS_ENVIRONMENT): Drop 'TMP'.
+* tests/gpgme/gpgme-defs.scm (create-gpgsmhome): Start the agent.  Do
+not create private key store, the agent does that for us.
+* tests/migrations/Makefile.am (TMP): Drop variable.
+(TESTS_ENVIRONMENT): Drop 'TMP'.
+* tests/migrations/common.scm (gpgconf): New variable.
+(run-test): Create and remove socket directory.
+* tests/migrations/extended-pkf.scm (src-tarball): Remove variable.
+(setup): Remove function.
+(trigger-migration): Likewise.
+Use 'run-test' to execute the test.
+* tests/migrations/from-classic.scm (src-tarball): Remove variable.
+(setup): Remove function.
+Use 'run-test' to execute the tests.
+* tests/openpgp/Makefile.am (TMP): Drop variable.
+(TESTS_ENVIRONMENT): Drop 'TMP'.
+* tests/openpgp/README: Do not mention 'TMP'.
+* tests/openpgp/defs.scm (with-home-directory): New macro.
+(create-legacy-gpghome): Do not create private key store, the agent
+does that for us.
+(start-agent): Make sure to terminate the right agent with 'atexit'.
+--
+
+Previously, the test suite relied upon creating home directories in
+'/tmp'.  This has been problematic in some build environments,
+although POSIX mandates that '/tmp' must be available.
+
+We now rely on 'gpgconf --create-socketdir' to create a suitable
+socket directory for us.  This allows us to get rid of some cruft.  It
+also aligns the environment the tests are run in closer with the
+environment that we intend that GnuPG runs in.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 7e19786a5ddef637d1d9d21593fecf5a36b6f372)
+---
+ tests/gpgme/Makefile.am           |  3 ---
+ tests/gpgme/gpgme-defs.scm        |  3 ++-
+ tests/gpgscm/tests.scm            | 13 +++++------
+ tests/gpgsm/Makefile.am           |  3 ---
+ tests/gpgsm/gpgsm-defs.scm        |  2 +-
+ tests/migrations/Makefile.am      |  3 ---
+ tests/migrations/common.scm       |  8 ++++++-
+ tests/migrations/extended-pkf.scm | 18 +++++----------
+ tests/migrations/from-classic.scm | 47 ++++++++++++++++++---------------------
+ tests/openpgp/Makefile.am         |  3 ---
+ tests/openpgp/README              |  2 +-
+ tests/openpgp/defs.scm            | 15 +++++++++++--
+ tests/openpgp/setup.scm           |  1 +
+ 13 files changed, 58 insertions(+), 63 deletions(-)
+
+diff --git a/tests/gpgme/Makefile.am b/tests/gpgme/Makefile.am
+index d7fd87c..0d0edc0 100644
+--- a/tests/gpgme/Makefile.am
++++ b/tests/gpgme/Makefile.am
+@@ -28,12 +28,9 @@ include $(top_srcdir)/am/cmacros.am
+ 
+ AM_CFLAGS =
+ 
+-TMP ?= /tmp
+-
+ TESTS_ENVIRONMENT = LC_ALL=C \
+ 	EXEEXT=$(EXEEXT) \
+ 	PATH=../gpgscm:$(PATH) \
+-	TMP=$(TMP) \
+ 	srcdir=$(abs_srcdir) \
+ 	objdir=$(abs_top_builddir) \
+ 	GPGSCM_PATH=$(abs_top_srcdir)/tests/gpgscm:$(abs_top_srcdir)/tests/openpgp:$(abs_top_srcdir)/tests/gpgme
+diff --git a/tests/gpgme/gpgme-defs.scm b/tests/gpgme/gpgme-defs.scm
+index c102c93..7a7166c 100644
+--- a/tests/gpgme/gpgme-defs.scm
++++ b/tests/gpgme/gpgme-defs.scm
+@@ -54,7 +54,8 @@
+   (create-file
+    "gpg-agent.conf"
+    (string-append "pinentry-program " (tool 'pinentry)))
+-  (mkdir "private-keys-v1.d" "-rwx")
++
++  (start-agent)
+ 
+   (log "Storing private keys")
+   (for-each
+diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm
+index e5858d9..b3da919 100644
+--- a/tests/gpgscm/tests.scm
++++ b/tests/gpgscm/tests.scm
+@@ -268,14 +268,13 @@
+ ;; Make a temporary directory.  If arguments are given, they are
+ ;; joined using path-join, and must end in a component ending in
+ ;; "XXXXXX".  If no arguments are given, a suitable location and
+-;; generic name is used.
++;; generic name is used.  Returns an absolute path.
+ (define (mkdtemp . components)
+-  (_mkdtemp (if (null? components)
+-		(path-join (getenv "TMP")
+-			   (string-append "gpgscm-" (get-isotime) "-"
+-					  (basename-suffix *scriptname* ".scm")
+-					  "-XXXXXX"))
+-		(apply path-join components))))
++  (canonical-path (_mkdtemp (if (null? components)
++				(string-append "gpgscm-" (get-isotime) "-"
++					       (basename-suffix *scriptname* ".scm")
++					       "-XXXXXX")
++				(apply path-join components)))))
+ 
+ (define-macro (with-temporary-working-directory . expressions)
+   (let ((tmp-sym (gensym)))
+diff --git a/tests/gpgsm/Makefile.am b/tests/gpgsm/Makefile.am
+index aad328b..28db501 100644
+--- a/tests/gpgsm/Makefile.am
++++ b/tests/gpgsm/Makefile.am
+@@ -28,12 +28,9 @@ include $(top_srcdir)/am/cmacros.am
+ 
+ AM_CFLAGS =
+ 
+-TMP ?= /tmp
+-
+ TESTS_ENVIRONMENT = LC_ALL=C \
+ 	EXEEXT=$(EXEEXT) \
+ 	PATH=../gpgscm:$(PATH) \
+-	TMP=$(TMP) \
+ 	srcdir=$(abs_srcdir) \
+ 	objdir=$(abs_top_builddir) \
+ 	GPGSCM_PATH=$(abs_top_srcdir)/tests/gpgscm:$(abs_top_srcdir)/tests/openpgp:$(abs_top_srcdir)/tests/gpgsm
+diff --git a/tests/gpgsm/gpgsm-defs.scm b/tests/gpgsm/gpgsm-defs.scm
+index aa5af3d..5f9be7f 100644
+--- a/tests/gpgsm/gpgsm-defs.scm
++++ b/tests/gpgsm/gpgsm-defs.scm
+@@ -73,6 +73,7 @@
+ 	       "faked-system-time 1008241200")
+   (create-file "gpg-agent.conf"
+ 	       (string-append "pinentry-program " (tool 'pinentry)))
++  (start-agent)
+   (create-file
+    "trustlist.txt"
+    "32100C27173EF6E9C4E9A25D3D69F86D37A4F939"
+@@ -80,7 +81,6 @@
+    "3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E S")
+ 
+   (log "Storing private keys")
+-  (mkdir "private-keys-v1.d" "-rwx")
+   (for-each
+    (lambda (name)
+      (file-copy (in-srcdir name)
+diff --git a/tests/migrations/Makefile.am b/tests/migrations/Makefile.am
+index d0cd9ee..0895aff 100644
+--- a/tests/migrations/Makefile.am
++++ b/tests/migrations/Makefile.am
+@@ -28,12 +28,9 @@ include $(top_srcdir)/am/cmacros.am
+ 
+ AM_CFLAGS =
+ 
+-TMP ?= /tmp
+-
+ TESTS_ENVIRONMENT = GPG_AGENT_INFO= LC_ALL=C \
+ 	EXEEXT=$(EXEEXT) \
+ 	PATH=../gpgscm:$(PATH) \
+-	TMP=$(TMP) \
+ 	srcdir=$(abs_srcdir) \
+ 	objdir=$(abs_top_builddir) \
+ 	GPGSCM_PATH=$(abs_top_srcdir)/tests/gpgscm:$(abs_top_srcdir)/tests/migrations
+diff --git a/tests/migrations/common.scm b/tests/migrations/common.scm
+index 30ac62b..fa8f129 100644
+--- a/tests/migrations/common.scm
++++ b/tests/migrations/common.scm
+@@ -26,6 +26,7 @@
+   (string-append executable (getenv "EXEEXT")))
+ 
+ ;; We may not use a relative name for gpg-agent.
++(define gpgconf (path-join (getenv "objdir") "tools" (qualify "gpgconf")))
+ (define GPG-AGENT (path-join (getenv "objdir") "agent" (qualify "gpg-agent")))
+ (define GPG `(,(path-join (getenv "objdir") "g10" (qualify "gpg"))
+ 	      --no-permission-warning --no-greeting
+@@ -51,4 +52,9 @@
+    (info message)
+    (untar-armored src-tarball)
+    (setenv "GNUPGHOME" (getcwd) #t)
+-   (test (getcwd))))
++
++   (catch (log "Warning: Creating socket directory failed:" (car *error*))
++	  (call-popen `(,gpgconf --create-socketdir) ""))
++   (test (getcwd))
++   (catch (log "Warning: Removing socket directory failed.")
++	  (call-popen `(,gpgconf --remove-socketdir) ""))))
+diff --git a/tests/migrations/extended-pkf.scm b/tests/migrations/extended-pkf.scm
+index bf2c49e..1317cd4 100755
+--- a/tests/migrations/extended-pkf.scm
++++ b/tests/migrations/extended-pkf.scm
+@@ -22,15 +22,6 @@
+ (catch (skip "gpgtar not built")
+        (call-check `(,GPGTAR --help)))
+ 
+-(define src-tarball (in-srcdir "extended-pkf.tar.asc"))
+-
+-(define (setup)
+-  (untar-armored src-tarball)
+-  (setenv "GNUPGHOME" (getcwd) #t))
+-
+-(define (trigger-migration)
+-  (call-check `(, at GPG --list-secret-keys)))
+-
+ (define (assert-keys-usable)
+   (for-each
+    (lambda (keyid)
+@@ -38,9 +29,10 @@
+ 	    (call-check `(, at GPG --list-secret-keys ,keyid))))
+    '("C40FDECF" "ECABF51D")))
+ 
+-(info "Testing the extended private key format ...")
+-(with-temporary-working-directory
+- (setup)
+- (assert-keys-usable))
++(run-test
++ "Testing the extended private key format ..."
++ (in-srcdir "extended-pkf.tar.asc")
++ (lambda (gpghome)
++   (assert-keys-usable)))
+ 
+ ;; XXX try changing a key, and check that the format is not changed.
+diff --git a/tests/migrations/from-classic.scm b/tests/migrations/from-classic.scm
+index d540470..ace458e 100755
+--- a/tests/migrations/from-classic.scm
++++ b/tests/migrations/from-classic.scm
+@@ -22,12 +22,6 @@
+ (catch (skip "gpgtar not built")
+        (call-check `(,GPGTAR --help)))
+ 
+-(define src-tarball (in-srcdir "from-classic.tar.asc"))
+-
+-(define (setup)
+-  (untar-armored src-tarball)
+-  (setenv "GNUPGHOME" (getcwd) #t))
+-
+ (define (trigger-migration)
+   (call-check `(, at GPG --list-secret-keys)))
+ 
+@@ -41,24 +35,27 @@
+ 	    (call-check `(, at GPG --list-secret-keys ,keyid))))
+    '("D74C5F22" "C40FDECF" "ECABF51D")))
+ 
+-(info "Testing a clean migration ...")
+-(with-temporary-working-directory
+- (setup)
+- (trigger-migration)
+- (assert-migrated))
+-
+-(info "Testing a migration with existing private-keys-v1.d ...")
+-(with-temporary-working-directory
+- (setup)
+- (mkdir "private-keys-v1.d" "-rwx")
+- (trigger-migration)
+- (assert-migrated))
+-
+-(info "Testing a migration with existing but weird private-keys-v1.d ...")
+-(with-temporary-working-directory
+- (setup)
+- (mkdir "private-keys-v1.d" "")
+- (trigger-migration)
+- (assert-migrated))
++(run-test
++ "Testing a clean migration ..."
++ (in-srcdir "from-classic.tar.asc")
++ (lambda (gpghome)
++   (trigger-migration)
++   (assert-migrated)))
++
++(run-test
++ "Testing a migration with existing private-keys-v1.d ..."
++ (in-srcdir "from-classic.tar.asc")
++ (lambda (gpghome)
++   (mkdir "private-keys-v1.d" "-rwx")
++   (trigger-migration)
++   (assert-migrated)))
++
++(run-test
++ "Testing a migration with existing but weird private-keys-v1.d ..."
++ (in-srcdir "from-classic.tar.asc")
++ (lambda (gpghome)
++   (mkdir "private-keys-v1.d" "")
++   (trigger-migration)
++   (assert-migrated)))
+ 
+ ;; XXX Check a case where the migration fails.
+diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am
+index afac58f..518af20 100644
+--- a/tests/openpgp/Makefile.am
++++ b/tests/openpgp/Makefile.am
+@@ -33,12 +33,9 @@ noinst_PROGRAMS = fake-pinentry
+ 
+ fake_pinentry_SOURCES = fake-pinentry.c
+ 
+-TMP ?= /tmp
+-
+ TESTS_ENVIRONMENT = LC_ALL=C \
+ 	EXEEXT=$(EXEEXT) \
+ 	PATH=../gpgscm:$(PATH) \
+-	TMP=$(TMP) \
+ 	srcdir=$(abs_srcdir) \
+ 	objdir=$(abs_top_builddir) \
+ 	GPGSCM_PATH=$(abs_top_srcdir)/tests/gpgscm:$(abs_top_srcdir)/tests/openpgp
+diff --git a/tests/openpgp/README b/tests/openpgp/README
+index eba77b1..b9d5607 100644
+--- a/tests/openpgp/README
++++ b/tests/openpgp/README
+@@ -30,7 +30,7 @@ This is a bit tricky because one needs to manually set some
+ environment variables.  We should make that easier.  See discussion
+ below.  From your build directory, do:
+ 
+-  obj $ TMP=/tmp srcdir=<path to>/tests/openpgp \
++  obj $ srcdir=<path to>/tests/openpgp \
+         GPGSCM_PATH=<path to>/tests/gpgscm:<path to>/tests/openpgp \
+         $(pwd)/tests/gpgscm/gpgscm [gpgscm args] \
+         run-tests.scm [test suite runner args]
+diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm
+index a06a570..568ffab 100644
+--- a/tests/openpgp/defs.scm
++++ b/tests/openpgp/defs.scm
+@@ -278,6 +278,15 @@
+ ;; GnuPG helper.
+ ;;
+ 
++;; Evaluate a sequence of expressions with the given home directory.
++(define-macro (with-home-directory gnupghome . expressions)
++  (let ((original-home-directory (gensym)))
++    `(let ((,original-home-directory (getenv "GNUPGHOME")))
++       (dynamic-wind
++	   (lambda () (setenv "GNUPGHOME" ,gnupghome #t))
++	   (lambda () , at expressions)
++	   (lambda () (setenv "GNUPGHOME" ,original-home-directory #t))))))
++
+ ;; Evaluate a sequence of expressions with an ephemeral home
+ ;; directory.
+ (define-macro (with-ephemeral-home-directory . expressions)
+@@ -364,7 +373,6 @@
+ 
+ (define (create-legacy-gpghome)
+   (create-sample-files)
+-  (mkdir "private-keys-v1.d" "-rwx")
+ 
+   (log "Storing private keys")
+   (for-each
+@@ -434,7 +442,10 @@
+ ;; Create the socket dir and start the agent.
+ (define (start-agent)
+   (log "Starting gpg-agent...")
+-  (atexit stop-agent)
++  (let ((gnupghome (getenv "GNUPGHOME")))
++    (atexit (lambda ()
++	      (with-home-directory gnupghome
++				   (stop-agent)))))
+   (catch (log "Warning: Creating socket directory failed:" (car *error*))
+ 	 (call-popen `(,(tool 'gpgconf) --create-socketdir) ""))
+   (call-check `(,(tool 'gpg-connect-agent) --verbose
+diff --git a/tests/openpgp/setup.scm b/tests/openpgp/setup.scm
+index d13799d..bf1876e 100755
+--- a/tests/openpgp/setup.scm
++++ b/tests/openpgp/setup.scm
+@@ -25,6 +25,7 @@
+ (with-ephemeral-home-directory
+  (chdir (getenv "GNUPGHOME"))
+  (create-gpghome)
++ (start-agent)
+  (create-legacy-gpghome)
+  (stop-agent)
+  (call-check `(,(tool 'gpgtar) --create --output ,(cadr *args*) ".")))
diff --git a/debian/patches/0033-scd-Close-THE_EVENT-handle.patch b/debian/patches/0033-scd-Close-THE_EVENT-handle.patch
new file mode 100644
index 0000000..fa172ef
--- /dev/null
+++ b/debian/patches/0033-scd-Close-THE_EVENT-handle.patch
@@ -0,0 +1,29 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 7 Mar 2017 10:19:40 +0900
+Subject: scd: Close THE_EVENT handle.
+
+* scd/scdaemon.c (handle_connections): Close the handle.
+
+--
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit cc933a96f8e83bc66fb69ed33d9593acdd60c929)
+---
+ scd/scdaemon.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/scd/scdaemon.c b/scd/scdaemon.c
+index 4b63c9b..13cf2e6 100644
+--- a/scd/scdaemon.c
++++ b/scd/scdaemon.c
+@@ -1378,6 +1378,10 @@ handle_connections (int listen_fd)
+         }
+     }
+ 
++#ifdef HAVE_W32_SYSTEM
++  if (the_event != INVALID_HANDLE_VALUE)
++    CloseHandle (the_event);
++#endif
+   cleanup ();
+   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
+   npth_attr_destroy (&tattr);
diff --git a/debian/patches/0034-tools-More-portable-for-openpty-use.patch b/debian/patches/0034-tools-More-portable-for-openpty-use.patch
new file mode 100644
index 0000000..28fe1b5
--- /dev/null
+++ b/debian/patches/0034-tools-More-portable-for-openpty-use.patch
@@ -0,0 +1,58 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 7 Mar 2017 10:29:37 +0900
+Subject: tools: More portable for openpty use.
+
+* configure.ac (AC_CHECK_HEADERS): Add util.h libutil.h and termios.h.
+* tools/symcryptrun.c: Include those headers.
+
+--
+
+This is for OpenBSD and FreeBSD.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit ce37ada87139ef418401f9f35439007a8c04a856)
+---
+ configure.ac        |  3 ++-
+ tools/symcryptrun.c | 12 ++++++++++++
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index a793a7e..d989f62 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1274,7 +1274,8 @@ AC_MSG_NOTICE([checking for header files])
+ AC_HEADER_STDC
+ AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h \
+                   pty.h utmp.h pwd.h inttypes.h signal.h sys/select.h     \
+-                  stdint.h signal.h])
++                  stdint.h signal.h util.h libutil.h termios.h])
++
+ AC_HEADER_TIME
+ 
+ 
+diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c
+index a72b9cf..b32d43a 100644
+--- a/tools/symcryptrun.c
++++ b/tools/symcryptrun.c
+@@ -71,9 +71,21 @@
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
++
+ #ifdef HAVE_PTY_H
+ #include <pty.h>
++#else
++#ifdef HAVE_TERMIOS_H
++#include <termios.h>
++#endif
++#ifdef HAVE_UTIL_H
++#include <util.h>
++#endif
++#ifdef HAVE_LIBUTIL_H
++#include <libutil.h>
+ #endif
++#endif
++
+ #ifdef HAVE_UTMP_H
+ #include <utmp.h>
+ #endif
diff --git a/debian/patches/0035-common-Fix-warning-for-portability.patch b/debian/patches/0035-common-Fix-warning-for-portability.patch
new file mode 100644
index 0000000..dd82ea2
--- /dev/null
+++ b/debian/patches/0035-common-Fix-warning-for-portability.patch
@@ -0,0 +1,26 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 7 Mar 2017 10:42:46 +0900
+Subject: common: Fix warning for portability.
+
+* common/localename.c (do_nl_locale_name): We don't use CATEGORY.
+
+--
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit b9ab733fc0dd2ca2a7eaac0bde3a817c07af36c5)
+---
+ common/localename.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/common/localename.c b/common/localename.c
+index 2650ea7..b620a74 100644
+--- a/common/localename.c
++++ b/common/localename.c
+@@ -79,6 +79,7 @@ do_nl_locale_name (int category, const char *categoryname)
+   (void)categoryname;
+   retval = setlocale (category, NULL);
+ # else
++  (void)category;
+   /* Setting of LC_ALL overwrites all other.  */
+   retval = getenv ("LC_ALL");
+   if (retval == NULL || retval[0] == '\0')
diff --git a/debian/patches/0036-agent-Fix-get_client_pid-for-portability.patch b/debian/patches/0036-agent-Fix-get_client_pid-for-portability.patch
new file mode 100644
index 0000000..d626c5c
--- /dev/null
+++ b/debian/patches/0036-agent-Fix-get_client_pid-for-portability.patch
@@ -0,0 +1,177 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 7 Mar 2017 14:01:17 +0900
+Subject: agent: Fix get_client_pid for portability.
+
+* configure.ac: Simply check getpeerucred and ucred.h, and structure
+members.
+* agent/command-ssh.c: Include ucred.h.
+(get_client_pid) [HAVE_STRUCT_SOCKPEERCRED_PID]: Use sockpeercred
+structure for OpenBSD.
+[LOCAL_PEERPID]: Use LOCAL_PEERPID for macOS.
+[LOCAL_PEEREID]: Use LOCAL_PEEREID for NetBSD.
+[HAVE_GETPEERUCRED]: Use getpeerucred for OpenSolaris.
+
+--
+
+This change also addresses following bug.
+
+GnuPG-bug-id: 2981.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit f7f806afa5083617f4aba02fc3b285b06a7d73d4)
+---
+ agent/command-ssh.c | 43 ++++++++++++++++++++++++++++++++-----------
+ configure.ac        | 49 +++++++------------------------------------------
+ 2 files changed, 39 insertions(+), 53 deletions(-)
+
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index 3ab41cf..c7afe3b 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -40,6 +40,9 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <assert.h>
++#ifdef HAVE_UCRED_H
++#include <ucred.h>
++#endif
+ 
+ #include "agent.h"
+ 
+@@ -3556,31 +3559,39 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
+ }
+ 
+ 
+-/* Return the peer's pid.  Stripped down code from libassuan.  */
++/* Return the peer's pid.  */
+ static unsigned long
+ get_client_pid (int fd)
+ {
+   pid_t client_pid = (pid_t)(-1);
+ 
+-#ifdef HAVE_SO_PEERCRED
++#ifdef SO_PEERCRED
+   {
++#ifdef HAVE_STRUCT_SOCKPEERCRED_PID
++    struct sockpeercred cr;
++#else
+     struct ucred cr;
++#endif
+     socklen_t cl = sizeof cr;
+ 
+     if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl))
+-      client_pid = cr.pid;
++      {
++#if defined (HAVE_STRUCT_SOCKPEERCRED_PID) || defined (HAVE_STRUCT_UCRED_PID)
++        client_pid = cr.pid;
++#elif defined (HAVE_STRUCT_UCRED_CR_PID)
++        client_pid = cr.cr_pid;
++#else
++#error "Unknown SO_PEERCRED struct"
++#endif
++      }
+   }
+-#elif defined (HAVE_GETPEERUCRED)
++#elif defined (LOCAL_PEERPID)
+   {
+-    ucred_t *ucred = NULL;
++    socklen_t len = sizeof (pid_t);
+ 
+-    if (getpeerucred (fd, &ucred) != -1)
+-      {
+-	client_pid= ucred_getpid (ucred);
+-	ucred_free (ucred);
+-      }
++    getsockopt(fd, SOL_LOCAL, LOCAL_PEERPID, &client_pid, &len);
+   }
+-#elif defined (HAVE_LOCAL_PEEREID)
++#elif defined (LOCAL_PEEREID)
+   {
+     struct unpcbid unp;
+     socklen_t unpl = sizeof unp;
+@@ -3588,6 +3599,16 @@ get_client_pid (int fd)
+     if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1)
+       client_pid = unp.unp_pid;
+   }
++#elif defined (HAVE_GETPEERUCRED)
++  {
++    ucred_t *ucred = NULL;
++
++    if (getpeerucred (fd, &ucred) != -1)
++      {
++        client_pid= ucred_getpid (ucred);
++        ucred_free (ucred);
++      }
++  }
+ #endif
+ 
+   return client_pid == (pid_t)(-1)? 0 : (unsigned long)client_pid;
+diff --git a/configure.ac b/configure.ac
+index d989f62..9631e88 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1274,7 +1274,8 @@ AC_MSG_NOTICE([checking for header files])
+ AC_HEADER_STDC
+ AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h \
+                   pty.h utmp.h pwd.h inttypes.h signal.h sys/select.h     \
+-                  stdint.h signal.h util.h libutil.h termios.h])
++                  stdint.h signal.h util.h libutil.h termios.h \
++                  ucred.h])
+ 
+ AC_HEADER_TIME
+ 
+@@ -1395,49 +1396,13 @@ fi
+ 
+ 
+ #
+-# Check for the getsockopt SO_PEERCRED
+-# (This has been copied from libassuan)
++# Check for the getsockopt SO_PEERCRED, etc.
+ #
+-AC_MSG_CHECKING(for SO_PEERCRED)
+-AC_CACHE_VAL(gnupg_cv_sys_so_peercred,
+-      [AC_TRY_COMPILE([#include <sys/socket.h>],
+-         [struct ucred cr;
+-          int cl = sizeof cr;
+-          getsockopt (1, SOL_SOCKET, SO_PEERCRED, &cr, &cl);],
+-          gnupg_cv_sys_so_peercred=yes,
+-          gnupg_cv_sys_so_peercred=no)
+-       ])
+-AC_MSG_RESULT($gnupg_cv_sys_so_peercred)
++AC_CHECK_MEMBERS([struct ucred.pid, struct ucred.cr_pid, struct sockpeercred.pid], [], [], [#include <sys/types.h>
++#include <sys/socket.h> ])
+ 
+-if test $gnupg_cv_sys_so_peercred = yes; then
+-  AC_DEFINE(HAVE_SO_PEERCRED, 1,
+-            [Defined if SO_PEERCRED is supported (Linux specific)])
+-else
+-  # Check for the getsockopt LOCAL_PEEREID (NetBSD)
+-  AC_MSG_CHECKING(for LOCAL_PEEREID)
+-  AC_CACHE_VAL(gnupg_cv_sys_so_local_peereid,
+-      [AC_TRY_COMPILE([#include <sys/socket.>
+-         #include <sys/un.h>],
+-         [struct unpcbid unp;
+-          int unpl = sizeof unp;
+-          getsockopt (1, SOL_SOCKET, LOCAL_PEEREID, &unp, &unpl);],
+-          gnupg_cv_sys_so_local_peereid=yes,
+-          gnupg_cv_sys_so_local_peereid=no)
+-       ])
+-  AC_MSG_RESULT($gnupg_cv_sys_so_local_peereid)
+-
+-  if test $gnupg_cv_sys_so_local_peereid = yes; then
+-    AC_DEFINE(HAVE_LOCAL_PEEREID, 1,
+-              [Defined if LOCAL_PEEREID is supported (NetBSD specific)])
+-  else
+-    # (Open)Solaris
+-    AC_CHECK_FUNCS([getpeerucred], AC_CHECK_HEADERS([ucred.h]))
+-    if test $ac_cv_func_getpeerucred != yes; then
+-        # FreeBSD
+-        AC_CHECK_FUNCS([getpeereid])
+-    fi
+-  fi
+-fi
++# (Open)Solaris
++AC_CHECK_FUNCS([getpeerucred])
+ 
+ 
+ #
diff --git a/debian/patches/0037-agent-Add-include-files.patch b/debian/patches/0037-agent-Add-include-files.patch
new file mode 100644
index 0000000..7976752
--- /dev/null
+++ b/debian/patches/0037-agent-Add-include-files.patch
@@ -0,0 +1,27 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 7 Mar 2017 14:22:34 +0900
+Subject: agent: Add include files.
+
+* agent/command-ssh.c: Add sys/socket.h and sys/un.h.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit bf03925751abb739f2fd9d631694d3dd33decf92)
+---
+ agent/command-ssh.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index c7afe3b..382f9e6 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -40,6 +40,10 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <assert.h>
++#ifndef HAVE_W32_SYSTEM
++#include <sys/socket.h>
++#include <sys/un.h>
++#endif /*!HAVE_W32_SYSTEM*/
+ #ifdef HAVE_UCRED_H
+ #include <ucred.h>
+ #endif
diff --git a/debian/patches/0038-agent-Resolve-conflict-of-util.h.patch b/debian/patches/0038-agent-Resolve-conflict-of-util.h.patch
new file mode 100644
index 0000000..307d673
--- /dev/null
+++ b/debian/patches/0038-agent-Resolve-conflict-of-util.h.patch
@@ -0,0 +1,263 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 7 Mar 2017 19:22:48 +0900
+Subject: agent: Resolve conflict of util.h.
+
+* agent/Makefile.am (AM_CPPFLAGS): Remove -I$(top_srcdir)/common.
+* agent/call-pinentry.c, agent/call-scd.c: Follow the change.
+* agent/command-ssh.c, agent/command.c, agent/cvt-openpgp.c: Ditto.
+* agent/divert-scd.c, agent/findkey.c, agent/genkey.c: Ditto.
+* agent/gpg-agent.c, agent/pksign.c, agent/preset-passphrase.c: Ditto.
+* agent/protect-tool.c, agent/protect.c, agent/trustlist.c: Ditto.
+* agent/w32main.c: Ditto.
+
+--
+
+For openpty function, we need to include util.h on some OS.
+We also have util.h in common/, so this change is needed.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 176e07ce10d892fa7c7b96725b38b2fec9a1f916)
+---
+ agent/Makefile.am         |  2 +-
+ agent/call-pinentry.c     |  4 ++--
+ agent/call-scd.c          |  2 +-
+ agent/command-ssh.c       |  6 +++---
+ agent/command.c           |  2 +-
+ agent/cvt-openpgp.c       |  4 ++--
+ agent/divert-scd.c        |  4 ++--
+ agent/findkey.c           |  2 +-
+ agent/genkey.c            |  6 +++---
+ agent/gpg-agent.c         | 10 +++++-----
+ agent/pksign.c            |  2 +-
+ agent/preset-passphrase.c |  6 +++---
+ agent/protect-tool.c      |  6 +++---
+ agent/protect.c           |  2 +-
+ agent/trustlist.c         |  2 +-
+ 15 files changed, 30 insertions(+), 30 deletions(-)
+
+diff --git a/agent/Makefile.am b/agent/Makefile.am
+index 045566e..668de2a 100644
+--- a/agent/Makefile.am
++++ b/agent/Makefile.am
+@@ -28,7 +28,7 @@ noinst_PROGRAMS = $(TESTS)
+ EXTRA_DIST = ChangeLog-2011 gpg-agent-w32info.rc
+ 
+ 
+-AM_CPPFLAGS = -I$(top_srcdir)/common
++AM_CPPFLAGS =
+ 
+ include $(top_srcdir)/am/cmacros.am
+ 
+diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
+index 0af1854..a35a3fb 100644
+--- a/agent/call-pinentry.c
++++ b/agent/call-pinentry.c
+@@ -37,8 +37,8 @@
+ 
+ #include "agent.h"
+ #include <assuan.h>
+-#include "sysutils.h"
+-#include "i18n.h"
++#include "../common/sysutils.h"
++#include "../common/i18n.h"
+ 
+ #ifdef _POSIX_OPEN_MAX
+ #define MAX_OPEN_FDS _POSIX_OPEN_MAX
+diff --git a/agent/call-scd.c b/agent/call-scd.c
+index 7dcd982..c27fe87 100644
+--- a/agent/call-scd.c
++++ b/agent/call-scd.c
+@@ -39,7 +39,7 @@
+ 
+ #include "agent.h"
+ #include <assuan.h>
+-#include "strlist.h"
++#include "../common/strlist.h"
+ 
+ #ifdef _POSIX_OPEN_MAX
+ #define MAX_OPEN_FDS _POSIX_OPEN_MAX
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index 382f9e6..5a02542 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -50,9 +50,9 @@
+ 
+ #include "agent.h"
+ 
+-#include "i18n.h"
+-#include "util.h"
+-#include "ssh-utils.h"
++#include "../common/i18n.h"
++#include "../common/util.h"
++#include "../common/ssh-utils.h"
+ 
+ 
+ 

+diff --git a/agent/command.c b/agent/command.c
+index acc3877..79fb0ce 100644
+--- a/agent/command.c
++++ b/agent/command.c
+@@ -37,7 +37,7 @@
+ 
+ #include "agent.h"
+ #include <assuan.h>
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "cvt-openpgp.h"
+ #include "../common/ssh-utils.h"
+ #include "../common/asshelp.h"
+diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
+index 510b6ff..ee12221 100644
+--- a/agent/cvt-openpgp.c
++++ b/agent/cvt-openpgp.c
+@@ -25,9 +25,9 @@
+ #include <assert.h>
+ 
+ #include "agent.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "cvt-openpgp.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ 
+ /* Helper to pass data via the callback to do_unprotect. */
+diff --git a/agent/divert-scd.c b/agent/divert-scd.c
+index d9d734c..153119b 100644
+--- a/agent/divert-scd.c
++++ b/agent/divert-scd.c
+@@ -28,8 +28,8 @@
+ #include <sys/stat.h>
+ 
+ #include "agent.h"
+-#include "i18n.h"
+-#include "sexp-parse.h"
++#include "../common/i18n.h"
++#include "../common/sexp-parse.h"
+ 
+ 
+ static int
+diff --git a/agent/findkey.c b/agent/findkey.c
+index ac74fa9..a196fdc 100644
+--- a/agent/findkey.c
++++ b/agent/findkey.c
+@@ -33,7 +33,7 @@
+ #include <npth.h> /* (we use pth_sleep) */
+ 
+ #include "agent.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "../common/ssh-utils.h"
+ #include "../common/name-value.h"
+ 
+diff --git a/agent/genkey.c b/agent/genkey.c
+index 7fb0139..31742a1 100644
+--- a/agent/genkey.c
++++ b/agent/genkey.c
+@@ -27,9 +27,9 @@
+ #include <assert.h>
+ 
+ #include "agent.h"
+-#include "i18n.h"
+-#include "exechelp.h"
+-#include "sysutils.h"
++#include "../common/i18n.h"
++#include "../common/exechelp.h"
++#include "../common/sysutils.h"
+ 
+ static int
+ store_key (gcry_sexp_t private, const char *passphrase, int force,
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 0f3884c..431dc37 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -56,11 +56,11 @@
+ #include "agent.h"
+ #include <assuan.h> /* Malloc hooks  and socket wrappers. */
+ 
+-#include "i18n.h"
+-#include "sysutils.h"
+-#include "gc-opt-flags.h"
+-#include "exechelp.h"
+-#include "asshelp.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
++#include "../common/gc-opt-flags.h"
++#include "../common/exechelp.h"
++#include "../common/asshelp.h"
+ #include "../common/init.h"
+ 
+ 
+diff --git a/agent/pksign.c b/agent/pksign.c
+index 3b2fcc4..f0b10e6 100644
+--- a/agent/pksign.c
++++ b/agent/pksign.c
+@@ -29,7 +29,7 @@
+ #include <sys/stat.h>
+ 
+ #include "agent.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ static int
+diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c
+index b8d2aaa..3d240b9 100644
+--- a/agent/preset-passphrase.c
++++ b/agent/preset-passphrase.c
+@@ -45,9 +45,9 @@
+ #endif
+ 
+ #include "agent.h"
+-#include "simple-pwquery.h"
+-#include "i18n.h"
+-#include "sysutils.h"
++#include "../common/simple-pwquery.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
+ #include "../common/init.h"
+ 
+ 
+diff --git a/agent/protect-tool.c b/agent/protect-tool.c
+index 2312744..a193e49 100644
+--- a/agent/protect-tool.c
++++ b/agent/protect-tool.c
+@@ -39,9 +39,9 @@
+ #endif
+ 
+ #include "agent.h"
+-#include "i18n.h"
+-#include "get-passphrase.h"
+-#include "sysutils.h"
++#include "../common/i18n.h"
++#include "../common/get-passphrase.h"
++#include "../common/sysutils.h"
+ #include "../common/init.h"
+ 
+ 
+diff --git a/agent/protect.c b/agent/protect.c
+index 7ae7e64..09aa503 100644
+--- a/agent/protect.c
++++ b/agent/protect.c
+@@ -39,7 +39,7 @@
+ #include "agent.h"
+ 
+ #include "cvt-openpgp.h"
+-#include "sexp-parse.h"
++#include "../common/sexp-parse.h"
+ 
+ 
+ /* To use the openpgp-s2k3-ocb-aes scheme by default set the value of
+diff --git a/agent/trustlist.c b/agent/trustlist.c
+index 9d33259..5554485 100644
+--- a/agent/trustlist.c
++++ b/agent/trustlist.c
+@@ -31,7 +31,7 @@
+ 
+ #include "agent.h"
+ #include <assuan.h> /* fixme: need a way to avoid assuan calls here */
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ /* A structure to store the information from the trust file. */
diff --git a/debian/patches/0039-tests-Avoid-overflowing-signed-32-bit-time_t.patch b/debian/patches/0039-tests-Avoid-overflowing-signed-32-bit-time_t.patch
new file mode 100644
index 0000000..53e7467
--- /dev/null
+++ b/debian/patches/0039-tests-Avoid-overflowing-signed-32-bit-time_t.patch
@@ -0,0 +1,56 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 7 Mar 2017 12:18:59 +0100
+Subject: tests: Avoid overflowing signed 32 bit time_t.
+
+* tests/openpgp/quick-key-manipulation.scm: Use expiration times in
+the year 2038 instead of 2105 to avoid overflowing 32 bit time_t.
+time_t is used internally to parse the expiraton time from the iso
+timestamp.
+
+GnuPG-bug-id: 2988
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit de3838372ae3cdecbd83eea2c53c8e2656d93052)
+---
+ tests/openpgp/quick-key-manipulation.scm | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/tests/openpgp/quick-key-manipulation.scm b/tests/openpgp/quick-key-manipulation.scm
+index 10f0bfe..08ef626 100755
+--- a/tests/openpgp/quick-key-manipulation.scm
++++ b/tests/openpgp/quick-key-manipulation.scm
+@@ -125,8 +125,13 @@
+    (default default never)
+    (rsa "sign auth encr" "seconds=600") ;; GPGME uses this
+    (rsa "auth,encr" "2") ;; "without a letter, days is assumed"
+-   (rsa "sign" "2105-01-01") ;; "last year GnuPG can represent is 2105"
+-   (rsa "sign" "21050101T115500") ;; "last year GnuPG can represent is 2105"
++   ;; Sadly, the timestamp is truncated by the use of time_t on
++   ;; systems where time_t is a signed 32 bit value.
++   (rsa "sign" "2038-01-01")      ;; unix millennium
++   (rsa "sign" "20380101T115500") ;; unix millennium
++   ;; Once fixed, we can use later timestamps:
++   ;; (rsa "sign" "2105-01-01")      ;; "last year GnuPG can represent is 2105"
++   ;; (rsa "sign" "21050101T115500") ;; "last year GnuPG can represent is 2105"
+    (rsa sign "2d")
+    (rsa1024 sign "2w")
+    (rsa2048 encr "2m")
+@@ -157,7 +162,8 @@
+   (lambda (subkey)
+     (assert (= 1 (:alg subkey)))
+     (assert (string-contains? (:cap subkey) "s"))
+-    (assert (time-matches? 4260207600 ;; 2105-01-01
++    (assert (time-matches? 2145916800    ;; 2038-01-01
++			   ;; 4260207600 ;; 2105-01-01
+ 			   (string->number (:expire subkey))
+ 			   ;; This is off by 12h, but I guess it just
+ 			   ;; choses the middle of the day.
+@@ -165,7 +171,8 @@
+   (lambda (subkey)
+     (assert (= 1 (:alg subkey)))
+     (assert (string-contains? (:cap subkey) "s"))
+-    (assert (time-matches? 4260254100 ;; UTC 2105-01-01 11:55:00
++    (assert (time-matches? 2145959700    ;; UTC 2038-01-01 11:55:00
++			   ;; 4260254100 ;; UTC 2105-01-01 11:55:00
+ 			   (string->number (:expire subkey))
+ 			   (minutes->seconds 5))))
+   (lambda (subkey)
diff --git a/debian/patches/0040-Remove-I-option-to-common.patch b/debian/patches/0040-Remove-I-option-to-common.patch
new file mode 100644
index 0000000..5944b04
--- /dev/null
+++ b/debian/patches/0040-Remove-I-option-to-common.patch
@@ -0,0 +1,3130 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 7 Mar 2017 20:21:23 +0900
+Subject: Remove -I option to common.
+
+* dirmngr/Makefile.am (AM_CPPFLAGS): Remove -I$(top_srcdir)/common.
+* g10/Makefile.am (AM_CPPFLAGS): Ditto.
+* g13/Makefile.am (AM_CPPFLAGS): Ditto.
+* kbx/Makefile.am (AM_CPPFLAGS): Ditto.
+* scd/Makefile.am (AM_CPPFLAGS): Ditto.
+* sm/Makefile.am (AM_CPPFLAGS): Ditto.
+* tools/Makefile.am (AM_CPPFLAGS): Ditto.
+* Throughout: Follow the change.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 70aca95d6816082b289fceca8eabfcf718a6b701)
+---
+ dirmngr/Makefile.am        |  2 +-
+ dirmngr/dirmngr-client.c   |  6 +++---
+ dirmngr/dirmngr.c          |  4 ++--
+ dirmngr/dirmngr_ldap.c     |  4 ++--
+ dirmngr/dns-stuff.c        |  4 ++--
+ dirmngr/http.c             |  4 ++--
+ dirmngr/ks-engine-finger.c |  2 +-
+ dirmngr/ks-engine-hkp.c    |  2 +-
+ dirmngr/ks-engine-kdns.c   |  2 +-
+ dirmngr/ks-engine-ldap.c   |  2 +-
+ dirmngr/ldap-parse-uri.c   |  2 +-
+ dirmngr/ldap-parse-uri.h   |  2 +-
+ dirmngr/ldap-wrapper.c     |  2 +-
+ dirmngr/ldap.c             |  4 ++--
+ dirmngr/misc.c             |  2 +-
+ dirmngr/server.c           |  6 +++---
+ dirmngr/t-dns-stuff.c      |  2 +-
+ dirmngr/t-http.c           |  4 ++--
+ g10/Makefile.am            |  2 +-
+ g10/armor.c                |  9 ++++-----
+ g10/build-packet.c         | 10 +++++-----
+ g10/call-agent.c           | 14 +++++++-------
+ g10/call-dirmngr.c         | 12 ++++++------
+ g10/card-util.c            |  8 ++++----
+ g10/cipher.c               |  8 ++++----
+ g10/compress-bz2.c         |  2 +-
+ g10/compress.c             |  2 +-
+ g10/cpr.c                  |  8 ++++----
+ g10/dearmor.c              |  8 ++++----
+ g10/decrypt-data.c         |  6 +++---
+ g10/decrypt.c              | 10 +++++-----
+ g10/delkey.c               | 11 +++++------
+ g10/ecdh.c                 |  2 +-
+ g10/encrypt.c              | 10 +++++-----
+ g10/exec.c                 | 10 +++++-----
+ g10/export.c               | 18 +++++++++---------
+ g10/filter.h               |  2 +-
+ g10/free-packet.c          |  2 +-
+ g10/getkey.c               | 12 ++++++------
+ g10/gpg.c                  | 16 ++++++++--------
+ g10/gpgsql.c               |  4 ++--
+ g10/gpgv.c                 | 12 ++++++------
+ g10/helptext.c             |  6 +++---
+ g10/import.c               | 11 +++++------
+ g10/kbnode.c               |  2 +-
+ g10/keydb.c                |  4 ++--
+ g10/keydb.h                |  4 ++--
+ g10/keyedit.c              | 14 +++++++-------
+ g10/keygen.c               | 12 ++++++------
+ g10/keyid.c                |  6 +++---
+ g10/keylist.c              | 14 +++++++-------
+ g10/keyring.c              |  4 ++--
+ g10/keyserver-internal.h   |  2 +-
+ g10/keyserver.c            | 14 +++++++-------
+ g10/main.h                 |  6 +++---
+ g10/mainproc.c             | 10 +++++-----
+ g10/mdfilter.c             |  6 +++---
+ g10/migrate.c              |  2 +-
+ g10/misc.c                 |  8 ++++----
+ g10/openfile.c             |  8 ++++----
+ g10/options.h              |  2 +-
+ g10/packet.h               |  4 ++--
+ g10/parse-packet.c         |  8 ++++----
+ g10/passphrase.c           |  8 ++++----
+ g10/photoid.c              | 10 +++++-----
+ g10/pkclist.c              | 10 +++++-----
+ g10/pkglue.c               |  2 +-
+ g10/plaintext.c            |  8 ++++----
+ g10/progress.c             |  6 +++---
+ g10/pubkey-enc.c           |  8 ++++----
+ g10/revoke.c               |  9 ++++-----
+ g10/server.c               |  6 +++---
+ g10/seskey.c               |  4 ++--
+ g10/sig-check.c            |  6 +++---
+ g10/sign.c                 | 16 ++++++++--------
+ g10/skclist.c              |  6 +++---
+ g10/t-stutter.c            |  2 +-
+ g10/tdbdump.c              |  8 ++++----
+ g10/tdbio.c                |  8 ++++----
+ g10/tdbio.h                |  2 +-
+ g10/test-stubs.c           | 12 ++++++------
+ g10/textfilter.c           | 10 +++++-----
+ g10/tofu.c                 | 16 ++++++++--------
+ g10/trust.c                |  6 +++---
+ g10/trustdb.c              | 10 +++++-----
+ g10/verify.c               | 11 +++++------
+ g13/Makefile.am            |  2 +-
+ g13/backend.c              |  2 +-
+ g13/be-dmcrypt.c           |  2 +-
+ g13/be-encfs.c             |  2 +-
+ g13/be-truecrypt.c         |  2 +-
+ g13/call-syshelp.c         |  4 ++--
+ g13/create.c               |  2 +-
+ g13/g13-common.c           |  4 ++--
+ g13/g13-syshelp.c          |  6 +++---
+ g13/g13.c                  |  8 ++++----
+ g13/keyblob.c              |  2 +-
+ g13/mount.c                |  4 ++--
+ g13/mountinfo.c            |  2 +-
+ g13/runner.c               |  2 +-
+ g13/server.c               |  2 +-
+ g13/sh-blockdev.c          |  4 ++--
+ g13/sh-cmd.c               |  2 +-
+ g13/sh-dmcrypt.c           |  4 ++--
+ g13/suspend.c              |  2 +-
+ g13/t-g13tuple.c           |  2 +-
+ kbx/Makefile.am            |  2 +-
+ kbx/kbxutil.c              |  2 +-
+ kbx/keybox-dump.c          |  2 +-
+ kbx/keybox-openpgp.c       |  2 +-
+ kbx/keybox-search.c        |  4 ++--
+ kbx/keybox-util.c          |  2 +-
+ scd/Makefile.am            |  2 +-
+ scd/apdu.c                 | 10 +++++-----
+ scd/app-dinsig.c           |  4 ++--
+ scd/app-geldkarte.c        |  4 ++--
+ scd/app-help.c             |  2 +-
+ scd/app-nks.c              |  6 +++---
+ scd/app-openpgp.c          | 10 +++++-----
+ scd/app-p15.c              |  2 +-
+ scd/app-sc-hsm.c           |  2 +-
+ scd/app.c                  |  4 ++--
+ scd/command.c              |  4 ++--
+ scd/scdaemon.c             | 10 +++++-----
+ sm/Makefile.am             |  2 +-
+ sm/call-agent.c            |  8 ++++----
+ sm/call-dirmngr.c          |  4 ++--
+ sm/certchain.c             |  4 ++--
+ sm/certcheck.c             |  2 +-
+ sm/certdump.c              |  2 +-
+ sm/certlist.c              |  2 +-
+ sm/certreqgen-ui.c         |  6 +++---
+ sm/certreqgen.c            |  2 +-
+ sm/decrypt.c               |  2 +-
+ sm/delete.c                |  2 +-
+ sm/encrypt.c               |  2 +-
+ sm/export.c                |  6 +++---
+ sm/fingerprint.c           |  2 +-
+ sm/gpgsm.c                 |  8 ++++----
+ sm/import.c                |  6 +++---
+ sm/keydb.c                 |  2 +-
+ sm/keylist.c               |  4 ++--
+ sm/misc.c                  |  4 ++--
+ sm/qualified.c             |  2 +-
+ sm/server.c                |  4 ++--
+ sm/sign.c                  |  2 +-
+ sm/verify.c                |  2 +-
+ tools/Makefile.am          |  2 +-
+ tools/call-dirmngr.c       |  8 ++++----
+ tools/gpg-check-pattern.c  |  6 +++---
+ tools/gpg-connect-agent.c  |  2 +-
+ tools/gpg-wks-client.c     | 22 +++++++++++-----------
+ tools/gpgconf-comp.c       | 10 +++++-----
+ tools/gpgconf.c            |  4 ++--
+ tools/gpgsplit.c           |  4 ++--
+ tools/gpgtar-create.c      |  2 +-
+ tools/gpgtar-extract.c     |  2 +-
+ tools/gpgtar-list.c        |  2 +-
+ tools/gpgtar.c             |  6 +++---
+ tools/mime-maker.c         |  4 ++--
+ tools/mime-parser.c        |  2 +-
+ tools/send-mail.c          |  6 +++---
+ tools/wks-receive.c        |  6 +++---
+ tools/wks-util.c           | 10 +++++-----
+ 164 files changed, 446 insertions(+), 451 deletions(-)
+
+diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am
+index 93880f8..34f2c5d 100644
+--- a/dirmngr/Makefile.am
++++ b/dirmngr/Makefile.am
+@@ -31,7 +31,7 @@ endif
+ noinst_PROGRAMS = $(module_tests) $(module_net_tests) $(module_maint_tests)
+ TESTS = $(module_tests) $(module_net_tests)
+ 
+-AM_CPPFLAGS = -I$(top_srcdir)/common
++AM_CPPFLAGS =
+ 
+ include $(top_srcdir)/am/cmacros.am
+ 
+diff --git a/dirmngr/dirmngr-client.c b/dirmngr/dirmngr-client.c
+index 01cface..c1ff635 100644
+--- a/dirmngr/dirmngr-client.c
++++ b/dirmngr/dirmngr-client.c
+@@ -38,9 +38,9 @@
+ #include "../common/strlist.h"
+ #include "../common/asshelp.h"
+ 
+-#include "i18n.h"
+-#include "util.h"
+-#include "init.h"
++#include "../common/i18n.h"
++#include "../common/util.h"
++#include "../common/init.h"
+ 
+ 
+ /* Constants for the options.  */
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index bab0ac5..bf9462a 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -65,12 +65,12 @@
+ #if USE_LDAP
+ # include "ldapserver.h"
+ #endif
+-#include "asshelp.h"
++#include "../common/asshelp.h"
+ #if USE_LDAP
+ # include "ldap-wrapper.h"
+ #endif
+ #include "../common/init.h"
+-#include "gc-opt-flags.h"
++#include "../common/gc-opt-flags.h"
+ #include "dns-stuff.h"
+ #include "http-common.h"
+ 
+diff --git a/dirmngr/dirmngr_ldap.c b/dirmngr/dirmngr_ldap.c
+index a0acb8e..836ced0 100644
+--- a/dirmngr/dirmngr_ldap.c
++++ b/dirmngr/dirmngr_ldap.c
+@@ -56,8 +56,8 @@
+ #include "../common/mischelp.h"
+ #include "../common/strlist.h"
+ 
+-#include "i18n.h"
+-#include "util.h"
++#include "../common/i18n.h"
++#include "../common/util.h"
+ #include "../common/init.h"
+ 
+ /* With the ldap wrapper, there is no need for the npth_unprotect and leave
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index d72d1c7..f083058 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -68,8 +68,8 @@
+ #endif
+ 
+ #include "./dirmngr-err.h"
+-#include "util.h"
+-#include "host2net.h"
++#include "../common/util.h"
++#include "../common/host2net.h"
+ #include "dns-stuff.h"
+ 
+ #ifdef USE_NPTH
+diff --git a/dirmngr/http.c b/dirmngr/http.c
+index 0f11af7..3adf6e5 100644
+--- a/dirmngr/http.c
++++ b/dirmngr/http.c
+@@ -96,8 +96,8 @@
+ 
+ #include <assuan.h>  /* We need the socket wrapper.  */
+ 
+-#include "util.h"
+-#include "i18n.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
+ #include "dns-stuff.h"
+ #include "http.h"
+ #include "http-common.h"
+diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c
+index 811b72d..82ef7a5 100644
+--- a/dirmngr/ks-engine-finger.c
++++ b/dirmngr/ks-engine-finger.c
+@@ -26,7 +26,7 @@
+ 
+ #include "dirmngr.h"
+ #include "misc.h"
+-#include "userids.h"
++#include "../common/userids.h"
+ #include "ks-engine.h"
+ 
+ /* Print a help output for the schemata supported by this module. */
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 96c625c..1ac0ca0 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -37,7 +37,7 @@
+ 
+ #include "dirmngr.h"
+ #include "misc.h"
+-#include "userids.h"
++#include "../common/userids.h"
+ #include "dns-stuff.h"
+ #include "ks-engine.h"
+ 
+diff --git a/dirmngr/ks-engine-kdns.c b/dirmngr/ks-engine-kdns.c
+index 9bb0d42..71463fe 100644
+--- a/dirmngr/ks-engine-kdns.c
++++ b/dirmngr/ks-engine-kdns.c
+@@ -26,7 +26,7 @@
+ 
+ #include "dirmngr.h"
+ #include "misc.h"
+-#include "userids.h"
++#include "../common/userids.h"
+ #include "ks-engine.h"
+ 
+ /* Print a help output for the schemata supported by this module. */
+diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c
+index f664655..f50ba50 100644
+--- a/dirmngr/ks-engine-ldap.c
++++ b/dirmngr/ks-engine-ldap.c
+@@ -45,7 +45,7 @@
+ 
+ #include "dirmngr.h"
+ #include "misc.h"
+-#include "userids.h"
++#include "../common/userids.h"
+ #include "ks-engine.h"
+ #include "ldap-parse-uri.h"
+ 
+diff --git a/dirmngr/ldap-parse-uri.c b/dirmngr/ldap-parse-uri.c
+index 9671496..94d4efd 100644
+--- a/dirmngr/ldap-parse-uri.c
++++ b/dirmngr/ldap-parse-uri.c
+@@ -27,7 +27,7 @@
+ # include <ldap.h>
+ #endif
+ 
+-#include "util.h"
++#include "../common/util.h"
+ #include "http.h"
+ 
+ /* Returns 1 if the string is an LDAP URL (begins with ldap:, ldaps:
+diff --git a/dirmngr/ldap-parse-uri.h b/dirmngr/ldap-parse-uri.h
+index bdbb6c3..e9a3f95 100644
+--- a/dirmngr/ldap-parse-uri.h
++++ b/dirmngr/ldap-parse-uri.h
+@@ -20,7 +20,7 @@
+ #ifndef DIRMNGR_LDAP_PARSE_URI_H
+ #define DIRMNGR_LDAP_PARSE_URI_H
+ 
+-#include "util.h"
++#include "../common/util.h"
+ #include "http.h"
+ 
+ extern int ldap_uri_p (const char *url);
+diff --git a/dirmngr/ldap-wrapper.c b/dirmngr/ldap-wrapper.c
+index b313848..ac4964a 100644
+--- a/dirmngr/ldap-wrapper.c
++++ b/dirmngr/ldap-wrapper.c
+@@ -58,7 +58,7 @@
+ #include <npth.h>
+ 
+ #include "dirmngr.h"
+-#include "exechelp.h"
++#include "../common/exechelp.h"
+ #include "misc.h"
+ #include "ldap-wrapper.h"
+ 
+diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c
+index a037f5d..d661a68 100644
+--- a/dirmngr/ldap.c
++++ b/dirmngr/ldap.c
+@@ -31,12 +31,12 @@
+ #include <npth.h>
+ 
+ #include "dirmngr.h"
+-#include "exechelp.h"
++#include "../common/exechelp.h"
+ #include "crlfetch.h"
+ #include "ldapserver.h"
+ #include "misc.h"
+ #include "ldap-wrapper.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ 
+ #define UNENCODED_URL_CHARS "abcdefghijklmnopqrstuvwxyz"   \
+diff --git a/dirmngr/misc.c b/dirmngr/misc.c
+index 6d7c963..1716141 100644
+--- a/dirmngr/misc.c
++++ b/dirmngr/misc.c
+@@ -27,7 +27,7 @@
+ #include <errno.h>
+ 
+ #include "dirmngr.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "misc.h"
+ 
+ 
+diff --git a/dirmngr/server.c b/dirmngr/server.c
+index 9fa8229..f4aeadb 100644
+--- a/dirmngr/server.c
++++ b/dirmngr/server.c
+@@ -51,9 +51,9 @@
+ # include "ldap-parse-uri.h"
+ #endif
+ #include "dns-stuff.h"
+-#include "mbox-util.h"
+-#include "zb32.h"
+-#include "server-help.h"
++#include "../common/mbox-util.h"
++#include "../common/zb32.h"
++#include "../common/server-help.h"
+ 
+ /* To avoid DoS attacks we limit the size of a certificate to
+    something reasonable.  The DoS was actually only an issue back when
+diff --git a/dirmngr/t-dns-stuff.c b/dirmngr/t-dns-stuff.c
+index 23c0c6a..5a3ede1 100644
+--- a/dirmngr/t-dns-stuff.c
++++ b/dirmngr/t-dns-stuff.c
+@@ -24,7 +24,7 @@
+ #include <assert.h>
+ 
+ 
+-#include "util.h"
++#include "../common/util.h"
+ #include "dns-stuff.h"
+ 
+ #define PGM "t-dns-stuff"
+diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c
+index 35f5947..622dce5 100644
+--- a/dirmngr/t-http.c
++++ b/dirmngr/t-http.c
+@@ -38,8 +38,8 @@
+ #include <unistd.h>
+ #include <assuan.h>
+ 
+-#include "util.h"
+-#include "logging.h"
++#include "../common/util.h"
++#include "../common/logging.h"
+ #include "http.h"
+ 
+ #include <ksba.h>
+diff --git a/g10/Makefile.am b/g10/Makefile.am
+index 604be93..f1d2d17 100644
+--- a/g10/Makefile.am
++++ b/g10/Makefile.am
+@@ -23,7 +23,7 @@ EXTRA_DIST = options.skel dirmngr-conf.skel distsigkey.gpg \
+ 	     gpg.w32-manifest.in test.c t-keydb-keyring.kbx \
+ 	     t-keydb-get-keyblock.gpg t-stutter-data.asc
+ 
+-AM_CPPFLAGS = -I$(top_srcdir)/common
++AM_CPPFLAGS =
+ 
+ include $(top_srcdir)/am/cmacros.am
+ 
+diff --git a/g10/armor.c b/g10/armor.c
+index 6b7c3f7..7fb9a89 100644
+--- a/g10/armor.c
++++ b/g10/armor.c
+@@ -26,15 +26,14 @@
+ #include <ctype.h>
+ 
+ #include "gpg.h"
+-#include "status.h"
+-#include "iobuf.h"
+-#include "util.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
++#include "../common/util.h"
+ #include "filter.h"
+ #include "packet.h"
+ #include "options.h"
+ #include "main.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ #define MAX_LINELEN 20000
+ 
+diff --git a/g10/build-packet.c b/g10/build-packet.c
+index 489fadd..c81c1ab 100644
+--- a/g10/build-packet.c
++++ b/g10/build-packet.c
+@@ -25,13 +25,13 @@
+ #include <ctype.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+-#include "status.h"
+-#include "iobuf.h"
+-#include "i18n.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
++#include "../common/i18n.h"
+ #include "options.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
+ static int do_key (iobuf_t out, int ctb, PKT_public_key *pk);
+diff --git a/g10/call-agent.c b/g10/call-agent.c
+index 7c30bdb..7d627bb 100644
+--- a/g10/call-agent.c
++++ b/g10/call-agent.c
+@@ -31,16 +31,16 @@
+ 
+ #include "gpg.h"
+ #include <assuan.h>
+-#include "util.h"
+-#include "membuf.h"
++#include "../common/util.h"
++#include "../common/membuf.h"
+ #include "options.h"
+-#include "i18n.h"
+-#include "asshelp.h"
+-#include "sysutils.h"
++#include "../common/i18n.h"
++#include "../common/asshelp.h"
++#include "../common/sysutils.h"
+ #include "call-agent.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "../common/shareddefs.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ #define CONTROL_D ('D' - 'A' + 1)
+ 
+diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
+index 2f2ba98..a33cdc7 100644
+--- a/g10/call-dirmngr.c
++++ b/g10/call-dirmngr.c
+@@ -31,13 +31,13 @@
+ 
+ #include "gpg.h"
+ #include <assuan.h>
+-#include "util.h"
+-#include "membuf.h"
++#include "../common/util.h"
++#include "../common/membuf.h"
+ #include "options.h"
+-#include "i18n.h"
+-#include "asshelp.h"
+-#include "keyserver.h"
+-#include "status.h"
++#include "../common/i18n.h"
++#include "../common/asshelp.h"
++#include "../common/keyserver.h"
++#include "../common/status.h"
+ #include "call-dirmngr.h"
+ 
+ 
+diff --git a/g10/card-util.c b/g10/card-util.c
+index 969f6c9..9bc3e25 100644
+--- a/g10/card-util.c
++++ b/g10/card-util.c
+@@ -31,10 +31,10 @@
+ #if GNUPG_MAJOR_VERSION != 1
+ # include "gpg.h"
+ #endif /*GNUPG_MAJOR_VERSION != 1*/
+-#include "util.h"
+-#include "i18n.h"
+-#include "ttyio.h"
+-#include "status.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
++#include "../common/ttyio.h"
++#include "../common/status.h"
+ #include "options.h"
+ #include "main.h"
+ #include "keyserver-internal.h"
+diff --git a/g10/cipher.c b/g10/cipher.c
+index 98f398e..655937f 100644
+--- a/g10/cipher.c
++++ b/g10/cipher.c
+@@ -25,14 +25,14 @@
+ #include <errno.h>
+ 
+ #include "gpg.h"
+-#include "status.h"
+-#include "iobuf.h"
+-#include "util.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
++#include "../common/util.h"
+ #include "filter.h"
+ #include "packet.h"
+ #include "options.h"
+ #include "main.h"
+-#include "status.h"
++#include "../common/status.h"
+ 
+ 
+ #define MIN_PARTIAL_SIZE 512
+diff --git a/g10/compress-bz2.c b/g10/compress-bz2.c
+index 22cefd9..4adca9b 100644
+--- a/g10/compress-bz2.c
++++ b/g10/compress-bz2.c
+@@ -23,7 +23,7 @@
+ #include <bzlib.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+ #include "filter.h"
+ #include "main.h"
+diff --git a/g10/compress.c b/g10/compress.c
+index a14d107..61bb756 100644
+--- a/g10/compress.c
++++ b/g10/compress.c
+@@ -38,7 +38,7 @@
+ #endif
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+ #include "filter.h"
+ #include "main.h"
+diff --git a/g10/cpr.c b/g10/cpr.c
+index 4984e89..3391071 100644
+--- a/g10/cpr.c
++++ b/g10/cpr.c
+@@ -29,12 +29,12 @@
+ #endif
+ 
+ #include "gpg.h"
+-#include "util.h"
+-#include "status.h"
+-#include "ttyio.h"
++#include "../common/util.h"
++#include "../common/status.h"
++#include "../common/ttyio.h"
+ #include "options.h"
+ #include "main.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ #define CONTROL_D ('D' - 'A' + 1)
+ 
+diff --git a/g10/dearmor.c b/g10/dearmor.c
+index 6217dda..92239cc 100644
+--- a/g10/dearmor.c
++++ b/g10/dearmor.c
+@@ -24,14 +24,14 @@
+ #include <errno.h>
+ 
+ #include "gpg.h"
+-#include "status.h"
+-#include "iobuf.h"
+-#include "util.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
++#include "../common/util.h"
+ #include "filter.h"
+ #include "packet.h"
+ #include "options.h"
+ #include "main.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ /****************
+  * Take an armor file and write it out without armor
+diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c
+index 585b150..11a253f 100644
+--- a/g10/decrypt-data.c
++++ b/g10/decrypt-data.c
+@@ -24,11 +24,11 @@
+ #include <string.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+ #include "options.h"
+-#include "i18n.h"
+-#include "status.h"
++#include "../common/i18n.h"
++#include "../common/status.h"
+ 
+ 
+ static int mdc_decode_filter ( void *opaque, int control, IOBUF a,
+diff --git a/g10/decrypt.c b/g10/decrypt.c
+index c99f064..4d6734d 100644
+--- a/g10/decrypt.c
++++ b/g10/decrypt.c
+@@ -27,13 +27,13 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
+-#include "iobuf.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/status.h"
++#include "../common/i18n.h"
+ 
+ /* Assume that the input is an encrypted message and decrypt
+  * (and if signed, verify the signature on) it.
+diff --git a/g10/delkey.c b/g10/delkey.c
+index 06aca9e..547b40d 100644
+--- a/g10/delkey.c
++++ b/g10/delkey.c
+@@ -29,16 +29,15 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
+-#include "iobuf.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+ #include "trustdb.h"
+ #include "filter.h"
+-#include "ttyio.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/ttyio.h"
++#include "../common/i18n.h"
+ #include "call-agent.h"
+ 
+ 
+diff --git a/g10/ecdh.c b/g10/ecdh.c
+index 89e8cf1..6c2a56b 100644
+--- a/g10/ecdh.c
++++ b/g10/ecdh.c
+@@ -24,7 +24,7 @@
+ #include <errno.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "pkglue.h"
+ #include "main.h"
+ #include "options.h"
+diff --git a/g10/encrypt.c b/g10/encrypt.c
+index 6130ba0..0a892c2 100644
+--- a/g10/encrypt.c
++++ b/g10/encrypt.c
+@@ -28,15 +28,15 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
+-#include "iobuf.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+ #include "filter.h"
+ #include "trustdb.h"
+-#include "i18n.h"
+-#include "status.h"
++#include "../common/i18n.h"
++#include "../common/status.h"
+ #include "pkglue.h"
+ 
+ 
+diff --git a/g10/exec.c b/g10/exec.c
+index b868a1f..74a8397 100644
+--- a/g10/exec.c
++++ b/g10/exec.c
+@@ -45,11 +45,11 @@
+ 
+ #include "gpg.h"
+ #include "options.h"
+-#include "i18n.h"
+-#include "iobuf.h"
+-#include "util.h"
+-#include "membuf.h"
+-#include "sysutils.h"
++#include "../common/i18n.h"
++#include "../common/iobuf.h"
++#include "../common/util.h"
++#include "../common/membuf.h"
++#include "../common/sysutils.h"
+ #include "exec.h"
+ 
+ #ifdef NO_EXEC
+diff --git a/g10/export.c b/g10/export.c
+index 323bf17..2da5309 100644
+--- a/g10/export.c
++++ b/g10/export.c
+@@ -28,17 +28,17 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+-#include "i18n.h"
+-#include "membuf.h"
+-#include "host2net.h"
+-#include "zb32.h"
+-#include "recsel.h"
+-#include "mbox-util.h"
+-#include "init.h"
++#include "../common/i18n.h"
++#include "../common/membuf.h"
++#include "../common/host2net.h"
++#include "../common/zb32.h"
++#include "../common/recsel.h"
++#include "../common/mbox-util.h"
++#include "../common/init.h"
+ #include "trustdb.h"
+ #include "call-agent.h"
+ 
+diff --git a/g10/filter.h b/g10/filter.h
+index 7accd7d..275608d 100644
+--- a/g10/filter.h
++++ b/g10/filter.h
+@@ -20,7 +20,7 @@
+ #ifndef G10_FILTER_H
+ #define G10_FILTER_H
+ 
+-#include "types.h"
++#include "../common/types.h"
+ #include "dek.h"
+ 
+ typedef struct {
+diff --git a/g10/free-packet.c b/g10/free-packet.c
+index 6038d26..01db2a0 100644
+--- a/g10/free-packet.c
++++ b/g10/free-packet.c
+@@ -24,7 +24,7 @@
+ #include <string.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+ #include "../common/iobuf.h"
+ #include "options.h"
+diff --git a/g10/getkey.c b/g10/getkey.c
+index be7367f..548f8bf 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -26,19 +26,19 @@
+ #include <ctype.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+-#include "iobuf.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+ #include "options.h"
+ #include "main.h"
+ #include "trustdb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keyserver-internal.h"
+ #include "call-agent.h"
+-#include "host2net.h"
+-#include "mbox-util.h"
+-#include "status.h"
++#include "../common/host2net.h"
++#include "../common/mbox-util.h"
++#include "../common/status.h"
+ 
+ #define MAX_PK_CACHE_ENTRIES   PK_UID_CACHE_SIZE
+ #define MAX_UID_CACHE_ENTRIES  PK_UID_CACHE_SIZE
+diff --git a/g10/gpg.c b/g10/gpg.c
+index 654dcb9..eeda60f 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -41,22 +41,22 @@
+ #include "gpg.h"
+ #include <assuan.h>
+ #include "../common/iobuf.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+-#include "membuf.h"
++#include "../common/membuf.h"
+ #include "main.h"
+ #include "options.h"
+ #include "keydb.h"
+ #include "trustdb.h"
+ #include "filter.h"
+-#include "ttyio.h"
+-#include "i18n.h"
+-#include "sysutils.h"
+-#include "status.h"
++#include "../common/ttyio.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
++#include "../common/status.h"
+ #include "keyserver-internal.h"
+ #include "exec.h"
+-#include "gc-opt-flags.h"
+-#include "asshelp.h"
++#include "../common/gc-opt-flags.h"
++#include "../common/asshelp.h"
+ #include "call-dirmngr.h"
+ #include "tofu.h"
+ #include "../common/init.h"
+diff --git a/g10/gpgsql.c b/g10/gpgsql.c
+index 661bd35..5b75569 100644
+--- a/g10/gpgsql.c
++++ b/g10/gpgsql.c
+@@ -23,8 +23,8 @@
+ #include <string.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
+-#include "logging.h"
++#include "../common/util.h"
++#include "../common/logging.h"
+ 
+ #include "gpgsql.h"
+ 
+diff --git a/g10/gpgv.c b/g10/gpgv.c
+index a6d1add..5ee26b4 100644
+--- a/g10/gpgv.c
++++ b/g10/gpgv.c
+@@ -35,18 +35,18 @@
+ 
+ #define INCLUDED_BY_MAIN_MODULE 1
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+-#include "iobuf.h"
++#include "../common/iobuf.h"
+ #include "main.h"
+ #include "options.h"
+ #include "keydb.h"
+ #include "trustdb.h"
+ #include "filter.h"
+-#include "ttyio.h"
+-#include "i18n.h"
+-#include "sysutils.h"
+-#include "status.h"
++#include "../common/ttyio.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
++#include "../common/status.h"
+ #include "call-agent.h"
+ #include "../common/init.h"
+ 
+diff --git a/g10/helptext.c b/g10/helptext.c
+index 730f699..8b85101 100644
+--- a/g10/helptext.c
++++ b/g10/helptext.c
+@@ -24,10 +24,10 @@
+ #include <string.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
+-#include "ttyio.h"
++#include "../common/util.h"
++#include "../common/ttyio.h"
+ #include "main.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ 
+diff --git a/g10/import.c b/g10/import.c
+index 6383d70..640618a 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -27,15 +27,14 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "trustdb.h"
+ #include "main.h"
+-#include "i18n.h"
+-#include "ttyio.h"
+-#include "status.h"
+-#include "recsel.h"
++#include "../common/i18n.h"
++#include "../common/ttyio.h"
++#include "../common/recsel.h"
+ #include "keyserver-internal.h"
+ #include "call-agent.h"
+ #include "../common/membuf.h"
+diff --git a/g10/kbnode.c b/g10/kbnode.c
+index 6700dc0..153dce2 100644
+--- a/g10/kbnode.c
++++ b/g10/kbnode.c
+@@ -24,7 +24,7 @@
+ #include <string.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "../common/init.h"
+ #include "packet.h"
+ #include "keydb.h"
+diff --git a/g10/keydb.c b/g10/keydb.c
+index 4c5149d..27dacf2 100644
+--- a/g10/keydb.c
++++ b/g10/keydb.c
+@@ -28,14 +28,14 @@
+ #include <unistd.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "options.h"
+ #include "main.h" /*try_make_homedir ()*/
+ #include "packet.h"
+ #include "keyring.h"
+ #include "../kbx/keybox.h"
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ static int active_handles;
+ 
+diff --git a/g10/keydb.h b/g10/keydb.h
+index c9f5b1c..6f57583 100644
+--- a/g10/keydb.h
++++ b/g10/keydb.h
+@@ -22,8 +22,8 @@
+ #ifndef G10_KEYDB_H
+ #define G10_KEYDB_H
+ 
+-#include "types.h"
+-#include "util.h"
++#include "../common/types.h"
++#include "../common/util.h"
+ #include "packet.h"
+ 
+ /* What qualifies as a certification (rather than a signature?) */
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index c591600..c10a011 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -33,20 +33,20 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
+-#include "iobuf.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+ #include "photoid.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+ #include "trustdb.h"
+ #include "filter.h"
+-#include "ttyio.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/ttyio.h"
++#include "../common/status.h"
++#include "../common/i18n.h"
+ #include "keyserver-internal.h"
+ #include "call-agent.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ #include "tofu.h"
+ 
+ static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
+diff --git a/g10/keygen.c b/g10/keygen.c
+index 201ebaa..44f139a 100644
+--- a/g10/keygen.c
++++ b/g10/keygen.c
+@@ -29,21 +29,21 @@
+ #include <unistd.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+ #include "packet.h"
+-#include "ttyio.h"
++#include "../common/ttyio.h"
+ #include "options.h"
+ #include "keydb.h"
+ #include "trustdb.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/status.h"
++#include "../common/i18n.h"
+ #include "keyserver-internal.h"
+ #include "call-agent.h"
+ #include "pkglue.h"
+ #include "../common/shareddefs.h"
+-#include "host2net.h"
+-#include "mbox-util.h"
++#include "../common/host2net.h"
++#include "../common/mbox-util.h"
+ 
+ 
+ /* The default algorithms.  If you change them remember to change them
+diff --git a/g10/keyid.c b/g10/keyid.c
+index 6e8d97f..1d3f46c 100644
+--- a/g10/keyid.c
++++ b/g10/keyid.c
+@@ -28,14 +28,14 @@
+ #include <time.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+ #include "packet.h"
+ #include "options.h"
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "rmd160.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ 
+ #define KEYID_STR_SIZE 19
+diff --git a/g10/keylist.c b/g10/keylist.c
+index 2684f59..93b5ee6 100644
+--- a/g10/keylist.c
++++ b/g10/keylist.c
+@@ -31,18 +31,18 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "keydb.h"
+ #include "photoid.h"
+-#include "util.h"
+-#include "ttyio.h"
++#include "../common/util.h"
++#include "../common/ttyio.h"
+ #include "trustdb.h"
+ #include "main.h"
+-#include "i18n.h"
+-#include "status.h"
++#include "../common/i18n.h"
++#include "../common/status.h"
+ #include "call-agent.h"
+-#include "mbox-util.h"
+-#include "zb32.h"
++#include "../common/mbox-util.h"
++#include "../common/zb32.h"
+ #include "tofu.h"
+ 
+ 
+diff --git a/g10/keyring.c b/g10/keyring.c
+index 9b7b5fd..31f60f9 100644
+--- a/g10/keyring.c
++++ b/g10/keyring.c
+@@ -28,13 +28,13 @@
+ #include <sys/stat.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "keyring.h"
+ #include "packet.h"
+ #include "keydb.h"
+ #include "options.h"
+ #include "main.h" /*for check_key_signature()*/
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "../kbx/keybox.h"
+ 
+ 
+diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h
+index 77b362e..02452e8 100644
+--- a/g10/keyserver-internal.h
++++ b/g10/keyserver-internal.h
+@@ -23,7 +23,7 @@
+ #include <time.h>
+ #include "../common/keyserver.h"
+ #include "../common/iobuf.h"
+-#include "types.h"
++#include "../common/types.h"
+ 
+ int parse_keyserver_options(char *options);
+ void free_keyserver_spec(struct keyserver_spec *keyserver);
+diff --git a/g10/keyserver.c b/g10/keyserver.c
+index c7363c9..0794527 100644
+--- a/g10/keyserver.c
++++ b/g10/keyserver.c
+@@ -27,21 +27,21 @@
+ #include <errno.h>
+ 
+ #include "gpg.h"
+-#include "iobuf.h"
++#include "../common/iobuf.h"
+ #include "filter.h"
+ #include "keydb.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "exec.h"
+ #include "main.h"
+-#include "i18n.h"
+-#include "ttyio.h"
++#include "../common/i18n.h"
++#include "../common/ttyio.h"
+ #include "options.h"
+ #include "packet.h"
+ #include "trustdb.h"
+ #include "keyserver-internal.h"
+-#include "util.h"
+-#include "membuf.h"
+-#include "mbox-util.h"
++#include "../common/util.h"
++#include "../common/membuf.h"
++#include "../common/mbox-util.h"
+ #include "call-dirmngr.h"
+ 
+ #ifdef HAVE_W32_SYSTEM
+diff --git a/g10/main.h b/g10/main.h
+index 6837e98..f58f041 100644
+--- a/g10/main.h
++++ b/g10/main.h
+@@ -20,10 +20,10 @@
+ #ifndef G10_MAIN_H
+ #define G10_MAIN_H
+ 
+-#include "types.h"
+-#include "iobuf.h"
++#include "../common/types.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ 
+ /* It could be argued that the default cipher should be 3DES rather
+    than AES128, and the default compression should be 0
+diff --git a/g10/mainproc.c b/g10/mainproc.c
+index 4f8d0be..2acd51e 100644
+--- a/g10/mainproc.c
++++ b/g10/mainproc.c
+@@ -25,19 +25,19 @@
+ #include <time.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+-#include "iobuf.h"
++#include "../common/iobuf.h"
+ #include "options.h"
+ #include "keydb.h"
+ #include "filter.h"
+ #include "main.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/status.h"
++#include "../common/i18n.h"
+ #include "trustdb.h"
+ #include "keyserver-internal.h"
+ #include "photoid.h"
+-#include "mbox-util.h"
++#include "../common/mbox-util.h"
+ #include "call-dirmngr.h"
+ 
+ /* Put an upper limit on nested packets.  The 32 is an arbitrary
+diff --git a/g10/mdfilter.c b/g10/mdfilter.c
+index 69b226c..f3318f1 100644
+--- a/g10/mdfilter.c
++++ b/g10/mdfilter.c
+@@ -24,9 +24,9 @@
+ #include <errno.h>
+ 
+ #include "gpg.h"
+-#include "status.h"
+-#include "iobuf.h"
+-#include "util.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
++#include "../common/util.h"
+ #include "filter.h"
+ 
+ 
+diff --git a/g10/migrate.c b/g10/migrate.c
+index 6ff1014..c52c67a 100644
+--- a/g10/migrate.c
++++ b/g10/migrate.c
+@@ -27,7 +27,7 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+ #include "call-agent.h"
+ 
+diff --git a/g10/misc.c b/g10/misc.c
+index ac00009..c69f994 100644
+--- a/g10/misc.c
++++ b/g10/misc.c
+@@ -59,15 +59,15 @@
+ 
+ #include "gpg.h"
+ #ifdef HAVE_W32_SYSTEM
+-# include "status.h"
++# include "../common/status.h"
+ #endif /*HAVE_W32_SYSTEM*/
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+ #include "photoid.h"
+ #include "options.h"
+ #include "call-agent.h"
+-#include "i18n.h"
+-#include "zb32.h"
++#include "../common/i18n.h"
++#include "../common/zb32.h"
+ 
+ 
+ #ifdef ENABLE_SELINUX_HACKS
+diff --git a/g10/openfile.c b/g10/openfile.c
+index f62deec..2257107 100644
+--- a/g10/openfile.c
++++ b/g10/openfile.c
+@@ -29,12 +29,12 @@
+ #include <unistd.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
+-#include "ttyio.h"
++#include "../common/util.h"
++#include "../common/ttyio.h"
+ #include "options.h"
+ #include "main.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/status.h"
++#include "../common/i18n.h"
+ 
+ #ifdef USE_ONLY_8DOT3
+ #define SKELEXT ".skl"
+diff --git a/g10/options.h b/g10/options.h
+index 88a8f32..def6385 100644
+--- a/g10/options.h
++++ b/g10/options.h
+@@ -22,7 +22,7 @@
+ #define G10_OPTIONS_H
+ 
+ #include <sys/types.h>
+-#include <types.h>
++#include "../common/types.h"
+ #include <stdint.h>
+ #include "main.h"
+ #include "packet.h"
+diff --git a/g10/packet.h b/g10/packet.h
+index 9780d93..3457f53 100644
+--- a/g10/packet.h
++++ b/g10/packet.h
+@@ -22,14 +22,14 @@
+ #ifndef G10_PACKET_H
+ #define G10_PACKET_H
+ 
+-#include "types.h"
++#include "../common/types.h"
+ #include "../common/iobuf.h"
+ #include "../common/strlist.h"
+ #include "dek.h"
+ #include "filter.h"
+ #include "../common/openpgpdefs.h"
+ #include "../common/userids.h"
+-#include "util.h"
++#include "../common/util.h"
+ 
+ #define DEBUG_PARSE_PACKET 1
+ 
+diff --git a/g10/parse-packet.c b/g10/parse-packet.c
+index 7f44ce5..06b286b 100644
+--- a/g10/parse-packet.c
++++ b/g10/parse-packet.c
+@@ -26,15 +26,15 @@
+ #include <string.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+-#include "iobuf.h"
++#include "../common/iobuf.h"
+ #include "filter.h"
+ #include "photoid.h"
+ #include "options.h"
+ #include "main.h"
+-#include "i18n.h"
+-#include "host2net.h"
++#include "../common/i18n.h"
++#include "../common/host2net.h"
+ 
+ 
+ /* Maximum length of packets to avoid excessive memory allocation.  */
+diff --git a/g10/passphrase.c b/g10/passphrase.c
+index 37abc0f..02371fe 100644
+--- a/g10/passphrase.c
++++ b/g10/passphrase.c
+@@ -33,13 +33,13 @@
+ #endif
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "options.h"
+-#include "ttyio.h"
++#include "../common/ttyio.h"
+ #include "keydb.h"
+ #include "main.h"
+-#include "i18n.h"
+-#include "status.h"
++#include "../common/i18n.h"
++#include "../common/status.h"
+ #include "call-agent.h"
+ #include "../common/shareddefs.h"
+ 
+diff --git a/g10/photoid.c b/g10/photoid.c
+index 8b193b3..bcea64f 100644
+--- a/g10/photoid.c
++++ b/g10/photoid.c
+@@ -32,17 +32,17 @@
+ #endif
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "exec.h"
+ #include "keydb.h"
+-#include "i18n.h"
+-#include "iobuf.h"
++#include "../common/i18n.h"
++#include "../common/iobuf.h"
+ #include "options.h"
+ #include "main.h"
+ #include "photoid.h"
+-#include "ttyio.h"
++#include "../common/ttyio.h"
+ #include "trustdb.h"
+ 
+ /* Generate a new photo id packet, or return NULL if canceled.
+diff --git a/g10/pkclist.c b/g10/pkclist.c
+index 012f751..698794e 100644
+--- a/g10/pkclist.c
++++ b/g10/pkclist.c
+@@ -27,15 +27,15 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+ #include "trustdb.h"
+-#include "ttyio.h"
+-#include "status.h"
++#include "../common/ttyio.h"
++#include "../common/status.h"
+ #include "photoid.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "tofu.h"
+ 
+ #define CONTROL_D ('D' - 'A' + 1)
+diff --git a/g10/pkglue.c b/g10/pkglue.c
+index ce24a2e..8021a94 100644
+--- a/g10/pkglue.c
++++ b/g10/pkglue.c
+@@ -25,7 +25,7 @@
+ #include <errno.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "pkglue.h"
+ #include "main.h"
+ #include "options.h"
+diff --git a/g10/plaintext.c b/g10/plaintext.c
+index 40ce603..c5d1ddb 100644
+--- a/g10/plaintext.c
++++ b/g10/plaintext.c
+@@ -29,14 +29,14 @@
+ #endif
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "ttyio.h"
++#include "../common/ttyio.h"
+ #include "filter.h"
+ #include "main.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/status.h"
++#include "../common/i18n.h"
+ 
+ 
+ /* Get the output filename.  On success, the actual filename that is
+diff --git a/g10/progress.c b/g10/progress.c
+index feb639e..7e777d4 100644
+--- a/g10/progress.c
++++ b/g10/progress.c
+@@ -21,10 +21,10 @@
+ #include <stdio.h>
+ 
+ #include "gpg.h"
+-#include "iobuf.h"
++#include "../common/iobuf.h"
+ #include "filter.h"
+-#include "status.h"
+-#include "util.h"
++#include "../common/status.h"
++#include "../common/util.h"
+ #include "options.h"
+ 
+ /* Create a new context for use with the progress filter.  We need to
+diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
+index e037c12..cc962cf 100644
+--- a/g10/pubkey-enc.c
++++ b/g10/pubkey-enc.c
+@@ -24,17 +24,17 @@
+ #include <string.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+ #include "keydb.h"
+ #include "trustdb.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "options.h"
+ #include "main.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "pkglue.h"
+ #include "call-agent.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ 
+ static gpg_error_t get_it (PKT_pubkey_enc *k,
+diff --git a/g10/revoke.c b/g10/revoke.c
+index 3a2b068..122699f 100644
+--- a/g10/revoke.c
++++ b/g10/revoke.c
+@@ -28,13 +28,12 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+-#include "ttyio.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/ttyio.h"
++#include "../common/i18n.h"
+ #include "call-agent.h"
+ 
+ struct revocation_reason_info {
+diff --git a/g10/server.c b/g10/server.c
+index e3a3bad..60b447c 100644
+--- a/g10/server.c
++++ b/g10/server.c
+@@ -29,12 +29,12 @@
+ 
+ #include "gpg.h"
+ #include <assuan.h>
+-#include "util.h"
+-#include "i18n.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
+ #include "options.h"
+ #include "../common/server-help.h"
+ #include "../common/sysutils.h"
+-#include "status.h"
++#include "../common/status.h"
+ 
+ 
+ #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
+diff --git a/g10/seskey.c b/g10/seskey.c
+index b2f7169..8617938 100644
+--- a/g10/seskey.c
++++ b/g10/seskey.c
+@@ -24,10 +24,10 @@
+ #include <string.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "options.h"
+ #include "main.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ /* Generate a new session key in *DEK that is appropriate for the
+diff --git a/g10/sig-check.c b/g10/sig-check.c
+index 4df29af..4e6ca43 100644
+--- a/g10/sig-check.c
++++ b/g10/sig-check.c
+@@ -25,12 +25,12 @@
+ #include <string.h>
+ 
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+ #include "keydb.h"
+ #include "main.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/status.h"
++#include "../common/i18n.h"
+ #include "options.h"
+ #include "pkglue.h"
+ 
+diff --git a/g10/sign.c b/g10/sign.c
+index ff099b3..801c809 100644
+--- a/g10/sign.c
++++ b/g10/sign.c
+@@ -27,20 +27,20 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
+-#include "iobuf.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+ #include "filter.h"
+-#include "ttyio.h"
++#include "../common/ttyio.h"
+ #include "trustdb.h"
+-#include "status.h"
+-#include "i18n.h"
++#include "../common/status.h"
++#include "../common/i18n.h"
+ #include "pkglue.h"
+-#include "sysutils.h"
++#include "../common/sysutils.h"
+ #include "call-agent.h"
+-#include "mbox-util.h"
++#include "../common/mbox-util.h"
+ 
+ #ifdef HAVE_DOSISH_SYSTEM
+ #define LF "\r\n"
+diff --git a/g10/skclist.c b/g10/skclist.c
+index cedbce7..7a791b3 100644
+--- a/g10/skclist.c
++++ b/g10/skclist.c
+@@ -27,10 +27,10 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "keydb.h"
+-#include "util.h"
+-#include "i18n.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
+ 
+ 
+ /* Return true if Libgcrypt's RNG is in faked mode.  */
+diff --git a/g10/t-stutter.c b/g10/t-stutter.c
+index 359cdf6..f4a9a59 100644
+--- a/g10/t-stutter.c
++++ b/g10/t-stutter.c
+@@ -54,7 +54,7 @@
+ #include "gpg.h"
+ #include "main.h"
+ #include "../common/types.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "dek.h"
+ #include "../common/logging.h"
+ 
+diff --git a/g10/tdbdump.c b/g10/tdbdump.c
+index ab2f072..a5ad32d 100644
+--- a/g10/tdbdump.c
++++ b/g10/tdbdump.c
+@@ -29,15 +29,15 @@
+ #include <unistd.h>
+ 
+ #include "gpg.h"
+-#include "status.h"
+-#include "iobuf.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "trustdb.h"
+ #include "options.h"
+ #include "packet.h"
+ #include "main.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "tdbio.h"
+ 
+ 
+diff --git a/g10/tdbio.c b/g10/tdbio.c
+index c1cb312..a7b7412 100644
+--- a/g10/tdbio.c
++++ b/g10/tdbio.c
+@@ -29,12 +29,12 @@
+ #include <unistd.h>
+ 
+ #include "gpg.h"
+-#include "status.h"
+-#include "iobuf.h"
+-#include "util.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
++#include "../common/util.h"
+ #include "options.h"
+ #include "main.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "trustdb.h"
+ #include "tdbio.h"
+ 
+diff --git a/g10/tdbio.h b/g10/tdbio.h
+index 1f66b03..e2cbbff 100644
+--- a/g10/tdbio.h
++++ b/g10/tdbio.h
+@@ -20,7 +20,7 @@
+ #ifndef G10_TDBIO_H
+ #define G10_TDBIO_H
+ 
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ #define TRUST_RECORD_LEN 40
+ #define SIGS_PER_RECORD 	((TRUST_RECORD_LEN-10)/5)
+diff --git a/g10/test-stubs.c b/g10/test-stubs.c
+index a74df20..d541e0d 100644
+--- a/g10/test-stubs.c
++++ b/g10/test-stubs.c
+@@ -28,18 +28,18 @@
+ 
+ #define INCLUDED_BY_MAIN_MODULE 1
+ #include "gpg.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "packet.h"
+-#include "iobuf.h"
++#include "../common/iobuf.h"
+ #include "main.h"
+ #include "options.h"
+ #include "keydb.h"
+ #include "trustdb.h"
+ #include "filter.h"
+-#include "ttyio.h"
+-#include "i18n.h"
+-#include "sysutils.h"
+-#include "status.h"
++#include "../common/ttyio.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
++#include "../common/status.h"
+ #include "call-agent.h"
+ 
+ int g10_errors_seen;
+diff --git a/g10/textfilter.c b/g10/textfilter.c
+index cb5d444..96666cf 100644
+--- a/g10/textfilter.c
++++ b/g10/textfilter.c
+@@ -24,13 +24,13 @@
+ #include <errno.h>
+ 
+ #include "gpg.h"
+-#include "status.h"
+-#include "iobuf.h"
+-#include "util.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
++#include "../common/util.h"
+ #include "filter.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "options.h"
+-#include "status.h"
++#include "../common/status.h"
+ 
+ #ifdef HAVE_DOSISH_SYSTEM
+ #define LF "\r\n"
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 8c41ad7..9d6a457 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -31,17 +31,17 @@
+ #include <time.h>
+ 
+ #include "gpg.h"
+-#include "types.h"
+-#include "logging.h"
+-#include "stringhelp.h"
++#include "../common/types.h"
++#include "../common/logging.h"
++#include "../common/stringhelp.h"
+ #include "options.h"
+-#include "mbox-util.h"
+-#include "i18n.h"
+-#include "ttyio.h"
++#include "../common/mbox-util.h"
++#include "../common/i18n.h"
++#include "../common/ttyio.h"
+ #include "trustdb.h"
+-#include "mkdir_p.h"
++#include "../common/mkdir_p.h"
+ #include "gpgsql.h"
+-#include "status.h"
++#include "../common/status.h"
+ #include "sqrtu32.h"
+ 
+ #include "tofu.h"
+diff --git a/g10/trust.c b/g10/trust.c
+index d0ea77e..77fde4c 100644
+--- a/g10/trust.c
++++ b/g10/trust.c
+@@ -26,13 +26,13 @@
+ 
+ #include "gpg.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "options.h"
+ #include "packet.h"
+ #include "main.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "trustdb.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ 
+ /* Return true if key is disabled.  Note that this is usually used via
+diff --git a/g10/trustdb.c b/g10/trustdb.c
+index 7443051..a0b9d5f 100644
+--- a/g10/trustdb.c
++++ b/g10/trustdb.c
+@@ -29,15 +29,15 @@
+ #endif /* !DISABLE_REGEX */
+ 
+ #include "gpg.h"
+-#include "status.h"
+-#include "iobuf.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "options.h"
+ #include "packet.h"
+ #include "main.h"
+-#include "mbox-util.h"
+-#include "i18n.h"
++#include "../common/mbox-util.h"
++#include "../common/i18n.h"
+ #include "tdbio.h"
+ #include "trustdb.h"
+ #include "tofu.h"
+diff --git a/g10/verify.c b/g10/verify.c
+index 7327e85..4399f71 100644
+--- a/g10/verify.c
++++ b/g10/verify.c
+@@ -27,15 +27,14 @@
+ #include "gpg.h"
+ #include "options.h"
+ #include "packet.h"
+-#include "status.h"
+-#include "iobuf.h"
++#include "../common/status.h"
++#include "../common/iobuf.h"
+ #include "keydb.h"
+-#include "util.h"
++#include "../common/util.h"
+ #include "main.h"
+-#include "status.h"
+ #include "filter.h"
+-#include "ttyio.h"
+-#include "i18n.h"
++#include "../common/ttyio.h"
++#include "../common/i18n.h"
+ 
+ 
+ /****************
+diff --git a/g13/Makefile.am b/g13/Makefile.am
+index cc0e6a8..dfacc99 100644
+--- a/g13/Makefile.am
++++ b/g13/Makefile.am
+@@ -26,7 +26,7 @@ sbin_PROGRAMS = g13-syshelp
+ noinst_PROGRAMS = $(module_tests)
+ TESTS = $(module_tests)
+ 
+-AM_CPPFLAGS = -I$(top_srcdir)/common
++AM_CPPFLAGS =
+ 
+ include $(top_srcdir)/am/cmacros.am
+ 
+diff --git a/g13/backend.c b/g13/backend.c
+index a495f8a..0123b45 100644
+--- a/g13/backend.c
++++ b/g13/backend.c
+@@ -26,7 +26,7 @@
+ #include <sys/stat.h>
+ 
+ #include "g13.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keyblob.h"
+ #include "backend.h"
+ #include "be-encfs.h"
+diff --git a/g13/be-dmcrypt.c b/g13/be-dmcrypt.c
+index e048b99..59b586d 100644
+--- a/g13/be-dmcrypt.c
++++ b/g13/be-dmcrypt.c
+@@ -25,7 +25,7 @@
+ #include <unistd.h>
+ 
+ #include "g13.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keyblob.h"
+ #include "call-syshelp.h"
+ #include "be-dmcrypt.h"
+diff --git a/g13/be-encfs.c b/g13/be-encfs.c
+index 6c648ab..0e2c68b 100644
+--- a/g13/be-encfs.c
++++ b/g13/be-encfs.c
+@@ -26,7 +26,7 @@
+ #include <assert.h>
+ 
+ #include "g13.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keyblob.h"
+ #include "be-encfs.h"
+ #include "runner.h"
+diff --git a/g13/be-truecrypt.c b/g13/be-truecrypt.c
+index e75b936..1ce992f 100644
+--- a/g13/be-truecrypt.c
++++ b/g13/be-truecrypt.c
+@@ -25,7 +25,7 @@
+ #include <unistd.h>
+ 
+ #include "g13.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "be-truecrypt.h"
+ 
+ 
+diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c
+index adffc6e..8a50c3f 100644
+--- a/g13/call-syshelp.c
++++ b/g13/call-syshelp.c
+@@ -28,10 +28,10 @@
+ 
+ #include "g13.h"
+ #include <assuan.h>
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "g13tuple.h"
+ #include "keyblob.h"
+-#include "membuf.h"
++#include "../common/membuf.h"
+ #include "create.h"
+ #include "call-syshelp.h"
+ 
+diff --git a/g13/create.c b/g13/create.c
+index 573039d..d55b859 100644
+--- a/g13/create.c
++++ b/g13/create.c
+@@ -27,7 +27,7 @@
+ #include <assert.h>
+ 
+ #include "g13.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "create.h"
+ 
+ #include "keyblob.h"
+diff --git a/g13/g13-common.c b/g13/g13-common.c
+index 8370907..35cb131 100644
+--- a/g13/g13-common.c
++++ b/g13/g13-common.c
+@@ -29,8 +29,8 @@
+ #include "g13-common.h"
+ #include <gcrypt.h>
+ #include <assuan.h>
+-#include "i18n.h"
+-#include "sysutils.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
+ 
+ 
+ 
+diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c
+index 8b8a4a7..bf71ac2 100644
+--- a/g13/g13-syshelp.c
++++ b/g13/g13-syshelp.c
+@@ -36,9 +36,9 @@
+ #include <gcrypt.h>
+ #include <assuan.h>
+ 
+-#include "i18n.h"
+-#include "sysutils.h"
+-#include "asshelp.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
++#include "../common/asshelp.h"
+ #include "../common/init.h"
+ #include "keyblob.h"
+ 
+diff --git a/g13/g13.c b/g13/g13.c
+index 0553c85..4b925ed 100644
+--- a/g13/g13.c
++++ b/g13/g13.c
+@@ -32,10 +32,10 @@
+ #include <gcrypt.h>
+ #include <assuan.h>
+ 
+-#include "i18n.h"
+-#include "sysutils.h"
+-#include "gc-opt-flags.h"
+-#include "asshelp.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
++#include "../common/gc-opt-flags.h"
++#include "../common/asshelp.h"
+ #include "../common/init.h"
+ #include "keyblob.h"
+ #include "server.h"
+diff --git a/g13/keyblob.c b/g13/keyblob.c
+index 81863bb..1fb9be7 100644
+--- a/g13/keyblob.c
++++ b/g13/keyblob.c
+@@ -32,7 +32,7 @@
+ 
+ #include "keyblob.h"
+ #include "../common/sysutils.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ 
+ /* Parse the header prefix and return the length of the entire header.  */
+diff --git a/g13/mount.c b/g13/mount.c
+index 7814d5c..dc415b1 100644
+--- a/g13/mount.c
++++ b/g13/mount.c
+@@ -27,7 +27,7 @@
+ #include <assert.h>
+ 
+ #include "g13.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "mount.h"
+ 
+ #include "keyblob.h"
+@@ -35,7 +35,7 @@
+ #include "g13tuple.h"
+ #include "mountinfo.h"
+ #include "runner.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ #include "server.h"  /*(g13_keyblob_decrypt)*/
+ #include "../common/sysutils.h"
+ #include "call-syshelp.h"
+diff --git a/g13/mountinfo.c b/g13/mountinfo.c
+index 26eca0c..ed898b8 100644
+--- a/g13/mountinfo.c
++++ b/g13/mountinfo.c
+@@ -27,7 +27,7 @@
+ #include <assert.h>
+ 
+ #include "g13.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "mountinfo.h"
+ 
+ #include "keyblob.h"
+diff --git a/g13/runner.c b/g13/runner.c
+index af2e836..138269d 100644
+--- a/g13/runner.c
++++ b/g13/runner.c
+@@ -27,7 +27,7 @@
+ #include <npth.h>
+ 
+ #include "g13.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keyblob.h"
+ #include "runner.h"
+ #include "../common/exechelp.h"
+diff --git a/g13/server.c b/g13/server.c
+index e3cb313..bbe42d4 100644
+--- a/g13/server.c
++++ b/g13/server.c
+@@ -27,7 +27,7 @@
+ 
+ #include "g13.h"
+ #include <assuan.h>
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keyblob.h"
+ #include "server.h"
+ #include "create.h"
+diff --git a/g13/sh-blockdev.c b/g13/sh-blockdev.c
+index 6c12dde..a477a67 100644
+--- a/g13/sh-blockdev.c
++++ b/g13/sh-blockdev.c
+@@ -28,8 +28,8 @@
+ 
+ #include "g13-syshelp.h"
+ #include <assuan.h>
+-#include "i18n.h"
+-#include "exectool.h"
++#include "../common/i18n.h"
++#include "../common/exectool.h"
+ #include "keyblob.h"
+ 
+ #ifndef HAVE_STRTOULL
+diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c
+index 523ec56..b57369d 100644
+--- a/g13/sh-cmd.c
++++ b/g13/sh-cmd.c
+@@ -27,7 +27,7 @@
+ 
+ #include "g13-syshelp.h"
+ #include <assuan.h>
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keyblob.h"
+ 
+ 
+diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c
+index bbeab65..f7ec797 100644
+--- a/g13/sh-dmcrypt.c
++++ b/g13/sh-dmcrypt.c
+@@ -32,9 +32,9 @@
+ 
+ #include "g13-syshelp.h"
+ #include <assuan.h>
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "g13tuple.h"
+-#include "exectool.h"
++#include "../common/exectool.h"
+ #include "keyblob.h"
+ 
+ /* The standard disk block size (logical).  */
+diff --git a/g13/suspend.c b/g13/suspend.c
+index 7bdf738..0aa20f0 100644
+--- a/g13/suspend.c
++++ b/g13/suspend.c
+@@ -27,7 +27,7 @@
+ #include <assert.h>
+ 
+ #include "g13.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "suspend.h"
+ 
+ #include "keyblob.h"
+diff --git a/g13/t-g13tuple.c b/g13/t-g13tuple.c
+index bbd9898..2809d23 100644
+--- a/g13/t-g13tuple.c
++++ b/g13/t-g13tuple.c
+@@ -23,7 +23,7 @@
+ #include <assert.h>
+ 
+ 
+-#include "util.h"
++#include "../common/util.h"
+ #include "keyblob.h"
+ #include "g13tuple.h"
+ 
+diff --git a/kbx/Makefile.am b/kbx/Makefile.am
+index fe7da1b..8fca24a 100644
+--- a/kbx/Makefile.am
++++ b/kbx/Makefile.am
+@@ -20,7 +20,7 @@
+ 
+ EXTRA_DIST = mkerrors
+ 
+-AM_CPPFLAGS = -I$(top_srcdir)/common
++AM_CPPFLAGS =
+ 
+ include $(top_srcdir)/am/cmacros.am
+ 
+diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c
+index dd8477c..6094298 100644
+--- a/kbx/kbxutil.c
++++ b/kbx/kbxutil.c
+@@ -33,7 +33,7 @@
+ #include "../common/argparse.h"
+ #include "../common/stringhelp.h"
+ #include "../common/utf8conv.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keybox-defs.h"
+ #include "../common/init.h"
+ #include <gcrypt.h>
+diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c
+index 0e8f63a..d24f117 100644
+--- a/kbx/keybox-dump.c
++++ b/kbx/keybox-dump.c
+@@ -25,7 +25,7 @@
+ 
+ #include "keybox-defs.h"
+ #include <gcrypt.h>
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ /* Argg, we can't include ../common/util.h */
+ char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
+diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c
+index 6885e05..d82c2cb 100644
+--- a/kbx/keybox-openpgp.c
++++ b/kbx/keybox-openpgp.c
+@@ -36,7 +36,7 @@
+ #include <gcrypt.h>
+ 
+ #include "../common/openpgpdefs.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ /* Assume a valid OpenPGP packet at the address pointed to by BUFBTR
+    which has a maximum length as stored at BUFLEN.  Return the header
+diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c
+index ec5aad1..cc114c6 100644
+--- a/kbx/keybox-search.c
++++ b/kbx/keybox-search.c
+@@ -27,8 +27,8 @@
+ 
+ #include "keybox-defs.h"
+ #include <gcrypt.h>
+-#include "host2net.h"
+-#include "mbox-util.h"
++#include "../common/host2net.h"
++#include "../common/mbox-util.h"
+ 
+ #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
+                      *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c
+index 486753c..b71335b 100644
+--- a/kbx/keybox-util.c
++++ b/kbx/keybox-util.c
+@@ -27,7 +27,7 @@
+ #endif
+ 
+ #include "keybox-defs.h"
+-#include "utilproto.h"
++#include "../common/utilproto.h"
+ 
+ 
+ static void *(*alloc_func)(size_t n) = malloc;
+diff --git a/scd/Makefile.am b/scd/Makefile.am
+index db096f6..cbd1f9f 100644
+--- a/scd/Makefile.am
++++ b/scd/Makefile.am
+@@ -21,7 +21,7 @@ EXTRA_DIST = ChangeLog-2011 scdaemon-w32info.rc
+ 
+ libexec_PROGRAMS = scdaemon
+ 
+-AM_CPPFLAGS = -I$(top_srcdir)/common $(LIBUSB_CPPFLAGS)
++AM_CPPFLAGS = $(LIBUSB_CPPFLAGS)
+ 
+ include $(top_srcdir)/am/cmacros.am
+ 
+diff --git a/scd/apdu.c b/scd/apdu.c
+index c8ce684..147bf73 100644
+--- a/scd/apdu.c
++++ b/scd/apdu.c
+@@ -48,18 +48,18 @@
+ /* This is used with GnuPG version < 1.9.  The code has been source
+    copied from the current GnuPG >= 1.9  and is maintained over
+    there. */
+-#include "options.h"
++#include "../common/options.h"
+ #include "errors.h"
+ #include "memory.h"
+-#include "util.h"
+-#include "i18n.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
+ #include "dynload.h"
+ #include "cardglue.h"
+ #else /* GNUPG_MAJOR_VERSION != 1 */
+ #include "scdaemon.h"
+-#include "exechelp.h"
++#include "../common/exechelp.h"
+ #endif /* GNUPG_MAJOR_VERSION != 1 */
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ #include "iso7816.h"
+ #include "apdu.h"
+diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c
+index f7ecc4b..bea2856 100644
+--- a/scd/app-dinsig.c
++++ b/scd/app-dinsig.c
+@@ -79,10 +79,10 @@
+ 
+ #include "scdaemon.h"
+ 
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "iso7816.h"
+ #include "app-common.h"
+-#include "tlv.h"
++#include "../common/tlv.h"
+ 
+ 
+ static gpg_error_t
+diff --git a/scd/app-geldkarte.c b/scd/app-geldkarte.c
+index c277171..510beb5 100644
+--- a/scd/app-geldkarte.c
++++ b/scd/app-geldkarte.c
+@@ -37,10 +37,10 @@
+ 
+ #include "scdaemon.h"
+ 
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "iso7816.h"
+ #include "app-common.h"
+-#include "tlv.h"
++#include "../common/tlv.h"
+ 
+ 
+ 
+diff --git a/scd/app-help.c b/scd/app-help.c
+index 85bcc66..842a73d 100644
+--- a/scd/app-help.c
++++ b/scd/app-help.c
+@@ -26,7 +26,7 @@
+ #include "scdaemon.h"
+ #include "app-common.h"
+ #include "iso7816.h"
+-#include "tlv.h"
++#include "../common/tlv.h"
+ 
+ 
+ /* Count the number of bits, assuming the A represents an unsigned big
+diff --git a/scd/app-nks.c b/scd/app-nks.c
+index 98dd588..9e720f0 100644
+--- a/scd/app-nks.c
++++ b/scd/app-nks.c
+@@ -51,12 +51,12 @@
+ #include <time.h>
+ 
+ #include "scdaemon.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "iso7816.h"
+ #include "app-common.h"
+-#include "tlv.h"
++#include "../common/tlv.h"
+ #include "apdu.h"
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ static char const aid_nks[]  = { 0xD2, 0x76, 0x00, 0x00, 0x03, 0x01, 0x02 };
+ static char const aid_sigg[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
+diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
+index af81dce..66b235d 100644
+--- a/scd/app-openpgp.c
++++ b/scd/app-openpgp.c
+@@ -62,13 +62,13 @@
+ #include "scdaemon.h"
+ #endif /* GNUPG_MAJOR_VERSION != 1 */
+ 
+-#include "util.h"
+-#include "i18n.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
+ #include "iso7816.h"
+ #include "app-common.h"
+-#include "tlv.h"
+-#include "host2net.h"
+-#include "openpgpdefs.h"
++#include "../common/tlv.h"
++#include "../common/host2net.h"
++#include "../common/openpgpdefs.h"
+ 
+ 
+ /* A table describing the DOs of the card.  */
+diff --git a/scd/app-p15.c b/scd/app-p15.c
+index 4072fb7..68e8c4f 100644
+--- a/scd/app-p15.c
++++ b/scd/app-p15.c
+@@ -39,7 +39,7 @@
+ 
+ #include "iso7816.h"
+ #include "app-common.h"
+-#include "tlv.h"
++#include "../common/tlv.h"
+ #include "apdu.h" /* fixme: we should move the card detection to a
+                      separate file */
+ 
+diff --git a/scd/app-sc-hsm.c b/scd/app-sc-hsm.c
+index dddc8dc..8094b24 100644
+--- a/scd/app-sc-hsm.c
++++ b/scd/app-sc-hsm.c
+@@ -34,7 +34,7 @@
+ 
+ #include "iso7816.h"
+ #include "app-common.h"
+-#include "tlv.h"
++#include "../common/tlv.h"
+ #include "apdu.h"
+ 
+ 
+diff --git a/scd/app.c b/scd/app.c
+index e1c4e10..472adc7 100644
+--- a/scd/app.c
++++ b/scd/app.c
+@@ -25,11 +25,11 @@
+ #include <npth.h>
+ 
+ #include "scdaemon.h"
+-#include "exechelp.h"
++#include "../common/exechelp.h"
+ #include "app-common.h"
+ #include "iso7816.h"
+ #include "apdu.h"
+-#include "tlv.h"
++#include "../common/tlv.h"
+ 
+ static npth_mutex_t app_list_lock;
+ static app_t app_top;
+diff --git a/scd/command.c b/scd/command.c
+index b1d5539..56fdf74 100644
+--- a/scd/command.c
++++ b/scd/command.c
+@@ -40,8 +40,8 @@
+ #ifdef HAVE_LIBUSB
+ #include "ccid-driver.h"
+ #endif
+-#include "asshelp.h"
+-#include "server-help.h"
++#include "../common/asshelp.h"
++#include "../common/server-help.h"
+ 
+ /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
+ #define MAXLEN_PIN 100
+diff --git a/scd/scdaemon.c b/scd/scdaemon.c
+index 13cf2e6..26e89dd 100644
+--- a/scd/scdaemon.c
++++ b/scd/scdaemon.c
+@@ -44,15 +44,15 @@
+ 
+ #include <assuan.h> /* malloc hooks */
+ 
+-#include "i18n.h"
+-#include "sysutils.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
+ #include "app-common.h"
+ #include "iso7816.h"
+ #include "apdu.h"
+ #include "ccid-driver.h"
+-#include "gc-opt-flags.h"
+-#include "asshelp.h"
+-#include "exechelp.h"
++#include "../common/gc-opt-flags.h"
++#include "../common/asshelp.h"
++#include "../common/exechelp.h"
+ #include "../common/init.h"
+ 
+ #ifndef ENAMETOOLONG
+diff --git a/sm/Makefile.am b/sm/Makefile.am
+index 4cfb246..ddc2e22 100644
+--- a/sm/Makefile.am
++++ b/sm/Makefile.am
+@@ -23,7 +23,7 @@ bin_PROGRAMS = gpgsm
+ 
+ AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS)
+ 
+-AM_CPPFLAGS = -I$(top_srcdir)/common -DKEYBOX_WITH_X509=1
++AM_CPPFLAGS = -DKEYBOX_WITH_X509=1
+ include $(top_srcdir)/am/cmacros.am
+ 
+ if HAVE_W32_SYSTEM
+diff --git a/sm/call-agent.c b/sm/call-agent.c
+index 16a2497..0e47c14 100644
+--- a/sm/call-agent.c
++++ b/sm/call-agent.c
+@@ -33,11 +33,11 @@
+ #include "gpgsm.h"
+ #include <gcrypt.h>
+ #include <assuan.h>
+-#include "i18n.h"
+-#include "asshelp.h"
++#include "../common/i18n.h"
++#include "../common/asshelp.h"
+ #include "keydb.h" /* fixme: Move this to import.c */
+-#include "membuf.h"
+-#include "shareddefs.h"
++#include "../common/membuf.h"
++#include "../common/shareddefs.h"
+ #include "passphrase.h"
+ 
+ 
+diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
+index 45303e8..5ee15b7 100644
+--- a/sm/call-dirmngr.c
++++ b/sm/call-dirmngr.c
+@@ -32,9 +32,9 @@
+ #include <gcrypt.h>
+ #include <assuan.h>
+ 
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keydb.h"
+-#include "asshelp.h"
++#include "../common/asshelp.h"
+ 
+ 
+ struct membuf {
+diff --git a/sm/certchain.c b/sm/certchain.c
+index b3e8656..a361aca 100644
+--- a/sm/certchain.c
++++ b/sm/certchain.c
+@@ -34,8 +34,8 @@
+ 
+ #include "keydb.h"
+ #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
+-#include "i18n.h"
+-#include "tlv.h"
++#include "../common/i18n.h"
++#include "../common/tlv.h"
+ 
+ 
+ /* Object to keep track of certain root certificates. */
+diff --git a/sm/certcheck.c b/sm/certcheck.c
+index 04b3917..1102bcc 100644
+--- a/sm/certcheck.c
++++ b/sm/certcheck.c
+@@ -31,7 +31,7 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ /* Return the number of bits of the Q parameter from the DSA key
+diff --git a/sm/certdump.c b/sm/certdump.c
+index bd37da4..edee76f 100644
+--- a/sm/certdump.c
++++ b/sm/certdump.c
+@@ -37,7 +37,7 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ struct dn_array_s {
+diff --git a/sm/certlist.c b/sm/certlist.c
+index bfc35ce..e493cda 100644
+--- a/sm/certlist.c
++++ b/sm/certlist.c
+@@ -32,7 +32,7 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ static const char oid_kp_serverAuth[]     = "1.3.6.1.5.5.7.3.1";
+diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c
+index b50d338..9772a3b 100644
+--- a/sm/certreqgen-ui.c
++++ b/sm/certreqgen-ui.c
+@@ -29,9 +29,9 @@
+ #include "gpgsm.h"
+ #include <gcrypt.h>
+ 
+-#include "i18n.h"
+-#include "ttyio.h"
+-#include "membuf.h"
++#include "../common/i18n.h"
++#include "../common/ttyio.h"
++#include "../common/membuf.h"
+ 
+ 
+ /* Prompt for lines and append them to MB.  */
+diff --git a/sm/certreqgen.c b/sm/certreqgen.c
+index fe35ea8..4431870 100644
+--- a/sm/certreqgen.c
++++ b/sm/certreqgen.c
+@@ -66,7 +66,7 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ enum para_name
+diff --git a/sm/decrypt.c b/sm/decrypt.c
+index cda4d29..976bd12 100644
+--- a/sm/decrypt.c
++++ b/sm/decrypt.c
+@@ -31,7 +31,7 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ struct decrypt_filter_parm_s
+ {
+diff --git a/sm/delete.c b/sm/delete.c
+index 3536968..56d5b1f 100644
+--- a/sm/delete.c
++++ b/sm/delete.c
+@@ -31,7 +31,7 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ /* Delete a certificate or an secret key from a key database. */
+diff --git a/sm/encrypt.c b/sm/encrypt.c
+index 3a7d4bb..c43a9e6 100644
+--- a/sm/encrypt.c
++++ b/sm/encrypt.c
+@@ -32,7 +32,7 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ struct dek_s {
+diff --git a/sm/export.c b/sm/export.c
+index d721d52..29a5ac3 100644
+--- a/sm/export.c
++++ b/sm/export.c
+@@ -31,9 +31,9 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "exechelp.h"
+-#include "i18n.h"
+-#include "sysutils.h"
++#include "../common/exechelp.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
+ #include "minip12.h"
+ 
+ /* A table to store a fingerprint as used in a duplicates table.  We
+diff --git a/sm/fingerprint.c b/sm/fingerprint.c
+index d8e8405..fbcec58 100644
+--- a/sm/fingerprint.c
++++ b/sm/fingerprint.c
+@@ -31,7 +31,7 @@
+ #include <gcrypt.h>
+ #include <ksba.h>
+ 
+-#include "host2net.h"
++#include "../common/host2net.h"
+ 
+ 
+ /* Return the fingerprint of the certificate (we can't put this into
+diff --git a/sm/gpgsm.c b/sm/gpgsm.c
+index 34a9b96..bcf479a 100644
+--- a/sm/gpgsm.c
++++ b/sm/gpgsm.c
+@@ -35,11 +35,11 @@
+ #include "passphrase.h"
+ #include "../common/shareddefs.h"
+ #include "../kbx/keybox.h" /* malloc hooks */
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "keydb.h"
+-#include "sysutils.h"
+-#include "gc-opt-flags.h"
+-#include "asshelp.h"
++#include "../common/sysutils.h"
++#include "../common/gc-opt-flags.h"
++#include "../common/asshelp.h"
+ #include "../common/init.h"
+ 
+ 
+diff --git a/sm/import.c b/sm/import.c
+index b284b51..c7b65ad 100644
+--- a/sm/import.c
++++ b/sm/import.c
+@@ -31,9 +31,9 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "exechelp.h"
+-#include "i18n.h"
+-#include "sysutils.h"
++#include "../common/exechelp.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
+ #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
+ #include "../common/membuf.h"
+ #include "minip12.h"
+diff --git a/sm/keydb.c b/sm/keydb.c
+index 75f83ee..87fc12d 100644
+--- a/sm/keydb.c
++++ b/sm/keydb.c
+@@ -31,7 +31,7 @@
+ #include "gpgsm.h"
+ #include "../kbx/keybox.h"
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ static int active_handles;
+ 
+diff --git a/sm/keylist.c b/sm/keylist.c
+index 6db42e3..d27d4f4 100644
+--- a/sm/keylist.c
++++ b/sm/keylist.c
+@@ -34,8 +34,8 @@
+ 
+ #include "keydb.h"
+ #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
+-#include "i18n.h"
+-#include "tlv.h"
++#include "../common/i18n.h"
++#include "../common/tlv.h"
+ 
+ struct list_external_parm_s
+ {
+diff --git a/sm/misc.c b/sm/misc.c
+index 40e989f..1e2465f 100644
+--- a/sm/misc.c
++++ b/sm/misc.c
+@@ -29,8 +29,8 @@
+ #endif
+ 
+ #include "gpgsm.h"
+-#include "i18n.h"
+-#include "sysutils.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
+ #include "../common/tlv.h"
+ #include "../common/sexp-parse.h"
+ 
+diff --git a/sm/qualified.c b/sm/qualified.c
+index 61b071c..718141e 100644
+--- a/sm/qualified.c
++++ b/sm/qualified.c
+@@ -26,7 +26,7 @@
+ #include <errno.h>
+ 
+ #include "gpgsm.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include <ksba.h>
+ 
+ 
+diff --git a/sm/server.c b/sm/server.c
+index 0fadcad..37d66e2 100644
+--- a/sm/server.c
++++ b/sm/server.c
+@@ -29,8 +29,8 @@
+ 
+ #include "gpgsm.h"
+ #include <assuan.h>
+-#include "sysutils.h"
+-#include "server-help.h"
++#include "../common/sysutils.h"
++#include "../common/server-help.h"
+ 
+ #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
+ 
+diff --git a/sm/sign.c b/sm/sign.c
+index 0ca575b..a153b51 100644
+--- a/sm/sign.c
++++ b/sm/sign.c
+@@ -32,7 +32,7 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ /* Hash the data and return if something was hashed.  Return -1 on error.  */
+diff --git a/sm/verify.c b/sm/verify.c
+index 1ac97cb..6c034e6 100644
+--- a/sm/verify.c
++++ b/sm/verify.c
+@@ -32,7 +32,7 @@
+ #include <ksba.h>
+ 
+ #include "keydb.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ static char *
+ strtimestamp_r (ksba_isotime_t atime)
+diff --git a/tools/Makefile.am b/tools/Makefile.am
+index 38abd7c..0c828a7 100644
+--- a/tools/Makefile.am
++++ b/tools/Makefile.am
+@@ -23,7 +23,7 @@ EXTRA_DIST = \
+ 	ccidmon.c ChangeLog-2011 gpg-connect-agent-w32info.rc
+ 
+ 
+-AM_CPPFLAGS = -I$(top_srcdir)/common
++AM_CPPFLAGS =
+ include $(top_srcdir)/am/cmacros.am
+ 
+ if HAVE_W32_SYSTEM
+diff --git a/tools/call-dirmngr.c b/tools/call-dirmngr.c
+index 51f1fa1..9e3e493 100644
+--- a/tools/call-dirmngr.c
++++ b/tools/call-dirmngr.c
+@@ -29,10 +29,10 @@
+ #endif
+ 
+ #include <assuan.h>
+-#include "util.h"
+-#include "i18n.h"
+-#include "asshelp.h"
+-#include "mbox-util.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
++#include "../common/asshelp.h"
++#include "../common/mbox-util.h"
+ #include "./call-dirmngr.h"
+ 
+ static struct
+diff --git a/tools/gpg-check-pattern.c b/tools/gpg-check-pattern.c
+index a3224ab..7197340 100644
+--- a/tools/gpg-check-pattern.c
++++ b/tools/gpg-check-pattern.c
+@@ -40,9 +40,9 @@
+ #include <regex.h>
+ #include <ctype.h>
+ 
+-#include "util.h"
+-#include "i18n.h"
+-#include "sysutils.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
+ #include "../common/init.h"
+ 
+ 
+diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c
+index 59e2192..ef71d27 100644
+--- a/tools/gpg-connect-agent.c
++++ b/tools/gpg-connect-agent.c
+@@ -29,7 +29,7 @@
+ #include <unistd.h>
+ #include <assert.h>
+ 
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "../common/util.h"
+ #include "../common/asshelp.h"
+ #include "../common/sysutils.h"
+diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
+index c31e3a1..c578105 100644
+--- a/tools/gpg-wks-client.c
++++ b/tools/gpg-wks-client.c
+@@ -22,17 +22,17 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#include "util.h"
+-#include "status.h"
+-#include "i18n.h"
+-#include "sysutils.h"
+-#include "init.h"
+-#include "asshelp.h"
+-#include "userids.h"
+-#include "ccparray.h"
+-#include "exectool.h"
+-#include "mbox-util.h"
+-#include "name-value.h"
++#include "../common/util.h"
++#include "../common/status.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
++#include "../common/init.h"
++#include "../common/asshelp.h"
++#include "../common/userids.h"
++#include "../common/ccparray.h"
++#include "../common/exectool.h"
++#include "../common/mbox-util.h"
++#include "../common/name-value.h"
+ #include "call-dirmngr.h"
+ #include "mime-maker.h"
+ #include "send-mail.h"
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index 0c939e5..1055212 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -44,12 +44,12 @@
+ #endif
+ 
+ /* For log_logv(), asctimestamp(), gnupg_get_time ().  */
+-#include "util.h"
+-#include "i18n.h"
+-#include "exechelp.h"
+-#include "sysutils.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
++#include "../common/exechelp.h"
++#include "../common/sysutils.h"
+ 
+-#include "gc-opt-flags.h"
++#include "../common/gc-opt-flags.h"
+ #include "gpgconf.h"
+ 
+ /* There is a problem with gpg 1.4 under Windows: --gpgconf-list
+diff --git a/tools/gpgconf.c b/tools/gpgconf.c
+index a9f4607..c6fb24e 100644
+--- a/tools/gpgconf.c
++++ b/tools/gpgconf.c
+@@ -26,8 +26,8 @@
+ #include <unistd.h>
+ 
+ #include "gpgconf.h"
+-#include "i18n.h"
+-#include "sysutils.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
+ #include "../common/init.h"
+ 
+ 
+diff --git a/tools/gpgsplit.c b/tools/gpgsplit.c
+index 3b4bb15..ce2777d 100644
+--- a/tools/gpgsplit.c
++++ b/tools/gpgsplit.c
+@@ -40,8 +40,8 @@
+ #endif
+ 
+ #define INCLUDED_BY_MAIN_MODULE 1
+-#include "util.h"
+-#include "openpgpdefs.h"
++#include "../common/util.h"
++#include "../common/openpgpdefs.h"
+ 
+ static int opt_verbose;
+ static const char *opt_prefix = "";
+diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c
+index ffd239f..c622a66 100644
+--- a/tools/gpgtar-create.c
++++ b/tools/gpgtar-create.c
+@@ -35,7 +35,7 @@
+ #endif /*!HAVE_W32_SYSTEM*/
+ #include <assert.h>
+ 
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "../common/exectool.h"
+ #include "../common/sysutils.h"
+ #include "../common/ccparray.h"
+diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c
+index f9a50e7..b0e17cb 100644
+--- a/tools/gpgtar-extract.c
++++ b/tools/gpgtar-extract.c
+@@ -27,7 +27,7 @@
+ #include <unistd.h>
+ #include <assert.h>
+ 
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "../common/exectool.h"
+ #include "../common/sysutils.h"
+ #include "../common/ccparray.h"
+diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c
+index 8286d08..0e10be8 100644
+--- a/tools/gpgtar-list.c
++++ b/tools/gpgtar-list.c
+@@ -24,7 +24,7 @@
+ #include <string.h>
+ #include <assert.h>
+ 
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "gpgtar.h"
+ #include "../common/exectool.h"
+ #include "../common/ccparray.h"
+diff --git a/tools/gpgtar.c b/tools/gpgtar.c
+index 3dff176..2757ab0 100644
+--- a/tools/gpgtar.c
++++ b/tools/gpgtar.c
+@@ -34,9 +34,9 @@
+ #include <string.h>
+ #include <assert.h>
+ 
+-#include "util.h"
+-#include "i18n.h"
+-#include "sysutils.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
++#include "../common/sysutils.h"
+ #include "../common/openpgpdefs.h"
+ #include "../common/init.h"
+ #include "../common/strlist.h"
+diff --git a/tools/mime-maker.c b/tools/mime-maker.c
+index 2e32069..0332f31 100644
+--- a/tools/mime-maker.c
++++ b/tools/mime-maker.c
+@@ -22,8 +22,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#include "util.h"
+-#include "zb32.h"
++#include "../common/util.h"
++#include "../common/zb32.h"
+ #include "mime-maker.h"
+ 
+ 
+diff --git a/tools/mime-parser.c b/tools/mime-parser.c
+index 169ea2b..08b0219 100644
+--- a/tools/mime-parser.c
++++ b/tools/mime-parser.c
+@@ -22,7 +22,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#include "util.h"
++#include "../common/util.h"
+ #include "rfc822parse.h"
+ #include "mime-parser.h"
+ 
+diff --git a/tools/send-mail.c b/tools/send-mail.c
+index 56f2500..34d47c1 100644
+--- a/tools/send-mail.c
++++ b/tools/send-mail.c
+@@ -22,9 +22,9 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#include "util.h"
+-#include "exectool.h"
+-#include "sysutils.h"
++#include "../common/util.h"
++#include "../common/exectool.h"
++#include "../common/sysutils.h"
+ #include "send-mail.h"
+ 
+ 
+diff --git a/tools/wks-receive.c b/tools/wks-receive.c
+index 94f8bc6..49a1517 100644
+--- a/tools/wks-receive.c
++++ b/tools/wks-receive.c
+@@ -22,9 +22,9 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#include "util.h"
+-#include "ccparray.h"
+-#include "exectool.h"
++#include "../common/util.h"
++#include "../common/ccparray.h"
++#include "../common/exectool.h"
+ #include "gpg-wks.h"
+ #include "rfc822parse.h"
+ #include "mime-parser.h"
+diff --git a/tools/wks-util.c b/tools/wks-util.c
+index e6f6b7a..389d4a4 100644
+--- a/tools/wks-util.c
++++ b/tools/wks-util.c
+@@ -22,11 +22,11 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-#include "util.h"
+-#include "status.h"
+-#include "ccparray.h"
+-#include "exectool.h"
+-#include "mbox-util.h"
++#include "../common/util.h"
++#include "../common/status.h"
++#include "../common/ccparray.h"
++#include "../common/exectool.h"
++#include "../common/mbox-util.h"
+ #include "mime-maker.h"
+ #include "send-mail.h"
+ #include "gpg-wks.h"
diff --git a/debian/patches/0041-More-change-for-common.patch b/debian/patches/0041-More-change-for-common.patch
new file mode 100644
index 0000000..107fa6a
--- /dev/null
+++ b/debian/patches/0041-More-change-for-common.patch
@@ -0,0 +1,69 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 7 Mar 2017 20:32:09 +0900
+Subject: More change for common.
+
+* g10, scd, test, tools: Follow the change of removal of -Icommon.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit d6c7bf1f8ab8899faba2fb81a35b096921c38f3c)
+---
+ scd/iso7816.c        | 4 ++--
+ tests/gpgscm/main.c  | 2 +-
+ tools/no-libgcrypt.c | 2 +-
+ tools/symcryptrun.c  | 2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/scd/iso7816.c b/scd/iso7816.c
+index 8f79698..d146bd0 100644
+--- a/scd/iso7816.c
++++ b/scd/iso7816.c
+@@ -32,8 +32,8 @@
+ #include "options.h"
+ #include "errors.h"
+ #include "memory.h"
+-#include "util.h"
+-#include "i18n.h"
++#include "../common/util.h"
++#include "../common/i18n.h"
+ #else /* GNUPG_MAJOR_VERSION != 1 */
+ #include "scdaemon.h"
+ #endif /* GNUPG_MAJOR_VERSION != 1 */
+diff --git a/tests/gpgscm/main.c b/tests/gpgscm/main.c
+index 3191e05..65929f0 100644
+--- a/tests/gpgscm/main.c
++++ b/tests/gpgscm/main.c
+@@ -34,7 +34,7 @@
+ #include "scheme.h"
+ #include "scheme-private.h"
+ #include "ffi.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "../../common/argparse.h"
+ #include "../../common/init.h"
+ #include "../../common/logging.h"
+diff --git a/tools/no-libgcrypt.c b/tools/no-libgcrypt.c
+index b56cc38..8739968 100644
+--- a/tools/no-libgcrypt.c
++++ b/tools/no-libgcrypt.c
+@@ -18,7 +18,7 @@
+ #include <errno.h>
+ 
+ #include "../common/util.h"
+-#include "i18n.h"
++#include "../common/i18n.h"
+ 
+ 
+ /* Replace libgcrypt's malloc functions which are used by
+diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c
+index b32d43a..563e56b 100644
+--- a/tools/symcryptrun.c
++++ b/tools/symcryptrun.c
+@@ -98,7 +98,7 @@
+ #endif
+ #include <gpg-error.h>
+ 
+-#include "i18n.h"
++#include "../common/i18n.h"
+ #include "../common/util.h"
+ #include "../common/init.h"
+ #include "../common/sysutils.h"
diff --git a/debian/patches/0042-tools-Removal-of-Icommon.patch b/debian/patches/0042-tools-Removal-of-Icommon.patch
new file mode 100644
index 0000000..5a8f609
--- /dev/null
+++ b/debian/patches/0042-tools-Removal-of-Icommon.patch
@@ -0,0 +1,39 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 7 Mar 2017 20:38:22 +0900
+Subject: tools: Removal of -Icommon.
+
+* tools/gpg-wks-server.c: Follow the change.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 80fb1a8a05b2194af16027555b09bbd5d48ec9ac)
+---
+ tools/gpg-wks-server.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c
+index 0376cce..f413df1 100644
+--- a/tools/gpg-wks-server.c
++++ b/tools/gpg-wks-server.c
+@@ -31,14 +31,14 @@
+ #include <sys/stat.h>
+ #include <dirent.h>
+ 
+-#include "util.h"
+-#include "init.h"
+-#include "sysutils.h"
+-#include "ccparray.h"
+-#include "exectool.h"
+-#include "zb32.h"
+-#include "mbox-util.h"
+-#include "name-value.h"
++#include "../common/util.h"
++#include "../common/init.h"
++#include "../common/sysutils.h"
++#include "../common/ccparray.h"
++#include "../common/exectool.h"
++#include "../common/zb32.h"
++#include "../common/mbox-util.h"
++#include "../common/name-value.h"
+ #include "mime-maker.h"
+ #include "send-mail.h"
+ #include "gpg-wks.h"
diff --git a/debian/patches/0043-gpg-Do-not-allow-the-user-to-revoke-the-last-valid-U.patch b/debian/patches/0043-gpg-Do-not-allow-the-user-to-revoke-the-last-valid-U.patch
new file mode 100644
index 0000000..b3aa9ad
--- /dev/null
+++ b/debian/patches/0043-gpg-Do-not-allow-the-user-to-revoke-the-last-valid-U.patch
@@ -0,0 +1,119 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 2 Mar 2017 14:14:55 +0100
+Subject: gpg: Do not allow the user to revoke the last valid UID.
+
+* g10/keyedit.c (keyedit_quick_revuid): Merge self signatures, then
+make sure that we do not revoke the last valid UID.
+(menu_revuid): Make sure that we do not revoke the last valid UID.
+* tests/openpgp/quick-key-manipulation.scm: Demonstrate that
+'--quick-revoke-uid' can not be used to revoke the last valid UID.
+
+GnuPG-bug-id: 2960
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 591b6a9d879cbcabb089d89a26d3c3e0306054e1)
+---
+ g10/keyedit.c                            | 41 +++++++++++++++++++++++++++++++-
+ tests/openpgp/quick-key-manipulation.scm |  5 ++++
+ 2 files changed, 45 insertions(+), 1 deletion(-)
+
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index c10a011..660e8bf 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -2966,6 +2966,7 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
+   kbnode_t node;
+   int modified = 0;
+   size_t revlen;
++  size_t valid_uids;
+ 
+ #ifdef HAVE_W32_SYSTEM
+   /* See keyedit_menu for why we need this.  */
+@@ -3019,7 +3020,16 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
+     }
+ 
+   fix_keyblock (&keyblock);
+-  setup_main_keyids (keyblock);
++  merge_keys_and_selfsig (keyblock);
++
++  /* Too make sure that we do not revoke the last valid UID, we first
++     count how many valid UIDs there are.  */
++  valid_uids = 0;
++  for (node = keyblock; node; node = node->next)
++    valid_uids +=
++      node->pkt->pkttype == PKT_USER_ID
++      && ! node->pkt->pkt.user_id->is_revoked
++      && ! node->pkt->pkt.user_id->is_expired;
+ 
+   revlen = strlen (uidtorev);
+   /* find the right UID */
+@@ -3031,6 +3041,15 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
+         {
+           struct revocation_reason_info *reason;
+ 
++          /* Make sure that we do not revoke the last valid UID.  */
++          if (valid_uids == 1
++              && ! node->pkt->pkt.user_id->is_revoked
++              && ! node->pkt->pkt.user_id->is_expired)
++            {
++              log_error (_("Cannot revoke the last valid user ID.\n"));
++              goto leave;
++            }
++
+           reason = get_default_uid_revocation_reason ();
+           err = core_revuid (ctrl, keyblock, node, reason, &modified);
+           release_revocation_reason_info (reason);
+@@ -6429,6 +6448,7 @@ menu_revuid (ctrl_t ctrl, kbnode_t pub_keyblock)
+   int changed = 0;
+   int rc;
+   struct revocation_reason_info *reason = NULL;
++  size_t valid_uids;
+ 
+   /* Note that this is correct as per the RFCs, but nevertheless
+      somewhat meaningless in the real world.  1991 did define the 0x30
+@@ -6445,11 +6465,30 @@ menu_revuid (ctrl_t ctrl, kbnode_t pub_keyblock)
+ 	  goto leave;
+       }
+ 
++  /* Too make sure that we do not revoke the last valid UID, we first
++     count how many valid UIDs there are.  */
++  valid_uids = 0;
++  for (node = pub_keyblock; node; node = node->next)
++    valid_uids +=
++      node->pkt->pkttype == PKT_USER_ID
++      && ! node->pkt->pkt.user_id->is_revoked
++      && ! node->pkt->pkt.user_id->is_expired;
++
+  reloop: /* (better this way because we are modifying the keyring) */
+   for (node = pub_keyblock; node; node = node->next)
+     if (node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
+       {
+         int modified = 0;
++
++        /* Make sure that we do not revoke the last valid UID.  */
++        if (valid_uids == 1
++            && ! node->pkt->pkt.user_id->is_revoked
++            && ! node->pkt->pkt.user_id->is_expired)
++          {
++            log_error (_("Cannot revoke the last valid user ID.\n"));
++            goto leave;
++          }
++
+         rc = core_revuid (ctrl, pub_keyblock, node, reason, &modified);
+         if (rc)
+           goto leave;
+diff --git a/tests/openpgp/quick-key-manipulation.scm b/tests/openpgp/quick-key-manipulation.scm
+index 08ef626..9fd5b6b 100755
+--- a/tests/openpgp/quick-key-manipulation.scm
++++ b/tests/openpgp/quick-key-manipulation.scm
+@@ -81,6 +81,11 @@
+        (call-check `(, at GPG --quick-revoke-uid ,(exact bravo) ,charlie))
+        (error "Expected an error, but get none."))
+ 
++(info "Checking that we get an error revoking the last valid user ID.")
++(catch '()
++       (call-check `(, at GPG --quick-revoke-uid ,(exact bravo) ,bravo))
++       (error "Expected an error, but get none."))
++
+ (assert (= 1 (count-uids-of-secret-key bravo)))
+ 
+ (info "Checking that we can change the expiration time.")
diff --git a/debian/patches/0044-gpgscm-Use-system-strlwr-if-available.patch b/debian/patches/0044-gpgscm-Use-system-strlwr-if-available.patch
new file mode 100644
index 0000000..0843495
--- /dev/null
+++ b/debian/patches/0044-gpgscm-Use-system-strlwr-if-available.patch
@@ -0,0 +1,51 @@
+From: Michael Haubenwallner <michael.haubenwallner at ssi-schaefer.com>
+Date: Tue, 7 Mar 2017 13:54:49 +0100
+Subject: gpgscm: Use system strlwr if available.
+
+* tests/gpgscm/scheme.c: Define local strlwr only when HAVE_STRLWR is
+not defined in config.h.
+* tests/gpgscm/scheme-config.h: Remove hack.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit c22a2a89d3bd3d08b3abb8e4e33df32b480338ec)
+---
+ tests/gpgscm/scheme-config.h | 4 ----
+ tests/gpgscm/scheme.c        | 6 +++++-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/tests/gpgscm/scheme-config.h b/tests/gpgscm/scheme-config.h
+index 2003498..15ca969 100644
+--- a/tests/gpgscm/scheme-config.h
++++ b/tests/gpgscm/scheme-config.h
+@@ -30,7 +30,3 @@
+ #define USE_PLIST		0
+ #define USE_INTERFACE		1
+ #define SHOW_ERROR_LINE		1
+-
+-#if __MINGW32__
+-# define USE_STRLWR 0
+-#endif /* __MINGW32__ */
+diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c
+index b2ff721..af97c27 100644
+--- a/tests/gpgscm/scheme.c
++++ b/tests/gpgscm/scheme.c
+@@ -12,6 +12,10 @@
+  *
+  */
+ 
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
+ #define _SCHEME_SOURCE
+ #include "scheme-private.h"
+ #ifndef WIN32
+@@ -88,7 +92,7 @@ static int stricmp(const char *s1, const char *s2)
+ }
+ #endif /* __APPLE__ */
+ 
+-#if USE_STRLWR
++#if USE_STRLWR && !defined(HAVE_STRLWR)
+ static const char *strlwr(char *s) {
+   const char *p=s;
+   while(*s) {
diff --git a/debian/patches/0045-doc-Add-a-note-to-the-trust-model-direct.patch b/debian/patches/0045-doc-Add-a-note-to-the-trust-model-direct.patch
new file mode 100644
index 0000000..1c2c41a
--- /dev/null
+++ b/debian/patches/0045-doc-Add-a-note-to-the-trust-model-direct.patch
@@ -0,0 +1,75 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 8 Mar 2017 10:46:09 +0100
+Subject: doc: Add a note to the trust model direct.
+
+* doc/gpg.texi (GPG Configuration Options): Add note.  Chnage Index
+from trust-mode:foo to trust-model:foo.
+
+(cherry picked from commit f0257b4a86b73f5b956028e68590b6d2a23ea4da)
+---
+ doc/gpg.texi | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index 55482b1..0e107ec 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -1608,17 +1608,17 @@ Set what trust model GnuPG should follow. The models are:
+ @table @asis
+ 
+   @item pgp
+-  @opindex trust-mode:pgp
++  @opindex trust-model:pgp
+   This is the Web of Trust combined with trust signatures as used in PGP
+   5.x and later. This is the default trust model when creating a new
+   trust database.
+ 
+   @item classic
+-  @opindex trust-mode:classic
++  @opindex trust-model:classic
+   This is the standard Web of Trust as introduced by PGP 2.
+ 
+   @item tofu
+-  @opindex trust-mode:tofu
++  @opindex trust-model:tofu
+   @anchor{trust-model-tofu}
+   TOFU stands for Trust On First Use.  In this trust model, the first
+   time a key is seen, it is memorized.  If later another key is seen
+@@ -1664,7 +1664,7 @@ Set what trust model GnuPG should follow. The models are:
+   @code{undefined} trust level is returned.
+ 
+   @item tofu+pgp
+-  @opindex trust-mode:tofu+pgp
++  @opindex trust-model:tofu+pgp
+   This trust model combines TOFU with the Web of Trust.  This is done
+   by computing the trust level for each model and then taking the
+   maximum trust level where the trust levels are ordered as follows:
+@@ -1677,12 +1677,16 @@ Set what trust model GnuPG should follow. The models are:
+   which some security-conscious users don't like.
+ 
+   @item direct
+-  @opindex trust-mode:direct
++  @opindex trust-model:direct
+   Key validity is set directly by the user and not calculated via the
+-  Web of Trust.
++  Web of Trust.  This model is soley based on the key and does
++  not distinguish user IDs.  Note that when changing to another trust
++  model the trust values assigned to a key are transformed into
++  ownertrust values, which also indicate how you trust the owner of
++  the key to sign other keys.
+ 
+   @item always
+-  @opindex trust-mode:always
++  @opindex trust-model:always
+   Skip key validation and assume that used keys are always fully
+   valid. You generally won't use this unless you are using some
+   external validation scheme. This option also suppresses the
+@@ -1692,7 +1696,7 @@ Set what trust model GnuPG should follow. The models are:
+   disabled keys.
+ 
+   @item auto
+-  @opindex trust-mode:auto
++  @opindex trust-model:auto
+   Select the trust model depending on whatever the internal trust
+   database says. This is the default model if such a database already
+   exists.
diff --git a/debian/patches/0046-dirmngr-Do-not-put-a-keyserver-into-a-new-dirmngr.co.patch b/debian/patches/0046-dirmngr-Do-not-put-a-keyserver-into-a-new-dirmngr.co.patch
new file mode 100644
index 0000000..9173d47
--- /dev/null
+++ b/debian/patches/0046-dirmngr-Do-not-put-a-keyserver-into-a-new-dirmngr.co.patch
@@ -0,0 +1,54 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 8 Mar 2017 11:34:41 +0100
+Subject: dirmngr: Do not put a keyserver into a new dirmngr.conf
+
+* g10/dirmngr-conf.skel: Do not define keyservers.
+--
+
+(cherry picked from commit 8f028642239fa992c6c059e3c1b4421a1813c827)
+---
+ g10/dirmngr-conf.skel | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/g10/dirmngr-conf.skel b/g10/dirmngr-conf.skel
+index fbb730b..e2885e6 100644
+--- a/g10/dirmngr-conf.skel
++++ b/g10/dirmngr-conf.skel
+@@ -42,20 +42,21 @@
+ # through the usual method:
+ #      hkp://keyserver.example.net:22742
+ #
+-# Most users just set the name and type of their preferred keyserver.
+ # Note that most servers (with the notable exception of
+ # ldap://keyserver.pgp.com) synchronize changes with each other.  Note
+ # also that a single server name may actually point to multiple
+-# servers via DNS round-robin.  hkp://keys.gnupg.net is an example of
+-# such a "server", which spreads the load over a number of physical
+-# servers.
++# servers via DNS round-robin or service records.
+ #
+ # If exactly two keyservers are configured and only one is a Tor hidden
+ # service, Dirmngr selects the keyserver to use depending on whether
+-# Tor is locally running or not (on a per session base).
++# Tor is locally running or not (on a per session base).  Example:
++#
++#  keyserver hkp://jirk5u4osbsr34t5.onion
++#  keyserver hkps://hkps.pool.sks-keyservers.net
++#
++# If no keyserver is specified GnuPG uses
++#  hkps://hkps.pool.sks-keyservers.net
+ 
+-keyserver hkp://jirk5u4osbsr34t5.onion
+-keyserver hkp://keys.gnupg.net
+ 
+ # --hkp-cacert FILENAME
+ #
+@@ -65,5 +66,8 @@ keyserver hkp://keys.gnupg.net
+ # root certificates here.  If that file is in PEM format a ".pem"
+ # suffix is expected.  This option may be given multiple times to add
+ # more root certificates.  Tilde expansion is supported.
++# This is not required when the default server
++#   hkps://hkps.pool.sks-keyservers.net
++# is used.
+ 
+ #hkp-cacert /path/to/CA/sks-keyservers.netCA.pem
diff --git a/debian/patches/0047-g10-Move-more-flags-into-the-flag-bitfield.patch b/debian/patches/0047-g10-Move-more-flags-into-the-flag-bitfield.patch
new file mode 100644
index 0000000..cee3a64
--- /dev/null
+++ b/debian/patches/0047-g10-Move-more-flags-into-the-flag-bitfield.patch
@@ -0,0 +1,728 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 8 Mar 2017 11:01:22 +0100
+Subject: g10: Move more flags into the flag bitfield.
+
+* g10/packet.h (PKT_user_id): Move 'is_primary', 'is_revoked', and
+'is_expired' into the flags bitfield, and drop the prefix.
+* g10/call-dirmngr.c: Adapt accordingly.
+* g10/export.c: Likewise.
+* g10/getkey.c: Likewise.
+* g10/import.c: Likewise.
+* g10/kbnode.c: Likewise.
+* g10/keyedit.c: Likewise.
+* g10/keylist.c: Likewise.
+* g10/keyserver.c: Likewise.
+* g10/mainproc.c: Likewise.
+* g10/pkclist.c: Likewise.
+* g10/pubkey-enc.c: Likewise.
+* g10/tofu.c: Likewise.
+* g10/trust.c: Likewise.
+* g10/trustdb.c: Likewise.
+--
+
+This patch has been created by applying the following semantic patch:
+
+    @@
+    expression E;
+    @@
+    -E->is_expired
+    +E->flags.expired
+
+    @@
+    expression E;
+    @@
+    -E->is_primary
+    +E->flags.primary
+
+    @@
+    expression E;
+    @@
+    -E->is_revoked
+    +E->flags.revoked
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 2649fdfff5d9e227025956e015b67502fd4962c4)
+---
+ g10/call-dirmngr.c |  4 ++--
+ g10/export.c       |  2 +-
+ g10/getkey.c       | 36 ++++++++++++++++++------------------
+ g10/import.c       |  6 +++---
+ g10/kbnode.c       |  6 +++---
+ g10/keyedit.c      | 50 +++++++++++++++++++++++++-------------------------
+ g10/keylist.c      | 15 +++++++--------
+ g10/keyserver.c    |  2 +-
+ g10/mainproc.c     | 16 ++++++++--------
+ g10/packet.h       |  7 +++----
+ g10/pkclist.c      |  6 +++---
+ g10/pubkey-enc.c   |  2 +-
+ g10/tofu.c         |  8 ++++----
+ g10/trust.c        | 10 +++++-----
+ g10/trustdb.c      | 12 ++++++------
+ 15 files changed, 90 insertions(+), 92 deletions(-)
+
+diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
+index a33cdc7..aa39155 100644
+--- a/g10/call-dirmngr.c
++++ b/g10/call-dirmngr.c
+@@ -987,9 +987,9 @@ ks_put_inq_cb (void *opaque, const char *line)
+ 		    int i;
+ 
+ 		    i = 0;
+-		    if (uid->is_revoked)
++		    if (uid->flags.revoked)
+ 		      validity[i ++] = 'r';
+-		    if (uid->is_expired)
++		    if (uid->flags.expired)
+ 		      validity[i ++] = 'e';
+ 		    validity[i] = '\0';
+ 
+diff --git a/g10/export.c b/g10/export.c
+index 2da5309..a7aecd6 100644
+--- a/g10/export.c
++++ b/g10/export.c
+@@ -1434,7 +1434,7 @@ print_pka_or_dane_records (iobuf_t out, kbnode_t keyblock, PKT_public_key *pk,
+         continue;
+       uid = node->pkt->pkt.user_id;
+ 
+-      if (uid->is_expired || uid->is_revoked)
++      if (uid->flags.expired || uid->flags.revoked)
+         continue;
+ 
+       xfree (mbox);
+diff --git a/g10/getkey.c b/g10/getkey.c
+index 548f8bf..9c9d8b2 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -274,7 +274,7 @@ get_primary_uid (KBNODE keyblock, size_t * uidlen)
+     {
+       if (k->pkt->pkttype == PKT_USER_ID
+ 	  && !k->pkt->pkt.user_id->attrib_data
+-	  && k->pkt->pkt.user_id->is_primary)
++	  && k->pkt->pkt.user_id->flags.primary)
+ 	{
+ 	  *uidlen = k->pkt->pkt.user_id->len;
+ 	  return k->pkt->pkt.user_id->name;
+@@ -970,7 +970,7 @@ skip_unusable (void *dummy, u32 * keyid, int uid_no)
+ 	      if (uids_seen != uid_no)
+ 		continue;
+ 
+-	      if (user_id->is_revoked || user_id->is_expired)
++	      if (user_id->flags.revoked || user_id->flags.expired)
+ 		unusable = 1;
+ 
+ 	      break;
+@@ -1494,7 +1494,7 @@ key_is_ok (const PKT_public_key *key)
+ static int
+ uid_is_ok (const PKT_public_key *key, const PKT_user_id *uid)
+ {
+-  return key_is_ok (key) && ! uid->is_revoked;
++  return key_is_ok (key) && ! uid->flags.revoked;
+ }
+ 
+ 
+@@ -2347,26 +2347,26 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated)
+   uid->created = 0;		/* Not created == invalid. */
+   if (IS_UID_REV (sig))
+     {
+-      uid->is_revoked = 1;
++      uid->flags.revoked = 1;
+       return; /* Has been revoked.  */
+     }
+   else
+-    uid->is_revoked = 0;
++    uid->flags.revoked = 0;
+ 
+   uid->expiredate = sig->expiredate;
+ 
+   if (sig->flags.expired)
+     {
+-      uid->is_expired = 1;
++      uid->flags.expired = 1;
+       return; /* Has expired.  */
+     }
+   else
+-    uid->is_expired = 0;
++    uid->flags.expired = 0;
+ 
+   uid->created = sig->timestamp; /* This one is okay. */
+   uid->selfsigversion = sig->version;
+   /* If we got this far, it's not expired :) */
+-  uid->is_expired = 0;
++  uid->flags.expired = 0;
+ 
+   /* Store the key flags in the helper variable for later processing.  */
+   uid->help_key_usage = parse_key_usage (sig);
+@@ -2380,10 +2380,10 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated)
+ 
+   /* Set the primary user ID flag - we will later wipe out some
+    * of them to only have one in our keyblock.  */
+-  uid->is_primary = 0;
++  uid->flags.primary = 0;
+   p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL);
+   if (p && *p)
+-    uid->is_primary = 2;
++    uid->flags.primary = 2;
+ 
+   /* We could also query this from the unhashed area if it is not in
+    * the hased area and then later try to decide which is the better
+@@ -2917,7 +2917,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
+       if (k->pkt->pkttype == PKT_USER_ID && !k->pkt->pkt.user_id->attrib_data)
+ 	{
+ 	  PKT_user_id *uid = k->pkt->pkt.user_id;
+-	  if (uid->is_primary)
++	  if (uid->flags.primary)
+ 	    {
+ 	      if (uid->created > uiddate)
+ 		{
+@@ -2961,7 +2961,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
+ 	    {
+ 	      PKT_user_id *uid = k->pkt->pkt.user_id;
+ 	      if (k != uidnode)
+-		uid->is_primary = 0;
++		uid->flags.primary = 0;
+ 	    }
+ 	}
+     }
+@@ -2969,7 +2969,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
+     {
+       /* None is flagged primary - use the latest user ID we have,
+          and disambiguate with the arbitrary packet comparison. */
+-      uidnode2->pkt->pkt.user_id->is_primary = 1;
++      uidnode2->pkt->pkt.user_id->flags.primary = 1;
+     }
+   else
+     {
+@@ -2988,7 +2988,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
+ 	      if (!uidnode)
+ 		{
+ 		  uidnode = k;
+-		  uidnode->pkt->pkt.user_id->is_primary = 1;
++		  uidnode->pkt->pkt.user_id->flags.primary = 1;
+ 		  continue;
+ 		}
+ 	      else
+@@ -2996,12 +2996,12 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
+ 		  if (cmp_user_ids (k->pkt->pkt.user_id,
+ 				    uidnode->pkt->pkt.user_id) > 0)
+ 		    {
+-		      uidnode->pkt->pkt.user_id->is_primary = 0;
++		      uidnode->pkt->pkt.user_id->flags.primary = 0;
+ 		      uidnode = k;
+-		      uidnode->pkt->pkt.user_id->is_primary = 1;
++		      uidnode->pkt->pkt.user_id->flags.primary = 1;
+ 		    }
+ 		  else
+-		    k->pkt->pkt.user_id->is_primary = 0;	/* just to be
++		    k->pkt->pkt.user_id->flags.primary = 0;	/* just to be
+ 								   safe */
+ 		}
+ 	    }
+@@ -3315,7 +3315,7 @@ merge_selfsigs (KBNODE keyblock)
+     {
+       if (k->pkt->pkttype == PKT_USER_ID
+ 	  && !k->pkt->pkt.user_id->attrib_data
+-	  && k->pkt->pkt.user_id->is_primary)
++	  && k->pkt->pkt.user_id->flags.primary)
+ 	{
+ 	  prefs = k->pkt->pkt.user_id->prefs;
+ 	  mdc_feature = k->pkt->pkt.user_id->flags.mdc;
+diff --git a/g10/import.c b/g10/import.c
+index 640618a..ea7a92f 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -1189,15 +1189,15 @@ impex_filter_getval (void *cookie, const char *propname)
+         }
+       else if (!strcmp (propname, "primary"))
+         {
+-          result = uid->is_primary? "1":"0";
++          result = uid->flags.primary? "1":"0";
+         }
+       else if (!strcmp (propname, "expired"))
+         {
+-          result = uid->is_expired? "1":"0";
++          result = uid->flags.expired? "1":"0";
+         }
+       else if (!strcmp (propname, "revoked"))
+         {
+-          result = uid->is_revoked? "1":"0";
++          result = uid->flags.revoked? "1":"0";
+         }
+       else
+         result = NULL;
+diff --git a/g10/kbnode.c b/g10/kbnode.c
+index 153dce2..b8c31b7 100644
+--- a/g10/kbnode.c
++++ b/g10/kbnode.c
+@@ -392,10 +392,10 @@ dump_kbnode (KBNODE node)
+           es_write_sanitized (log_get_stream (), uid->name, uid->len,
+                               NULL, NULL);
+           log_printf ("\" %c%c%c%c\n",
+-                      uid->is_expired? 'e':'.',
+-                      uid->is_revoked? 'r':'.',
++                      uid->flags.expired? 'e':'.',
++                      uid->flags.revoked? 'r':'.',
+                       uid->created?    'v':'.',
+-                      uid->is_primary? 'p':'.' );
++                      uid->flags.primary? 'p':'.' );
+         }
+       else if (node->pkt->pkttype == PKT_SIGNATURE)
+         {
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index 660e8bf..2b0f45e 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -1164,7 +1164,7 @@ sign_uids (ctrl_t ctrl, estream_t fp,
+                       uidnode->flag &= ~NODFLG_MARK_A;
+                       uidnode = NULL;
+                     }
+-		  else if (uidnode->pkt->pkt.user_id->is_revoked)
++		  else if (uidnode->pkt->pkt.user_id->flags.revoked)
+ 		    {
+ 		      tty_fprintf (fp, _("User ID \"%s\" is revoked."), user);
+ 
+@@ -1192,7 +1192,7 @@ sign_uids (ctrl_t ctrl, estream_t fp,
+ 			  tty_fprintf (fp, _("  Unable to sign.\n"));
+ 			}
+ 		    }
+-		  else if (uidnode->pkt->pkt.user_id->is_expired)
++		  else if (uidnode->pkt->pkt.user_id->flags.expired)
+ 		    {
+ 		      tty_fprintf (fp, _("User ID \"%s\" is expired."), user);
+ 
+@@ -3028,8 +3028,8 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
+   for (node = keyblock; node; node = node->next)
+     valid_uids +=
+       node->pkt->pkttype == PKT_USER_ID
+-      && ! node->pkt->pkt.user_id->is_revoked
+-      && ! node->pkt->pkt.user_id->is_expired;
++      && ! node->pkt->pkt.user_id->flags.revoked
++      && ! node->pkt->pkt.user_id->flags.expired;
+ 
+   revlen = strlen (uidtorev);
+   /* find the right UID */
+@@ -3043,8 +3043,8 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
+ 
+           /* Make sure that we do not revoke the last valid UID.  */
+           if (valid_uids == 1
+-              && ! node->pkt->pkt.user_id->is_revoked
+-              && ! node->pkt->pkt.user_id->is_expired)
++              && ! node->pkt->pkt.user_id->flags.revoked
++              && ! node->pkt->pkt.user_id->flags.expired)
+             {
+               log_error (_("Cannot revoke the last valid user ID.\n"));
+               goto leave;
+@@ -3735,9 +3735,9 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
+ 	  else
+ 	    es_fputs ("uid:", fp);
+ 
+-	  if (uid->is_revoked)
++	  if (uid->flags.revoked)
+ 	    es_fputs ("r::::::::", fp);
+-	  else if (uid->is_expired)
++	  else if (uid->flags.expired)
+ 	    es_fputs ("e::::::::", fp);
+ 	  else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
+ 	    es_fputs ("::::::::", fp);
+@@ -3785,11 +3785,11 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
+ 	  es_putc (':', fp);
+ 	  /* flags */
+ 	  es_fprintf (fp, "%d,", i);
+-	  if (uid->is_primary)
++	  if (uid->flags.primary)
+ 	    es_putc ('p', fp);
+-	  if (uid->is_revoked)
++	  if (uid->flags.revoked)
+ 	    es_putc ('r', fp);
+-	  if (uid->is_expired)
++	  if (uid->flags.expired)
+ 	    es_putc ('e', fp);
+ 	  if ((node->flag & NODFLG_SELUID))
+ 	    es_putc ('s', fp);
+@@ -3835,7 +3835,7 @@ show_names (ctrl_t ctrl, estream_t fp,
+ 		tty_fprintf (fp, "     ");
+ 	      else if (node->flag & NODFLG_SELUID)
+ 		tty_fprintf (fp, "(%d)* ", i);
+-	      else if (uid->is_primary)
++	      else if (uid->flags.primary)
+ 		tty_fprintf (fp, "(%d). ", i);
+ 	      else
+ 		tty_fprintf (fp, "(%d)  ", i);
+@@ -4167,9 +4167,9 @@ show_basic_key_info (KBNODE keyblock)
+ 	  ++i;
+ 
+ 	  tty_printf ("     ");
+-	  if (uid->is_revoked)
++	  if (uid->flags.revoked)
+ 	    tty_printf ("[%s] ", _("revoked"));
+-	  else if (uid->is_expired)
++	  else if (uid->flags.expired)
+ 	    tty_printf ("[%s] ", _("expired"));
+ 	  tty_print_utf8_string (uid->name, uid->len);
+ 	  tty_printf ("\n");
+@@ -4277,7 +4277,7 @@ no_primary_warning (KBNODE keyblock)
+ 	{
+ 	  uid_count++;
+ 
+-	  if (node->pkt->pkt.user_id->is_primary == 2)
++	  if (node->pkt->pkt.user_id->flags.primary == 2)
+ 	    {
+ 	      have_primary = 1;
+ 	      break;
+@@ -4478,7 +4478,7 @@ menu_deluid (KBNODE pub_keyblock)
+ 	    {
+ 	      /* Only cause a trust update if we delete a
+ 	         non-revoked user id */
+-	      if (!node->pkt->pkt.user_id->is_revoked)
++	      if (!node->pkt->pkt.user_id->flags.revoked)
+ 		update_trust = 1;
+ 	      delete_kbnode (node);
+ 	    }
+@@ -4598,9 +4598,9 @@ menu_clean (KBNODE keyblock, int self_only)
+ 	    {
+ 	      const char *reason;
+ 
+-	      if (uidnode->pkt->pkt.user_id->is_revoked)
++	      if (uidnode->pkt->pkt.user_id->flags.revoked)
+ 		reason = _("revoked");
+-	      else if (uidnode->pkt->pkt.user_id->is_expired)
++	      else if (uidnode->pkt->pkt.user_id->flags.expired)
+ 		reason = _("expired");
+ 	      else
+ 		reason = _("invalid");
+@@ -6335,7 +6335,7 @@ reloop:			/* (must use this, because we are modifing the list) */
+       /* Are we revoking our own uid? */
+       if (primary_pk->keyid[0] == sig->keyid[0] &&
+ 	  primary_pk->keyid[1] == sig->keyid[1])
+-	unode->pkt->pkt.user_id->is_revoked = 1;
++	unode->pkt->pkt.user_id->flags.revoked = 1;
+       pkt = xmalloc_clear (sizeof *pkt);
+       pkt->pkttype = PKT_SIGNATURE;
+       pkt->pkt.signature = sig;
+@@ -6369,7 +6369,7 @@ core_revuid (ctrl_t ctrl, kbnode_t keyblock, KBNODE node,
+     {
+       PKT_user_id *uid = node->pkt->pkt.user_id;
+ 
+-      if (uid->is_revoked)
++      if (uid->flags.revoked)
+         {
+           char *user = utf8_to_native (uid->name, uid->len, 0);
+           log_info (_("user ID \"%s\" is already revoked\n"), user);
+@@ -6429,7 +6429,7 @@ core_revuid (ctrl_t ctrl, kbnode_t keyblock, KBNODE node,
+                 update_trust = 1;
+ #endif /*!NO_TRUST_MODELS*/
+ 
+-              node->pkt->pkt.user_id->is_revoked = 1;
++              node->pkt->pkt.user_id->flags.revoked = 1;
+               if (modified)
+                 *modified = 1;
+             }
+@@ -6471,8 +6471,8 @@ menu_revuid (ctrl_t ctrl, kbnode_t pub_keyblock)
+   for (node = pub_keyblock; node; node = node->next)
+     valid_uids +=
+       node->pkt->pkttype == PKT_USER_ID
+-      && ! node->pkt->pkt.user_id->is_revoked
+-      && ! node->pkt->pkt.user_id->is_expired;
++      && ! node->pkt->pkt.user_id->flags.revoked
++      && ! node->pkt->pkt.user_id->flags.expired;
+ 
+  reloop: /* (better this way because we are modifying the keyring) */
+   for (node = pub_keyblock; node; node = node->next)
+@@ -6482,8 +6482,8 @@ menu_revuid (ctrl_t ctrl, kbnode_t pub_keyblock)
+ 
+         /* Make sure that we do not revoke the last valid UID.  */
+         if (valid_uids == 1
+-            && ! node->pkt->pkt.user_id->is_revoked
+-            && ! node->pkt->pkt.user_id->is_expired)
++            && ! node->pkt->pkt.user_id->flags.revoked
++            && ! node->pkt->pkt.user_id->flags.expired)
+           {
+             log_error (_("Cannot revoke the last valid user ID.\n"));
+             goto leave;
+diff --git a/g10/keylist.c b/g10/keylist.c
+index 93b5ee6..3f9e313 100644
+--- a/g10/keylist.c
++++ b/g10/keylist.c
+@@ -849,9 +849,8 @@ dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
+ 		   (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
+ 		   uid->numattribs, (ulong) uid->created,
+ 		   (ulong) uid->expiredate,
+-		   ((uid->is_primary ? 0x01 : 0) | (uid->
+-						    is_revoked ? 0x02 : 0) |
+-		    (uid->is_expired ? 0x04 : 0)));
++		   ((uid->flags.primary ? 0x01 : 0) | (uid->flags.revoked ? 0x02 : 0) |
++		    (uid->flags.expired ? 0x04 : 0)));
+ 	  write_status_text (STATUS_ATTRIBUTE, buf);
+ 	}
+ 
+@@ -926,7 +925,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
+           int indent;
+           int kl = opt.keyid_format == KF_NONE? 10 : keystrlen ();
+ 
+-	  if ((uid->is_expired || uid->is_revoked)
++	  if ((uid->flags.expired || uid->flags.revoked)
+ 	      && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
+ 	    {
+ 	      skip_sigs = 1;
+@@ -938,7 +937,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
+ 	  if (attrib_fp && uid->attrib_data != NULL)
+ 	    dump_attribs (uid, pk);
+ 
+-	  if ((uid->is_revoked || uid->is_expired)
++	  if ((uid->flags.revoked || uid->flags.expired)
+ 	      || ((opt.list_options & LIST_SHOW_UID_VALIDITY)
+                   && !listctx->no_validity))
+ 	    {
+@@ -1297,9 +1296,9 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
+ 	  if (attrib_fp && uid->attrib_data != NULL)
+ 	    dump_attribs (uid, pk);
+ 
+-	  if (uid->is_revoked)
++	  if (uid->flags.revoked)
+ 	    uid_validity = 'r';
+-	  else if (uid->is_expired)
++	  else if (uid->flags.expired)
+ 	    uid_validity = 'e';
+ 	  else if (opt.no_expensive_trust_checks)
+ 	    uid_validity = 0;
+@@ -1556,7 +1555,7 @@ do_reorder_keyblock (KBNODE keyblock, int attr)
+       if (node->pkt->pkttype == PKT_USER_ID &&
+ 	  ((attr && node->pkt->pkt.user_id->attrib_data) ||
+ 	   (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
+-	  node->pkt->pkt.user_id->is_primary)
++	  node->pkt->pkt.user_id->flags.primary)
+ 	{
+ 	  primary = primary2 = node;
+ 	  for (node = node->next; node; primary2 = node, node = node->next)
+diff --git a/g10/keyserver.c b/g10/keyserver.c
+index 0794527..1fe3ea8 100644
+--- a/g10/keyserver.c
++++ b/g10/keyserver.c
+@@ -1323,7 +1323,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
+ 	      for(node=node->next;node;node=node->next)
+ 		{
+ 		  if(node->pkt->pkttype==PKT_USER_ID
+-		     && node->pkt->pkt.user_id->is_primary)
++		     && node->pkt->pkt.user_id->flags.primary)
+ 		    uid=node->pkt->pkt.user_id;
+ 		  else if(node->pkt->pkttype==PKT_SIGNATURE
+ 			  && node->pkt->pkt.signature->
+diff --git a/g10/mainproc.c b/g10/mainproc.c
+index 2acd51e..4c5dce1 100644
+--- a/g10/mainproc.c
++++ b/g10/mainproc.c
+@@ -1960,11 +1960,11 @@ check_sig_and_print (CTX c, kbnode_t node)
+             continue;
+           if (!un->pkt->pkt.user_id->created)
+             continue;
+-          if (un->pkt->pkt.user_id->is_revoked)
++          if (un->pkt->pkt.user_id->flags.revoked)
+             continue;
+-          if (un->pkt->pkt.user_id->is_expired)
++          if (un->pkt->pkt.user_id->flags.expired)
+             continue;
+-          if (!un->pkt->pkt.user_id->is_primary)
++          if (!un->pkt->pkt.user_id->flags.primary)
+             continue;
+           /* We want the textual primary user ID here */
+           if (un->pkt->pkt.user_id->attrib_data)
+@@ -2041,12 +2041,12 @@ check_sig_and_print (CTX c, kbnode_t node)
+             {
+               if (un->pkt->pkttype != PKT_USER_ID)
+                 continue;
+-              if ((un->pkt->pkt.user_id->is_revoked
+-                   || un->pkt->pkt.user_id->is_expired)
++              if ((un->pkt->pkt.user_id->flags.revoked
++                   || un->pkt->pkt.user_id->flags.expired)
+                   && !(opt.verify_options & VERIFY_SHOW_UNUSABLE_UIDS))
+                 continue;
+               /* Skip textual primary user ids which we printed above. */
+-              if (un->pkt->pkt.user_id->is_primary
++              if (un->pkt->pkt.user_id->flags.primary
+                   && !un->pkt->pkt.user_id->attrib_data )
+                 continue;
+ 
+@@ -2071,9 +2071,9 @@ check_sig_and_print (CTX c, kbnode_t node)
+                 {
+                   const char *valid;
+ 
+-                  if (un->pkt->pkt.user_id->is_revoked)
++                  if (un->pkt->pkt.user_id->flags.revoked)
+                     valid = _("revoked");
+-                  else if (un->pkt->pkt.user_id->is_expired)
++                  else if (un->pkt->pkt.user_id->flags.expired)
+                     valid = _("expired");
+                   else
+ 		    /* Since this is just informational, don't
+diff --git a/g10/packet.h b/g10/packet.h
+index 3457f53..efccc76 100644
+--- a/g10/packet.h
++++ b/g10/packet.h
+@@ -280,19 +280,18 @@ typedef struct
+   u32 help_key_expire;
+   int help_full_count;
+   int help_marginal_count;
+-  int is_primary;       /* 2 if set via the primary flag, 1 if calculated */
+-  int is_revoked;
+-  int is_expired;
+   u32 expiredate;       /* expires at this date or 0 if not at all */
+   prefitem_t *prefs;    /* list of preferences (may be NULL)*/
+   u32 created;          /* according to the self-signature */
+   byte selfsigversion;
+   struct
+   {
+-    /* TODO: Move more flags here */
+     unsigned int mdc:1;
+     unsigned int ks_modify:1;
+     unsigned int compacted:1;
++    unsigned int primary:2;       /* 2 if set via the primary flag, 1 if calculated */
++    unsigned int revoked:1;
++    unsigned int expired:1;
+   } flags;
+   char *mbox;   /* NULL or the result of mailbox_from_userid.  */
+   /* The text contained in the user id packet, which is normally the
+diff --git a/g10/pkclist.c b/g10/pkclist.c
+index 698794e..bf43d56 100644
+--- a/g10/pkclist.c
++++ b/g10/pkclist.c
+@@ -235,12 +235,12 @@ do_edit_ownertrust (ctrl_t ctrl, PKT_public_key *pk, int mode,
+ 	      {
+                 if (un->pkt->pkttype != PKT_USER_ID )
+ 		  continue;
+-                if (un->pkt->pkt.user_id->is_revoked )
++                if (un->pkt->pkt.user_id->flags.revoked)
+ 		  continue;
+-                if (un->pkt->pkt.user_id->is_expired )
++                if (un->pkt->pkt.user_id->flags.expired)
+ 		  continue;
+ 		/* Only skip textual primaries */
+-                if (un->pkt->pkt.user_id->is_primary
++                if (un->pkt->pkt.user_id->flags.primary
+ 		    && !un->pkt->pkt.user_id->attrib_data )
+ 		  continue;
+ 
+diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
+index cc962cf..d2261b0 100644
+--- a/g10/pubkey-enc.c
++++ b/g10/pubkey-enc.c
+@@ -54,7 +54,7 @@ is_algo_in_prefs (kbnode_t keyblock, preftype_t type, int algo)
+           PKT_user_id *uid = k->pkt->pkt.user_id;
+           prefitem_t *prefs = uid->prefs;
+ 
+-          if (uid->created && prefs && !uid->is_revoked && !uid->is_expired)
++          if (uid->created && prefs && !uid->flags.revoked && !uid->flags.expired)
+             {
+               for (; prefs->type; prefs++)
+                 if (prefs->type == type && prefs->value == algo)
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 9d6a457..9d9d8df 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -2209,9 +2209,9 @@ build_conflict_set (tofu_dbs_t dbs,
+             {
+               found_user_id = 1;
+ 
+-              if (user_id2->is_revoked)
++              if (user_id2->flags.revoked)
+                 iter->flags |= BINDING_REVOKED;
+-              if (user_id2->is_expired)
++              if (user_id2->flags.expired)
+                 iter->flags |= BINDING_EXPIRED;
+             }
+ 
+@@ -3486,7 +3486,7 @@ tofu_register_encryption (ctrl_t ctrl,
+         {
+ 	  PKT_user_id *uid = n->pkt->pkt.user_id;
+ 
+-          if (uid->is_revoked)
++          if (uid->flags.revoked)
+             continue;
+ 
+           add_to_strlist (&user_id_list, uid->name);
+@@ -3871,7 +3871,7 @@ tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy)
+ 	continue;
+ 
+       user_id = kb->pkt->pkt.user_id;
+-      if (user_id->is_revoked)
++      if (user_id->flags.revoked)
+ 	/* Skip revoked user ids.  (Don't skip expired user ids, the
+ 	   expiry can be changed.)  */
+ 	continue;
+diff --git a/g10/trust.c b/g10/trust.c
+index 77fde4c..b1f6222 100644
+--- a/g10/trust.c
++++ b/g10/trust.c
+@@ -145,9 +145,9 @@ uid_trust_string_fixed (ctrl_t ctrl, PKT_public_key *key, PKT_user_id *uid)
+          uid are both NULL, or neither are NULL. */
+       return _("10 translator see trust.c:uid_trust_string_fixed");
+     }
+-  else if(uid->is_revoked || (key && key->flags.revoked))
++  else if(uid->flags.revoked || (key && key->flags.revoked))
+     return                         _("[ revoked]");
+-  else if(uid->is_expired)
++  else if(uid->flags.expired)
+     return                         _("[ expired]");
+   else if(key)
+     {
+@@ -703,7 +703,7 @@ clean_uid_from_key (kbnode_t keyblock, kbnode_t uidnode, int noisy)
+      IDs if --allow-non-selfsigned-uid is set. */
+   if (uid->created
+       || uid->flags.compacted
+-      || (!uid->is_expired && !uid->is_revoked && opt.allow_non_selfsigned_uid))
++      || (!uid->flags.expired && !uid->flags.revoked && opt.allow_non_selfsigned_uid))
+     return 0;
+ 
+   for (node=uidnode->next;
+@@ -723,9 +723,9 @@ clean_uid_from_key (kbnode_t keyblock, kbnode_t uidnode, int noisy)
+       const char *reason;
+       char *user = utf8_to_native (uid->name, uid->len, 0);
+ 
+-      if (uid->is_revoked)
++      if (uid->flags.revoked)
+ 	reason = _("revoked");
+-      else if (uid->is_expired)
++      else if (uid->flags.expired)
+ 	reason = _("expired");
+       else
+ 	reason = _("invalid");
+diff --git a/g10/trustdb.c b/g10/trustdb.c
+index a0b9d5f..7b76ac8 100644
+--- a/g10/trustdb.c
++++ b/g10/trustdb.c
+@@ -1140,14 +1140,14 @@ tdb_get_validity_core (ctrl_t ctrl,
+             }
+ 
+           /* If the user id is revoked or expired, then skip it.  */
+-          if (user_id->is_revoked || user_id->is_expired)
++          if (user_id->flags.revoked || user_id->flags.expired)
+             {
+               if (DBG_TRUST)
+                 {
+                   char *s;
+-                  if (user_id->is_revoked && user_id->is_expired)
++                  if (user_id->flags.revoked && user_id->flags.expired)
+                     s = "revoked and expired";
+-                  else if (user_id->is_revoked)
++                  else if (user_id->flags.revoked)
+                     s = "revoked";
+                   else
+                     s = "expire";
+@@ -1156,7 +1156,7 @@ tdb_get_validity_core (ctrl_t ctrl,
+                              s, user_id->name);
+                 }
+ 
+-              if (user_id->is_revoked)
++              if (user_id->flags.revoked)
+                 continue;
+ 
+               expired = 1;
+@@ -1645,8 +1645,8 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
+ 	 resigned.  -dshaw */
+ 
+       if (node->pkt->pkttype == PKT_USER_ID
+-	  && !node->pkt->pkt.user_id->is_revoked
+-	  && !node->pkt->pkt.user_id->is_expired)
++	  && !node->pkt->pkt.user_id->flags.revoked
++	  && !node->pkt->pkt.user_id->flags.expired)
+         {
+           if (uidnode && issigned)
+             {
diff --git a/debian/patches/0048-tests-Rework-environment-setup.patch b/debian/patches/0048-tests-Rework-environment-setup.patch
new file mode 100644
index 0000000..4d60783
--- /dev/null
+++ b/debian/patches/0048-tests-Rework-environment-setup.patch
@@ -0,0 +1,227 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 9 Mar 2017 13:26:06 +0100
+Subject: tests: Rework environment setup.
+
+* tests/gpgscm/tests.scm (test::scm): Add a setup argument.
+(test::binary): Likewise.
+(run-tests-parallel): Remove setup parameter.
+(run-tests-sequential): Likewise.
+(make-environment-cache): New function that handles the cache
+protocol.
+* tests/gpgme/run-tests.scm: Adapt accordingly.
+* tests/gpgsm/run-tests.scm: Likewise.
+* tests/migrations/run-tests.scm: Likewise.
+* tests/openpgp/run-tests.scm: Likewise.
+--
+This change allows us to have different environments for tests.  This
+is needed to run more GPGME tests, and to increase concurrency while
+running all tests.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit cca91a3f8f7e3e36b7149fc93f7b6df11d21eb1d)
+---
+ tests/gpgme/run-tests.scm      | 15 ++++----
+ tests/gpgscm/tests.scm         | 78 +++++++++++++++++++++++-------------------
+ tests/gpgsm/run-tests.scm      |  6 ++--
+ tests/migrations/run-tests.scm |  3 +-
+ tests/openpgp/run-tests.scm    |  4 +--
+ 5 files changed, 58 insertions(+), 48 deletions(-)
+
+diff --git a/tests/gpgme/run-tests.scm b/tests/gpgme/run-tests.scm
+index cb17977..4d3a7e6 100644
+--- a/tests/gpgme/run-tests.scm
++++ b/tests/gpgme/run-tests.scm
+@@ -39,9 +39,10 @@
+ (let* ((runner (if (member "--parallel" *args*)
+ 		   run-tests-parallel
+ 		   run-tests-sequential))
++       (setup-c (make-environment-cache
++		 (test::scm #f "setup.scm" (in-srcdir "setup.scm") "--" "tests" "gpg")))
+        (tests (filter (lambda (arg) (not (string-prefix? arg "--"))) *args*)))
+   (runner
+-   (test::scm "setup.scm" (in-srcdir "setup.scm") "--" "tests" "gpg")
+    (apply
+     append
+     (map (lambda (cmpnts)
+@@ -50,6 +51,7 @@
+ 		      (string-suffix? name ".test"))))
+ 	   (define :path car)
+ 	   (define :key cadr)
++	   (define :setup caddr)
+ 	   (define (find-test name)
+ 	     (apply path-join
+ 		    `(,(if (compiled? name)
+@@ -59,11 +61,12 @@
+ 							    "Makefile.am"))))
+ 	     (map (lambda (name)
+ 		    (apply test::scm
+-			   `(,name ,(in-srcdir "wrap.scm") --executable
+-				   ,(find-test name)
+-				   -- ,@(:path cmpnts))))
++			   `(,(:setup cmpnts)
++			     ,name ,(in-srcdir "wrap.scm") --executable
++			     ,(find-test name)
++			     -- ,@(:path cmpnts))))
+ 		  (if (null? tests) (all-tests makefile (:key cmpnts)) tests))))
+-	 '((("tests" "gpg") "c_tests")
++	 `((("tests" "gpg") "c_tests" ,setup-c)
+ 	   ;; XXX: Not yet.
+ 	   ;; (("lang" "python" "tests") "py_tests")
+-	   (("lang" "qt" "tests") "TESTS"))))))
++	   (("lang" "qt" "tests") "TESTS" ,setup-c))))))
+diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm
+index b3da919..0c02c34 100644
+--- a/tests/gpgscm/tests.scm
++++ b/tests/gpgscm/tests.scm
+@@ -551,18 +551,20 @@
+ ;; A single test.
+ (define test
+   (package
+-   (define (scm name path . args)
++   (define (scm setup name path . args)
+      ;; Start the process.
+      (define (spawn-scm args' in out err)
+        (spawn-process-fd `(,*argv0* ,@(verbosity (*verbose*))
+ 				    ,(locate-test path)
++				    ,@(if setup (force setup) '())
+ 				    , at args' , at args) in out err))
+      (new name #f spawn-scm #f #f CLOSED_FD))
+ 
+-   (define (binary name path . args)
++   (define (binary setup name path . args)
+      ;; Start the process.
+      (define (spawn-binary args' in out err)
+-       (spawn-process-fd `(,path , at args' , at args) in out err))
++       (spawn-process-fd `(,path ,@(if setup (force setup) '()) , at args' , at args)
++			 in out err))
+      (new name #f spawn-binary #f #f CLOSED_FD))
+ 
+    (define (new name directory spawn pid retcode logfd)
+@@ -613,41 +615,47 @@
+ 
+ ;; Run the setup target to create an environment, then run all given
+ ;; tests in parallel.
+-(define (run-tests-parallel setup tests)
+-  (lettmp (gpghome-tar)
+-    (setup::run-sync '--create-tarball gpghome-tar)
+-    (let loop ((pool (test-pool::new '())) (tests' tests))
+-      (if (null? tests')
+-	  (let ((results (pool::wait)))
+-	    (for-each (lambda (t)
+-			(catch (echo "Removing" t::directory "failed:" *error*)
+-			       (unlink-recursively t::directory))
+-			(t::report)) (reverse results::procs))
+-	    (exit (results::report)))
+-	  (let* ((wd (mkdtemp))
+-		 (test (car tests'))
+-		 (test' (test::set-directory wd)))
+-	    (loop (pool::add (test'::run-async '--unpack-tarball gpghome-tar))
+-		  (cdr tests')))))))
++(define (run-tests-parallel tests)
++  (let loop ((pool (test-pool::new '())) (tests' tests))
++    (if (null? tests')
++	(let ((results (pool::wait)))
++	  (for-each (lambda (t)
++		      (catch (echo "Removing" t::directory "failed:" *error*)
++			     (unlink-recursively t::directory))
++		      (t::report)) (reverse results::procs))
++	  (exit (results::report)))
++	(let* ((wd (mkdtemp))
++	       (test (car tests'))
++	       (test' (test::set-directory wd)))
++	  (loop (pool::add (test'::run-async))
++		(cdr tests'))))))
+ 
+ ;; Run the setup target to create an environment, then run all given
+ ;; tests in sequence.
+-(define (run-tests-sequential setup tests)
+-  (lettmp (gpghome-tar)
+-    (setup::run-sync '--create-tarball gpghome-tar)
+-    (let loop ((pool (test-pool::new '())) (tests' tests))
+-      (if (null? tests')
+-	  (let ((results (pool::wait)))
+-	    (for-each (lambda (t)
+-			(catch (echo "Removing" t::directory "failed:" *error*)
+-			       (unlink-recursively t::directory)))
+-		      results::procs)
+-	    (exit (results::report)))
+-	  (let* ((wd (mkdtemp))
+-		 (test (car tests'))
+-		 (test' (test::set-directory wd)))
+-	    (loop (pool::add (test'::run-sync '--unpack-tarball gpghome-tar))
+-		  (cdr tests')))))))
++(define (run-tests-sequential tests)
++  (let loop ((pool (test-pool::new '())) (tests' tests))
++    (if (null? tests')
++	(let ((results (pool::wait)))
++	  (for-each (lambda (t)
++		      (catch (echo "Removing" t::directory "failed:" *error*)
++			     (unlink-recursively t::directory)))
++		    results::procs)
++	  (exit (results::report)))
++	(let* ((wd (mkdtemp))
++	       (test (car tests'))
++	       (test' (test::set-directory wd)))
++	  (loop (pool::add (test'::run-sync))
++		(cdr tests'))))))
++
++;; Helper to create environment caches from test functions.  SETUP
++;; must be a test implementing the producer side cache protocol.
++;; Returns a promise containing the arguments that must be passed to a
++;; test implementing the consumer side of the cache protocol.
++(define (make-environment-cache setup)
++  (delay (let* ((tarball (make-temporary-file "environment-cache")))
++	   (atexit (lambda () (remove-temporary-file tarball)))
++	   (setup::run-sync '--create-tarball tarball)
++	   `(--unpack-tarball ,tarball))))
+ 
+ ;; Command line flag handling.  Returns the elements following KEY in
+ ;; ARGUMENTS up to the next argument, or #f if KEY is not in
+diff --git a/tests/gpgsm/run-tests.scm b/tests/gpgsm/run-tests.scm
+index dfd5b02..e444245 100644
+--- a/tests/gpgsm/run-tests.scm
++++ b/tests/gpgsm/run-tests.scm
+@@ -20,13 +20,13 @@
+ (if (string=? "" (getenv "srcdir"))
+     (begin
+       (echo "Environment variable 'srcdir' not set.  Please point it to"
+-	    "tests/openpgp.")
++	    "tests/gpgsm.")
+       (exit 2)))
+ 
+ (let* ((tests (filter (lambda (arg) (not (string-prefix? arg "--"))) *args*))
++       (setup (make-environment-cache (test::scm #f "setup.scm" "setup.scm")))
+        (runner (if (and (member "--parallel" *args*)
+ 			(> (length tests) 1))
+ 		   run-tests-parallel
+ 		   run-tests-sequential)))
+-  (runner (test::scm "setup.scm" "setup.scm")
+-	  (map (lambda (t) (test::scm t t)) tests)))
++  (runner (map (lambda (t) (test::scm setup t t)) tests)))
+diff --git a/tests/migrations/run-tests.scm b/tests/migrations/run-tests.scm
+index 069af5b..b4ad260 100644
+--- a/tests/migrations/run-tests.scm
++++ b/tests/migrations/run-tests.scm
+@@ -22,5 +22,4 @@
+ 			(> (length tests) 1))
+ 		   run-tests-parallel
+ 		   run-tests-sequential)))
+-  (runner (test::scm "setup.scm" "setup.scm")
+-	  (map (lambda (t) (test::scm t t)) tests)))
++  (runner (map (lambda (t) (test::scm #f t t)) tests)))
+diff --git a/tests/openpgp/run-tests.scm b/tests/openpgp/run-tests.scm
+index 546d7d4..139f618 100644
+--- a/tests/openpgp/run-tests.scm
++++ b/tests/openpgp/run-tests.scm
+@@ -27,9 +27,9 @@
+ (setenv "objdir" (getcwd) #f)
+ 
+ (let* ((tests (filter (lambda (arg) (not (string-prefix? arg "--"))) *args*))
++       (setup (make-environment-cache (test::scm #f "setup.scm" "setup.scm")))
+        (runner (if (and (member "--parallel" *args*)
+ 			(> (length tests) 1))
+ 		   run-tests-parallel
+ 		   run-tests-sequential)))
+-  (runner (test::scm "setup.scm" "setup.scm")
+-	  (map (lambda (t) (test::scm t t)) tests)))
++  (runner (map (lambda (t) (test::scm setup t t)) tests))))
diff --git a/debian/patches/0049-tests-Run-the-tests-for-the-Python-bindings-of-GPGME.patch b/debian/patches/0049-tests-Run-the-tests-for-the-Python-bindings-of-GPGME.patch
new file mode 100644
index 0000000..f09ff56
--- /dev/null
+++ b/debian/patches/0049-tests-Run-the-tests-for-the-Python-bindings-of-GPGME.patch
@@ -0,0 +1,141 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 9 Mar 2017 14:33:02 +0100
+Subject: tests: Run the tests for the Python bindings of GPGME.
+
+* tests/gpgme/gpgme-defs.scm (create-file): Write lines.
+(create-gpgmehome): Extend function to create the right environment
+for the Python tests.
+* tests/gpgme/run-tests.scm: Make an environment cache for the Python
+tests and enable them.
+* tests/gpgme/wrap.scm: Do not hardcode the path of the Python
+interpreter.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 046a15a88c83b40a753b4ad7ecc1456efa5b527f)
+---
+ tests/gpgme/gpgme-defs.scm | 34 +++++++++++++++++++++++++++++++---
+ tests/gpgme/run-tests.scm  |  9 ++++++---
+ tests/gpgme/wrap.scm       | 23 ++++++++++++++---------
+ 3 files changed, 51 insertions(+), 15 deletions(-)
+
+diff --git a/tests/gpgme/gpgme-defs.scm b/tests/gpgme/gpgme-defs.scm
+index 7a7166c..12e033c 100644
+--- a/tests/gpgme/gpgme-defs.scm
++++ b/tests/gpgme/gpgme-defs.scm
+@@ -45,12 +45,25 @@
+ ;; The tests expect the pinentry to return the passphrase "abc".
+ (setenv "PINENTRY_USER_DATA" "abc" #t)
+ 
+-(define (create-file name content)
++(define (create-file name . lines)
+   (letfd ((fd (open name (logior O_WRONLY O_CREAT O_BINARY) #o600)))
+-    (display content (fdopen fd "wb"))))
++    (let ((port (fdopen fd "wb")))
++      (for-each (lambda (line) (display line port) (newline port)) lines))))
+ 
+ (define (create-gpgmehome . path)
+-  (create-file "gpg.conf" "no-force-v3-sigs\n")
++  ;; Support for various environments.
++  (define mode
++    (cond
++     ((equal? path '("lang" "python" "tests"))
++      (set! path '("tests" "gpg")) ;; Mostly uses files from tests/gpg.
++      'python)
++     (else
++      'gpg)))
++
++  (create-file
++   "gpg.conf"
++   "no-force-v3-sigs"
++   (string-append "agent-program " (tool 'gpg-agent) "|--debug-quick-random\n"))
+   (create-file
+    "gpg-agent.conf"
+    (string-append "pinentry-program " (tool 'pinentry)))
+@@ -75,6 +88,21 @@
+      (call-check `(, at GPG --yes --import ,(apply in-gpgme-srcdir
+ 						`(, at path ,file)))))
+    (list "pubdemo.asc" "secdemo.asc"))
++
++  (when (equal? mode 'python)
++	(log "Importing extra keys for Python tests")
++	(for-each
++	 (lambda (file)
++	   (call-check `(, at GPG --yes --import
++			       ,(apply in-gpgme-srcdir
++				       `("lang" "python" "tests" ,file)))))
++	 (list "encrypt-only.asc" "sign-only.asc"))
++
++	(log "Marking key as trusted")
++	(pipe:do
++	 (pipe:echo "A0FF4590BB6122EDEF6E3C542D727CC768697734:6:\n")
++	 (pipe:spawn `(,(tool 'gpg) --import-ownertrust))))
++
+   (stop-agent))
+ 
+ ;; Initialize the test environment, install appropriate configuration
+diff --git a/tests/gpgme/run-tests.scm b/tests/gpgme/run-tests.scm
+index 4d3a7e6..72de495 100644
+--- a/tests/gpgme/run-tests.scm
++++ b/tests/gpgme/run-tests.scm
+@@ -40,7 +40,11 @@
+ 		   run-tests-parallel
+ 		   run-tests-sequential))
+        (setup-c (make-environment-cache
+-		 (test::scm #f "setup.scm" (in-srcdir "setup.scm") "--" "tests" "gpg")))
++		 (test::scm #f "setup.scm (tests/gpg)" (in-srcdir "setup.scm")
++			    "--" "tests" "gpg")))
++       (setup-py (make-environment-cache
++		  (test::scm #f "setup.scm (lang/python/tests)" (in-srcdir "setup.scm")
++			     "--" "lang" "python" "tests")))
+        (tests (filter (lambda (arg) (not (string-prefix? arg "--"))) *args*)))
+   (runner
+    (apply
+@@ -67,6 +71,5 @@
+ 			     -- ,@(:path cmpnts))))
+ 		  (if (null? tests) (all-tests makefile (:key cmpnts)) tests))))
+ 	 `((("tests" "gpg") "c_tests" ,setup-c)
+-	   ;; XXX: Not yet.
+-	   ;; (("lang" "python" "tests") "py_tests")
++	   (("lang" "python" "tests") "py_tests" ,setup-py)
+ 	   (("lang" "qt" "tests") "TESTS" ,setup-c))))))
+diff --git a/tests/gpgme/wrap.scm b/tests/gpgme/wrap.scm
+index e8f2b1f..d338892 100644
+--- a/tests/gpgme/wrap.scm
++++ b/tests/gpgme/wrap.scm
+@@ -29,6 +29,9 @@
+ (setenv "top_srcdir" gpgme-srcdir #t)
+ (setenv "srcdir" (path-join gpgme-srcdir "tests" "gpg") #t)
+ 
++(define python (catch #f
++		      (path-expand "python" (string-split (getenv "PATH") *pathsep*))))
++
+ (define (run what)
+   (if (string-suffix? (car what) ".py")
+       (begin
+@@ -39,15 +42,17 @@
+ 				   (getenv "LD_LIBRARY_PATH"))
+ 		    (path-join gpgme-builddir "src/.libs"))
+ 		#t)
+-	(call-with-fds
+-	 `("/usr/bin/python"
+-	   ,(in-gpgme-srcdir "lang" "python" "tests" "run-tests.py")
+-	   --quiet
+-	   --interpreters=/usr/bin/python
+-	   --builddir ,(path-join gpgme-builddir "lang" "python" "tests")
+-	   , at what)
+-	 STDIN_FILENO STDOUT_FILENO STDERR_FILENO))
+-      (if #f 77 (call-with-fds what STDIN_FILENO STDOUT_FILENO STDERR_FILENO))))
++	(if python
++	    (call-with-fds
++	     `(,python
++	       ,(in-gpgme-srcdir "lang" "python" "tests" "run-tests.py")
++	       --quiet
++	       ,(string-append "--interpreters=" python)
++	       --builddir ,(path-join gpgme-builddir "lang" "python" "tests")
++	       , at what)
++	     STDIN_FILENO STDOUT_FILENO STDERR_FILENO)
++	    77))
++      (call-with-fds what STDIN_FILENO STDOUT_FILENO STDERR_FILENO)))
+ 
+ (let ((name (basename (car executable))))
+   (cond
diff --git a/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch b/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch
new file mode 100644
index 0000000..1cf3b91
--- /dev/null
+++ b/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch
@@ -0,0 +1,37 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 13 Mar 2017 17:42:08 +0100
+Subject: gpg: Flush stdout before printing stats with --check-sigs.
+
+* g10/keylist.c (print_signature_stats): Flush stdout.
+(list_keyblock_colon): Use es_flush instead of fflush.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 9a77b3b6e41f97b1209ad61c04b3dd33242ecae8)
+---
+ g10/keylist.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/g10/keylist.c b/g10/keylist.c
+index 3f9e313..32cf1e8 100644
+--- a/g10/keylist.c
++++ b/g10/keylist.c
+@@ -465,6 +465,10 @@ print_signature_stats (struct keylist_context *s)
+   if (!s->check_sigs)
+     return;  /* Signature checking was not requested.  */
+ 
++  /* Better flush stdout so that the stats are always printed after
++   * the output.  */
++  es_fflush (es_stdout);
++
+   if (s->good_sigs)
+     log_info (ngettext("%d good signature\n",
+                        "%d good signatures\n", s->good_sigs), s->good_sigs);
+@@ -1446,7 +1450,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
+ 	    {
+ 	      PKT_public_key *signer_pk = NULL;
+ 
+-	      fflush (stdout);
++	      es_fflush (es_stdout);
+ 	      if (opt.no_sig_cache)
+ 		signer_pk = xmalloc_clear (sizeof (PKT_public_key));
+ 
diff --git a/debian/patches/0051-doc-Explain-in-README-how-to-create-run-user-directo.patch b/debian/patches/0051-doc-Explain-in-README-how-to-create-run-user-directo.patch
new file mode 100644
index 0000000..b4b91fb
--- /dev/null
+++ b/debian/patches/0051-doc-Explain-in-README-how-to-create-run-user-directo.patch
@@ -0,0 +1,47 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Tue, 14 Mar 2017 12:34:23 +0100
+Subject: doc: Explain in README how to create /run/user directories.
+
+--
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 40b7911130a969677d6f0b5796236a29f10a9e69)
+---
+ README | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/README b/README
+index 4cb0b6c..0ff9099 100644
+--- a/README
++++ b/README
+@@ -148,6 +148,30 @@
+   use of the GnuPG directories.  Dirmngr is started by gpg or gpgsm as
+   needed. There is no more need to install a separate Dirmngr package.
+ 
++* RECOMMENDATIONS
++
++** Socket directory
++
++  GnuPG uses Unix domain sockets to connect its components (on Windows
++  an emulation of these sockets is used).  Depending on the type of
++  the file system, it is sometimes not possible to use the GnuPG home
++  directory (i.e. ~/.gnupg) as the location for the sockets.  To solve
++  this problem GnuPG prefers the use of a per-user directory below the
++  the /run (or /var/run) hierarchy for the the sockets.  It is thus
++  suggested to create per-user directories on system or session
++  startup.  For example the following snippet can be used in
++  /etc/rc.local to create these directories:
++
++      [ ! -d /run/user ] && mkdir /run/user
++      awk -F: </etc/passwd '$3 >= 1000 && $3 < 65000 {print $3}' \
++        | ( while read uid rest; do
++              if [ ! -d "/run/user/$uid" ]; then
++                mkdir /run/user/$uid
++                chown $uid /run/user/$uid
++                chmod 700 /run/user/$uid
++              fi
++            done )
++
+ 
+ * DOCUMENTATION
+ 
diff --git a/debian/patches/0052-tests-Skip-Python-tests-if-the-bindings-are-not-buil.patch b/debian/patches/0052-tests-Skip-Python-tests-if-the-bindings-are-not-buil.patch
new file mode 100644
index 0000000..e8890d7
--- /dev/null
+++ b/debian/patches/0052-tests-Skip-Python-tests-if-the-bindings-are-not-buil.patch
@@ -0,0 +1,63 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 14 Mar 2017 12:45:29 +0100
+Subject: tests: Skip Python tests if the bindings are not built.
+
+* tests/gpgme/wrap.scm (python): Move variable...
+* tests/gpgme/gpgme-defs.scm (python): ... here.
+(run-python-tests?): New function.
+* tests/gpgme/run-tests.scm: Only run Python tests if the bindings can
+be located in GPGME's build directory.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit d82abbb1b6e80d5980e6259ddcfc770e65a6b1b3)
+---
+ tests/gpgme/gpgme-defs.scm | 10 ++++++++++
+ tests/gpgme/run-tests.scm  |  4 +++-
+ tests/gpgme/wrap.scm       |  3 ---
+ 3 files changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/tests/gpgme/gpgme-defs.scm b/tests/gpgme/gpgme-defs.scm
+index 12e033c..2b104f2 100644
+--- a/tests/gpgme/gpgme-defs.scm
++++ b/tests/gpgme/gpgme-defs.scm
+@@ -171,3 +171,13 @@
+ 	    (else
+ 	     (expand-one (append acc (list (car v))) (cdr v))))))
+ 	values)))
++
++(define python (catch #f
++		      (path-expand "python" (string-split (getenv "PATH") *pathsep*))))
++(define (run-python-tests?)
++  (let* ((python-version
++	  (string-trim char-whitespace?
++		       (call-popen `(,python -c "import sys; print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))") "")))
++	 (build-path (path-join gpgme-builddir "lang" "python"
++				(string-append "python" python-version "-gpg"))))
++    (trace (file-exists? (trace build-path)))))
+diff --git a/tests/gpgme/run-tests.scm b/tests/gpgme/run-tests.scm
+index 72de495..be70f17 100644
+--- a/tests/gpgme/run-tests.scm
++++ b/tests/gpgme/run-tests.scm
+@@ -71,5 +71,7 @@
+ 			     -- ,@(:path cmpnts))))
+ 		  (if (null? tests) (all-tests makefile (:key cmpnts)) tests))))
+ 	 `((("tests" "gpg") "c_tests" ,setup-c)
+-	   (("lang" "python" "tests") "py_tests" ,setup-py)
++	   ,@(if (run-python-tests?)
++		 `((("lang" "python" "tests") "py_tests" ,setup-py))
++		 '())
+ 	   (("lang" "qt" "tests") "TESTS" ,setup-c))))))
+diff --git a/tests/gpgme/wrap.scm b/tests/gpgme/wrap.scm
+index d338892..4c96a09 100644
+--- a/tests/gpgme/wrap.scm
++++ b/tests/gpgme/wrap.scm
+@@ -29,9 +29,6 @@
+ (setenv "top_srcdir" gpgme-srcdir #t)
+ (setenv "srcdir" (path-join gpgme-srcdir "tests" "gpg") #t)
+ 
+-(define python (catch #f
+-		      (path-expand "python" (string-split (getenv "PATH") *pathsep*))))
+-
+ (define (run what)
+   (if (string-suffix? (car what) ".py")
+       (begin
diff --git a/debian/patches/0053-tests-Fix-running-python-condition.patch b/debian/patches/0053-tests-Fix-running-python-condition.patch
new file mode 100644
index 0000000..15c60bd
--- /dev/null
+++ b/debian/patches/0053-tests-Fix-running-python-condition.patch
@@ -0,0 +1,33 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Wed, 15 Mar 2017 16:45:18 +0900
+Subject: tests: Fix running python condition.
+
+* tests/gpgme/gpgme-defs.scm (run-python-tests?): We need Python.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit a672ddec03f96475866d712b28be18b3fab43aef)
+---
+ tests/gpgme/gpgme-defs.scm | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/tests/gpgme/gpgme-defs.scm b/tests/gpgme/gpgme-defs.scm
+index 2b104f2..0583774 100644
+--- a/tests/gpgme/gpgme-defs.scm
++++ b/tests/gpgme/gpgme-defs.scm
+@@ -175,9 +175,10 @@
+ (define python (catch #f
+ 		      (path-expand "python" (string-split (getenv "PATH") *pathsep*))))
+ (define (run-python-tests?)
+-  (let* ((python-version
+-	  (string-trim char-whitespace?
+-		       (call-popen `(,python -c "import sys; print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))") "")))
+-	 (build-path (path-join gpgme-builddir "lang" "python"
+-				(string-append "python" python-version "-gpg"))))
+-    (trace (file-exists? (trace build-path)))))
++  (and python
++       (let* ((python-version
++	       (string-trim char-whitespace?
++			    (call-popen `(,python -c "import sys; print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))") "")))
++	      (build-path (path-join gpgme-builddir "lang" "python"
++				     (string-append "python" python-version "-gpg"))))
++	 (trace (file-exists? (trace build-path))))))
diff --git a/debian/patches/0054-g10-Remove-unused-function.patch b/debian/patches/0054-g10-Remove-unused-function.patch
new file mode 100644
index 0000000..277d3fe
--- /dev/null
+++ b/debian/patches/0054-g10-Remove-unused-function.patch
@@ -0,0 +1,120 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Wed, 15 Mar 2017 16:48:01 +0900
+Subject: g10: Remove unused function.
+
+* g10/call-agent.c (select_openpgp): Remove.
+
+--
+
+By this change, the function get_serialno_cb will be also unused.  But
+please don't remove the function, because it will be soon used.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit ed3248219e921ee24f6f1b2985abb7e0945d70e9)
+---
+ g10/call-agent.c | 92 --------------------------------------------------------
+ 1 file changed, 92 deletions(-)
+
+diff --git a/g10/call-agent.c b/g10/call-agent.c
+index 7d627bb..1606797 100644
+--- a/g10/call-agent.c
++++ b/g10/call-agent.c
+@@ -1028,98 +1028,6 @@ agent_scd_genkey (int keyno, int force, u32 *createtime)
+ 
+ 
+ 

+-/* Issue an SCD SERIALNO openpgp command and if SERIALNO is not NULL
+-   ask the user to insert the requested card.  */
+-gpg_error_t
+-select_openpgp (const char *serialno)
+-{
+-  gpg_error_t err;
+-
+-  /* Send the serialno command to initialize the connection.  Without
+-     a given S/N we don't care about the data returned.  If the card
+-     has already been initialized, this is a very fast command.  We
+-     request the openpgp card because that is what we expect.
+-
+-     Note that an opt.limit_card_insert_tries of 1 means: No tries at
+-     all whereas 0 means do not limit the number of tries.  Due to the
+-     sue of a pinentry prompt with a cancel option we use it here in a
+-     boolean sense.  */
+-  if (!serialno || opt.limit_card_insert_tries == 1)
+-    err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
+-                           NULL, NULL, NULL, NULL, NULL, NULL);
+-  else
+-    {
+-      char *this_sn = NULL;
+-      char *desc;
+-      int ask;
+-      char *want_sn;
+-      char *p;
+-
+-      want_sn = xtrystrdup (serialno);
+-      if (!want_sn)
+-        return gpg_error_from_syserror ();
+-      p = strchr (want_sn, '/');
+-      if (p)
+-        *p = 0;
+-
+-      do
+-        {
+-          ask = 0;
+-          err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
+-                                 NULL, NULL, NULL, NULL,
+-                                 get_serialno_cb, &this_sn);
+-          if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
+-            ask = 1;
+-          else if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
+-            ask = 2;
+-          else if (err)
+-            ;
+-          else if (this_sn)
+-            {
+-              if (strcmp (want_sn, this_sn))
+-                ask = 2;
+-            }
+-
+-          xfree (this_sn);
+-          this_sn = NULL;
+-
+-          if (ask)
+-            {
+-              char *formatted = NULL;
+-              char *ocodeset = i18n_switchto_utf8 ();
+-
+-              if (!strncmp (want_sn, "D27600012401", 12)
+-                  && strlen (want_sn) == 32 )
+-                formatted = xtryasprintf ("(%.4s) %.8s",
+-                                          want_sn + 16, want_sn + 20);
+-
+-              err = 0;
+-              desc = xtryasprintf
+-                ("%s:\n\n"
+-                 "  \"%s\"",
+-                 ask == 1
+-                 ? _("Please insert the card with serial number")
+-                 : _("Please remove the current card and "
+-                     "insert the one with serial number"),
+-                 formatted? formatted : want_sn);
+-              if (!desc)
+-                err = gpg_error_from_syserror ();
+-              xfree (formatted);
+-              i18n_switchback (ocodeset);
+-              if (!err)
+-                err = gpg_agent_get_confirmation (desc);
+-              xfree (desc);
+-            }
+-        }
+-      while (ask && !err);
+-      xfree (want_sn);
+-    }
+-
+-  return err;
+-}
+-
+-
+-

+ /* Send a READCERT command to the SCdaemon. */
+ int
+ agent_scd_readcert (const char *certidstr,
diff --git a/debian/patches/0055-g10-Fix-check-of-serialno.patch b/debian/patches/0055-g10-Fix-check-of-serialno.patch
new file mode 100644
index 0000000..119f329
--- /dev/null
+++ b/debian/patches/0055-g10-Fix-check-of-serialno.patch
@@ -0,0 +1,25 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Wed, 15 Mar 2017 16:50:48 +0900
+Subject: g10: Fix check of serialno.
+
+* g10/card-util.c (card_status): Fix.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 61785b679c542bbd789395fa632eb8b5133b01ad)
+---
+ g10/card-util.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/card-util.c b/g10/card-util.c
+index 9bc3e25..d643724 100644
+--- a/g10/card-util.c
++++ b/g10/card-util.c
+@@ -435,7 +435,7 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
+ 
+   if (!serialno)
+     ;
+-  else if (strlen (serialno)+1 > serialnobuflen)
++  else if (strlen (info.serialno)+1 > serialnobuflen)
+     log_error ("serial number longer than expected\n");
+   else
+     strcpy (serialno, info.serialno);
diff --git a/debian/patches/0056-build-Remove-disable-tools-configuration-option.patch b/debian/patches/0056-build-Remove-disable-tools-configuration-option.patch
new file mode 100644
index 0000000..c109d18
--- /dev/null
+++ b/debian/patches/0056-build-Remove-disable-tools-configuration-option.patch
@@ -0,0 +1,62 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 15 Mar 2017 10:51:03 +0100
+Subject: build: Remove '--disable-tools' configuration option.
+
+* Makefile.am (SUBDIRS): Unconditionally include 'tools'.
+* configure.ac: Remove '--disable-tools' configuration option.
+--
+gpgconf is a core component nowadays and is always required.
+
+GnuPG-bug-id: 2993
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 6993e42088c191f18468317ba2b5b8fbc8c3edff)
+---
+ Makefile.am  | 7 +------
+ configure.ac | 2 --
+ 2 files changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 71e691a..7d023c1 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -81,11 +81,6 @@ dirmngr = dirmngr
+ else
+ dirmngr =
+ endif
+-if BUILD_TOOLS
+-tools = tools
+-else
+-tools =
+-endif
+ if BUILD_DOC
+ doc = doc
+ else
+@@ -94,7 +89,7 @@ endif
+ 
+ SUBDIRS = m4 common kbx \
+           ${gpg} ${sm} ${agent} ${scd} ${g13} ${dirmngr} \
+-          ${tools} po ${doc} tests
++          tools po ${doc} tests
+ 
+ dist_doc_DATA = README
+ 
+diff --git a/configure.ac b/configure.ac
+index 9631e88..2132ba4 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -126,7 +126,6 @@ build_agent=yes
+ GNUPG_BUILD_PROGRAM(scdaemon, yes)
+ GNUPG_BUILD_PROGRAM(g13, no)
+ GNUPG_BUILD_PROGRAM(dirmngr, yes)
+-GNUPG_BUILD_PROGRAM(tools, yes)
+ GNUPG_BUILD_PROGRAM(doc, yes)
+ GNUPG_BUILD_PROGRAM(symcryptrun, no)
+ # We use gpgtar to unpack test data, hence we always build it.  If the
+@@ -1703,7 +1702,6 @@ AM_CONDITIONAL(BUILD_AGENT,       test "$build_agent" = "yes")
+ AM_CONDITIONAL(BUILD_SCDAEMON,    test "$build_scdaemon" = "yes")
+ AM_CONDITIONAL(BUILD_G13,         test "$build_g13" = "yes")
+ AM_CONDITIONAL(BUILD_DIRMNGR,     test "$build_dirmngr" = "yes")
+-AM_CONDITIONAL(BUILD_TOOLS,       test "$build_tools" = "yes")
+ AM_CONDITIONAL(BUILD_DOC,         test "$build_doc" = "yes")
+ AM_CONDITIONAL(BUILD_SYMCRYPTRUN, test "$build_symcryptrun" = "yes")
+ AM_CONDITIONAL(BUILD_GPGTAR,      test "$build_gpgtar" = "yes")
diff --git a/debian/patches/0057-tests-Dump-the-tools-that-the-tests-are-going-to-use.patch b/debian/patches/0057-tests-Dump-the-tools-that-the-tests-are-going-to-use.patch
new file mode 100644
index 0000000..7a6291b
--- /dev/null
+++ b/debian/patches/0057-tests-Dump-the-tools-that-the-tests-are-going-to-use.patch
@@ -0,0 +1,44 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 15 Mar 2017 12:34:04 +0100
+Subject: tests: Dump the tools that the tests are going to use.
+
+* tests/openpgp/setup.scm: Dump the tools that the tests are going to
+use.  This will help us diagnose problems with the tests picking the
+wrong paths in the future.
+
+GnuPG-bug-id: 2979
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit c7833eca38fdb8d9ba7b59438ea87d651b8bf7ba)
+---
+ tests/openpgp/setup.scm | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/tests/openpgp/setup.scm b/tests/openpgp/setup.scm
+index bf1876e..4b3bfcb 100755
+--- a/tests/openpgp/setup.scm
++++ b/tests/openpgp/setup.scm
+@@ -22,6 +22,24 @@
+ (unless (member "--create-tarball" *args*)
+ 	(fail "Usage: setup.scm --create-tarball <file>"))
+ 
++(when (> (*verbose*) 0)
++      (define (pad symbol length)
++	(let loop ((cs (string->list (symbol->string symbol)))
++		   (result (make-string length #\space))
++		   (i 0))
++	  (if (null? cs)
++	      result
++	      (begin
++		(string-set! result i (car cs))
++		(loop (cdr cs) result (+ 1 i))))))
++      (log " I am going to use these tools:\n"
++	   "==============================")
++      (for-each
++       (lambda (t)
++	 (log (pad t 25) (tool t)))
++       '(gpgconf gpg gpg-agent scdaemon gpgsm dirmngr gpg-connect-agent
++		 gpg-preset-passphrase gpgtar pinentry)))
++
+ (with-ephemeral-home-directory
+  (chdir (getenv "GNUPGHOME"))
+  (create-gpghome)
diff --git a/debian/patches/0058-tests-Fix-using-tools-from-the-build-directory.patch b/debian/patches/0058-tests-Fix-using-tools-from-the-build-directory.patch
new file mode 100644
index 0000000..b9ff3dc
--- /dev/null
+++ b/debian/patches/0058-tests-Fix-using-tools-from-the-build-directory.patch
@@ -0,0 +1,59 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 15 Mar 2017 14:36:27 +0100
+Subject: tests: Fix using tools from the build directory.
+
+* tests/openpgp/defs.scm (gpg-conf'): Explicitly pass the build prefix
+to gpgconf here...
+(gpg-components): ... instead of only here.
+--
+
+Previously, gpgconf was not invoked with '--build-prefix' when
+changing the configuration.  This made tests using this facility fail
+(e.g. the TOFU test).  This only affected release builds, because in
+development builds gpgconf picks up the build prefix from the
+environment.
+
+GnuPG-bug-id: 2979
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit a98459d3f4ec3d196fb0adb0e90dadf40abc8c81)
+---
+ tests/openpgp/defs.scm | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm
+index 568ffab..7c8e10a 100644
+--- a/tests/openpgp/defs.scm
++++ b/tests/openpgp/defs.scm
+@@ -140,10 +140,16 @@
+ (define valgrind
+   '("/usr/bin/valgrind" --leak-check=full --error-exitcode=154))
+ 
++(unless installed?
++	(setenv "GNUPG_BUILDDIR" (getenv "objdir") #t))
++
+ (define (gpg-conf . args)
+   (gpg-conf' "" args))
+ (define (gpg-conf' input args)
+-  (let ((s (call-popen `(,(tool-hardcoded 'gpgconf) , at args) input)))
++  (let ((s (call-popen `(,(tool-hardcoded 'gpgconf)
++			 ,@(if installed? '()
++			       (list '--build-prefix (getenv "objdir")))
++			 , at args) input)))
+     (map (lambda (line) (map percent-decode (string-split line #\:)))
+ 	 (string-split-newlines s))))
+ (define :gc:c:name car)
+@@ -180,13 +186,7 @@
+      (gpg-conf' (string-append key ":16:")
+ 		`(--change-options ,component)))))
+ 
+-
+-(unless installed?
+-	(setenv "GNUPG_BUILDDIR" (getenv "objdir") #t))
+-(define gpg-components (apply gpg-conf
+-			`(,@(if installed? '()
+-				(list '--build-prefix (getenv "objdir")))
+-			  --list-components)))
++(define gpg-components (apply gpg-conf '(--list-components)))
+ 
+ (define (tool which)
+   (case which
diff --git a/debian/patches/0059-agent-g10-Remove-redundant-SERIALNO-request.patch b/debian/patches/0059-agent-g10-Remove-redundant-SERIALNO-request.patch
new file mode 100644
index 0000000..1f2d04c
--- /dev/null
+++ b/debian/patches/0059-agent-g10-Remove-redundant-SERIALNO-request.patch
@@ -0,0 +1,234 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Thu, 16 Mar 2017 14:32:51 +0900
+Subject: agent,g10: Remove redundant SERIALNO request.
+
+* agent/learncard.c (agent_handle_learn): Don't call
+agent_card_serialno.  Get the serialno in status response.
+* g10/call-agent.c (agent_scd_learn): Don't request "SCD SERIALNO".
+(agent_scd_serialno): New.
+(card_cardlist_cb, agent_scd_cardlist): New.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 8c8ce8711d9c938fcb982b0341e6b052742cb887)
+---
+ agent/learncard.c |  21 +++++------
+ g10/call-agent.c  | 104 +++++++++++++++++++++++++++++++++++++++++++++++-------
+ g10/call-agent.h  |   6 ++++
+ 3 files changed, 109 insertions(+), 22 deletions(-)
+
+diff --git a/agent/learncard.c b/agent/learncard.c
+index cce9c3a..e0c882a 100644
+--- a/agent/learncard.c
++++ b/agent/learncard.c
+@@ -302,11 +302,10 @@ int
+ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force)
+ {
+   int rc;
+-
+   struct kpinfo_cb_parm_s parm;
+   struct certinfo_cb_parm_s cparm;
+   struct sinfo_cb_parm_s sparm;
+-  char *serialno = NULL;
++  const char *serialno = NULL;
+   KEYPAIR_INFO item;
+   SINFO sitem;
+   unsigned char grip[20];
+@@ -329,11 +328,6 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force)
+   parm.ctrl = ctrl;
+   cparm.ctrl = ctrl;
+ 
+-  /* Check whether a card is present and get the serial number */
+-  rc = agent_card_serialno (ctrl, &serialno, NULL);
+-  if (rc)
+-    goto leave;
+-
+   /* Now gather all the available info. */
+   rc = agent_card_learn (ctrl, kpinfo_cb, &parm, certinfo_cb, &cparm,
+                          sinfo_cb, &sparm);
+@@ -345,17 +339,25 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force)
+       goto leave;
+     }
+ 
+-  log_info ("card has S/N: %s\n", serialno);
+-
+   /* Pass on all the collected status information. */
+   if (assuan_context)
+     {
+       for (sitem = sparm.info; sitem; sitem = sitem->next)
+         {
++          if (!strcmp (sitem->keyword, "SERIALNO"))
++            serialno = sitem->data;
+           assuan_write_status (assuan_context, sitem->keyword, sitem->data);
+         }
+     }
+ 
++  if (!serialno)
++    {
++      rc = GPG_ERR_NOT_FOUND;
++      goto leave;
++    }
++
++  log_info ("card has S/N: %s\n", serialno);
++
+   /* Write out the certificates in a standard order. */
+   for (i=0; certtype_list[i] != -1; i++)
+     {
+@@ -438,7 +440,6 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force)
+ 
+ 
+  leave:
+-  xfree (serialno);
+   release_keypair_info (parm.info);
+   release_certinfo (cparm.info);
+   release_sinfo (sparm.info);
+diff --git a/g10/call-agent.c b/g10/call-agent.c
+index 1606797..af06bf5 100644
+--- a/g10/call-agent.c
++++ b/g10/call-agent.c
+@@ -656,18 +656,6 @@ agent_scd_learn (struct agent_card_info_s *info, int force)
+   if (rc)
+     return rc;
+ 
+-  /* Send the serialno command to initialize the connection.  We don't
+-     care about the data returned.  If the card has already been
+-     initialized, this is a very fast command.  The main reason we
+-     need to do this here is to handle a card removed case so that an
+-     "l" command in --edit-card can be used to show ta newly inserted
+-     card.  We request the openpgp card because that is what we
+-     expect. */
+-  rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
+-                        NULL, NULL, NULL, NULL, NULL, NULL);
+-  if (rc)
+-    return rc;
+-
+   parm.ctx = agent_ctx;
+   rc = assuan_transact (agent_ctx,
+                         force ? "LEARN --sendinfo --force" : "LEARN --sendinfo",
+@@ -1024,9 +1012,37 @@ agent_scd_genkey (int keyno, int force, u32 *createtime)
+   status_sc_op_failure (rc);
+   return rc;
+ }
++

++/* Return the serial number of the card or an appropriate error.  The
++   serial number is returned as a hexstring. */
++int
++agent_scd_serialno (char **r_serialno, const char *demand)
++{
++  int err;
++  char *serialno = NULL;
++  char line[ASSUAN_LINELENGTH];
+ 
++  err = start_agent (NULL, 1);
++  if (err)
++    return err;
+ 
++  if (!demand)
++    strcpy (line, "SCD SERIALNO");
++  else
++    snprintf (line, DIM(line), "SCD SERIALNO --demand=%s", demand);
+ 
++  err = assuan_transact (agent_ctx, line,
++                         NULL, NULL, NULL, NULL,
++                         get_serialno_cb, &serialno);
++  if (err)
++    {
++      xfree (serialno);
++      return err;
++    }
++
++  *r_serialno = serialno;
++  return 0;
++}
+ 

+ /* Send a READCERT command to the SCdaemon. */
+ int
+@@ -1066,8 +1082,72 @@ agent_scd_readcert (const char *certidstr,
+ 
+   return 0;
+ }
++

++struct card_cardlist_parm_s {
++  int error;
++  strlist_t list;
++};
++
+ 
++/* Callback function for agent_card_cardlist.  */
++static gpg_error_t
++card_cardlist_cb (void *opaque, const char *line)
++{
++  struct card_cardlist_parm_s *parm = opaque;
++  const char *keyword = line;
++  int keywordlen;
+ 
++  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
++    ;
++  while (spacep (line))
++    line++;
++
++  if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
++    {
++      const char *s;
++      int n;
++
++      for (n=0,s=line; hexdigitp (s); s++, n++)
++        ;
++
++      if (!n || (n&1) || *s)
++        parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
++      else
++        add_to_strlist (&parm->list, line);
++    }
++
++  return 0;
++}
++
++/* Return cardlist.  */
++int
++agent_scd_cardlist (strlist_t *result)
++{
++  int err;
++  char line[ASSUAN_LINELENGTH];
++  struct card_cardlist_parm_s parm;
++
++  memset (&parm, 0, sizeof parm);
++  *result = NULL;
++  err = start_agent (NULL, 1);
++  if (err)
++    return err;
++
++  strcpy (line, "SCD GETINFO card_list");
++
++  err = assuan_transact (agent_ctx, line,
++                         NULL, NULL, NULL, NULL,
++                         card_cardlist_cb, &parm);
++  if (!err && parm.error)
++    err = parm.error;
++
++  if (!err)
++    *result = parm.list;
++  else
++    free_strlist (parm.list);
++
++  return 0;
++}
+ 

+ /* Change the PIN of an OpenPGP card or reset the retry counter.
+    CHVNO 1: Change the PIN
+diff --git a/g10/call-agent.h b/g10/call-agent.h
+index e4fea57..a04fc73 100644
+--- a/g10/call-agent.h
++++ b/g10/call-agent.h
+@@ -76,6 +76,12 @@ void agent_release_card_info (struct agent_card_info_s *info);
+ /* Return card info. */
+ int agent_scd_learn (struct agent_card_info_s *info, int force);
+ 
++/* Return list of cards.  */
++int agent_scd_cardlist (strlist_t *result);
++
++/* Return the serial number, possibly select by DEMAND.  */
++int agent_scd_serialno (char **r_serialno, const char *demand);
++
+ /* Send an APDU to the card.  */
+ gpg_error_t agent_scd_apdu (const char *hexapdu, unsigned int *r_sw);
+ 
diff --git a/debian/patches/series b/debian/patches/series
index 651daa5..360f691 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -22,3 +22,38 @@ gpg-agent-idling/0011-agent-Avoid-scheduled-checks-on-socket-when-inotify-.patch
 0022-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch
 0023-scd-Fix-scd_kick_the_loop.patch
 0024-dirmngr-Fix-commit-de6d8313.patch
+0025-agent-For-SSH-robustly-handling-scdaemon-s-errors.patch
+0026-scd-Fix-API-of-select_file-_path.patch
+0027-scd-Clean-up-old-code.patch
+0028-scd-More-cleanup-of-old-code.patch
+0029-scd-Fix-compiler-warnings-for-app-openpgp.c.patch
+0030-gpg-Fix-attempt-to-double-free-an-UID-structure.patch
+0031-gpgscm-Fix-creation-of-temporary-directories.patch
+0032-tests-Harmonize-temporary-and-socket-directory-handl.patch
+0033-scd-Close-THE_EVENT-handle.patch
+0034-tools-More-portable-for-openpty-use.patch
+0035-common-Fix-warning-for-portability.patch
+0036-agent-Fix-get_client_pid-for-portability.patch
+0037-agent-Add-include-files.patch
+0038-agent-Resolve-conflict-of-util.h.patch
+0039-tests-Avoid-overflowing-signed-32-bit-time_t.patch
+0040-Remove-I-option-to-common.patch
+0041-More-change-for-common.patch
+0042-tools-Removal-of-Icommon.patch
+0043-gpg-Do-not-allow-the-user-to-revoke-the-last-valid-U.patch
+0044-gpgscm-Use-system-strlwr-if-available.patch
+0045-doc-Add-a-note-to-the-trust-model-direct.patch
+0046-dirmngr-Do-not-put-a-keyserver-into-a-new-dirmngr.co.patch
+0047-g10-Move-more-flags-into-the-flag-bitfield.patch
+0048-tests-Rework-environment-setup.patch
+0049-tests-Run-the-tests-for-the-Python-bindings-of-GPGME.patch
+0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch
+0051-doc-Explain-in-README-how-to-create-run-user-directo.patch
+0052-tests-Skip-Python-tests-if-the-bindings-are-not-buil.patch
+0053-tests-Fix-running-python-condition.patch
+0054-g10-Remove-unused-function.patch
+0055-g10-Fix-check-of-serialno.patch
+0056-build-Remove-disable-tools-configuration-option.patch
+0057-tests-Dump-the-tools-that-the-tests-are-going-to-use.patch
+0058-tests-Fix-using-tools-from-the-build-directory.patch
+0059-agent-g10-Remove-redundant-SERIALNO-request.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list