gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-donau] branch master updated (f0caa19 -> afcc8b8)


From: gnunet
Subject: [taler-donau] branch master updated (f0caa19 -> afcc8b8)
Date: Wed, 29 Nov 2023 14:56:21 +0100

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

pius-loosli pushed a change to branch master
in repository donau.

    from f0caa19  [build] Finish cleanup of src/donau/Makefile.am
     new ff18df2  [build] Clean up src/lib/: Makefile and comment out portions 
of code in files
     new 6c0b1c7  [build] Clean up src/donau-tools: Makefile and comment 
portions of code
     new 03c977e  [build] src/include/donau_service.h: comment out portions of 
code
     new afcc8b8  [build] minor changes in doc/Makefile.am and src/Makefile.am

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 doc/Makefile.am                       |    2 +-
 src/Makefile.am                       |    6 +-
 src/donau-tools/Makefile.am           |   16 -
 src/donau-tools/taler-donau-dbinit.c  |  164 +-
 src/donau-tools/taler-donau-offline.c | 9380 ++++++++++++++++-----------------
 src/include/donau_service.h           |  219 +-
 src/lib/Makefile.am                   |  133 +-
 src/lib/donau_api_charities_open.c    | 1028 ++--
 src/lib/donau_api_common.h            |   34 +-
 src/lib/donau_api_handle.h            |    5 +-
 10 files changed, 5439 insertions(+), 5548 deletions(-)

diff --git a/doc/Makefile.am b/doc/Makefile.am
index f25a481..e291521 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -7,7 +7,7 @@ AM_MAKEINFOHTMLFLAGS = $(TEXINFO_HTMLFLAGS)
 infoimagedir = $(infodir)/images
 
 man_MANS = \
-  prebuilt/man/taler.conf.5            \
+  # prebuilt/man/taler.conf.5            \
   prebuilt/man/taler-config.1            \
   prebuilt/man/taler-aggregator-benchmark.1   \
   # prebuilt/man/taler-auditor.1             \
diff --git a/src/Makefile.am b/src/Makefile.am
index 2654c76..021ed99 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,11 +4,11 @@ if HAVE_POSTGRESQL
   PQ_DIR = pq
 endif
 
-pkgcfgdir = $(prefix)/share/taler/config.d/
-pkgcfg_DATA = \
+# pkgcfgdir = $(prefix)/share/taler/config.d/
+# pkgcfg_DATA = \
   taler.conf
 
-EXTRA_DIST = \
+# EXTRA_DIST = \
   taler.conf
 
 SUBDIRS = \
diff --git a/src/donau-tools/Makefile.am b/src/donau-tools/Makefile.am
index ce9f3a8..f5b94ec 100644
--- a/src/donau-tools/Makefile.am
+++ b/src/donau-tools/Makefile.am
@@ -13,7 +13,6 @@ if USE_COVERAGE
 endif
 
 bin_PROGRAMS = \
-  taler-auditor-offline \
   taler-donau-offline \
   taler-donau-dbinit
 
@@ -24,21 +23,6 @@ taler_donau_offline_LDADD = \
   $(top_builddir)/src/lib/libtalerdonau.la \
   $(top_builddir)/src/json/libtalerjson.la \
   $(top_builddir)/src/util/libtalerdonauutil.la \
-  $(top_builddir)/src/extensions/libtalerextensions.la \
-  -lgnunetjson \
-  -lgnunetcurl \
-  -ljansson \
-  -lgnunetutil \
-  $(XLIB)
-
-taler_auditor_offline_SOURCES = \
-  taler-auditor-offline.c
-taler_auditor_offline_LDADD = \
-  $(LIBGCRYPT_LIBS) \
-  $(top_builddir)/src/lib/libtalerdonau.la \
-  $(top_builddir)/src/json/libtalerjson.la \
-  $(top_builddir)/src/util/libtalerdonauutil.la \
-  $(top_builddir)/src/extensions/libtalerextensions.la \
   -lgnunetjson \
   -lgnunetcurl \
   -ljansson \
diff --git a/src/donau-tools/taler-donau-dbinit.c 
b/src/donau-tools/taler-donau-dbinit.c
index e3f8e8e..6f81404 100644
--- a/src/donau-tools/taler-donau-dbinit.c
+++ b/src/donau-tools/taler-donau-dbinit.c
@@ -21,7 +21,7 @@
  */
 #include "taler/platform.h"
 #include <gnunet/gnunet_util_lib.h>
-#include "taler_donaudb_lib.h"
+#include "donaudb_lib.h"
 
 
 /**
@@ -62,80 +62,80 @@ static int force_create_partitions;
  * @param cfgfile name of the configuration file used (for saving, can be 
NULL!)
  * @param cfg configuration
  */
-static void
-run (void *cls,
-     char *const *args,
-     const char *cfgfile,
-     const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
-  struct DONAUDB_Plugin *plugin;
-
-  (void) cls;
-  (void) args;
-  (void) cfgfile;
-
-  if (NULL ==
-      (plugin = DONAUDB_plugin_load (cfg)))
-  {
-    fprintf (stderr,
-             "Failed to initialize database plugin.\n");
-    global_ret = EXIT_NOTINSTALLED;
-    return;
-  }
-  if (reset_db)
-  {
-    if (GNUNET_OK !=
-        plugin->drop_tables (plugin->cls))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Could not drop tables as requested. Either database was not 
yet initialized, or permission denied. Consult the logs. Will still try to 
create new tables.\n");
-    }
-  }
-  if (GNUNET_OK !=
-      plugin->create_tables (plugin->cls,
-                             force_create_partitions || num_partitions > 0,
-                             num_partitions))
-  {
-    fprintf (stderr,
-             "Failed to initialize database.\n");
-    DONAUDB_plugin_unload (plugin);
-    plugin = NULL;
-    global_ret = EXIT_NOPERMISSION;
-    return;
-  }
-  if (gc_db || clear_shards)
-  {
-    if (GNUNET_OK !=
-        plugin->preflight (plugin->cls))
-    {
-      fprintf (stderr,
-               "Failed to prepare database.\n");
-      DONAUDB_plugin_unload (plugin);
-      plugin = NULL;
-      global_ret = EXIT_NOPERMISSION;
-      return;
-    }
-    if (clear_shards)
-    {
-      if (GNUNET_OK !=
-          plugin->delete_shard_locks (plugin->cls))
-      {
-        fprintf (stderr,
-                 "Clearing revolving shards failed!\n");
-      }
-    }
-    if (gc_db)
-    {
-      if (GNUNET_SYSERR == plugin->gc (plugin->cls))
-      {
-        fprintf (stderr,
-                 "Garbage collection failed!\n");
-      }
-    }
-  }
-  DONAUDB_plugin_unload (plugin);
-  plugin = NULL;
-}
+// static void
+// run (void *cls,
+//      char *const *args,
+//      const char *cfgfile,
+//      const struct GNUNET_CONFIGURATION_Handle *cfg)
+// {
+//   struct DONAUDB_Plugin *plugin;
+
+//   (void) cls;
+//   (void) args;
+//   (void) cfgfile;
+
+//   if (NULL ==
+//       (plugin = DONAUDB_plugin_load (cfg)))
+//   {
+//     fprintf (stderr,
+//              "Failed to initialize database plugin.\n");
+//     global_ret = EXIT_NOTINSTALLED;
+//     return;
+//   }
+//   if (reset_db)
+//   {
+//     if (GNUNET_OK !=
+//         plugin->drop_tables (plugin->cls))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Could not drop tables as requested. Either database was 
not yet initialized, or permission denied. Consult the logs. Will still try to 
create new tables.\n");
+//     }
+//   }
+//   if (GNUNET_OK !=
+//       plugin->create_tables (plugin->cls,
+//                              force_create_partitions || num_partitions > 0,
+//                              num_partitions))
+//   {
+//     fprintf (stderr,
+//              "Failed to initialize database.\n");
+//     DONAUDB_plugin_unload (plugin);
+//     plugin = NULL;
+//     global_ret = EXIT_NOPERMISSION;
+//     return;
+//   }
+//   if (gc_db || clear_shards)
+//   {
+//     if (GNUNET_OK !=
+//         plugin->preflight (plugin->cls))
+//     {
+//       fprintf (stderr,
+//                "Failed to prepare database.\n");
+//       DONAUDB_plugin_unload (plugin);
+//       plugin = NULL;
+//       global_ret = EXIT_NOPERMISSION;
+//       return;
+//     }
+//     if (clear_shards)
+//     {
+//       if (GNUNET_OK !=
+//           plugin->delete_shard_locks (plugin->cls))
+//       {
+//         fprintf (stderr,
+//                  "Clearing revolving shards failed!\n");
+//       }
+//     }
+//     if (gc_db)
+//     {
+//       if (GNUNET_SYSERR == plugin->gc (plugin->cls))
+//       {
+//         fprintf (stderr,
+//                  "Garbage collection failed!\n");
+//       }
+//     }
+//   }
+//   DONAUDB_plugin_unload (plugin);
+//   plugin = NULL;
+// }
 
 
 /**
@@ -183,13 +183,13 @@ main (int argc,
   /* force linker to link against libtalerutil; if we do
      not do this, the linker may "optimize" libtalerutil
      away and skip #TALER_OS_init(), which we do need */
-  TALER_OS_init ();
-  ret = GNUNET_PROGRAM_run (
-    argc, argv,
-    "taler-donau-dbinit",
-    gettext_noop ("Initialize Taler donau database"),
-    options,
-    &run, NULL);
+  // TALER_OS_init ();
+  // ret = GNUNET_PROGRAM_run (
+  //   argc, argv,
+  //   "taler-donau-dbinit",
+  //   gettext_noop ("Initialize Taler donau database"),
+  //   options,
+  //   &run, NULL);
   GNUNET_free_nz ((void *) argv);
   if (GNUNET_SYSERR == ret)
     return EXIT_INVALIDARGUMENT;
diff --git a/src/donau-tools/taler-donau-offline.c 
b/src/donau-tools/taler-donau-offline.c
index 827b9ec..f52c91e 100644
--- a/src/donau-tools/taler-donau-offline.c
+++ b/src/donau-tools/taler-donau-offline.c
@@ -18,11 +18,11 @@
  * @brief Support for operations involving the donau's offline master key.
  * @author Christian Grothoff
  */
-#include <platform.h>
+#include <taler/platform.h>
 #include <gnunet/gnunet_json_lib.h>
 #include <gnunet/gnunet_util_lib.h>
 #include "taler/taler_json_lib.h"
-#include "taler_donau_service.h"
+#include "donau_service.h"
 #include "taler/taler_extensions.h"
 #include <regex.h>
 
@@ -713,4686 +713,4686 @@ static struct DrainProfitsRequest *dpr_tail;
  *
  * @param cls NULL
  */
-static void
-do_shutdown (void *cls)
-{
-  (void) cls;
-
-  {
-    struct AmlStaffRequest *asr;
-
-    while (NULL != (asr = asr_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete AML staff update #%u\n",
-                  (unsigned int) asr->idx);
-      DONAU_management_update_aml_officer_cancel (asr->h);
-      GNUNET_CONTAINER_DLL_remove (asr_head,
-                                   asr_tail,
-                                   asr);
-      GNUNET_free (asr);
-    }
-  }
-  {
-    struct PartnerAddRequest *par;
-
-    while (NULL != (par = par_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete partner add request #%u\n",
-                  (unsigned int) par->idx);
-      DONAU_management_add_partner_cancel (par->h);
-      GNUNET_CONTAINER_DLL_remove (par_head,
-                                   par_tail,
-                                   par);
-      GNUNET_free (par);
-    }
-  }
-  {
-    struct DenomRevocationRequest *drr;
-
-    while (NULL != (drr = drr_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete denomination revocation #%u\n",
-                  (unsigned int) drr->idx);
-      DONAU_management_revoke_denomination_key_cancel (drr->h);
-      GNUNET_CONTAINER_DLL_remove (drr_head,
-                                   drr_tail,
-                                   drr);
-      GNUNET_free (drr);
-    }
-  }
-  {
-    struct SignkeyRevocationRequest *srr;
-
-    while (NULL != (srr = srr_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete signkey revocation #%u\n",
-                  (unsigned int) srr->idx);
-      DONAU_management_revoke_signing_key_cancel (srr->h);
-      GNUNET_CONTAINER_DLL_remove (srr_head,
-                                   srr_tail,
-                                   srr);
-      GNUNET_free (srr);
-    }
-  }
-
-  {
-    struct AuditorAddRequest *aar;
-
-    while (NULL != (aar = aar_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete auditor add #%u\n",
-                  (unsigned int) aar->idx);
-      DONAU_management_enable_auditor_cancel (aar->h);
-      GNUNET_CONTAINER_DLL_remove (aar_head,
-                                   aar_tail,
-                                   aar);
-      GNUNET_free (aar);
-    }
-  }
-  {
-    struct AuditorDelRequest *adr;
-
-    while (NULL != (adr = adr_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete auditor del #%u\n",
-                  (unsigned int) adr->idx);
-      DONAU_management_disable_auditor_cancel (adr->h);
-      GNUNET_CONTAINER_DLL_remove (adr_head,
-                                   adr_tail,
-                                   adr);
-      GNUNET_free (adr);
-    }
-  }
-  {
-    struct WireAddRequest *war;
-
-    while (NULL != (war = war_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete wire add #%u\n",
-                  (unsigned int) war->idx);
-      DONAU_management_enable_wire_cancel (war->h);
-      GNUNET_CONTAINER_DLL_remove (war_head,
-                                   war_tail,
-                                   war);
-      GNUNET_free (war);
-    }
-  }
-  {
-    struct WireDelRequest *wdr;
-
-    while (NULL != (wdr = wdr_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete wire del #%u\n",
-                  (unsigned int) wdr->idx);
-      DONAU_management_disable_wire_cancel (wdr->h);
-      GNUNET_CONTAINER_DLL_remove (wdr_head,
-                                   wdr_tail,
-                                   wdr);
-      GNUNET_free (wdr);
-    }
-  }
-  {
-    struct WireFeeRequest *wfr;
-
-    while (NULL != (wfr = wfr_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete wire fee #%u\n",
-                  (unsigned int) wfr->idx);
-      DONAU_management_set_wire_fees_cancel (wfr->h);
-      GNUNET_CONTAINER_DLL_remove (wfr_head,
-                                   wfr_tail,
-                                   wfr);
-      GNUNET_free (wfr);
-    }
-  }
-  {
-    struct GlobalFeeRequest *gfr;
-
-    while (NULL != (gfr = gfr_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete global fee #%u\n",
-                  (unsigned int) gfr->idx);
-      DONAU_management_set_global_fees_cancel (gfr->h);
-      GNUNET_CONTAINER_DLL_remove (gfr_head,
-                                   gfr_tail,
-                                   gfr);
-      GNUNET_free (gfr);
-    }
-  }
-  {
-    struct UploadKeysRequest *ukr;
-
-    while (NULL != (ukr = ukr_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete key signature upload #%u\n",
-                  (unsigned int) ukr->idx);
-      DONAU_post_management_keys_cancel (ukr->h);
-      GNUNET_CONTAINER_DLL_remove (ukr_head,
-                                   ukr_tail,
-                                   ukr);
-      GNUNET_free (ukr);
-    }
-  }
-  {
-    struct UploadExtensionsRequest *uer;
-
-    while (NULL != (uer = uer_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete extensions signature upload #%u\n",
-                  (unsigned int) uer->idx);
-      DONAU_management_post_extensions_cancel (uer->h);
-      GNUNET_CONTAINER_DLL_remove (uer_head,
-                                   uer_tail,
-                                   uer);
-      GNUNET_free (uer);
-    }
-  }
-
-  {
-    struct DrainProfitsRequest *dpr;
-
-    while (NULL != (dpr = dpr_head))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Aborting incomplete drain profits request #%u\n",
-                  (unsigned int) dpr->idx);
-      DONAU_management_drain_profits_cancel (dpr->h);
-      GNUNET_CONTAINER_DLL_remove (dpr_head,
-                                   dpr_tail,
-                                   dpr);
-      GNUNET_free (dpr);
-    }
-  }
-
-  if (NULL != out)
-  {
-    json_dumpf (out,
-                stdout,
-                JSON_INDENT (2));
-    json_decref (out);
-    out = NULL;
-  }
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Input not consumed!\n");
-    json_decref (in);
-    in = NULL;
-  }
-  if (NULL != nxt)
-  {
-    GNUNET_SCHEDULER_cancel (nxt);
-    nxt = NULL;
-  }
-  if (NULL != mgkh)
-  {
-    DONAU_get_management_keys_cancel (mgkh);
-    mgkh = NULL;
-  }
-  if (NULL != ctx)
-  {
-    GNUNET_CURL_fini (ctx);
-    ctx = NULL;
-  }
-  if (NULL != rc)
-  {
-    GNUNET_CURL_gnunet_rc_destroy (rc);
-    rc = NULL;
-  }
-}
-
-
-/**
- * Test if we should shut down because all tasks are done.
- */
-static void
-test_shutdown (void)
-{
-  if ( (NULL == drr_head) &&
-       (NULL == par_head) &&
-       (NULL == asr_head) &&
-       (NULL == srr_head) &&
-       (NULL == aar_head) &&
-       (NULL == adr_head) &&
-       (NULL == war_head) &&
-       (NULL == wdr_head) &&
-       (NULL == wfr_head) &&
-       (NULL == gfr_head) &&
-       (NULL == ukr_head) &&
-       (NULL == uer_head) &&
-       (NULL == dpr_head) &&
-       (NULL == mgkh) &&
-       (NULL == nxt) )
-    GNUNET_SCHEDULER_shutdown ();
-}
-
-
-/**
- * Function to continue processing the next command.
- *
- * @param cls must be a `char *const*` with the array of
- *        command-line arguments to process next
- */
-static void
-work (void *cls);
-
-
-/**
- * Function to schedule job to process the next command.
- *
- * @param args the array of command-line arguments to process next
- */
-static void
-next (char *const *args)
-{
-  GNUNET_assert (NULL == nxt);
-  if (NULL == args[0])
-  {
-    test_shutdown ();
-    return;
-  }
-  nxt = GNUNET_SCHEDULER_add_now (&work,
-                                  (void *) args);
-}
-
-
-/**
- * Add an operation to the #out JSON array for processing later.
- *
- * @param op_name name of the operation
- * @param op_value values for the operation (consumed)
- */
-static void
-output_operation (const char *op_name,
-                  json_t *op_value)
-{
-  json_t *action;
-
-  GNUNET_break (NULL != op_value);
-  if (NULL == out)
-  {
-    out = json_array ();
-    GNUNET_assert (NULL != out);
-  }
-  action = GNUNET_JSON_PACK (
-    GNUNET_JSON_pack_string ("operation",
-                             op_name),
-    GNUNET_JSON_pack_object_steal ("arguments",
-                                   op_value));
-  GNUNET_assert (0 ==
-                 json_array_append_new (out,
-                                        action));
-}
-
-
-/**
- * Information about a subroutine for an upload.
- */
-struct UploadHandler
-{
-  /**
-   * Key to trigger this subroutine.
-   */
-  const char *key;
-
-  /**
-   * Function implementing an upload.
-   *
-   * @param donau_url URL of the donau
-   * @param idx index of the operation we are performing
-   * @param value arguments to drive the upload.
-   */
-  void (*cb)(const char *donau_url,
-             size_t idx,
-             const json_t *value);
-
-};
-
-
-/**
- * Load the offline key (if not yet done). Triggers shutdown on failure.
- *
- * @param do_create #GNUNET_YES if the key may be created
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-load_offline_key (int do_create)
-{
-  static bool done;
-  int ret;
-  char *fn;
-
-  if (done)
-    return GNUNET_OK;
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (kcfg,
-                                               "donau-offline",
-                                               "MASTER_PRIV_FILE",
-                                               &fn))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "donau-offline",
-                               "MASTER_PRIV_FILE");
-    test_shutdown ();
-    return GNUNET_SYSERR;
-  }
-  if (GNUNET_YES !=
-      GNUNET_DISK_file_test (fn))
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Donau master private key `%s' does not exist yet, creating 
it!\n",
-                fn);
-  ret = GNUNET_CRYPTO_eddsa_key_from_file (fn,
-                                           do_create,
-                                           &master_priv.eddsa_priv);
-  if (GNUNET_SYSERR == ret)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to initialize master key from file `%s': %s\n",
-                fn,
-                "could not create file");
-    GNUNET_free (fn);
-    test_shutdown ();
-    return GNUNET_SYSERR;
-  }
-  GNUNET_free (fn);
-  GNUNET_CRYPTO_eddsa_key_get_public (&master_priv.eddsa_priv,
-                                      &master_pub.eddsa_pub);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Using master public key %s\n",
-              TALER_B2S (&master_pub));
-  done = true;
-  return GNUNET_OK;
-}
-
-
-/**
- * Function called with information about the post revocation operation result.
- *
- * @param cls closure with a `struct DenomRevocationRequest`
- * @param dr response data
- */
-static void
-denom_revocation_cb (
-  void *cls,
-  const struct DONAU_ManagementRevokeDenominationResponse *dr)
-{
-  struct DenomRevocationRequest *drr = cls;
-  const struct DONAU_HttpResponse *hr = &dr->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) drr->idx,
-                hr->http_status,
-                hr->hint,
-                TALER_JSON_get_error_hint (hr->reply));
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (drr_head,
-                               drr_tail,
-                               drr);
-  GNUNET_free (drr);
-  test_shutdown ();
-}
-
-
-/**
- * Upload denomination revocation request data.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for denomination revocation
- */
-static void
-upload_denom_revocation (const char *donau_url,
-                         size_t idx,
-                         const json_t *value)
-{
-  struct TALER_MasterSignatureP master_sig;
-  struct TALER_DenominationHashP h_denom_pub;
-  struct DenomRevocationRequest *drr;
-  const char *err_name;
-  unsigned int err_line;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
-                                 &h_denom_pub),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input for denomination revocation: %s#%u at %u 
(skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  drr = GNUNET_new (struct DenomRevocationRequest);
-  drr->idx = idx;
-  drr->h =
-    DONAU_management_revoke_denomination_key (ctx,
-                                              donau_url,
-                                              &h_denom_pub,
-                                              &master_sig,
-                                              &denom_revocation_cb,
-                                              drr);
-  GNUNET_CONTAINER_DLL_insert (drr_head,
-                               drr_tail,
-                               drr);
-}
-
-
-/**
- * Function called with information about the post revocation operation result.
- *
- * @param cls closure with a `struct SignkeyRevocationRequest`
- * @param sr response data
- */
-static void
-signkey_revocation_cb (
-  void *cls,
-  const struct DONAU_ManagementRevokeSigningKeyResponse *sr)
-{
-  struct SignkeyRevocationRequest *srr = cls;
-  const struct DONAU_HttpResponse *hr = &sr->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) srr->idx,
-                hr->http_status,
-                hr->hint,
-                TALER_JSON_get_error_hint (hr->reply));
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (srr_head,
-                               srr_tail,
-                               srr);
-  GNUNET_free (srr);
-  test_shutdown ();
-}
-
-
-/**
- * Upload signkey revocation request data.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for denomination revocation
- */
-static void
-upload_signkey_revocation (const char *donau_url,
-                           size_t idx,
-                           const json_t *value)
-{
-  struct TALER_MasterSignatureP master_sig;
-  struct DONAU_DonauPublicKeyP donau_pub;
-  struct SignkeyRevocationRequest *srr;
-  const char *err_name;
-  unsigned int err_line;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_fixed_auto ("donau_pub",
-                                 &donau_pub),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input for signkey revocation: %s#%u at %u 
(skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  srr = GNUNET_new (struct SignkeyRevocationRequest);
-  srr->idx = idx;
-  srr->h =
-    DONAU_management_revoke_signing_key (ctx,
-                                         donau_url,
-                                         &donau_pub,
-                                         &master_sig,
-                                         &signkey_revocation_cb,
-                                         srr);
-  GNUNET_CONTAINER_DLL_insert (srr_head,
-                               srr_tail,
-                               srr);
-}
-
-
-/**
- * Function called with information about the post auditor add operation 
result.
- *
- * @param cls closure with a `struct AuditorAddRequest`
- * @param mer response data
- */
-static void
-auditor_add_cb (
-  void *cls,
-  const struct DONAU_ManagementAuditorEnableResponse *mer)
-{
-  struct AuditorAddRequest *aar = cls;
-  const struct DONAU_HttpResponse *hr = &mer->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) aar->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (aar_head,
-                               aar_tail,
-                               aar);
-  GNUNET_free (aar);
-  test_shutdown ();
-}
-
-
-/**
- * Upload auditor add data.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for denomination revocation
- */
-static void
-upload_auditor_add (const char *donau_url,
-                    size_t idx,
-                    const json_t *value)
-{
-  struct TALER_MasterSignatureP master_sig;
-  const char *auditor_url;
-  const char *auditor_name;
-  struct GNUNET_TIME_Timestamp start_time;
-  struct TALER_AuditorPublicKeyP auditor_pub;
-  struct AuditorAddRequest *aar;
-  const char *err_name;
-  unsigned int err_line;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_string ("auditor_url",
-                             &auditor_url),
-    GNUNET_JSON_spec_string ("auditor_name",
-                             &auditor_name),
-    GNUNET_JSON_spec_timestamp ("validity_start",
-                                &start_time),
-    GNUNET_JSON_spec_fixed_auto ("auditor_pub",
-                                 &auditor_pub),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input for adding auditor: %s#%u at %u (skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  aar = GNUNET_new (struct AuditorAddRequest);
-  aar->idx = idx;
-  aar->h =
-    DONAU_management_enable_auditor (ctx,
-                                     donau_url,
-                                     &auditor_pub,
-                                     auditor_url,
-                                     auditor_name,
-                                     start_time,
-                                     &master_sig,
-                                     &auditor_add_cb,
-                                     aar);
-  GNUNET_CONTAINER_DLL_insert (aar_head,
-                               aar_tail,
-                               aar);
-}
-
-
-/**
- * Function called with information about the post auditor del operation 
result.
- *
- * @param cls closure with a `struct AuditorDelRequest`
- * @param mdr response data
- */
-static void
-auditor_del_cb (void *cls,
-                const struct
-                DONAU_ManagementAuditorDisableResponse *mdr)
-{
-  struct AuditorDelRequest *adr = cls;
-  const struct DONAU_HttpResponse *hr = &mdr->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) adr->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (adr_head,
-                               adr_tail,
-                               adr);
-  GNUNET_free (adr);
-  test_shutdown ();
-}
-
-
-/**
- * Upload auditor del data.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for denomination revocation
- */
-static void
-upload_auditor_del (const char *donau_url,
-                    size_t idx,
-                    const json_t *value)
-{
-  struct TALER_AuditorPublicKeyP auditor_pub;
-  struct TALER_MasterSignatureP master_sig;
-  struct GNUNET_TIME_Timestamp end_time;
-  struct AuditorDelRequest *adr;
-  const char *err_name;
-  unsigned int err_line;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_fixed_auto ("auditor_pub",
-                                 &auditor_pub),
-    GNUNET_JSON_spec_timestamp ("validity_end",
-                                &end_time),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to disable auditor: %s#%u at %u (skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  adr = GNUNET_new (struct AuditorDelRequest);
-  adr->idx = idx;
-  adr->h =
-    DONAU_management_disable_auditor (ctx,
-                                      donau_url,
-                                      &auditor_pub,
-                                      end_time,
-                                      &master_sig,
-                                      &auditor_del_cb,
-                                      adr);
-  GNUNET_CONTAINER_DLL_insert (adr_head,
-                               adr_tail,
-                               adr);
-}
-
-
-/**
- * Function called with information about the post wire add operation result.
- *
- * @param cls closure with a `struct WireAddRequest`
- * @param wer response data
- */
-static void
-wire_add_cb (void *cls,
-             const struct DONAU_ManagementWireEnableResponse *wer)
-{
-  struct WireAddRequest *war = cls;
-  const struct DONAU_HttpResponse *hr = &wer->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) war->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (war_head,
-                               war_tail,
-                               war);
-  GNUNET_free (war);
-  test_shutdown ();
-}
-
-
-/**
- * Upload wire add data.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for denomination revocation
- */
-static void
-upload_wire_add (const char *donau_url,
-                 size_t idx,
-                 const json_t *value)
-{
-  struct TALER_MasterSignatureP master_sig_add;
-  struct TALER_MasterSignatureP master_sig_wire;
-  const char *payto_uri;
-  struct GNUNET_TIME_Timestamp start_time;
-  struct WireAddRequest *war;
-  const char *err_name;
-  const char *conversion_url = NULL;
-  const json_t *debit_restrictions;
-  const json_t *credit_restrictions;
-  unsigned int err_line;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_string ("payto_uri",
-                             &payto_uri),
-    GNUNET_JSON_spec_mark_optional (
-      GNUNET_JSON_spec_string ("conversion_url",
-                               &conversion_url),
-      NULL),
-    GNUNET_JSON_spec_array_const ("debit_restrictions",
-                                  &debit_restrictions),
-    GNUNET_JSON_spec_array_const ("credit_restrictions",
-                                  &credit_restrictions),
-    GNUNET_JSON_spec_timestamp ("validity_start",
-                                &start_time),
-    GNUNET_JSON_spec_fixed_auto ("master_sig_add",
-                                 &master_sig_add),
-    GNUNET_JSON_spec_fixed_auto ("master_sig_wire",
-                                 &master_sig_wire),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input for adding wire account: %s#%u at %u 
(skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  {
-    char *wire_method;
-
-    wire_method = TALER_payto_get_method (payto_uri);
-    if (NULL == wire_method)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "payto:// URI `%s' is malformed\n",
-                  payto_uri);
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return;
-    }
-    GNUNET_free (wire_method);
-  }
-  {
-    char *msg = TALER_payto_validate (payto_uri);
-
-    if (NULL != msg)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "payto URI is malformed: %s\n",
-                  msg);
-      GNUNET_free (msg);
-      test_shutdown ();
-      global_ret = EXIT_INVALIDARGUMENT;
-      return;
-    }
-  }
-  war = GNUNET_new (struct WireAddRequest);
-  war->idx = idx;
-  war->h =
-    DONAU_management_enable_wire (ctx,
-                                  donau_url,
-                                  payto_uri,
-                                  conversion_url,
-                                  debit_restrictions,
-                                  credit_restrictions,
-                                  start_time,
-                                  &master_sig_add,
-                                  &master_sig_wire,
-                                  &wire_add_cb,
-                                  war);
-  GNUNET_CONTAINER_DLL_insert (war_head,
-                               war_tail,
-                               war);
-}
-
-
-/**
- * Function called with information about the post wire del operation result.
- *
- * @param cls closure with a `struct WireDelRequest`
- * @param wdres response data
- */
-static void
-wire_del_cb (void *cls,
-             const struct DONAU_ManagementWireDisableResponse *wdres)
-{
-  struct WireDelRequest *wdr = cls;
-  const struct DONAU_HttpResponse *hr = &wdres->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) wdr->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (wdr_head,
-                               wdr_tail,
-                               wdr);
-  GNUNET_free (wdr);
-  test_shutdown ();
-}
-
-
-/**
- * Upload wire del data.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for denomination revocation
- */
-static void
-upload_wire_del (const char *donau_url,
-                 size_t idx,
-                 const json_t *value)
-{
-  struct TALER_MasterSignatureP master_sig;
-  const char *payto_uri;
-  struct GNUNET_TIME_Timestamp end_time;
-  struct WireDelRequest *wdr;
-  const char *err_name;
-  unsigned int err_line;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_string ("payto_uri",
-                             &payto_uri),
-    GNUNET_JSON_spec_timestamp ("validity_end",
-                                &end_time),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to disable wire account: %s#%u at %u 
(skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  wdr = GNUNET_new (struct WireDelRequest);
-  wdr->idx = idx;
-  wdr->h =
-    DONAU_management_disable_wire (ctx,
-                                   donau_url,
-                                   payto_uri,
-                                   end_time,
-                                   &master_sig,
-                                   &wire_del_cb,
-                                   wdr);
-  GNUNET_CONTAINER_DLL_insert (wdr_head,
-                               wdr_tail,
-                               wdr);
-}
-
-
-/**
- * Function called with information about the post wire fee operation result.
- *
- * @param cls closure with a `struct WireFeeRequest`
- * @param swr response data
- */
-static void
-wire_fee_cb (
-  void *cls,
-  const struct DONAU_ManagementSetWireFeeResponse *swr)
-{
-  struct WireFeeRequest *wfr = cls;
-  const struct DONAU_HttpResponse *hr = &swr->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) wfr->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (wfr_head,
-                               wfr_tail,
-                               wfr);
-  GNUNET_free (wfr);
-  test_shutdown ();
-}
-
-
-/**
- * Upload wire fee.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for denomination revocation
- */
-static void
-upload_wire_fee (const char *donau_url,
-                 size_t idx,
-                 const json_t *value)
-{
-  struct TALER_MasterSignatureP master_sig;
-  const char *wire_method;
-  struct WireFeeRequest *wfr;
-  const char *err_name;
-  unsigned int err_line;
-  struct TALER_WireFeeSet fees;
-  struct GNUNET_TIME_Timestamp start_time;
-  struct GNUNET_TIME_Timestamp end_time;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_string ("wire_method",
-                             &wire_method),
-    TALER_JSON_spec_amount ("wire_fee",
-                            currency,
-                            &fees.wire),
-    TALER_JSON_spec_amount ("closing_fee",
-                            currency,
-                            &fees.closing),
-    GNUNET_JSON_spec_timestamp ("start_time",
-                                &start_time),
-    GNUNET_JSON_spec_timestamp ("end_time",
-                                &end_time),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to set wire fee: %s#%u at %u (skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  wfr = GNUNET_new (struct WireFeeRequest);
-  wfr->idx = idx;
-  wfr->h =
-    DONAU_management_set_wire_fees (ctx,
-                                    donau_url,
-                                    wire_method,
-                                    start_time,
-                                    end_time,
-                                    &fees,
-                                    &master_sig,
-                                    &wire_fee_cb,
-                                    wfr);
-  GNUNET_CONTAINER_DLL_insert (wfr_head,
-                               wfr_tail,
-                               wfr);
-}
-
-
-/**
- * Function called with information about the post global fee operation result.
- *
- * @param cls closure with a `struct WireFeeRequest`
- * @param gr response data
- */
-static void
-global_fee_cb (
-  void *cls,
-  const struct DONAU_ManagementSetGlobalFeeResponse *gr)
-{
-  struct GlobalFeeRequest *gfr = cls;
-  const struct DONAU_HttpResponse *hr = &gr->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) gfr->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (gfr_head,
-                               gfr_tail,
-                               gfr);
-  GNUNET_free (gfr);
-  test_shutdown ();
-}
-
-
-/**
- * Upload global fee.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for denomination revocation
- */
-static void
-upload_global_fee (const char *donau_url,
-                   size_t idx,
-                   const json_t *value)
-{
-  struct TALER_MasterSignatureP master_sig;
-  struct GlobalFeeRequest *gfr;
-  const char *err_name;
-  unsigned int err_line;
-  struct TALER_GlobalFeeSet fees;
-  struct GNUNET_TIME_Timestamp start_time;
-  struct GNUNET_TIME_Timestamp end_time;
-  struct GNUNET_TIME_Relative purse_timeout;
-  struct GNUNET_TIME_Relative history_expiration;
-  uint32_t purse_account_limit;
-  struct GNUNET_JSON_Specification spec[] = {
-    TALER_JSON_spec_amount ("history_fee",
-                            currency,
-                            &fees.history),
-    TALER_JSON_spec_amount ("account_fee",
-                            currency,
-                            &fees.account),
-    TALER_JSON_spec_amount ("purse_fee",
-                            currency,
-                            &fees.purse),
-    GNUNET_JSON_spec_relative_time ("purse_timeout",
-                                    &purse_timeout),
-    GNUNET_JSON_spec_relative_time ("history_expiration",
-                                    &history_expiration),
-    GNUNET_JSON_spec_uint32 ("purse_account_limit",
-                             &purse_account_limit),
-    GNUNET_JSON_spec_timestamp ("start_time",
-                                &start_time),
-    GNUNET_JSON_spec_timestamp ("end_time",
-                                &end_time),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to set wire fee: %s#%u at %u (skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  gfr = GNUNET_new (struct GlobalFeeRequest);
-  gfr->idx = idx;
-  gfr->h =
-    DONAU_management_set_global_fees (ctx,
-                                      donau_url,
-                                      start_time,
-                                      end_time,
-                                      &fees,
-                                      purse_timeout,
-                                      history_expiration,
-                                      purse_account_limit,
-                                      &master_sig,
-                                      &global_fee_cb,
-                                      gfr);
-  GNUNET_CONTAINER_DLL_insert (gfr_head,
-                               gfr_tail,
-                               gfr);
-}
-
-
-/**
- * Function called with information about the drain profits operation.
- *
- * @param cls closure with a `struct DrainProfitsRequest`
- * @param mdr response data
- */
-static void
-drain_profits_cb (
-  void *cls,
-  const struct DONAU_ManagementDrainResponse *mdr)
-{
-  struct DrainProfitsRequest *dpr = cls;
-  const struct DONAU_HttpResponse *hr = &mdr->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) dpr->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (dpr_head,
-                               dpr_tail,
-                               dpr);
-  GNUNET_free (dpr);
-  test_shutdown ();
-}
-
-
-/**
- * Upload drain profit action.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for drain profits
- */
-static void
-upload_drain (const char *donau_url,
-              size_t idx,
-              const json_t *value)
-{
-  struct TALER_WireTransferIdentifierRawP wtid;
-  struct TALER_MasterSignatureP master_sig;
-  const char *err_name;
-  unsigned int err_line;
-  struct TALER_Amount amount;
-  struct GNUNET_TIME_Timestamp date;
-  const char *payto_uri;
-  const char *account_section;
-  struct DrainProfitsRequest *dpr;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_fixed_auto ("wtid",
-                                 &wtid),
-    TALER_JSON_spec_amount ("amount",
-                            currency,
-                            &amount),
-    GNUNET_JSON_spec_timestamp ("date",
-                                &date),
-    GNUNET_JSON_spec_string ("account_section",
-                             &account_section),
-    GNUNET_JSON_spec_string ("payto_uri",
-                             &payto_uri),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to drain profits: %s#%u at %u (skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  dpr = GNUNET_new (struct DrainProfitsRequest);
-  dpr->idx = idx;
-  dpr->h =
-    DONAU_management_drain_profits (ctx,
-                                    donau_url,
-                                    &wtid,
-                                    &amount,
-                                    date,
-                                    account_section,
-                                    payto_uri,
-                                    &master_sig,
-                                    &drain_profits_cb,
-                                    dpr);
-  GNUNET_CONTAINER_DLL_insert (dpr_head,
-                               dpr_tail,
-                               dpr);
-}
-
-
-/**
- * Function called with information about the post upload keys operation 
result.
- *
- * @param cls closure with a `struct UploadKeysRequest`
- * @param mr response data
- */
-static void
-keys_cb (
-  void *cls,
-  const struct DONAU_ManagementPostKeysResponse *mr)
-{
-  struct UploadKeysRequest *ukr = cls;
-  const struct DONAU_HttpResponse *hr = &mr->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) ukr->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (ukr_head,
-                               ukr_tail,
-                               ukr);
-  GNUNET_free (ukr);
-  test_shutdown ();
-}
-
-
-/**
- * Upload (denomination and signing) key master signatures.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for POSTing keys
- */
-static void
-upload_keys (const char *donau_url,
-             size_t idx,
-             const json_t *value)
-{
-  struct DONAU_ManagementPostKeysData pkd;
-  struct UploadKeysRequest *ukr;
-  const char *err_name;
-  unsigned int err_line;
-  const json_t *denom_sigs;
-  const json_t *signkey_sigs;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_array_const ("denom_sigs",
-                                  &denom_sigs),
-    GNUNET_JSON_spec_array_const ("signkey_sigs",
-                                  &signkey_sigs),
-    GNUNET_JSON_spec_end ()
-  };
-  bool ok = true;
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to 'upload': %s#%u (skipping)\n",
-                err_name,
-                err_line);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  pkd.num_sign_sigs = json_array_size (signkey_sigs);
-  pkd.num_denom_sigs = json_array_size (denom_sigs);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Uploading %u denomination and %u signing key signatures\n",
-              pkd.num_denom_sigs,
-              pkd.num_sign_sigs);
-  pkd.sign_sigs = GNUNET_new_array (
-    pkd.num_sign_sigs,
-    struct DONAU_SigningKeySignature);
-  pkd.denom_sigs = GNUNET_new_array (
-    pkd.num_denom_sigs,
-    struct DONAU_DenominationKeySignature);
-  for (unsigned int i = 0; i<pkd.num_sign_sigs; i++)
-  {
-    struct DONAU_SigningKeySignature *ss = &pkd.sign_sigs[i];
-    json_t *val = json_array_get (signkey_sigs,
-                                  i);
-    struct GNUNET_JSON_Specification spec[] = {
-      GNUNET_JSON_spec_fixed_auto ("donau_pub",
-                                   &ss->donau_pub),
-      GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                   &ss->master_sig),
-      GNUNET_JSON_spec_end ()
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_JSON_parse (val,
-                           spec,
-                           &err_name,
-                           &err_line))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid input for signkey validity: %s#%u at %u 
(aborting)\n",
-                  err_name,
-                  err_line,
-                  i);
-      json_dumpf (val,
-                  stderr,
-                  JSON_INDENT (2));
-      ok = false;
-    }
-  }
-  for (unsigned int i = 0; i<pkd.num_denom_sigs; i++)
-  {
-    struct DONAU_DenominationKeySignature *ds = &pkd.denom_sigs[i];
-    json_t *val = json_array_get (denom_sigs,
-                                  i);
-    struct GNUNET_JSON_Specification spec[] = {
-      GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
-                                   &ds->h_denom_pub),
-      GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                   &ds->master_sig),
-      GNUNET_JSON_spec_end ()
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_JSON_parse (val,
-                           spec,
-                           &err_name,
-                           &err_line))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid input for denomination validity: %s#%u at %u 
(aborting)\n",
-                  err_name,
-                  err_line,
-                  i);
-      json_dumpf (val,
-                  stderr,
-                  JSON_INDENT (2));
-      ok = false;
-    }
-  }
-
-  if (ok)
-  {
-    ukr = GNUNET_new (struct UploadKeysRequest);
-    ukr->idx = idx;
-    ukr->h =
-      DONAU_post_management_keys (ctx,
-                                  donau_url,
-                                  &pkd,
-                                  &keys_cb,
-                                  ukr);
-    GNUNET_CONTAINER_DLL_insert (ukr_head,
-                                 ukr_tail,
-                                 ukr);
-  }
-  else
-  {
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-  }
-  GNUNET_free (pkd.sign_sigs);
-  GNUNET_free (pkd.denom_sigs);
-}
-
-
-/**
- * Function called with information about the post upload extensions operation 
result.
- *
- * @param cls closure with a `struct UploadExtensionsRequest`
- * @param er response data
- */
-static void
-extensions_cb (
-  void *cls,
-  const struct DONAU_ManagementPostExtensionsResponse *er)
-{
-  struct UploadExtensionsRequest *uer = cls;
-  const struct DONAU_HttpResponse *hr = &er->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) uer->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (uer_head,
-                               uer_tail,
-                               uer);
-  GNUNET_free (uer);
-  test_shutdown ();
-}
-
-
-/**
- * Upload extension configuration
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for POSTing configurations of extensions
- */
-static void
-upload_extensions (const char *donau_url,
-                   size_t idx,
-                   const json_t *value)
-{
-  const json_t *extensions;
-  struct TALER_MasterSignatureP sig;
-  const char *err_name;
-  unsigned int err_line;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_object_const ("extensions",
-                                   &extensions),
-    GNUNET_JSON_spec_fixed_auto ("extensions_sig",
-                                 &sig),
-    GNUNET_JSON_spec_end ()
-  };
-
-  /* 1. Parse the signed extensions */
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to set extensions: %s#%u at %u (skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-
-  /* 2. Verify the signature */
-  {
-    struct TALER_ExtensionManifestsHashP h_manifests;
-
-    if (GNUNET_OK !=
-        TALER_JSON_extensions_manifests_hash (extensions,
-                                              &h_manifests))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "couldn't hash extensions' manifests\n");
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return;
-    }
-
-    if (GNUNET_OK !=
-        load_offline_key (GNUNET_NO))
-      return;
-
-    if (GNUNET_OK != TALER_donau_offline_extension_manifests_hash_verify (
-          &h_manifests,
-          &master_pub,
-          &sig))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "invalid signature for extensions\n");
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return;
-    }
-  }
-
-  /* 3. Upload the extensions */
-  {
-    struct DONAU_ManagementPostExtensionsData ped = {
-      .extensions = extensions,
-      .extensions_sig = sig,
-    };
-    struct UploadExtensionsRequest *uer
-      = GNUNET_new (struct UploadExtensionsRequest);
-
-    uer->idx = idx;
-    uer->h = DONAU_management_post_extensions (
-      ctx,
-      donau_url,
-      &ped,
-      &extensions_cb,
-      uer);
-    GNUNET_CONTAINER_DLL_insert (uer_head,
-                                 uer_tail,
-                                 uer);
-  }
-}
-
-
-/**
- * Function called with information about the add partner operation.
- *
- * @param cls closure with a `struct PartnerAddRequest`
- * @param apr response data
- */
-static void
-add_partner_cb (
-  void *cls,
-  const struct DONAU_ManagementAddPartnerResponse *apr)
-{
-  struct PartnerAddRequest *par = cls;
-  const struct DONAU_HttpResponse *hr = &apr->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) par->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (par_head,
-                               par_tail,
-                               par);
-  GNUNET_free (par);
-  test_shutdown ();
-}
-
-
-/**
- * Add partner action.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for add partner
- */
-static void
-add_partner (const char *donau_url,
-             size_t idx,
-             const json_t *value)
-{
-  struct TALER_MasterPublicKeyP partner_pub;
-  struct GNUNET_TIME_Timestamp start_date;
-  struct GNUNET_TIME_Timestamp end_date;
-  struct GNUNET_TIME_Relative wad_frequency;
-  struct TALER_Amount wad_fee;
-  const char *partner_base_url;
-  struct TALER_MasterSignatureP master_sig;
-  struct PartnerAddRequest *par;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_fixed_auto ("partner_pub",
-                                 &partner_pub),
-    TALER_JSON_spec_amount ("wad_fee",
-                            currency,
-                            &wad_fee),
-    GNUNET_JSON_spec_relative_time ("wad_frequency",
-                                    &wad_frequency),
-    GNUNET_JSON_spec_timestamp ("start_date",
-                                &start_date),
-    GNUNET_JSON_spec_timestamp ("end_date",
-                                &end_date),
-    GNUNET_JSON_spec_string ("partner_base_url",
-                             &partner_base_url),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-  const char *err_name;
-  unsigned int err_line;
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to add partner: %s#%u at %u (skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  par = GNUNET_new (struct PartnerAddRequest);
-  par->idx = idx;
-  par->h =
-    DONAU_management_add_partner (ctx,
-                                  donau_url,
-                                  &partner_pub,
-                                  start_date,
-                                  end_date,
-                                  wad_frequency,
-                                  &wad_fee,
-                                  partner_base_url,
-                                  &master_sig,
-                                  &add_partner_cb,
-                                  par);
-  GNUNET_CONTAINER_DLL_insert (par_head,
-                               par_tail,
-                               par);
-}
-
-
-/**
- * Function called with information about the AML officer update operation.
- *
- * @param cls closure with a `struct AmlStaffRequest`
- * @param ar response data
- */
-static void
-update_aml_officer_cb (
-  void *cls,
-  const struct DONAU_ManagementUpdateAmlOfficerResponse *ar)
-{
-  struct AmlStaffRequest *asr = cls;
-  const struct DONAU_HttpResponse *hr = &ar->hr;
-
-  if (MHD_HTTP_NO_CONTENT != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Upload failed for command %u with status %u: %s (%s)\n",
-                (unsigned int) asr->idx,
-                hr->http_status,
-                TALER_ErrorCode_get_hint (hr->ec),
-                hr->hint);
-    global_ret = EXIT_FAILURE;
-  }
-  GNUNET_CONTAINER_DLL_remove (asr_head,
-                               asr_tail,
-                               asr);
-  GNUNET_free (asr);
-  test_shutdown ();
-}
-
-
-/**
- * Upload AML staff action.
- *
- * @param donau_url base URL of the donau
- * @param idx index of the operation we are performing (for logging)
- * @param value arguments for AML staff change
- */
-static void
-update_aml_staff (const char *donau_url,
-                  size_t idx,
-                  const json_t *value)
-{
-  struct TALER_AmlOfficerPublicKeyP officer_pub;
-  const char *officer_name;
-  struct GNUNET_TIME_Timestamp change_date;
-  bool is_active;
-  bool read_only;
-  struct TALER_MasterSignatureP master_sig;
-  struct AmlStaffRequest *asr;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_fixed_auto ("officer_pub",
-                                 &officer_pub),
-    GNUNET_JSON_spec_timestamp ("change_date",
-                                &change_date),
-    GNUNET_JSON_spec_bool ("is_active",
-                           &is_active),
-    GNUNET_JSON_spec_bool ("read_only",
-                           &read_only),
-    GNUNET_JSON_spec_string ("officer_name",
-                             &officer_name),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",
-                                 &master_sig),
-    GNUNET_JSON_spec_end ()
-  };
-  const char *err_name;
-  unsigned int err_line;
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (value,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to AML staff update: %s#%u at %u (skipping)\n",
-                err_name,
-                err_line,
-                (unsigned int) idx);
-    json_dumpf (value,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return;
-  }
-  asr = GNUNET_new (struct AmlStaffRequest);
-  asr->idx = idx;
-  asr->h =
-    DONAU_management_update_aml_officer (ctx,
-                                         donau_url,
-                                         &officer_pub,
-                                         officer_name,
-                                         change_date,
-                                         is_active,
-                                         read_only,
-                                         &master_sig,
-                                         &update_aml_officer_cb,
-                                         asr);
-  GNUNET_CONTAINER_DLL_insert (asr_head,
-                               asr_tail,
-                               asr);
-}
-
-
-/**
- * Perform uploads based on the JSON in #out.
- *
- * @param donau_url base URL of the donau to use
- */
-static void
-trigger_upload (const char *donau_url)
-{
-  struct UploadHandler uhs[] = {
-    {
-      .key = OP_REVOKE_DENOMINATION,
-      .cb = &upload_denom_revocation
-    },
-    {
-      .key = OP_REVOKE_SIGNKEY,
-      .cb = &upload_signkey_revocation
-    },
-    {
-      .key = OP_ENABLE_AUDITOR,
-      .cb = &upload_auditor_add
-    },
-    {
-      .key = OP_DISABLE_AUDITOR,
-      .cb = &upload_auditor_del
-    },
-    {
-      .key = OP_ENABLE_WIRE,
-      .cb = &upload_wire_add
-    },
-    {
-      .key = OP_DISABLE_WIRE,
-      .cb = &upload_wire_del
-    },
-    {
-      .key = OP_SET_WIRE_FEE,
-      .cb = &upload_wire_fee
-    },
-    {
-      .key = OP_SET_GLOBAL_FEE,
-      .cb = &upload_global_fee
-    },
-    {
-      .key = OP_UPLOAD_SIGS,
-      .cb = &upload_keys
-    },
-    {
-      .key = OP_DRAIN_PROFITS,
-      .cb = &upload_drain
-    },
-    {
-      .key = OP_EXTENSIONS,
-      .cb = &upload_extensions
-    },
-    {
-      .key = OP_UPDATE_AML_STAFF,
-      .cb = &update_aml_staff
-    },
-    {
-      .key = OP_ADD_PARTNER,
-      .cb = &add_partner
-    },
-    /* array termination */
-    {
-      .key = NULL
-    }
-  };
-  size_t index;
-  json_t *obj;
-
-  json_array_foreach (out, index, obj) {
-    bool found = false;
-    const char *key;
-    const json_t *value;
-
-    key = json_string_value (json_object_get (obj, "operation"));
-    value = json_object_get (obj, "arguments");
-    if (NULL == key)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Malformed JSON input\n");
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return;
-    }
-    /* block of code that uses key and value */
-    for (unsigned int i = 0; NULL != uhs[i].key; i++)
-    {
-      if (0 == strcasecmp (key,
-                           uhs[i].key))
-      {
-
-        found = true;
-        uhs[i].cb (donau_url,
-                   index,
-                   value);
-        break;
-      }
-    }
-    if (! found)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Upload does not know how to handle `%s'\n",
-                  key);
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return;
-    }
-  }
-}
-
-
-/**
- * Upload operation result (signatures) to donau.
- *
- * @param args the array of command-line arguments to process next
- */
-static void
-do_upload (char *const *args)
-{
-  (void) args;
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, refusing upload\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if (NULL == out)
-  {
-    json_error_t err;
-
-    out = json_loadf (stdin,
-                      JSON_REJECT_DUPLICATES,
-                      &err);
-    if (NULL == out)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Failed to read JSON input: %s at %d:%s (offset: %d)\n",
-                  err.text,
-                  err.line,
-                  err.source,
-                  err.position);
-      test_shutdown ();
-      global_ret = EXIT_FAILURE;
-      return;
-    }
-  }
-  if (! json_is_array (out))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Error: expected JSON array for `upload` command\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == CFG_donau_url) &&
-       (GNUNET_OK !=
-        GNUNET_CONFIGURATION_get_value_string (kcfg,
-                                               "donau",
-                                               "BASE_URL",
-                                               &CFG_donau_url)) )
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "donau",
-                               "BASE_URL");
-    global_ret = EXIT_NOTCONFIGURED;
-    test_shutdown ();
-    return;
-  }
-  trigger_upload (CFG_donau_url);
-  json_decref (out);
-  out = NULL;
-}
-
-
-/**
- * Revoke denomination key.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the hash of the denomination key to revoke
- */
-static void
-do_revoke_denomination_key (char *const *args)
-{
-  struct TALER_DenominationHashP h_denom_pub;
-  struct TALER_MasterSignatureP master_sig;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, refusing revocation\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (GNUNET_OK !=
-        GNUNET_STRINGS_string_to_data (args[0],
-                                       strlen (args[0]),
-                                       &h_denom_pub,
-                                       sizeof (h_denom_pub))) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify a denomination key with this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  TALER_donau_offline_denomination_revoke_sign (&h_denom_pub,
-                                                &master_priv,
-                                                &master_sig);
-  output_operation (OP_REVOKE_DENOMINATION,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_data_auto ("h_denom_pub",
-                                                  &h_denom_pub),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + 1);
-}
-
-
-/**
- * Revoke signkey.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the hash of the denomination key to revoke
- */
-static void
-do_revoke_signkey (char *const *args)
-{
-  struct DONAU_DonauPublicKeyP donau_pub;
-  struct TALER_MasterSignatureP master_sig;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, refusing revocation\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (GNUNET_OK !=
-        GNUNET_STRINGS_string_to_data (args[0],
-                                       strlen (args[0]),
-                                       &donau_pub,
-                                       sizeof (donau_pub))) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify an donau signing key with this 
subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  TALER_donau_offline_signkey_revoke_sign (&donau_pub,
-                                           &master_priv,
-                                           &master_sig);
-  output_operation (OP_REVOKE_SIGNKEY,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_data_auto ("donau_pub",
-                                                  &donau_pub),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + 1);
-}
-
-
-/**
- * Add auditor.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the auditor's public key, args[1] the auditor's
- *        API base URL, and args[2] the auditor's name.
- */
-static void
-do_add_auditor (char *const *args)
-{
-  struct TALER_MasterSignatureP master_sig;
-  struct TALER_AuditorPublicKeyP auditor_pub;
-  struct GNUNET_TIME_Timestamp now;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, not adding auditor\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (GNUNET_OK !=
-        GNUNET_STRINGS_string_to_data (args[0],
-                                       strlen (args[0]),
-                                       &auditor_pub,
-                                       sizeof (auditor_pub))) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify an auditor public key as first argument for 
this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-
-  if ( (NULL == args[1]) ||
-       (0 != strncmp ("http",
-                      args[1],
-                      strlen ("http"))) ||
-       (NULL == args[2]) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify an auditor URI and auditor name as 2nd and 
3rd arguments to this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  now = GNUNET_TIME_timestamp_get ();
-  TALER_donau_offline_auditor_add_sign (&auditor_pub,
-                                        args[1],
-                                        now,
-                                        &master_priv,
-                                        &master_sig);
-  output_operation (OP_ENABLE_AUDITOR,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_string ("auditor_url",
-                                               args[1]),
-                      GNUNET_JSON_pack_string ("auditor_name",
-                                               args[2]),
-                      GNUNET_JSON_pack_timestamp ("validity_start",
-                                                  now),
-                      GNUNET_JSON_pack_data_auto ("auditor_pub",
-                                                  &auditor_pub),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + 3);
-}
-
-
-/**
- * Disable auditor account.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the hash of the denomination key to revoke
- */
-static void
-do_del_auditor (char *const *args)
-{
-  struct TALER_MasterSignatureP master_sig;
-  struct TALER_AuditorPublicKeyP auditor_pub;
-  struct GNUNET_TIME_Timestamp now;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, not deleting auditor 
account\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (GNUNET_OK !=
-        GNUNET_STRINGS_string_to_data (args[0],
-                                       strlen (args[0]),
-                                       &auditor_pub,
-                                       sizeof (auditor_pub))) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify an auditor public key as first argument for 
this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  now = GNUNET_TIME_timestamp_get ();
-  TALER_donau_offline_auditor_del_sign (&auditor_pub,
-                                        now,
-                                        &master_priv,
-                                        &master_sig);
-  output_operation (OP_DISABLE_AUDITOR,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_data_auto ("auditor_pub",
-                                                  &auditor_pub),
-                      GNUNET_JSON_pack_timestamp ("validity_end",
-                                                  now),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + 1);
-}
-
-
-/**
- * Parse account restriction.
- *
- * @param args the array of command-line arguments to process next
- * @param[in,out] restrictions JSON array to update
- * @return -1 on error, otherwise number of arguments from @a args that were 
used
- */
-static int
-parse_restriction (char *const *args,
-                   json_t *restrictions)
-{
-  if (NULL == args[0])
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Restriction TYPE argument missing\n");
-    return -1;
-  }
-  if (0 == strcmp (args[0],
-                   "deny"))
-  {
-    GNUNET_assert (0 ==
-                   json_array_append_new (
-                     restrictions,
-                     GNUNET_JSON_PACK (
-                       GNUNET_JSON_pack_string ("type",
-                                                "deny"))));
-    return 1;
-  }
-  if (0 == strcmp (args[0],
-                   "regex"))
-  {
-    json_t *i18n;
-    json_error_t err;
-
-    if ( (NULL == args[1]) ||
-         (NULL == args[2]) ||
-         (NULL == args[3]) )
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Mandatory arguments for restriction of type `regex' missing 
(REGEX, HINT, HINT-I18 required)\n");
-      return -1;
-    }
-    {
-      regex_t ex;
-
-      if (0 != regcomp (&ex,
-                        args[1],
-                        REG_NOSUB | REG_EXTENDED))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "Invalid regular expression `%s'\n",
-                    args[1]);
-        return -1;
-      }
-      regfree (&ex);
-    }
-
-    i18n = json_loads (args[3],
-                       JSON_REJECT_DUPLICATES,
-                       &err);
-    if (NULL == i18n)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid JSON for restriction of type `regex': `%s` at %d\n",
-                  args[3],
-                  err.position);
-      return -1;
-    }
-    GNUNET_assert (0 ==
-                   json_array_append_new (
-                     restrictions,
-                     GNUNET_JSON_PACK (
-                       GNUNET_JSON_pack_string ("type",
-                                                "regex"),
-                       GNUNET_JSON_pack_string ("regex",
-                                                args[1]),
-                       GNUNET_JSON_pack_string ("human_hint",
-                                                args[2]),
-                       GNUNET_JSON_pack_object_steal ("human_hint_i18n",
-                                                      i18n)
-                       )));
-    return 4;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-              "Restriction TYPE `%s' unsupported\n",
-              args[0]);
-  return -1;
-}
-
-
-/**
- * Add wire account.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the hash of the denomination key to revoke
- */
-static void
-do_add_wire (char *const *args)
-{
-  struct TALER_MasterSignatureP master_sig_add;
-  struct TALER_MasterSignatureP master_sig_wire;
-  struct GNUNET_TIME_Timestamp now;
-  const char *conversion_url = NULL;
-  json_t *debit_restrictions;
-  json_t *credit_restrictions;
-  unsigned int num_args = 1;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, not adding wire account\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if (NULL == args[0])
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify a payto://-URI with this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  {
-    char *msg = TALER_payto_validate (args[0]);
-
-    if (NULL != msg)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "payto URI is malformed: %s\n",
-                  msg);
-      GNUNET_free (msg);
-      test_shutdown ();
-      global_ret = EXIT_INVALIDARGUMENT;
-      return;
-    }
-  }
-  now = GNUNET_TIME_timestamp_get ();
-  {
-    char *wire_method;
-
-    wire_method = TALER_payto_get_method (args[0]);
-    if (NULL == wire_method)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "payto:// URI `%s' is malformed\n",
-                  args[0]);
-      global_ret = EXIT_INVALIDARGUMENT;
-      test_shutdown ();
-      return;
-    }
-    GNUNET_free (wire_method);
-  }
-  debit_restrictions = json_array ();
-  GNUNET_assert (NULL != debit_restrictions);
-  credit_restrictions = json_array ();
-  GNUNET_assert (NULL != credit_restrictions);
-  while (NULL != args[num_args])
-  {
-    if (0 == strcmp (args[num_args],
-                     "conversion-url"))
-    {
-      num_args++;
-      conversion_url = args[num_args];
-      if (NULL == conversion_url)
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "'conversion-url' requires an argument\n");
-        global_ret = EXIT_INVALIDARGUMENT;
-        test_shutdown ();
-        json_decref (debit_restrictions);
-        json_decref (credit_restrictions);
-        return;
-      }
-      num_args++;
-      continue;
-    }
-    if (0 == strcmp (args[num_args],
-                     "credit-restriction"))
-    {
-      int iret;
-
-      num_args++;
-      iret = parse_restriction (&args[num_args],
-                                credit_restrictions);
-      if (iret <= 0)
-      {
-        global_ret = EXIT_INVALIDARGUMENT;
-        test_shutdown ();
-        json_decref (debit_restrictions);
-        json_decref (credit_restrictions);
-        return;
-      }
-      num_args += iret;
-      continue;
-    }
-    if (0 == strcmp (args[num_args],
-                     "debit-restriction"))
-    {
-      int iret;
-
-      num_args++;
-      iret = parse_restriction (&args[num_args],
-                                debit_restrictions);
-      if (iret <= 0)
-      {
-        global_ret = EXIT_INVALIDARGUMENT;
-        test_shutdown ();
-        json_decref (debit_restrictions);
-        json_decref (credit_restrictions);
-        return;
-      }
-      num_args += iret;
-      continue;
-    }
-    break;
-  }
-  TALER_donau_offline_wire_add_sign (args[0],
-                                     conversion_url,
-                                     debit_restrictions,
-                                     credit_restrictions,
-                                     now,
-                                     &master_priv,
-                                     &master_sig_add);
-  TALER_donau_wire_signature_make (args[0],
-                                   conversion_url,
-                                   debit_restrictions,
-                                   credit_restrictions,
-                                   &master_priv,
-                                   &master_sig_wire);
-  output_operation (OP_ENABLE_WIRE,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_string ("payto_uri",
-                                               args[0]),
-                      GNUNET_JSON_pack_array_steal ("debit_restrictions",
-                                                    debit_restrictions),
-                      GNUNET_JSON_pack_array_steal ("credit_restrictions",
-                                                    credit_restrictions),
-                      GNUNET_JSON_pack_allow_null (
-                        GNUNET_JSON_pack_string ("conversion_url",
-                                                 conversion_url)),
-                      GNUNET_JSON_pack_timestamp ("validity_start",
-                                                  now),
-                      GNUNET_JSON_pack_data_auto ("master_sig_add",
-                                                  &master_sig_add),
-                      GNUNET_JSON_pack_data_auto ("master_sig_wire",
-                                                  &master_sig_wire)));
-  next (args + num_args);
-}
-
-
-/**
- * Disable wire account.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the hash of the denomination key to revoke
- */
-static void
-do_del_wire (char *const *args)
-{
-  struct TALER_MasterSignatureP master_sig;
-  struct GNUNET_TIME_Timestamp now;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, not deleting wire 
account\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if (NULL == args[0])
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify a payto://-URI with this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  now = GNUNET_TIME_timestamp_get ();
-  TALER_donau_offline_wire_del_sign (args[0],
-                                     now,
-                                     &master_priv,
-                                     &master_sig);
-  output_operation (OP_DISABLE_WIRE,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_string ("payto_uri",
-                                               args[0]),
-                      GNUNET_JSON_pack_timestamp ("validity_end",
-                                                  now),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + 1);
-}
-
-
-/**
- * Set wire fees for the given year.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the year, args[1] the wire method, args[2] the wire 
fee and args[3]
- *        the closing fee.
- */
-static void
-do_set_wire_fee (char *const *args)
-{
-  struct TALER_MasterSignatureP master_sig;
-  char dummy;
-  unsigned int year;
-  struct TALER_WireFeeSet fees;
-  struct GNUNET_TIME_Timestamp start_time;
-  struct GNUNET_TIME_Timestamp end_time;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, not setting wire fee\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (NULL == args[1]) ||
-       (NULL == args[2]) ||
-       (NULL == args[3]) ||
-       ( (1 != sscanf (args[0],
-                       "%u%c",
-                       &year,
-                       &dummy)) &&
-         (0 != strcasecmp ("now",
-                           args[0])) ) ||
-       (GNUNET_OK !=
-        TALER_string_to_amount (args[2],
-                                &fees.wire)) ||
-       (GNUNET_OK !=
-        TALER_string_to_amount (args[3],
-                                &fees.closing)) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must use YEAR, METHOD, WIRE-FEE, and CLOSING-FEE as 
arguments for this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (0 == strcasecmp ("now",
-                       args[0]))
-    year = GNUNET_TIME_get_current_year ();
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  start_time = GNUNET_TIME_absolute_to_timestamp (
-    GNUNET_TIME_year_to_time (year));
-  end_time = GNUNET_TIME_absolute_to_timestamp (
-    GNUNET_TIME_year_to_time (year + 1));
-
-  TALER_donau_offline_wire_fee_sign (args[1],
-                                     start_time,
-                                     end_time,
-                                     &fees,
-                                     &master_priv,
-                                     &master_sig);
-  output_operation (OP_SET_WIRE_FEE,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_string ("wire_method",
-                                               args[1]),
-                      GNUNET_JSON_pack_timestamp ("start_time",
-                                                  start_time),
-                      GNUNET_JSON_pack_timestamp ("end_time",
-                                                  end_time),
-                      TALER_JSON_pack_amount ("wire_fee",
-                                              &fees.wire),
-                      TALER_JSON_pack_amount ("closing_fee",
-                                              &fees.closing),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + 4);
-}
-
-
-/**
- * Set global fees for the given year.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the year, args[1] the history fee, args[2]
- *        the account fee and args[3] the purse fee. These are followed by 
args[4] purse timeout,
- *        args[5] history expiration. Last is args[6] the (free) purse account 
limit.
- */
-static void
-do_set_global_fee (char *const *args)
-{
-  struct TALER_MasterSignatureP master_sig;
-  char dummy;
-  unsigned int year;
-  struct TALER_GlobalFeeSet fees;
-  struct GNUNET_TIME_Relative purse_timeout;
-  struct GNUNET_TIME_Relative history_expiration;
-  unsigned int purse_account_limit;
-  struct GNUNET_TIME_Timestamp start_time;
-  struct GNUNET_TIME_Timestamp end_time;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, not setting global fee\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (NULL == args[1]) ||
-       (NULL == args[2]) ||
-       (NULL == args[3]) ||
-       (NULL == args[4]) ||
-       (NULL == args[5]) ||
-       (NULL == args[6]) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must use YEAR, HISTORY-FEE, ACCOUNT-FEE, PURSE-FEE, 
PURSE-TIMEOUT, HISTORY-EXPIRATION and PURSE-ACCOUNT-LIMIT as arguments for this 
subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if ( (1 != sscanf (args[0],
-                     "%u%c",
-                     &year,
-                     &dummy)) &&
-       (0 != strcasecmp ("now",
-                         args[0])) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid YEAR given for 'global-fee' subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if ( (GNUNET_OK !=
-        TALER_string_to_amount (args[1],
-                                &fees.history)) ||
-       (GNUNET_OK !=
-        TALER_string_to_amount (args[2],
-                                &fees.account)) ||
-       (GNUNET_OK !=
-        TALER_string_to_amount (args[3],
-                                &fees.purse)) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid amount given for 'global-fee' subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if ( (GNUNET_OK !=
-        GNUNET_STRINGS_fancy_time_to_relative (args[4],
-                                               &purse_timeout)) ||
-       (GNUNET_OK !=
-        GNUNET_STRINGS_fancy_time_to_relative (args[5],
-                                               &history_expiration)) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid delay given for 'global-fee' subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (1 != sscanf (args[6],
-                   "%u%c",
-                   &purse_account_limit,
-                   &dummy))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid purse account limit given for 'global-fee' 
subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (0 == strcasecmp ("now",
-                       args[0]))
-    year = GNUNET_TIME_get_current_year ();
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  start_time = GNUNET_TIME_absolute_to_timestamp (
-    GNUNET_TIME_year_to_time (year));
-  end_time = GNUNET_TIME_absolute_to_timestamp (
-    GNUNET_TIME_year_to_time (year + 1));
-
-  TALER_donau_offline_global_fee_sign (start_time,
-                                       end_time,
-                                       &fees,
-                                       purse_timeout,
-                                       history_expiration,
-                                       (uint32_t) purse_account_limit,
-                                       &master_priv,
-                                       &master_sig);
-  output_operation (OP_SET_GLOBAL_FEE,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_timestamp ("start_time",
-                                                  start_time),
-                      GNUNET_JSON_pack_timestamp ("end_time",
-                                                  end_time),
-                      TALER_JSON_pack_amount ("history_fee",
-                                              &fees.history),
-                      TALER_JSON_pack_amount ("account_fee",
-                                              &fees.account),
-                      TALER_JSON_pack_amount ("purse_fee",
-                                              &fees.purse),
-                      GNUNET_JSON_pack_time_rel ("purse_timeout",
-                                                 purse_timeout),
-                      GNUNET_JSON_pack_time_rel ("history_expiration",
-                                                 history_expiration),
-                      GNUNET_JSON_pack_uint64 ("purse_account_limit",
-                                               (uint32_t) purse_account_limit),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + 7);
-}
-
-
-/**
- * Drain profits from donau's escrow account to
- * regular donau account.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the amount,
- *        args[1] must be the section of the escrow account to drain
- *        args[2] must be the payto://-URI of the target account
- */
-static void
-do_drain (char *const *args)
-{
-  struct TALER_WireTransferIdentifierRawP wtid;
-  struct GNUNET_TIME_Timestamp date;
-  struct TALER_Amount amount;
-  const char *account_section;
-  const char *payto_uri;
-  struct TALER_MasterSignatureP master_sig;
-  char *err;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, refusing drain\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (NULL == args[1]) ||
-       (NULL == args[2]) ||
-       (GNUNET_OK !=
-        TALER_string_to_amount (args[0],
-                                &amount)) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Drain requires an amount, section name and target 
payto://-URI as arguments\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (NULL == args[1]) ||
-       (NULL == args[2]) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Drain requires an amount, section name and target 
payto://-URI as arguments\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (GNUNET_OK !=
-      TALER_string_to_amount (args[0],
-                              &amount))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid amount `%s' specified for drain\n",
-                args[0]);
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  account_section = args[1];
-  payto_uri = args[2];
-  err = TALER_payto_validate (payto_uri);
-  if (NULL != err)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid payto://-URI `%s' specified for drain: %s\n",
-                payto_uri,
-                err);
-    GNUNET_free (err);
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
-                              &wtid,
-                              sizeof (wtid));
-  date = GNUNET_TIME_timestamp_get ();
-  TALER_donau_offline_profit_drain_sign (&wtid,
-                                         date,
-                                         &amount,
-                                         account_section,
-                                         payto_uri,
-                                         &master_priv,
-                                         &master_sig);
-  output_operation (OP_DRAIN_PROFITS,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_data_auto ("wtid",
-                                                  &wtid),
-                      GNUNET_JSON_pack_string ("account_section",
-                                               account_section),
-                      GNUNET_JSON_pack_string ("payto_uri",
-                                               payto_uri),
-                      TALER_JSON_pack_amount ("amount",
-                                              &amount),
-                      GNUNET_JSON_pack_timestamp ("date",
-                                                  date),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + 3);
-}
-
-
-/**
- * Add partner.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the partner's master public key, args[1] the 
partner's
- *        API base URL, args[2] the wad fee, args[3] the wad frequency, and
- *        args[4] the year (including possibly 'now')
- */
-static void
-do_add_partner (char *const *args)
-{
-  struct TALER_MasterPublicKeyP partner_pub;
-  struct GNUNET_TIME_Timestamp start_date;
-  struct GNUNET_TIME_Timestamp end_date;
-  struct GNUNET_TIME_Relative wad_frequency;
-  struct TALER_Amount wad_fee;
-  const char *partner_base_url;
-  struct TALER_MasterSignatureP master_sig;
-  char dummy;
-  unsigned int year;
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, not adding partner\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (GNUNET_OK !=
-        GNUNET_STRINGS_string_to_data (args[0],
-                                       strlen (args[0]),
-                                       &partner_pub,
-                                       sizeof (partner_pub))) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify the partner master public key as first 
argument for this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if ( (NULL == args[1]) ||
-       (0 != strncmp ("http",
-                      args[1],
-                      strlen ("http"))) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify the partner's base URL as the 2nd argument 
to this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  partner_base_url = args[1];
-  if ( (NULL == args[2]) ||
-       (GNUNET_OK !=
-        TALER_string_to_amount (args[2],
-                                &wad_fee)) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid amount `%s' specified for wad fee of partner\n",
-                args[2]);
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if ( (NULL == args[3]) ||
-       (GNUNET_OK !=
-        GNUNET_STRINGS_fancy_time_to_relative (args[3],
-                                               &wad_frequency)) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid wad frequency `%s' specified for add partner\n",
-                args[3]);
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if ( (NULL == args[4]) ||
-       ( (1 != sscanf (args[4],
-                       "%u%c",
-                       &year,
-                       &dummy)) &&
-         (0 != strcasecmp ("now",
-                           args[4])) ) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid year `%s' specified for add partner\n",
-                args[4]);
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (0 == strcasecmp ("now",
-                       args[4]))
-    year = GNUNET_TIME_get_current_year ();
-  start_date = GNUNET_TIME_absolute_to_timestamp (
-    GNUNET_TIME_year_to_time (year));
-  end_date = GNUNET_TIME_absolute_to_timestamp (
-    GNUNET_TIME_year_to_time (year + 1));
-
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  TALER_donau_offline_partner_details_sign (&partner_pub,
-                                            start_date,
-                                            end_date,
-                                            wad_frequency,
-                                            &wad_fee,
-                                            partner_base_url,
-                                            &master_priv,
-                                            &master_sig);
-  output_operation (OP_ADD_PARTNER,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_string ("partner_base_url",
-                                               partner_base_url),
-                      GNUNET_JSON_pack_time_rel ("wad_frequency",
-                                                 wad_frequency),
-                      GNUNET_JSON_pack_timestamp ("start_date",
-                                                  start_date),
-                      GNUNET_JSON_pack_timestamp ("end_date",
-                                                  end_date),
-                      GNUNET_JSON_pack_data_auto ("partner_pub",
-                                                  &partner_pub),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + 5);
-}
-
-
-/**
- * Enable or disable AML staff.
- *
- * @param is_active true to enable, false to disable
- * @param args the array of command-line arguments to process next; args[0] 
must be the AML staff's public key, args[1] the AML staff's legal name, and if 
@a is_active then args[2] rw (read write) or ro (read only)
- */
-static void
-do_set_aml_staff (bool is_active,
-                  char *const *args)
-{
-  struct TALER_AmlOfficerPublicKeyP officer_pub;
-  const char *officer_name;
-  bool read_only;
-  struct TALER_MasterSignatureP master_sig;
-  struct GNUNET_TIME_Timestamp now
-    = GNUNET_TIME_timestamp_get ();
-
-  if (NULL != in)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Downloaded data was not consumed, not updating AML staff 
status\n");
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if ( (NULL == args[0]) ||
-       (GNUNET_OK !=
-        GNUNET_STRINGS_string_to_data (args[0],
-                                       strlen (args[0]),
-                                       &officer_pub,
-                                       sizeof (officer_pub))) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify the AML officer's public key as first 
argument for this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  if (NULL == args[1])
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must specify the officer's legal name as the 2nd argument 
to this subcommand\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-  officer_name = args[1];
-  if (is_active)
-  {
-    if ( (NULL == args[2]) ||
-         ( (0 != strcmp (args[2],
-                         "ro")) &&
-           (0 != strcmp (args[2],
-                         "rw")) ) )
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "You must specify 'ro' or 'rw' (and not `%s') for the access 
level\n",
-                  args[2]);
-      test_shutdown ();
-      global_ret = EXIT_INVALIDARGUMENT;
-      return;
-    }
-    read_only = (0 == strcmp (args[2],
-                              "ro"));
-  }
-  else
-  {
-    read_only = true;
-  }
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  TALER_donau_offline_aml_officer_status_sign (&officer_pub,
-                                               officer_name,
-                                               now,
-                                               is_active,
-                                               read_only,
-                                               &master_priv,
-                                               &master_sig);
-  output_operation (OP_UPDATE_AML_STAFF,
-                    GNUNET_JSON_PACK (
-                      GNUNET_JSON_pack_string ("officer_name",
-                                               officer_name),
-                      GNUNET_JSON_pack_timestamp ("change_date",
-                                                  now),
-                      GNUNET_JSON_pack_bool ("is_active",
-                                             is_active),
-                      GNUNET_JSON_pack_bool ("read_only",
-                                             read_only),
-                      GNUNET_JSON_pack_data_auto ("officer_pub",
-                                                  &officer_pub),
-                      GNUNET_JSON_pack_data_auto ("master_sig",
-                                                  &master_sig)));
-  next (args + (is_active ? 3 : 2));
-}
-
-
-/**
- * Disable AML staff.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the AML staff's public key, args[1] the AML staff's 
legal name, args[2] rw (read write) or ro (read only)
- */
-static void
-disable_aml_staff (char *const *args)
-{
-  do_set_aml_staff (false,
-                    args);
-}
-
-
-/**
- * Enable AML staff.
- *
- * @param args the array of command-line arguments to process next;
- *        args[0] must be the AML staff's public key, args[1] the AML staff's 
legal name, args[2] rw (read write) or ro (read only)
- */
-static void
-enable_aml_staff (char *const *args)
-{
-  do_set_aml_staff (true,
-                    args);
-}
-
-
-/**
- * Function called with information about future keys.  Dumps the JSON output
- * (on success), either into an internal buffer or to stdout (depending on
- * whether there are subsequent commands).
- *
- * @param cls closure with the `char **` remaining args
- * @param mgr response data
- */
-static void
-download_cb (void *cls,
-             const struct DONAU_ManagementGetKeysResponse *mgr)
-{
-  char *const *args = cls;
-  const struct DONAU_HttpResponse *hr = &mgr->hr;
-
-  mgkh = NULL;
-  switch (hr->http_status)
-  {
-  case MHD_HTTP_OK:
-    break;
-  default:
-    if (0 != hr->http_status)
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Failed to download keys from `%s': %s (HTTP status: 
%u/%u)\n",
-                  CFG_donau_url,
-                  hr->hint,
-                  hr->http_status,
-                  (unsigned int) hr->ec);
-    else
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Failed to download keys from `%s' (no HTTP response)\n",
-                  CFG_donau_url);
-    test_shutdown ();
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  in = GNUNET_JSON_PACK (
-    GNUNET_JSON_pack_string ("operation",
-                             OP_INPUT_KEYS),
-    GNUNET_JSON_pack_object_incref ("arguments",
-                                    (json_t *) hr->reply));
-  if (NULL == args[0])
-  {
-    json_dumpf (in,
-                stdout,
-                JSON_INDENT (2));
-    json_decref (in);
-    in = NULL;
-  }
-  next (args);
-}
-
-
-/**
- * Download future keys.
- *
- * @param args the array of command-line arguments to process next
- */
-static void
-do_download (char *const *args)
-{
-  if ( (NULL == CFG_donau_url) &&
-       (GNUNET_OK !=
-        GNUNET_CONFIGURATION_get_value_string (kcfg,
-                                               "donau",
-                                               "BASE_URL",
-                                               &CFG_donau_url)) )
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "donau",
-                               "BASE_URL");
-    test_shutdown ();
-    global_ret = EXIT_NOTCONFIGURED;
-    return;
-  }
-  mgkh = DONAU_get_management_keys (ctx,
-                                    CFG_donau_url,
-                                    &download_cb,
-                                    (void *) args);
-}
-
-
-/**
- * Check that the security module keys are the same as before.  If we had no
- * keys in store before, remember them (Trust On First Use).
- *
- * @param secmset security module keys
- * @return #GNUNET_OK if keys match with what we have in store
- *         #GNUNET_NO if we had nothing in store but now do
- *         #GNUNET_SYSERR if keys changed from what we remember or other error
- */
-static enum GNUNET_GenericReturnValue
-tofu_check (const struct TALER_SecurityModulePublicKeySetP *secmset)
-{
-  char *fn;
-  struct TALER_SecurityModulePublicKeySetP oldset;
-  ssize_t ret;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (kcfg,
-                                               "donau-offline",
-                                               "SECM_TOFU_FILE",
-                                               &fn))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "donau-offline",
-                               "SECM_TOFU_FILE");
-    return GNUNET_SYSERR;
-  }
-  if (GNUNET_OK ==
-      GNUNET_DISK_file_test (fn))
-  {
-    ret = GNUNET_DISK_fn_read (fn,
-                               &oldset,
-                               sizeof (oldset));
-    if (GNUNET_SYSERR != ret)
-    {
-      if (ret != sizeof (oldset))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "File `%s' corrupt\n",
-                    fn);
-        GNUNET_free (fn);
-        return GNUNET_SYSERR;
-      }
-      /* TOFU check */
-      if (0 != memcmp (&oldset,
-                       secmset,
-                       sizeof (*secmset)))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "Fatal: security module keys changed (file `%s')!\n",
-                    fn);
-        GNUNET_free (fn);
-        return GNUNET_SYSERR;
-      }
-      GNUNET_free (fn);
-      return GNUNET_OK;
-    }
-  }
-
-  {
-    char *key;
-
-    /* check against SECMOD-keys pinned in configuration */
-    if (GNUNET_OK ==
-        GNUNET_CONFIGURATION_get_value_string (kcfg,
-                                               "donau-offline",
-                                               "SECM_ESIGN_PUBKEY",
-                                               &key))
-    {
-      struct TALER_SecurityModulePublicKeyP k;
-
-      if (GNUNET_OK !=
-          GNUNET_STRINGS_string_to_data (key,
-                                         strlen (key),
-                                         &k,
-                                         sizeof (k)))
-      {
-        GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
-                                   "donau-offline",
-                                   "SECM_ESIGN_PUBKEY",
-                                   "key malformed");
-        GNUNET_free (key);
-        GNUNET_free (fn);
-        return GNUNET_SYSERR;
-      }
-      GNUNET_free (key);
-      if (0 !=
-          GNUNET_memcmp (&k,
-                         &secmset->eddsa))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "ESIGN security module key does not match 
SECM_ESIGN_PUBKEY in configuration\n");
-        GNUNET_free (fn);
-        return GNUNET_SYSERR;
-      }
-    }
-    if (GNUNET_OK ==
-        GNUNET_CONFIGURATION_get_value_string (kcfg,
-                                               "donau-offline",
-                                               "SECM_DENOM_PUBKEY",
-                                               &key))
-    {
-      struct TALER_SecurityModulePublicKeyP k;
-
-      if (GNUNET_OK !=
-          GNUNET_STRINGS_string_to_data (key,
-                                         strlen (key),
-                                         &k,
-                                         sizeof (k)))
-      {
-        GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
-                                   "donau-offline",
-                                   "SECM_DENOM_PUBKEY",
-                                   "key malformed");
-        GNUNET_free (key);
-        GNUNET_free (fn);
-        return GNUNET_SYSERR;
-      }
-      GNUNET_free (key);
-      if (0 !=
-          GNUNET_memcmp (&k,
-                         &secmset->rsa))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "DENOM security module key does not match 
SECM_DENOM_PUBKEY in configuration\n");
-        GNUNET_free (fn);
-        return GNUNET_SYSERR;
-      }
-    }
-    if (GNUNET_OK ==
-        GNUNET_CONFIGURATION_get_value_string (kcfg,
-                                               "donau-offline",
-                                               "SECM_DENOM_CS_PUBKEY",
-                                               &key))
-    {
-      struct TALER_SecurityModulePublicKeyP k;
-
-      if (GNUNET_OK !=
-          GNUNET_STRINGS_string_to_data (key,
-                                         strlen (key),
-                                         &k,
-                                         sizeof (k)))
-      {
-        GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
-                                   "donau-offline",
-                                   "SECM_DENOM_CS_PUBKEY",
-                                   "key malformed");
-        GNUNET_free (key);
-        GNUNET_free (fn);
-        return GNUNET_SYSERR;
-      }
-      GNUNET_free (key);
-      if (0 !=
-          GNUNET_memcmp (&k,
-                         &secmset->cs))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "DENOM security module key does not match 
SECM_DENOM_CS_PUBKEY in configuration\n");
-        GNUNET_free (fn);
-        return GNUNET_SYSERR;
-      }
-    }
-  }
-  if (GNUNET_OK !=
-      GNUNET_DISK_directory_create_for_file (fn))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed create directory to store key material in file `%s'\n",
-                fn);
-    GNUNET_free (fn);
-    return GNUNET_SYSERR;
-  }
-  /* persist keys for future runs */
-  if (GNUNET_OK !=
-      GNUNET_DISK_fn_write (fn,
-                            secmset,
-                            sizeof (oldset),
-                            GNUNET_DISK_PERM_USER_READ))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to store key material in file `%s'\n",
-                fn);
-    GNUNET_free (fn);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_free (fn);
-  return GNUNET_NO;
-}
-
-
-/**
- * Output @a signkeys for human consumption.
- *
- * @param secm_pub security module public key used to sign the denominations
- * @param signkeys keys to output
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-show_signkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
-               const json_t *signkeys)
-{
-  size_t index;
-  json_t *value;
-
-  json_array_foreach (signkeys, index, value) {
-    const char *err_name;
-    unsigned int err_line;
-    struct DONAU_DonauPublicKeyP donau_pub;
-    struct TALER_SecurityModuleSignatureP secm_sig;
-    struct GNUNET_TIME_Timestamp start_time;
-    struct GNUNET_TIME_Timestamp sign_end;
-    struct GNUNET_TIME_Timestamp legal_end;
-    struct GNUNET_TIME_Relative duration;
-    struct GNUNET_JSON_Specification spec[] = {
-      GNUNET_JSON_spec_timestamp ("stamp_start",
-                                  &start_time),
-      GNUNET_JSON_spec_timestamp ("stamp_expire",
-                                  &sign_end),
-      GNUNET_JSON_spec_timestamp ("stamp_end",
-                                  &legal_end),
-      GNUNET_JSON_spec_fixed_auto ("key",
-                                   &donau_pub),
-      GNUNET_JSON_spec_fixed_auto ("signkey_secmod_sig",
-                                   &secm_sig),
-      GNUNET_JSON_spec_end ()
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_JSON_parse (value,
-                           spec,
-                           &err_name,
-                           &err_line))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid input for signing key to 'show': %s#%u at %u 
(skipping)\n",
-                  err_name,
-                  err_line,
-                  (unsigned int) index);
-      json_dumpf (value,
-                  stderr,
-                  JSON_INDENT (2));
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return GNUNET_SYSERR;
-    }
-    duration = GNUNET_TIME_absolute_get_difference (start_time.abs_time,
-                                                    sign_end.abs_time);
-    if (GNUNET_OK !=
-        TALER_donau_secmod_eddsa_verify (&donau_pub,
-                                         start_time,
-                                         duration,
-                                         secm_pub,
-                                         &secm_sig))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid security module signature for signing key %s 
(aborting)\n",
-                  TALER_B2S (&donau_pub));
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return GNUNET_SYSERR;
-    }
-    {
-      char *legal_end_s;
-
-      legal_end_s = GNUNET_strdup (
-        GNUNET_TIME_timestamp2s (legal_end));
-      printf ("DONAU-KEY %s starting at %s (used for: %s, legal end: %s)\n",
-              TALER_B2S (&donau_pub),
-              GNUNET_TIME_timestamp2s (start_time),
-              GNUNET_TIME_relative2s (duration,
-                                      false),
-              legal_end_s);
-      GNUNET_free (legal_end_s);
-    }
-  }
-  return GNUNET_OK;
-}
-
-
-/**
- * Output @a denomkeys for human consumption.
- *
- * @param secm_pub_rsa security module public key used to sign the RSA 
denominations
- * @param secm_pub_cs security module public key used to sign the CS 
denominations
- * @param denomkeys keys to output
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-show_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub_rsa,
-                const struct TALER_SecurityModulePublicKeyP *secm_pub_cs,
-                const json_t *denomkeys)
-{
-  size_t index;
-  json_t *value;
-
-  json_array_foreach (denomkeys, index, value) {
-    const char *err_name;
-    unsigned int err_line;
-    const char *section_name;
-    struct TALER_DenominationPublicKey denom_pub;
-    struct GNUNET_TIME_Timestamp stamp_start;
-    struct GNUNET_TIME_Timestamp stamp_expire_withdraw;
-    struct GNUNET_TIME_Timestamp stamp_expire_deposit;
-    struct GNUNET_TIME_Timestamp stamp_expire_legal;
-    struct TALER_Amount coin_value;
-    struct TALER_DenomFeeSet fees;
-    struct TALER_SecurityModuleSignatureP secm_sig;
-    struct GNUNET_JSON_Specification spec[] = {
-      GNUNET_JSON_spec_string ("section_name",
-                               &section_name),
-      TALER_JSON_spec_denom_pub ("denom_pub",
-                                 &denom_pub),
-      TALER_JSON_spec_amount ("value",
-                              currency,
-                              &coin_value),
-      TALER_JSON_SPEC_DENOM_FEES ("fee",
-                                  currency,
-                                  &fees),
-      GNUNET_JSON_spec_timestamp ("stamp_start",
-                                  &stamp_start),
-      GNUNET_JSON_spec_timestamp ("stamp_expire_withdraw",
-                                  &stamp_expire_withdraw),
-      GNUNET_JSON_spec_timestamp ("stamp_expire_deposit",
-                                  &stamp_expire_deposit),
-      GNUNET_JSON_spec_timestamp ("stamp_expire_legal",
-                                  &stamp_expire_legal),
-      GNUNET_JSON_spec_fixed_auto ("denom_secmod_sig",
-                                   &secm_sig),
-      GNUNET_JSON_spec_end ()
-    };
-    struct GNUNET_TIME_Relative duration;
-    struct TALER_DenominationHashP h_denom_pub;
-    enum GNUNET_GenericReturnValue ok;
-
-    if (GNUNET_OK !=
-        GNUNET_JSON_parse (value,
-                           spec,
-                           &err_name,
-                           &err_line))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid input for denomination key to 'show': %s#%u at %u 
(skipping)\n",
-                  err_name,
-                  err_line,
-                  (unsigned int) index);
-      json_dumpf (value,
-                  stderr,
-                  JSON_INDENT (2));
-      GNUNET_JSON_parse_free (spec);
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return GNUNET_SYSERR;
-    }
-    duration = GNUNET_TIME_absolute_get_difference (
-      stamp_start.abs_time,
-      stamp_expire_withdraw.abs_time);
-    TALER_denom_pub_hash (&denom_pub,
-                          &h_denom_pub);
-    switch (denom_pub.cipher)
-    {
-    case TALER_DENOMINATION_RSA:
-      {
-        struct TALER_RsaPubHashP h_rsa;
-
-        TALER_rsa_pub_hash (denom_pub.details.rsa_public_key,
-                            &h_rsa);
-        ok = TALER_donau_secmod_rsa_verify (&h_rsa,
-                                            section_name,
-                                            stamp_start,
-                                            duration,
-                                            secm_pub_rsa,
-                                            &secm_sig);
-      }
-      break;
-    case TALER_DENOMINATION_CS:
-      {
-        struct TALER_CsPubHashP h_cs;
-
-        TALER_cs_pub_hash (&denom_pub.details.cs_public_key,
-                           &h_cs);
-        ok = TALER_donau_secmod_cs_verify (&h_cs,
-                                           section_name,
-                                           stamp_start,
-                                           duration,
-                                           secm_pub_cs,
-                                           &secm_sig);
-      }
-      break;
-    default:
-      GNUNET_break (0);
-      ok = GNUNET_SYSERR;
-      break;
-    }
-    if (GNUNET_OK != ok)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid security module signature for denomination key %s 
(aborting)\n",
-                  GNUNET_h2s (&h_denom_pub.hash));
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return GNUNET_SYSERR;
-    }
-
-    {
-      char *withdraw_fee_s;
-      char *deposit_fee_s;
-      char *refresh_fee_s;
-      char *refund_fee_s;
-      char *deposit_s;
-      char *legal_s;
-
-      withdraw_fee_s = TALER_amount_to_string (&fees.withdraw);
-      deposit_fee_s = TALER_amount_to_string (&fees.deposit);
-      refresh_fee_s = TALER_amount_to_string (&fees.refresh);
-      refund_fee_s = TALER_amount_to_string (&fees.refund);
-      deposit_s = GNUNET_strdup (
-        GNUNET_TIME_timestamp2s (stamp_expire_deposit));
-      legal_s = GNUNET_strdup (
-        GNUNET_TIME_timestamp2s (stamp_expire_legal));
-
-      printf (
-        "DENOMINATION-KEY(%s) %s of value %s starting at %s "
-        "(used for: %s, deposit until: %s legal end: %s) with fees 
%s/%s/%s/%s\n",
-        section_name,
-        TALER_B2S (&h_denom_pub),
-        TALER_amount2s (&coin_value),
-        GNUNET_TIME_timestamp2s (stamp_start),
-        GNUNET_TIME_relative2s (duration,
-                                false),
-        deposit_s,
-        legal_s,
-        withdraw_fee_s,
-        deposit_fee_s,
-        refresh_fee_s,
-        refund_fee_s);
-      GNUNET_free (withdraw_fee_s);
-      GNUNET_free (deposit_fee_s);
-      GNUNET_free (refresh_fee_s);
-      GNUNET_free (refund_fee_s);
-      GNUNET_free (deposit_s);
-      GNUNET_free (legal_s);
-    }
-
-    GNUNET_JSON_parse_free (spec);
-  }
-  return GNUNET_OK;
-}
-
-
-/**
- * Parse the input of donau keys for the 'show' and 'sign' commands.
- *
- * @param command_name name of the command, for logging
- * @return NULL on error, otherwise the keys details to be free'd by caller
- */
-static json_t *
-parse_keys_input (const char *command_name)
-{
-  const char *op_str;
-  json_t *keys;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("arguments",
-                           &keys),
-    GNUNET_JSON_spec_string ("operation",
-                             &op_str),
-    GNUNET_JSON_spec_end ()
-  };
-  const char *err_name;
-  unsigned int err_line;
-
-  if (NULL == in)
-  {
-    json_error_t err;
-
-    in = json_loadf (stdin,
-                     JSON_REJECT_DUPLICATES,
-                     &err);
-    if (NULL == in)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Failed to read JSON input: %s at %d:%s (offset: %d)\n",
-                  err.text,
-                  err.line,
-                  err.source,
-                  err.position);
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return NULL;
-    }
-  }
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (in,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to '%s': %s#%u (skipping)\n",
-                command_name,
-                err_name,
-                err_line);
-    json_dumpf (in,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    return NULL;
-  }
-  if (0 != strcmp (op_str,
-                   OP_INPUT_KEYS))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to '%s' : operation is `%s', expected `%s'\n",
-                command_name,
-                op_str,
-                OP_INPUT_KEYS);
-    GNUNET_JSON_parse_free (spec);
-    return NULL;
-  }
-  json_decref (in);
-  in = NULL;
-  return keys;
-}
-
-
-/**
- * Show future keys.
- *
- * @param args the array of command-line arguments to process next
- */
-static void
-do_show (char *const *args)
-{
-  json_t *keys;
-  const char *err_name;
-  unsigned int err_line;
-  const json_t *denomkeys;
-  const json_t *signkeys;
-  struct TALER_MasterPublicKeyP mpub;
-  struct TALER_SecurityModulePublicKeySetP secmset;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_array_const ("future_denoms",
-                                  &denomkeys),
-    GNUNET_JSON_spec_array_const ("future_signkeys",
-                                  &signkeys),
-    GNUNET_JSON_spec_fixed_auto ("master_pub",
-                                 &mpub),
-    GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
-                                 &secmset.rsa),
-    GNUNET_JSON_spec_fixed_auto ("denom_secmod_cs_public_key",
-                                 &secmset.cs),
-    GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
-                                 &secmset.eddsa),
-    GNUNET_JSON_spec_end ()
-  };
-
-  keys = parse_keys_input ("show");
-  if (NULL == keys)
-    return;
-
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-    return;
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (keys,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to 'show': %s #%u (skipping)\n",
-                err_name,
-                err_line);
-    json_dumpf (in,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    json_decref (keys);
-    return;
-  }
-  if (0 !=
-      GNUNET_memcmp (&master_pub,
-                     &mpub))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Fatal: donau uses different master key!\n");
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    json_decref (keys);
-    return;
-  }
-  if (GNUNET_SYSERR ==
-      tofu_check (&secmset))
-  {
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    json_decref (keys);
-    return;
-  }
-  if ( (GNUNET_OK !=
-        show_signkeys (&secmset.eddsa,
-                       signkeys)) ||
-       (GNUNET_OK !=
-        show_denomkeys (&secmset.rsa,
-                        &secmset.cs,
-                        denomkeys)) )
-  {
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    json_decref (keys);
-    return;
-  }
-  json_decref (keys);
-  next (args);
-}
-
-
-/**
- * Sign @a signkeys with offline key.
- *
- * @param secm_pub security module public key used to sign the denominations
- * @param signkeys keys to output
- * @param[in,out] result array where to output the signatures
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-sign_signkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
-               const json_t *signkeys,
-               json_t *result)
-{
-  size_t index;
-  json_t *value;
-
-  json_array_foreach (signkeys, index, value) {
-    const char *err_name;
-    unsigned int err_line;
-    struct DONAU_DonauPublicKeyP donau_pub;
-    struct TALER_SecurityModuleSignatureP secm_sig;
-    struct GNUNET_TIME_Timestamp start_time;
-    struct GNUNET_TIME_Timestamp sign_end;
-    struct GNUNET_TIME_Timestamp legal_end;
-    struct GNUNET_TIME_Relative duration;
-    struct GNUNET_JSON_Specification spec[] = {
-      GNUNET_JSON_spec_timestamp ("stamp_start",
-                                  &start_time),
-      GNUNET_JSON_spec_timestamp ("stamp_expire",
-                                  &sign_end),
-      GNUNET_JSON_spec_timestamp ("stamp_end",
-                                  &legal_end),
-      GNUNET_JSON_spec_fixed_auto ("key",
-                                   &donau_pub),
-      GNUNET_JSON_spec_fixed_auto ("signkey_secmod_sig",
-                                   &secm_sig),
-      GNUNET_JSON_spec_end ()
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_JSON_parse (value,
-                           spec,
-                           &err_name,
-                           &err_line))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid input for signing key to 'show': %s #%u at %u 
(skipping)\n",
-                  err_name,
-                  err_line,
-                  (unsigned int) index);
-      json_dumpf (value,
-                  stderr,
-                  JSON_INDENT (2));
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return GNUNET_SYSERR;
-    }
-
-    duration = GNUNET_TIME_absolute_get_difference (start_time.abs_time,
-                                                    sign_end.abs_time);
-    if (GNUNET_OK !=
-        TALER_donau_secmod_eddsa_verify (&donau_pub,
-                                         start_time,
-                                         duration,
-                                         secm_pub,
-                                         &secm_sig))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid security module signature for signing key %s 
(aborting)\n",
-                  TALER_B2S (&donau_pub));
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      GNUNET_JSON_parse_free (spec);
-      return GNUNET_SYSERR;
-    }
-    {
-      struct TALER_MasterSignatureP master_sig;
-
-      TALER_donau_offline_signkey_validity_sign (&donau_pub,
-                                                 start_time,
-                                                 sign_end,
-                                                 legal_end,
-                                                 &master_priv,
-                                                 &master_sig);
-      GNUNET_assert (0 ==
-                     json_array_append_new (
-                       result,
-                       GNUNET_JSON_PACK (
-                         GNUNET_JSON_pack_data_auto ("donau_pub",
-                                                     &donau_pub),
-                         GNUNET_JSON_pack_data_auto ("master_sig",
-                                                     &master_sig))));
-    }
-    GNUNET_JSON_parse_free (spec);
-  }
-  return GNUNET_OK;
-}
-
-
-/**
- * Looks up the AGE_RESTRICTED setting for a denomination in the config and
- * returns the age restriction (mask) accordingly.
- *
- * @param section_name Section in the configuration for the particular
- *    denomination.
- */
-static struct TALER_AgeMask
-load_age_mask (const char*section_name)
-{
-  static const struct TALER_AgeMask null_mask = {0};
-  enum GNUNET_GenericReturnValue ret;
-
-  if (! ar_enabled)
-    return null_mask;
-
-  if (GNUNET_OK != (GNUNET_CONFIGURATION_have_value (
-                      kcfg,
-                      section_name,
-                      "AGE_RESTRICTED")))
-    return null_mask;
-
-  ret = GNUNET_CONFIGURATION_get_value_yesno (kcfg,
-                                              section_name,
-                                              "AGE_RESTRICTED");
-  if (GNUNET_SYSERR == ret)
-    GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
-                               section_name,
-                               "AGE_RESTRICTED",
-                               "Value must be YES or NO\n");
-  if (GNUNET_YES == ret)
-    return ar_config.mask;
-
-  return null_mask;
-}
-
-
-/**
- * Sign @a denomkeys with offline key.
- *
- * @param secm_pub_rsa security module public key used to sign the RSA 
denominations
- * @param secm_pub_cs security module public key used to sign the CS 
denominations
- * @param denomkeys keys to output
- * @param[in,out] result array where to output the signatures
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub_rsa,
-                const struct TALER_SecurityModulePublicKeyP *secm_pub_cs,
-                const json_t *denomkeys,
-                json_t *result)
-{
-  size_t index;
-  json_t *value;
-
-  json_array_foreach (denomkeys, index, value) {
-    const char *err_name;
-    unsigned int err_line;
-    const char *section_name;
-    struct TALER_DenominationPublicKey denom_pub;
-    struct GNUNET_TIME_Timestamp stamp_start;
-    struct GNUNET_TIME_Timestamp stamp_expire_withdraw;
-    struct GNUNET_TIME_Timestamp stamp_expire_deposit;
-    struct GNUNET_TIME_Timestamp stamp_expire_legal;
-    struct TALER_Amount coin_value;
-    struct TALER_DenomFeeSet fees;
-    struct TALER_SecurityModuleSignatureP secm_sig;
-    struct GNUNET_JSON_Specification spec[] = {
-      GNUNET_JSON_spec_string ("section_name",
-                               &section_name),
-      TALER_JSON_spec_denom_pub ("denom_pub",
-                                 &denom_pub),
-      TALER_JSON_spec_amount ("value",
-                              currency,
-                              &coin_value),
-      TALER_JSON_SPEC_DENOM_FEES ("fee",
-                                  currency,
-                                  &fees),
-      GNUNET_JSON_spec_timestamp ("stamp_start",
-                                  &stamp_start),
-      GNUNET_JSON_spec_timestamp ("stamp_expire_withdraw",
-                                  &stamp_expire_withdraw),
-      GNUNET_JSON_spec_timestamp ("stamp_expire_deposit",
-                                  &stamp_expire_deposit),
-      GNUNET_JSON_spec_timestamp ("stamp_expire_legal",
-                                  &stamp_expire_legal),
-      GNUNET_JSON_spec_fixed_auto ("denom_secmod_sig",
-                                   &secm_sig),
-      GNUNET_JSON_spec_end ()
-    };
-    struct GNUNET_TIME_Relative duration;
-    struct TALER_DenominationHashP h_denom_pub;
-
-    if (GNUNET_OK !=
-        GNUNET_JSON_parse (value,
-                           spec,
-                           &err_name,
-                           &err_line))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid input for denomination key to 'sign': %s #%u at %u 
(skipping)\n",
-                  err_name,
-                  err_line,
-                  (unsigned int) index);
-      json_dumpf (value,
-                  stderr,
-                  JSON_INDENT (2));
-      GNUNET_JSON_parse_free (spec);
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      return GNUNET_SYSERR;
-    }
-    duration = GNUNET_TIME_absolute_get_difference (
-      stamp_start.abs_time,
-      stamp_expire_withdraw.abs_time);
-
-    /* Load the age mask, if applicable to this denomination */
-    denom_pub.age_mask = load_age_mask (section_name);
-
-    TALER_denom_pub_hash (&denom_pub,
-                          &h_denom_pub);
-    switch (denom_pub.cipher)
-    {
-    case TALER_DENOMINATION_RSA:
-      {
-        struct TALER_RsaPubHashP h_rsa;
-
-        TALER_rsa_pub_hash (denom_pub.details.rsa_public_key,
-                            &h_rsa);
-        if (GNUNET_OK !=
-            TALER_donau_secmod_rsa_verify (&h_rsa,
-                                           section_name,
-                                           stamp_start,
-                                           duration,
-                                           secm_pub_rsa,
-                                           &secm_sig))
-        {
-          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                      "Invalid security module signature for denomination key 
%s (aborting)\n",
-                      GNUNET_h2s (&h_denom_pub.hash));
-          global_ret = EXIT_FAILURE;
-          test_shutdown ();
-          GNUNET_JSON_parse_free (spec);
-          return GNUNET_SYSERR;
-        }
-      }
-      break;
-    case TALER_DENOMINATION_CS:
-      {
-        struct TALER_CsPubHashP h_cs;
-
-        TALER_cs_pub_hash (&denom_pub.details.cs_public_key,
-                           &h_cs);
-        if (GNUNET_OK !=
-            TALER_donau_secmod_cs_verify (&h_cs,
-                                          section_name,
-                                          stamp_start,
-                                          duration,
-                                          secm_pub_cs,
-                                          &secm_sig))
-        {
-          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                      "Invalid security module signature for denomination key 
%s (aborting)\n",
-                      GNUNET_h2s (&h_denom_pub.hash));
-          global_ret = EXIT_FAILURE;
-          test_shutdown ();
-          GNUNET_JSON_parse_free (spec);
-          return GNUNET_SYSERR;
-        }
-      }
-      break;
-    default:
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      GNUNET_JSON_parse_free (spec);
-      return GNUNET_SYSERR;
-    }
-
-    {
-      struct TALER_MasterSignatureP master_sig;
-
-      TALER_donau_offline_denom_validity_sign (&h_denom_pub,
-                                               stamp_start,
-                                               stamp_expire_withdraw,
-                                               stamp_expire_deposit,
-                                               stamp_expire_legal,
-                                               &coin_value,
-                                               &fees,
-                                               &master_priv,
-                                               &master_sig);
-      GNUNET_assert (0 ==
-                     json_array_append_new (
-                       result,
-                       GNUNET_JSON_PACK (
-                         GNUNET_JSON_pack_data_auto ("h_denom_pub",
-                                                     &h_denom_pub),
-                         GNUNET_JSON_pack_data_auto ("master_sig",
-                                                     &master_sig))));
-    }
-    GNUNET_JSON_parse_free (spec);
-  }
-  return GNUNET_OK;
-}
-
-
-/**
- * Sign future keys.
- *
- * @param args the array of command-line arguments to process next
- */
-static void
-do_sign (char *const *args)
-{
-  json_t *keys;
-  const char *err_name;
-  unsigned int err_line;
-  const json_t *denomkeys;
-  const json_t *signkeys;
-  struct TALER_MasterPublicKeyP mpub;
-  struct TALER_SecurityModulePublicKeySetP secmset;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_array_const ("future_denoms",
-                                  &denomkeys),
-    GNUNET_JSON_spec_array_const ("future_signkeys",
-                                  &signkeys),
-    GNUNET_JSON_spec_fixed_auto ("master_pub",
-                                 &mpub),
-    GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
-                                 &secmset.rsa),
-    GNUNET_JSON_spec_fixed_auto ("denom_secmod_cs_public_key",
-                                 &secmset.cs),
-    GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
-                                 &secmset.eddsa),
-    GNUNET_JSON_spec_end ()
-  };
-
-  keys = parse_keys_input ("sign");
-  if (NULL == keys)
-    return;
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-  {
-    json_decref (keys);
-    return;
-  }
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (keys,
-                         spec,
-                         &err_name,
-                         &err_line))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Invalid input to 'sign' : %s #%u (skipping)\n",
-                err_name,
-                err_line);
-    json_dumpf (in,
-                stderr,
-                JSON_INDENT (2));
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    json_decref (keys);
-    return;
-  }
-  if (0 !=
-      GNUNET_memcmp (&master_pub,
-                     &mpub))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Fatal: donau uses different master key!\n");
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    json_decref (keys);
-    return;
-  }
-  if (GNUNET_SYSERR ==
-      tofu_check (&secmset))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Fatal: security module keys changed!\n");
-    global_ret = EXIT_FAILURE;
-    test_shutdown ();
-    json_decref (keys);
-    return;
-  }
-  {
-    json_t *signkey_sig_array = json_array ();
-    json_t *denomkey_sig_array = json_array ();
-
-    GNUNET_assert (NULL != signkey_sig_array);
-    GNUNET_assert (NULL != denomkey_sig_array);
-    if ( (GNUNET_OK !=
-          sign_signkeys (&secmset.eddsa,
-                         signkeys,
-                         signkey_sig_array)) ||
-         (GNUNET_OK !=
-          sign_denomkeys (&secmset.rsa,
-                          &secmset.cs,
-                          denomkeys,
-                          denomkey_sig_array)) )
-    {
-      global_ret = EXIT_FAILURE;
-      test_shutdown ();
-      json_decref (signkey_sig_array);
-      json_decref (denomkey_sig_array);
-      json_decref (keys);
-      return;
-    }
-
-    output_operation (OP_UPLOAD_SIGS,
-                      GNUNET_JSON_PACK (
-                        GNUNET_JSON_pack_array_steal ("denom_sigs",
-                                                      denomkey_sig_array),
-                        GNUNET_JSON_pack_array_steal ("signkey_sigs",
-                                                      signkey_sig_array)));
-  }
-  json_decref (keys);
-  next (args);
-}
-
-
-/**
- * Setup and output offline signing key.
- *
- * @param args the array of command-line arguments to process next
- */
-static void
-do_setup (char *const *args)
-{
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_YES))
-  {
-    global_ret = EXIT_NOPERMISSION;
-    return;
-  }
-  if (NULL != *args)
-  {
-    output_operation (OP_SETUP,
-                      GNUNET_JSON_PACK (
-                        GNUNET_JSON_pack_data_auto ("donau_offline_pub",
-                                                    &master_pub)));
-  }
-
-  else
-  {
-    char *pub_s;
-
-    pub_s = GNUNET_STRINGS_data_to_string_alloc (&master_pub,
-                                                 sizeof (master_pub));
-    fprintf (stdout,
-             "%s\n",
-             pub_s);
-    GNUNET_free (pub_s);
-  }
-  if ( (NULL != *args) &&
-       (0 == strcmp (*args,
-                     "-")) )
-    args++;
-  next (args);
-}
-
-
-/**
- * Print the current extensions as configured
- *
- * @param args the array of command-line arguments to process next
- */
-static void
-do_extensions_show (char *const *args)
-{
-  const struct TALER_Extensions *it;
-  json_t *exts = json_object ();
-  json_t *obj;
-
-  GNUNET_assert (NULL != exts);
-  for (it = TALER_extensions_get_head ();
-       NULL != it && NULL != it->extension;
-       it = it->next)
-  {
-    const struct TALER_Extension *extension = it->extension;
-    int ret;
-
-    ret = json_object_set_new (exts,
-                               extension->name,
-                               extension->manifest (extension));
-    GNUNET_assert (-1 != ret);
-  }
-
-  obj = GNUNET_JSON_PACK (
-    GNUNET_JSON_pack_object_steal ("extensions",
-                                   exts));
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "%s\n",
-              json_dumps (obj,
-                          JSON_INDENT (2)));
-  json_decref (obj);
-  next (args);
-}
-
-
-/**
- * Sign the configurations of the enabled extensions
- */
-static void
-do_extensions_sign (char *const *args)
-{
-  json_t *extensions = json_object ();
-  struct TALER_ExtensionManifestsHashP h_manifests;
-  struct TALER_MasterSignatureP sig;
-  const struct TALER_Extensions *it;
-  bool found = false;
-  json_t *obj;
-
-  GNUNET_assert (NULL != extensions);
-  for (it = TALER_extensions_get_head ();
-       NULL != it && NULL != it->extension;
-       it = it->next)
-  {
-    const struct TALER_Extension *ext = it->extension;
-    GNUNET_assert (ext);
-
-    found = true;
-
-    GNUNET_assert (0 ==
-                   json_object_set_new (extensions,
-                                        ext->name,
-                                        ext->manifest (ext)));
-  }
-
-  if (! found)
-    return;
-
-  if (GNUNET_OK !=
-      TALER_JSON_extensions_manifests_hash (extensions,
-                                            &h_manifests))
-  {
-    json_decref (extensions);
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "error while hashing manifest for extensions\n");
-    return;
-  }
-
-  if (GNUNET_OK !=
-      load_offline_key (GNUNET_NO))
-  {
-    json_decref (extensions);
-    return;
-  }
-
-  TALER_donau_offline_extension_manifests_hash_sign (&h_manifests,
-                                                     &master_priv,
-                                                     &sig);
-  obj = GNUNET_JSON_PACK (
-    GNUNET_JSON_pack_object_steal ("extensions",
-                                   extensions),
-    GNUNET_JSON_pack_data_auto (
-      "extensions_sig",
-      &sig));
-
-  output_operation (OP_EXTENSIONS,
-                    obj);
-  next (args);
-}
-
-
-/**
- * Dispatch @a args in the @a cmds array.
- *
- * @param args arguments with subcommand to dispatch
- * @param cmds array of possible subcommands to call
- */
-static void
-cmd_handler (char *const *args,
-             const struct SubCommand *cmds)
-{
-  nxt = NULL;
-  for (unsigned int i = 0; NULL != cmds[i].name; i++)
-  {
-    if (0 == strcasecmp (cmds[i].name,
-                         args[0]))
-    {
-      cmds[i].cb (&args[1]);
-      return;
-    }
-  }
-
-  if (0 != strcasecmp ("help",
-                       args[0]))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-                "Unexpected command `%s'\n",
-                args[0]);
-    global_ret = EXIT_INVALIDARGUMENT;
-  }
-
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "Supported subcommands:\n");
-  for (unsigned int i = 0; NULL != cmds[i].name; i++)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-                "- %s: %s\n",
-                cmds[i].name,
-                cmds[i].help);
-  }
-  json_decref (out);
-  out = NULL;
-  GNUNET_SCHEDULER_shutdown ();
-}
-
-
-static void
-do_work_extensions (char *const *args)
-{
-  struct SubCommand cmds[] = {
-    {
-      .name = "show",
-      .help =
-        "show the extensions in the Taler-config and their configured 
parameters",
-      .cb = &do_extensions_show
-    },
-    {
-      .name = "sign",
-      .help =
-        "sign the configuration of the extensions and publish it with the 
donau",
-      .cb = &do_extensions_sign
-    },
-    {
-      .name = NULL,
-    }
-  };
-
-  if (NULL == args[0])
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "You must provide a subcommand: `show` or `sign`.\n");
-    test_shutdown ();
-    global_ret = EXIT_INVALIDARGUMENT;
-    return;
-  }
-
-  cmd_handler (args, cmds);
-}
-
-
-static void
-work (void *cls)
-{
-  char *const *args = cls;
-  struct SubCommand cmds[] = {
-    {
-      .name = "setup",
-      .help =
-        "initialize offline key signing material and display public offline 
key",
-      .cb = &do_setup
-    },
-    {
-      .name = "download",
-      .help =
-        "obtain future public keys from donau (to be performed online!)",
-      .cb = &do_download
-    },
-    {
-      .name = "show",
-      .help =
-        "display future public keys from donau for human review (pass '-' as 
argument to disable consuming input)",
-      .cb = &do_show
-    },
-    {
-      .name = "sign",
-      .help = "sign all future public keys from the input",
-      .cb = &do_sign
-    },
-    {
-      .name = "revoke-denomination",
-      .help =
-        "revoke denomination key (hash of public key must be given as 
argument)",
-      .cb = &do_revoke_denomination_key
-    },
-    {
-      .name = "revoke-signkey",
-      .help =
-        "revoke donau online signing key (public key must be given as 
argument)",
-      .cb = &do_revoke_signkey
-    },
-    {
-      .name = "enable-auditor",
-      .help =
-        "enable auditor for the donau (auditor-public key, auditor-URI and 
auditor-name must be given as arguments)",
-      .cb = &do_add_auditor
-    },
-    {
-      .name = "disable-auditor",
-      .help =
-        "disable auditor at the donau (auditor-public key must be given as 
argument)",
-      .cb = &do_del_auditor
-    },
-    {
-      .name = "enable-account",
-      .help =
-        "enable wire account of the donau (payto-URI must be given as 
argument; for optional argument see man page)",
-      .cb = &do_add_wire
-    },
-    {
-      .name = "disable-account",
-      .help =
-        "disable wire account of the donau (payto-URI must be given as 
argument)",
-      .cb = &do_del_wire
-    },
-    {
-      .name = "wire-fee",
-      .help =
-        "sign wire fees for the given year (year, wire method, wire fee, and 
closing fee must be given as arguments)",
-      .cb = &do_set_wire_fee
-    },
-    {
-      .name = "global-fee",
-      .help =
-        "sign global fees for the given year (year, history fee, account fee, 
purse fee, purse timeout, history expiration and the maximum number of free 
purses per account must be given as arguments)",
-      .cb = &do_set_global_fee
-    },
-    {
-      .name = "drain",
-      .help =
-        "drain profits from donau escrow account to regular donau operator 
account (amount, debit account configuration section and credit account 
payto://-URI must be given as arguments)",
-      .cb = &do_drain
-    },
-    {
-      .name = "add-partner",
-      .help =
-        "add partner donau for P2P wad transfers (partner master public key, 
partner base URL, wad fee, wad frequency and validity year must be given as 
arguments)",
-      .cb = &do_add_partner
-    },
-    {
-      .name = "aml-enable",
-      .help =
-        "enable AML staff member (staff member public key, legal name and rw 
(read write) or ro (read only) must be given as arguments)",
-      .cb = &enable_aml_staff
-    },
-    {
-      .name = "aml-disable",
-      .help =
-        "disable AML staff member (staff member public key and legal name must 
be given as arguments)",
-      .cb = &disable_aml_staff
-    },
-    {
-      .name = "upload",
-      .help =
-        "upload operation result to donau (to be performed online!)",
-      .cb = &do_upload
-    },
-    {
-      .name = "extensions",
-      .help = "subcommands for extension handling",
-      .cb = &do_work_extensions
-    },
-    /* list terminator */
-    {
-      .name = NULL,
-    }
-  };
-  (void) cls;
-
-  cmd_handler (args, cmds);
-}
-
-
-/**
- * Main function that will be run.
- *
- * @param cls closure
- * @param args remaining command-line arguments
- * @param cfgfile name of the configuration file used (for saving, can be 
NULL!)
- * @param cfg configuration
- */
-static void
-run (void *cls,
-     char *const *args,
-     const char *cfgfile,
-     const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
-  (void) cls;
-  (void) cfgfile;
-  kcfg = cfg;
-
-  /* load extensions */
-  GNUNET_assert (GNUNET_OK ==
-                 TALER_extensions_init (kcfg));
-
-  /* setup age restriction, if applicable */
-  {
-    const struct TALER_AgeRestrictionConfig *arc;
-
-    if (NULL !=
-        (arc = TALER_extensions_get_age_restriction_config ()))
-    {
-      ar_config  = *arc;
-      ar_enabled = true;
-    }
-  }
-
-
-  if (GNUNET_OK !=
-      TALER_config_get_currency (kcfg,
-                                 &currency))
-  {
-    global_ret = EXIT_NOTCONFIGURED;
-    return;
-  }
-
-  ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
-                          &rc);
-  rc = GNUNET_CURL_gnunet_rc_create (ctx);
-  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
-                                 NULL);
-  next (args);
-}
-
-
-/**
- * The main function of the taler-donau-offline tool.  This tool is used to
- * create the signing and denomination keys for the donau.  It uses the
- * long-term offline private key and generates signatures with it. It also
- * supports online operations with the donau to download its input data and
- * to upload its results. Those online operations should be performed on
- * another machine in production!
- *
- * @param argc number of arguments from the command line
- * @param argv command line arguments
- * @return 0 ok, 1 on error
- */
+// static void
+// do_shutdown (void *cls)
+// {
+//   (void) cls;
+
+//   {
+//     struct AmlStaffRequest *asr;
+
+//     while (NULL != (asr = asr_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete AML staff update #%u\n",
+//                   (unsigned int) asr->idx);
+//       DONAU_management_update_aml_officer_cancel (asr->h);
+//       GNUNET_CONTAINER_DLL_remove (asr_head,
+//                                    asr_tail,
+//                                    asr);
+//       GNUNET_free (asr);
+//     }
+//   }
+//   {
+//     struct PartnerAddRequest *par;
+
+//     while (NULL != (par = par_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete partner add request #%u\n",
+//                   (unsigned int) par->idx);
+//       DONAU_management_add_partner_cancel (par->h);
+//       GNUNET_CONTAINER_DLL_remove (par_head,
+//                                    par_tail,
+//                                    par);
+//       GNUNET_free (par);
+//     }
+//   }
+//   {
+//     struct DenomRevocationRequest *drr;
+
+//     while (NULL != (drr = drr_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete denomination revocation #%u\n",
+//                   (unsigned int) drr->idx);
+//       DONAU_management_revoke_denomination_key_cancel (drr->h);
+//       GNUNET_CONTAINER_DLL_remove (drr_head,
+//                                    drr_tail,
+//                                    drr);
+//       GNUNET_free (drr);
+//     }
+//   }
+//   {
+//     struct SignkeyRevocationRequest *srr;
+
+//     while (NULL != (srr = srr_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete signkey revocation #%u\n",
+//                   (unsigned int) srr->idx);
+//       DONAU_management_revoke_signing_key_cancel (srr->h);
+//       GNUNET_CONTAINER_DLL_remove (srr_head,
+//                                    srr_tail,
+//                                    srr);
+//       GNUNET_free (srr);
+//     }
+//   }
+
+//   {
+//     struct AuditorAddRequest *aar;
+
+//     while (NULL != (aar = aar_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete auditor add #%u\n",
+//                   (unsigned int) aar->idx);
+//       DONAU_management_enable_auditor_cancel (aar->h);
+//       GNUNET_CONTAINER_DLL_remove (aar_head,
+//                                    aar_tail,
+//                                    aar);
+//       GNUNET_free (aar);
+//     }
+//   }
+//   {
+//     struct AuditorDelRequest *adr;
+
+//     while (NULL != (adr = adr_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete auditor del #%u\n",
+//                   (unsigned int) adr->idx);
+//       DONAU_management_disable_auditor_cancel (adr->h);
+//       GNUNET_CONTAINER_DLL_remove (adr_head,
+//                                    adr_tail,
+//                                    adr);
+//       GNUNET_free (adr);
+//     }
+//   }
+//   {
+//     struct WireAddRequest *war;
+
+//     while (NULL != (war = war_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete wire add #%u\n",
+//                   (unsigned int) war->idx);
+//       DONAU_management_enable_wire_cancel (war->h);
+//       GNUNET_CONTAINER_DLL_remove (war_head,
+//                                    war_tail,
+//                                    war);
+//       GNUNET_free (war);
+//     }
+//   }
+//   {
+//     struct WireDelRequest *wdr;
+
+//     while (NULL != (wdr = wdr_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete wire del #%u\n",
+//                   (unsigned int) wdr->idx);
+//       DONAU_management_disable_wire_cancel (wdr->h);
+//       GNUNET_CONTAINER_DLL_remove (wdr_head,
+//                                    wdr_tail,
+//                                    wdr);
+//       GNUNET_free (wdr);
+//     }
+//   }
+//   {
+//     struct WireFeeRequest *wfr;
+
+//     while (NULL != (wfr = wfr_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete wire fee #%u\n",
+//                   (unsigned int) wfr->idx);
+//       DONAU_management_set_wire_fees_cancel (wfr->h);
+//       GNUNET_CONTAINER_DLL_remove (wfr_head,
+//                                    wfr_tail,
+//                                    wfr);
+//       GNUNET_free (wfr);
+//     }
+//   }
+//   {
+//     struct GlobalFeeRequest *gfr;
+
+//     while (NULL != (gfr = gfr_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete global fee #%u\n",
+//                   (unsigned int) gfr->idx);
+//       DONAU_management_set_global_fees_cancel (gfr->h);
+//       GNUNET_CONTAINER_DLL_remove (gfr_head,
+//                                    gfr_tail,
+//                                    gfr);
+//       GNUNET_free (gfr);
+//     }
+//   }
+//   {
+//     struct UploadKeysRequest *ukr;
+
+//     while (NULL != (ukr = ukr_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete key signature upload #%u\n",
+//                   (unsigned int) ukr->idx);
+//       DONAU_post_management_keys_cancel (ukr->h);
+//       GNUNET_CONTAINER_DLL_remove (ukr_head,
+//                                    ukr_tail,
+//                                    ukr);
+//       GNUNET_free (ukr);
+//     }
+//   }
+//   {
+//     struct UploadExtensionsRequest *uer;
+
+//     while (NULL != (uer = uer_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete extensions signature upload #%u\n",
+//                   (unsigned int) uer->idx);
+//       DONAU_management_post_extensions_cancel (uer->h);
+//       GNUNET_CONTAINER_DLL_remove (uer_head,
+//                                    uer_tail,
+//                                    uer);
+//       GNUNET_free (uer);
+//     }
+//   }
+
+//   {
+//     struct DrainProfitsRequest *dpr;
+
+//     while (NULL != (dpr = dpr_head))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Aborting incomplete drain profits request #%u\n",
+//                   (unsigned int) dpr->idx);
+//       DONAU_management_drain_profits_cancel (dpr->h);
+//       GNUNET_CONTAINER_DLL_remove (dpr_head,
+//                                    dpr_tail,
+//                                    dpr);
+//       GNUNET_free (dpr);
+//     }
+//   }
+
+//   if (NULL != out)
+//   {
+//     json_dumpf (out,
+//                 stdout,
+//                 JSON_INDENT (2));
+//     json_decref (out);
+//     out = NULL;
+//   }
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+//                 "Input not consumed!\n");
+//     json_decref (in);
+//     in = NULL;
+//   }
+//   if (NULL != nxt)
+//   {
+//     GNUNET_SCHEDULER_cancel (nxt);
+//     nxt = NULL;
+//   }
+//   if (NULL != mgkh)
+//   {
+//     DONAU_get_management_keys_cancel (mgkh);
+//     mgkh = NULL;
+//   }
+//   if (NULL != ctx)
+//   {
+//     GNUNET_CURL_fini (ctx);
+//     ctx = NULL;
+//   }
+//   if (NULL != rc)
+//   {
+//     GNUNET_CURL_gnunet_rc_destroy (rc);
+//     rc = NULL;
+//   }
+// }
+
+
+// /**
+//  * Test if we should shut down because all tasks are done.
+//  */
+// static void
+// test_shutdown (void)
+// {
+//   if ( (NULL == drr_head) &&
+//        (NULL == par_head) &&
+//        (NULL == asr_head) &&
+//        (NULL == srr_head) &&
+//        (NULL == aar_head) &&
+//        (NULL == adr_head) &&
+//        (NULL == war_head) &&
+//        (NULL == wdr_head) &&
+//        (NULL == wfr_head) &&
+//        (NULL == gfr_head) &&
+//        (NULL == ukr_head) &&
+//        (NULL == uer_head) &&
+//        (NULL == dpr_head) &&
+//        (NULL == mgkh) &&
+//        (NULL == nxt) )
+//     GNUNET_SCHEDULER_shutdown ();
+// }
+
+
+// /**
+//  * Function to continue processing the next command.
+//  *
+//  * @param cls must be a `char *const*` with the array of
+//  *        command-line arguments to process next
+//  */
+// static void
+// work (void *cls);
+
+
+// /**
+//  * Function to schedule job to process the next command.
+//  *
+//  * @param args the array of command-line arguments to process next
+//  */
+// static void
+// next (char *const *args)
+// {
+//   GNUNET_assert (NULL == nxt);
+//   if (NULL == args[0])
+//   {
+//     test_shutdown ();
+//     return;
+//   }
+//   nxt = GNUNET_SCHEDULER_add_now (&work,
+//                                   (void *) args);
+// }
+
+
+// /**
+//  * Add an operation to the #out JSON array for processing later.
+//  *
+//  * @param op_name name of the operation
+//  * @param op_value values for the operation (consumed)
+//  */
+// static void
+// output_operation (const char *op_name,
+//                   json_t *op_value)
+// {
+//   json_t *action;
+
+//   GNUNET_break (NULL != op_value);
+//   if (NULL == out)
+//   {
+//     out = json_array ();
+//     GNUNET_assert (NULL != out);
+//   }
+//   action = GNUNET_JSON_PACK (
+//     GNUNET_JSON_pack_string ("operation",
+//                              op_name),
+//     GNUNET_JSON_pack_object_steal ("arguments",
+//                                    op_value));
+//   GNUNET_assert (0 ==
+//                  json_array_append_new (out,
+//                                         action));
+// }
+
+
+// /**
+//  * Information about a subroutine for an upload.
+//  */
+// struct UploadHandler
+// {
+//   /**
+//    * Key to trigger this subroutine.
+//    */
+//   const char *key;
+
+//   /**
+//    * Function implementing an upload.
+//    *
+//    * @param donau_url URL of the donau
+//    * @param idx index of the operation we are performing
+//    * @param value arguments to drive the upload.
+//    */
+//   void (*cb)(const char *donau_url,
+//              size_t idx,
+//              const json_t *value);
+
+// };
+
+
+// /**
+//  * Load the offline key (if not yet done). Triggers shutdown on failure.
+//  *
+//  * @param do_create #GNUNET_YES if the key may be created
+//  * @return #GNUNET_OK on success
+//  */
+// static enum GNUNET_GenericReturnValue
+// load_offline_key (int do_create)
+// {
+//   static bool done;
+//   int ret;
+//   char *fn;
+
+//   if (done)
+//     return GNUNET_OK;
+//   if (GNUNET_OK !=
+//       GNUNET_CONFIGURATION_get_value_filename (kcfg,
+//                                                "donau-offline",
+//                                                "MASTER_PRIV_FILE",
+//                                                &fn))
+//   {
+//     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+//                                "donau-offline",
+//                                "MASTER_PRIV_FILE");
+//     test_shutdown ();
+//     return GNUNET_SYSERR;
+//   }
+//   if (GNUNET_YES !=
+//       GNUNET_DISK_file_test (fn))
+//     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+//                 "Donau master private key `%s' does not exist yet, creating 
it!\n",
+//                 fn);
+//   ret = GNUNET_CRYPTO_eddsa_key_from_file (fn,
+//                                            do_create,
+//                                            &master_priv.eddsa_priv);
+//   if (GNUNET_SYSERR == ret)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Failed to initialize master key from file `%s': %s\n",
+//                 fn,
+//                 "could not create file");
+//     GNUNET_free (fn);
+//     test_shutdown ();
+//     return GNUNET_SYSERR;
+//   }
+//   GNUNET_free (fn);
+//   GNUNET_CRYPTO_eddsa_key_get_public (&master_priv.eddsa_priv,
+//                                       &master_pub.eddsa_pub);
+//   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+//               "Using master public key %s\n",
+//               TALER_B2S (&master_pub));
+//   done = true;
+//   return GNUNET_OK;
+// }
+
+
+// /**
+//  * Function called with information about the post revocation operation 
result.
+//  *
+//  * @param cls closure with a `struct DenomRevocationRequest`
+//  * @param dr response data
+//  */
+// static void
+// denom_revocation_cb (
+//   void *cls,
+//   const struct DONAU_ManagementRevokeDenominationResponse *dr)
+// {
+//   struct DenomRevocationRequest *drr = cls;
+//   const struct DONAU_HttpResponse *hr = &dr->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) drr->idx,
+//                 hr->http_status,
+//                 hr->hint,
+//                 TALER_JSON_get_error_hint (hr->reply));
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (drr_head,
+//                                drr_tail,
+//                                drr);
+//   GNUNET_free (drr);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload denomination revocation request data.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for denomination revocation
+//  */
+// static void
+// upload_denom_revocation (const char *donau_url,
+//                          size_t idx,
+//                          const json_t *value)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   struct TALER_DenominationHashP h_denom_pub;
+//   struct DenomRevocationRequest *drr;
+//   const char *err_name;
+//   unsigned int err_line;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
+//                                  &h_denom_pub),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input for denomination revocation: %s#%u at %u 
(skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   drr = GNUNET_new (struct DenomRevocationRequest);
+//   drr->idx = idx;
+//   drr->h =
+//     DONAU_management_revoke_denomination_key (ctx,
+//                                               donau_url,
+//                                               &h_denom_pub,
+//                                               &master_sig,
+//                                               &denom_revocation_cb,
+//                                               drr);
+//   GNUNET_CONTAINER_DLL_insert (drr_head,
+//                                drr_tail,
+//                                drr);
+// }
+
+
+// /**
+//  * Function called with information about the post revocation operation 
result.
+//  *
+//  * @param cls closure with a `struct SignkeyRevocationRequest`
+//  * @param sr response data
+//  */
+// static void
+// signkey_revocation_cb (
+//   void *cls,
+//   const struct DONAU_ManagementRevokeSigningKeyResponse *sr)
+// {
+//   struct SignkeyRevocationRequest *srr = cls;
+//   const struct DONAU_HttpResponse *hr = &sr->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) srr->idx,
+//                 hr->http_status,
+//                 hr->hint,
+//                 TALER_JSON_get_error_hint (hr->reply));
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (srr_head,
+//                                srr_tail,
+//                                srr);
+//   GNUNET_free (srr);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload signkey revocation request data.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for denomination revocation
+//  */
+// static void
+// upload_signkey_revocation (const char *donau_url,
+//                            size_t idx,
+//                            const json_t *value)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   struct DONAU_DonauPublicKeyP donau_pub;
+//   struct SignkeyRevocationRequest *srr;
+//   const char *err_name;
+//   unsigned int err_line;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_fixed_auto ("donau_pub",
+//                                  &donau_pub),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input for signkey revocation: %s#%u at %u 
(skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   srr = GNUNET_new (struct SignkeyRevocationRequest);
+//   srr->idx = idx;
+//   srr->h =
+//     DONAU_management_revoke_signing_key (ctx,
+//                                          donau_url,
+//                                          &donau_pub,
+//                                          &master_sig,
+//                                          &signkey_revocation_cb,
+//                                          srr);
+//   GNUNET_CONTAINER_DLL_insert (srr_head,
+//                                srr_tail,
+//                                srr);
+// }
+
+
+// /**
+//  * Function called with information about the post auditor add operation 
result.
+//  *
+//  * @param cls closure with a `struct AuditorAddRequest`
+//  * @param mer response data
+//  */
+// static void
+// auditor_add_cb (
+//   void *cls,
+//   const struct DONAU_ManagementAuditorEnableResponse *mer)
+// {
+//   struct AuditorAddRequest *aar = cls;
+//   const struct DONAU_HttpResponse *hr = &mer->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) aar->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (aar_head,
+//                                aar_tail,
+//                                aar);
+//   GNUNET_free (aar);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload auditor add data.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for denomination revocation
+//  */
+// static void
+// upload_auditor_add (const char *donau_url,
+//                     size_t idx,
+//                     const json_t *value)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   const char *auditor_url;
+//   const char *auditor_name;
+//   struct GNUNET_TIME_Timestamp start_time;
+//   struct TALER_AuditorPublicKeyP auditor_pub;
+//   struct AuditorAddRequest *aar;
+//   const char *err_name;
+//   unsigned int err_line;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_string ("auditor_url",
+//                              &auditor_url),
+//     GNUNET_JSON_spec_string ("auditor_name",
+//                              &auditor_name),
+//     GNUNET_JSON_spec_timestamp ("validity_start",
+//                                 &start_time),
+//     GNUNET_JSON_spec_fixed_auto ("auditor_pub",
+//                                  &auditor_pub),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input for adding auditor: %s#%u at %u 
(skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   aar = GNUNET_new (struct AuditorAddRequest);
+//   aar->idx = idx;
+//   aar->h =
+//     DONAU_management_enable_auditor (ctx,
+//                                      donau_url,
+//                                      &auditor_pub,
+//                                      auditor_url,
+//                                      auditor_name,
+//                                      start_time,
+//                                      &master_sig,
+//                                      &auditor_add_cb,
+//                                      aar);
+//   GNUNET_CONTAINER_DLL_insert (aar_head,
+//                                aar_tail,
+//                                aar);
+// }
+
+
+// /**
+//  * Function called with information about the post auditor del operation 
result.
+//  *
+//  * @param cls closure with a `struct AuditorDelRequest`
+//  * @param mdr response data
+//  */
+// static void
+// auditor_del_cb (void *cls,
+//                 const struct
+//                 DONAU_ManagementAuditorDisableResponse *mdr)
+// {
+//   struct AuditorDelRequest *adr = cls;
+//   const struct DONAU_HttpResponse *hr = &mdr->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) adr->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (adr_head,
+//                                adr_tail,
+//                                adr);
+//   GNUNET_free (adr);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload auditor del data.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for denomination revocation
+//  */
+// static void
+// upload_auditor_del (const char *donau_url,
+//                     size_t idx,
+//                     const json_t *value)
+// {
+//   struct TALER_AuditorPublicKeyP auditor_pub;
+//   struct TALER_MasterSignatureP master_sig;
+//   struct GNUNET_TIME_Timestamp end_time;
+//   struct AuditorDelRequest *adr;
+//   const char *err_name;
+//   unsigned int err_line;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_fixed_auto ("auditor_pub",
+//                                  &auditor_pub),
+//     GNUNET_JSON_spec_timestamp ("validity_end",
+//                                 &end_time),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to disable auditor: %s#%u at %u 
(skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   adr = GNUNET_new (struct AuditorDelRequest);
+//   adr->idx = idx;
+//   adr->h =
+//     DONAU_management_disable_auditor (ctx,
+//                                       donau_url,
+//                                       &auditor_pub,
+//                                       end_time,
+//                                       &master_sig,
+//                                       &auditor_del_cb,
+//                                       adr);
+//   GNUNET_CONTAINER_DLL_insert (adr_head,
+//                                adr_tail,
+//                                adr);
+// }
+
+
+// /**
+//  * Function called with information about the post wire add operation 
result.
+//  *
+//  * @param cls closure with a `struct WireAddRequest`
+//  * @param wer response data
+//  */
+// static void
+// wire_add_cb (void *cls,
+//              const struct DONAU_ManagementWireEnableResponse *wer)
+// {
+//   struct WireAddRequest *war = cls;
+//   const struct DONAU_HttpResponse *hr = &wer->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) war->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (war_head,
+//                                war_tail,
+//                                war);
+//   GNUNET_free (war);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload wire add data.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for denomination revocation
+//  */
+// static void
+// upload_wire_add (const char *donau_url,
+//                  size_t idx,
+//                  const json_t *value)
+// {
+//   struct TALER_MasterSignatureP master_sig_add;
+//   struct TALER_MasterSignatureP master_sig_wire;
+//   const char *payto_uri;
+//   struct GNUNET_TIME_Timestamp start_time;
+//   struct WireAddRequest *war;
+//   const char *err_name;
+//   const char *conversion_url = NULL;
+//   const json_t *debit_restrictions;
+//   const json_t *credit_restrictions;
+//   unsigned int err_line;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_string ("payto_uri",
+//                              &payto_uri),
+//     GNUNET_JSON_spec_mark_optional (
+//       GNUNET_JSON_spec_string ("conversion_url",
+//                                &conversion_url),
+//       NULL),
+//     GNUNET_JSON_spec_array_const ("debit_restrictions",
+//                                   &debit_restrictions),
+//     GNUNET_JSON_spec_array_const ("credit_restrictions",
+//                                   &credit_restrictions),
+//     GNUNET_JSON_spec_timestamp ("validity_start",
+//                                 &start_time),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig_add",
+//                                  &master_sig_add),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig_wire",
+//                                  &master_sig_wire),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input for adding wire account: %s#%u at %u 
(skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   {
+//     char *wire_method;
+
+//     wire_method = TALER_payto_get_method (payto_uri);
+//     if (NULL == wire_method)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "payto:// URI `%s' is malformed\n",
+//                   payto_uri);
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return;
+//     }
+//     GNUNET_free (wire_method);
+//   }
+//   {
+//     char *msg = TALER_payto_validate (payto_uri);
+
+//     if (NULL != msg)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "payto URI is malformed: %s\n",
+//                   msg);
+//       GNUNET_free (msg);
+//       test_shutdown ();
+//       global_ret = EXIT_INVALIDARGUMENT;
+//       return;
+//     }
+//   }
+//   war = GNUNET_new (struct WireAddRequest);
+//   war->idx = idx;
+//   war->h =
+//     DONAU_management_enable_wire (ctx,
+//                                   donau_url,
+//                                   payto_uri,
+//                                   conversion_url,
+//                                   debit_restrictions,
+//                                   credit_restrictions,
+//                                   start_time,
+//                                   &master_sig_add,
+//                                   &master_sig_wire,
+//                                   &wire_add_cb,
+//                                   war);
+//   GNUNET_CONTAINER_DLL_insert (war_head,
+//                                war_tail,
+//                                war);
+// }
+
+
+// /**
+//  * Function called with information about the post wire del operation 
result.
+//  *
+//  * @param cls closure with a `struct WireDelRequest`
+//  * @param wdres response data
+//  */
+// static void
+// wire_del_cb (void *cls,
+//              const struct DONAU_ManagementWireDisableResponse *wdres)
+// {
+//   struct WireDelRequest *wdr = cls;
+//   const struct DONAU_HttpResponse *hr = &wdres->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) wdr->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (wdr_head,
+//                                wdr_tail,
+//                                wdr);
+//   GNUNET_free (wdr);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload wire del data.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for denomination revocation
+//  */
+// static void
+// upload_wire_del (const char *donau_url,
+//                  size_t idx,
+//                  const json_t *value)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   const char *payto_uri;
+//   struct GNUNET_TIME_Timestamp end_time;
+//   struct WireDelRequest *wdr;
+//   const char *err_name;
+//   unsigned int err_line;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_string ("payto_uri",
+//                              &payto_uri),
+//     GNUNET_JSON_spec_timestamp ("validity_end",
+//                                 &end_time),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to disable wire account: %s#%u at %u 
(skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   wdr = GNUNET_new (struct WireDelRequest);
+//   wdr->idx = idx;
+//   wdr->h =
+//     DONAU_management_disable_wire (ctx,
+//                                    donau_url,
+//                                    payto_uri,
+//                                    end_time,
+//                                    &master_sig,
+//                                    &wire_del_cb,
+//                                    wdr);
+//   GNUNET_CONTAINER_DLL_insert (wdr_head,
+//                                wdr_tail,
+//                                wdr);
+// }
+
+
+// /**
+//  * Function called with information about the post wire fee operation 
result.
+//  *
+//  * @param cls closure with a `struct WireFeeRequest`
+//  * @param swr response data
+//  */
+// static void
+// wire_fee_cb (
+//   void *cls,
+//   const struct DONAU_ManagementSetWireFeeResponse *swr)
+// {
+//   struct WireFeeRequest *wfr = cls;
+//   const struct DONAU_HttpResponse *hr = &swr->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) wfr->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (wfr_head,
+//                                wfr_tail,
+//                                wfr);
+//   GNUNET_free (wfr);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload wire fee.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for denomination revocation
+//  */
+// static void
+// upload_wire_fee (const char *donau_url,
+//                  size_t idx,
+//                  const json_t *value)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   const char *wire_method;
+//   struct WireFeeRequest *wfr;
+//   const char *err_name;
+//   unsigned int err_line;
+//   struct TALER_WireFeeSet fees;
+//   struct GNUNET_TIME_Timestamp start_time;
+//   struct GNUNET_TIME_Timestamp end_time;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_string ("wire_method",
+//                              &wire_method),
+//     TALER_JSON_spec_amount ("wire_fee",
+//                             currency,
+//                             &fees.wire),
+//     TALER_JSON_spec_amount ("closing_fee",
+//                             currency,
+//                             &fees.closing),
+//     GNUNET_JSON_spec_timestamp ("start_time",
+//                                 &start_time),
+//     GNUNET_JSON_spec_timestamp ("end_time",
+//                                 &end_time),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to set wire fee: %s#%u at %u (skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   wfr = GNUNET_new (struct WireFeeRequest);
+//   wfr->idx = idx;
+//   wfr->h =
+//     DONAU_management_set_wire_fees (ctx,
+//                                     donau_url,
+//                                     wire_method,
+//                                     start_time,
+//                                     end_time,
+//                                     &fees,
+//                                     &master_sig,
+//                                     &wire_fee_cb,
+//                                     wfr);
+//   GNUNET_CONTAINER_DLL_insert (wfr_head,
+//                                wfr_tail,
+//                                wfr);
+// }
+
+
+// /**
+//  * Function called with information about the post global fee operation 
result.
+//  *
+//  * @param cls closure with a `struct WireFeeRequest`
+//  * @param gr response data
+//  */
+// static void
+// global_fee_cb (
+//   void *cls,
+//   const struct DONAU_ManagementSetGlobalFeeResponse *gr)
+// {
+//   struct GlobalFeeRequest *gfr = cls;
+//   const struct DONAU_HttpResponse *hr = &gr->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) gfr->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (gfr_head,
+//                                gfr_tail,
+//                                gfr);
+//   GNUNET_free (gfr);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload global fee.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for denomination revocation
+//  */
+// static void
+// upload_global_fee (const char *donau_url,
+//                    size_t idx,
+//                    const json_t *value)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   struct GlobalFeeRequest *gfr;
+//   const char *err_name;
+//   unsigned int err_line;
+//   struct TALER_GlobalFeeSet fees;
+//   struct GNUNET_TIME_Timestamp start_time;
+//   struct GNUNET_TIME_Timestamp end_time;
+//   struct GNUNET_TIME_Relative purse_timeout;
+//   struct GNUNET_TIME_Relative history_expiration;
+//   uint32_t purse_account_limit;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     TALER_JSON_spec_amount ("history_fee",
+//                             currency,
+//                             &fees.history),
+//     TALER_JSON_spec_amount ("account_fee",
+//                             currency,
+//                             &fees.account),
+//     TALER_JSON_spec_amount ("purse_fee",
+//                             currency,
+//                             &fees.purse),
+//     GNUNET_JSON_spec_relative_time ("purse_timeout",
+//                                     &purse_timeout),
+//     GNUNET_JSON_spec_relative_time ("history_expiration",
+//                                     &history_expiration),
+//     GNUNET_JSON_spec_uint32 ("purse_account_limit",
+//                              &purse_account_limit),
+//     GNUNET_JSON_spec_timestamp ("start_time",
+//                                 &start_time),
+//     GNUNET_JSON_spec_timestamp ("end_time",
+//                                 &end_time),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to set wire fee: %s#%u at %u (skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   gfr = GNUNET_new (struct GlobalFeeRequest);
+//   gfr->idx = idx;
+//   gfr->h =
+//     DONAU_management_set_global_fees (ctx,
+//                                       donau_url,
+//                                       start_time,
+//                                       end_time,
+//                                       &fees,
+//                                       purse_timeout,
+//                                       history_expiration,
+//                                       purse_account_limit,
+//                                       &master_sig,
+//                                       &global_fee_cb,
+//                                       gfr);
+//   GNUNET_CONTAINER_DLL_insert (gfr_head,
+//                                gfr_tail,
+//                                gfr);
+// }
+
+
+// /**
+//  * Function called with information about the drain profits operation.
+//  *
+//  * @param cls closure with a `struct DrainProfitsRequest`
+//  * @param mdr response data
+//  */
+// static void
+// drain_profits_cb (
+//   void *cls,
+//   const struct DONAU_ManagementDrainResponse *mdr)
+// {
+//   struct DrainProfitsRequest *dpr = cls;
+//   const struct DONAU_HttpResponse *hr = &mdr->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) dpr->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (dpr_head,
+//                                dpr_tail,
+//                                dpr);
+//   GNUNET_free (dpr);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload drain profit action.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for drain profits
+//  */
+// static void
+// upload_drain (const char *donau_url,
+//               size_t idx,
+//               const json_t *value)
+// {
+//   struct TALER_WireTransferIdentifierRawP wtid;
+//   struct TALER_MasterSignatureP master_sig;
+//   const char *err_name;
+//   unsigned int err_line;
+//   struct TALER_Amount amount;
+//   struct GNUNET_TIME_Timestamp date;
+//   const char *payto_uri;
+//   const char *account_section;
+//   struct DrainProfitsRequest *dpr;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_fixed_auto ("wtid",
+//                                  &wtid),
+//     TALER_JSON_spec_amount ("amount",
+//                             currency,
+//                             &amount),
+//     GNUNET_JSON_spec_timestamp ("date",
+//                                 &date),
+//     GNUNET_JSON_spec_string ("account_section",
+//                              &account_section),
+//     GNUNET_JSON_spec_string ("payto_uri",
+//                              &payto_uri),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to drain profits: %s#%u at %u (skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   dpr = GNUNET_new (struct DrainProfitsRequest);
+//   dpr->idx = idx;
+//   dpr->h =
+//     DONAU_management_drain_profits (ctx,
+//                                     donau_url,
+//                                     &wtid,
+//                                     &amount,
+//                                     date,
+//                                     account_section,
+//                                     payto_uri,
+//                                     &master_sig,
+//                                     &drain_profits_cb,
+//                                     dpr);
+//   GNUNET_CONTAINER_DLL_insert (dpr_head,
+//                                dpr_tail,
+//                                dpr);
+// }
+
+
+// /**
+//  * Function called with information about the post upload keys operation 
result.
+//  *
+//  * @param cls closure with a `struct UploadKeysRequest`
+//  * @param mr response data
+//  */
+// static void
+// keys_cb (
+//   void *cls,
+//   const struct DONAU_ManagementPostKeysResponse *mr)
+// {
+//   struct UploadKeysRequest *ukr = cls;
+//   const struct DONAU_HttpResponse *hr = &mr->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) ukr->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (ukr_head,
+//                                ukr_tail,
+//                                ukr);
+//   GNUNET_free (ukr);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload (denomination and signing) key master signatures.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for POSTing keys
+//  */
+// static void
+// upload_keys (const char *donau_url,
+//              size_t idx,
+//              const json_t *value)
+// {
+//   struct DONAU_ManagementPostKeysData pkd;
+//   struct UploadKeysRequest *ukr;
+//   const char *err_name;
+//   unsigned int err_line;
+//   const json_t *denom_sigs;
+//   const json_t *signkey_sigs;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_array_const ("denom_sigs",
+//                                   &denom_sigs),
+//     GNUNET_JSON_spec_array_const ("signkey_sigs",
+//                                   &signkey_sigs),
+//     GNUNET_JSON_spec_end ()
+//   };
+//   bool ok = true;
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to 'upload': %s#%u (skipping)\n",
+//                 err_name,
+//                 err_line);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   pkd.num_sign_sigs = json_array_size (signkey_sigs);
+//   pkd.num_denom_sigs = json_array_size (denom_sigs);
+//   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+//               "Uploading %u denomination and %u signing key signatures\n",
+//               pkd.num_denom_sigs,
+//               pkd.num_sign_sigs);
+//   pkd.sign_sigs = GNUNET_new_array (
+//     pkd.num_sign_sigs,
+//     struct DONAU_SigningKeySignature);
+//   pkd.denom_sigs = GNUNET_new_array (
+//     pkd.num_denom_sigs,
+//     struct DONAU_DenominationKeySignature);
+//   for (unsigned int i = 0; i<pkd.num_sign_sigs; i++)
+//   {
+//     struct DONAU_SigningKeySignature *ss = &pkd.sign_sigs[i];
+//     json_t *val = json_array_get (signkey_sigs,
+//                                   i);
+//     struct GNUNET_JSON_Specification spec[] = {
+//       GNUNET_JSON_spec_fixed_auto ("donau_pub",
+//                                    &ss->donau_pub),
+//       GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                    &ss->master_sig),
+//       GNUNET_JSON_spec_end ()
+//     };
+
+//     if (GNUNET_OK !=
+//         GNUNET_JSON_parse (val,
+//                            spec,
+//                            &err_name,
+//                            &err_line))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid input for signkey validity: %s#%u at %u 
(aborting)\n",
+//                   err_name,
+//                   err_line,
+//                   i);
+//       json_dumpf (val,
+//                   stderr,
+//                   JSON_INDENT (2));
+//       ok = false;
+//     }
+//   }
+//   for (unsigned int i = 0; i<pkd.num_denom_sigs; i++)
+//   {
+//     struct DONAU_DenominationKeySignature *ds = &pkd.denom_sigs[i];
+//     json_t *val = json_array_get (denom_sigs,
+//                                   i);
+//     struct GNUNET_JSON_Specification spec[] = {
+//       GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
+//                                    &ds->h_denom_pub),
+//       GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                    &ds->master_sig),
+//       GNUNET_JSON_spec_end ()
+//     };
+
+//     if (GNUNET_OK !=
+//         GNUNET_JSON_parse (val,
+//                            spec,
+//                            &err_name,
+//                            &err_line))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid input for denomination validity: %s#%u at %u 
(aborting)\n",
+//                   err_name,
+//                   err_line,
+//                   i);
+//       json_dumpf (val,
+//                   stderr,
+//                   JSON_INDENT (2));
+//       ok = false;
+//     }
+//   }
+
+//   if (ok)
+//   {
+//     ukr = GNUNET_new (struct UploadKeysRequest);
+//     ukr->idx = idx;
+//     ukr->h =
+//       DONAU_post_management_keys (ctx,
+//                                   donau_url,
+//                                   &pkd,
+//                                   &keys_cb,
+//                                   ukr);
+//     GNUNET_CONTAINER_DLL_insert (ukr_head,
+//                                  ukr_tail,
+//                                  ukr);
+//   }
+//   else
+//   {
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//   }
+//   GNUNET_free (pkd.sign_sigs);
+//   GNUNET_free (pkd.denom_sigs);
+// }
+
+
+// /**
+//  * Function called with information about the post upload extensions 
operation result.
+//  *
+//  * @param cls closure with a `struct UploadExtensionsRequest`
+//  * @param er response data
+//  */
+// static void
+// extensions_cb (
+//   void *cls,
+//   const struct DONAU_ManagementPostExtensionsResponse *er)
+// {
+//   struct UploadExtensionsRequest *uer = cls;
+//   const struct DONAU_HttpResponse *hr = &er->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) uer->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (uer_head,
+//                                uer_tail,
+//                                uer);
+//   GNUNET_free (uer);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload extension configuration
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for POSTing configurations of extensions
+//  */
+// static void
+// upload_extensions (const char *donau_url,
+//                    size_t idx,
+//                    const json_t *value)
+// {
+//   const json_t *extensions;
+//   struct TALER_MasterSignatureP sig;
+//   const char *err_name;
+//   unsigned int err_line;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_object_const ("extensions",
+//                                    &extensions),
+//     GNUNET_JSON_spec_fixed_auto ("extensions_sig",
+//                                  &sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   /* 1. Parse the signed extensions */
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to set extensions: %s#%u at %u (skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+
+//   /* 2. Verify the signature */
+//   {
+//     struct TALER_ExtensionManifestsHashP h_manifests;
+
+//     if (GNUNET_OK !=
+//         TALER_JSON_extensions_manifests_hash (extensions,
+//                                               &h_manifests))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "couldn't hash extensions' manifests\n");
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return;
+//     }
+
+//     if (GNUNET_OK !=
+//         load_offline_key (GNUNET_NO))
+//       return;
+
+//     if (GNUNET_OK != TALER_donau_offline_extension_manifests_hash_verify (
+//           &h_manifests,
+//           &master_pub,
+//           &sig))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "invalid signature for extensions\n");
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return;
+//     }
+//   }
+
+//   /* 3. Upload the extensions */
+//   {
+//     struct DONAU_ManagementPostExtensionsData ped = {
+//       .extensions = extensions,
+//       .extensions_sig = sig,
+//     };
+//     struct UploadExtensionsRequest *uer
+//       = GNUNET_new (struct UploadExtensionsRequest);
+
+//     uer->idx = idx;
+//     uer->h = DONAU_management_post_extensions (
+//       ctx,
+//       donau_url,
+//       &ped,
+//       &extensions_cb,
+//       uer);
+//     GNUNET_CONTAINER_DLL_insert (uer_head,
+//                                  uer_tail,
+//                                  uer);
+//   }
+// }
+
+
+// /**
+//  * Function called with information about the add partner operation.
+//  *
+//  * @param cls closure with a `struct PartnerAddRequest`
+//  * @param apr response data
+//  */
+// static void
+// add_partner_cb (
+//   void *cls,
+//   const struct DONAU_ManagementAddPartnerResponse *apr)
+// {
+//   struct PartnerAddRequest *par = cls;
+//   const struct DONAU_HttpResponse *hr = &apr->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) par->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (par_head,
+//                                par_tail,
+//                                par);
+//   GNUNET_free (par);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Add partner action.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for add partner
+//  */
+// static void
+// add_partner (const char *donau_url,
+//              size_t idx,
+//              const json_t *value)
+// {
+//   struct TALER_MasterPublicKeyP partner_pub;
+//   struct GNUNET_TIME_Timestamp start_date;
+//   struct GNUNET_TIME_Timestamp end_date;
+//   struct GNUNET_TIME_Relative wad_frequency;
+//   struct TALER_Amount wad_fee;
+//   const char *partner_base_url;
+//   struct TALER_MasterSignatureP master_sig;
+//   struct PartnerAddRequest *par;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_fixed_auto ("partner_pub",
+//                                  &partner_pub),
+//     TALER_JSON_spec_amount ("wad_fee",
+//                             currency,
+//                             &wad_fee),
+//     GNUNET_JSON_spec_relative_time ("wad_frequency",
+//                                     &wad_frequency),
+//     GNUNET_JSON_spec_timestamp ("start_date",
+//                                 &start_date),
+//     GNUNET_JSON_spec_timestamp ("end_date",
+//                                 &end_date),
+//     GNUNET_JSON_spec_string ("partner_base_url",
+//                              &partner_base_url),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+//   const char *err_name;
+//   unsigned int err_line;
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to add partner: %s#%u at %u (skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   par = GNUNET_new (struct PartnerAddRequest);
+//   par->idx = idx;
+//   par->h =
+//     DONAU_management_add_partner (ctx,
+//                                   donau_url,
+//                                   &partner_pub,
+//                                   start_date,
+//                                   end_date,
+//                                   wad_frequency,
+//                                   &wad_fee,
+//                                   partner_base_url,
+//                                   &master_sig,
+//                                   &add_partner_cb,
+//                                   par);
+//   GNUNET_CONTAINER_DLL_insert (par_head,
+//                                par_tail,
+//                                par);
+// }
+
+
+// /**
+//  * Function called with information about the AML officer update operation.
+//  *
+//  * @param cls closure with a `struct AmlStaffRequest`
+//  * @param ar response data
+//  */
+// static void
+// update_aml_officer_cb (
+//   void *cls,
+//   const struct DONAU_ManagementUpdateAmlOfficerResponse *ar)
+// {
+//   struct AmlStaffRequest *asr = cls;
+//   const struct DONAU_HttpResponse *hr = &ar->hr;
+
+//   if (MHD_HTTP_NO_CONTENT != hr->http_status)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Upload failed for command %u with status %u: %s (%s)\n",
+//                 (unsigned int) asr->idx,
+//                 hr->http_status,
+//                 TALER_ErrorCode_get_hint (hr->ec),
+//                 hr->hint);
+//     global_ret = EXIT_FAILURE;
+//   }
+//   GNUNET_CONTAINER_DLL_remove (asr_head,
+//                                asr_tail,
+//                                asr);
+//   GNUNET_free (asr);
+//   test_shutdown ();
+// }
+
+
+// /**
+//  * Upload AML staff action.
+//  *
+//  * @param donau_url base URL of the donau
+//  * @param idx index of the operation we are performing (for logging)
+//  * @param value arguments for AML staff change
+//  */
+// static void
+// update_aml_staff (const char *donau_url,
+//                   size_t idx,
+//                   const json_t *value)
+// {
+//   struct TALER_AmlOfficerPublicKeyP officer_pub;
+//   const char *officer_name;
+//   struct GNUNET_TIME_Timestamp change_date;
+//   bool is_active;
+//   bool read_only;
+//   struct TALER_MasterSignatureP master_sig;
+//   struct AmlStaffRequest *asr;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_fixed_auto ("officer_pub",
+//                                  &officer_pub),
+//     GNUNET_JSON_spec_timestamp ("change_date",
+//                                 &change_date),
+//     GNUNET_JSON_spec_bool ("is_active",
+//                            &is_active),
+//     GNUNET_JSON_spec_bool ("read_only",
+//                            &read_only),
+//     GNUNET_JSON_spec_string ("officer_name",
+//                              &officer_name),
+//     GNUNET_JSON_spec_fixed_auto ("master_sig",
+//                                  &master_sig),
+//     GNUNET_JSON_spec_end ()
+//   };
+//   const char *err_name;
+//   unsigned int err_line;
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (value,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to AML staff update: %s#%u at %u 
(skipping)\n",
+//                 err_name,
+//                 err_line,
+//                 (unsigned int) idx);
+//     json_dumpf (value,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return;
+//   }
+//   asr = GNUNET_new (struct AmlStaffRequest);
+//   asr->idx = idx;
+//   asr->h =
+//     DONAU_management_update_aml_officer (ctx,
+//                                          donau_url,
+//                                          &officer_pub,
+//                                          officer_name,
+//                                          change_date,
+//                                          is_active,
+//                                          read_only,
+//                                          &master_sig,
+//                                          &update_aml_officer_cb,
+//                                          asr);
+//   GNUNET_CONTAINER_DLL_insert (asr_head,
+//                                asr_tail,
+//                                asr);
+// }
+
+
+// /**
+//  * Perform uploads based on the JSON in #out.
+//  *
+//  * @param donau_url base URL of the donau to use
+//  */
+// static void
+// trigger_upload (const char *donau_url)
+// {
+//   struct UploadHandler uhs[] = {
+//     {
+//       .key = OP_REVOKE_DENOMINATION,
+//       .cb = &upload_denom_revocation
+//     },
+//     {
+//       .key = OP_REVOKE_SIGNKEY,
+//       .cb = &upload_signkey_revocation
+//     },
+//     {
+//       .key = OP_ENABLE_AUDITOR,
+//       .cb = &upload_auditor_add
+//     },
+//     {
+//       .key = OP_DISABLE_AUDITOR,
+//       .cb = &upload_auditor_del
+//     },
+//     {
+//       .key = OP_ENABLE_WIRE,
+//       .cb = &upload_wire_add
+//     },
+//     {
+//       .key = OP_DISABLE_WIRE,
+//       .cb = &upload_wire_del
+//     },
+//     {
+//       .key = OP_SET_WIRE_FEE,
+//       .cb = &upload_wire_fee
+//     },
+//     {
+//       .key = OP_SET_GLOBAL_FEE,
+//       .cb = &upload_global_fee
+//     },
+//     {
+//       .key = OP_UPLOAD_SIGS,
+//       .cb = &upload_keys
+//     },
+//     {
+//       .key = OP_DRAIN_PROFITS,
+//       .cb = &upload_drain
+//     },
+//     {
+//       .key = OP_EXTENSIONS,
+//       .cb = &upload_extensions
+//     },
+//     {
+//       .key = OP_UPDATE_AML_STAFF,
+//       .cb = &update_aml_staff
+//     },
+//     {
+//       .key = OP_ADD_PARTNER,
+//       .cb = &add_partner
+//     },
+//     /* array termination */
+//     {
+//       .key = NULL
+//     }
+//   };
+//   size_t index;
+//   json_t *obj;
+
+//   json_array_foreach (out, index, obj) {
+//     bool found = false;
+//     const char *key;
+//     const json_t *value;
+
+//     key = json_string_value (json_object_get (obj, "operation"));
+//     value = json_object_get (obj, "arguments");
+//     if (NULL == key)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Malformed JSON input\n");
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return;
+//     }
+//     /* block of code that uses key and value */
+//     for (unsigned int i = 0; NULL != uhs[i].key; i++)
+//     {
+//       if (0 == strcasecmp (key,
+//                            uhs[i].key))
+//       {
+
+//         found = true;
+//         uhs[i].cb (donau_url,
+//                    index,
+//                    value);
+//         break;
+//       }
+//     }
+//     if (! found)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Upload does not know how to handle `%s'\n",
+//                   key);
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return;
+//     }
+//   }
+// }
+
+
+// /**
+//  * Upload operation result (signatures) to donau.
+//  *
+//  * @param args the array of command-line arguments to process next
+//  */
+// static void
+// do_upload (char *const *args)
+// {
+//   (void) args;
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, refusing upload\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if (NULL == out)
+//   {
+//     json_error_t err;
+
+//     out = json_loadf (stdin,
+//                       JSON_REJECT_DUPLICATES,
+//                       &err);
+//     if (NULL == out)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Failed to read JSON input: %s at %d:%s (offset: %d)\n",
+//                   err.text,
+//                   err.line,
+//                   err.source,
+//                   err.position);
+//       test_shutdown ();
+//       global_ret = EXIT_FAILURE;
+//       return;
+//     }
+//   }
+//   if (! json_is_array (out))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Error: expected JSON array for `upload` command\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == CFG_donau_url) &&
+//        (GNUNET_OK !=
+//         GNUNET_CONFIGURATION_get_value_string (kcfg,
+//                                                "donau",
+//                                                "BASE_URL",
+//                                                &CFG_donau_url)) )
+//   {
+//     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+//                                "donau",
+//                                "BASE_URL");
+//     global_ret = EXIT_NOTCONFIGURED;
+//     test_shutdown ();
+//     return;
+//   }
+//   trigger_upload (CFG_donau_url);
+//   json_decref (out);
+//   out = NULL;
+// }
+
+
+// /**
+//  * Revoke denomination key.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the hash of the denomination key to revoke
+//  */
+// static void
+// do_revoke_denomination_key (char *const *args)
+// {
+//   struct TALER_DenominationHashP h_denom_pub;
+//   struct TALER_MasterSignatureP master_sig;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, refusing revocation\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (GNUNET_OK !=
+//         GNUNET_STRINGS_string_to_data (args[0],
+//                                        strlen (args[0]),
+//                                        &h_denom_pub,
+//                                        sizeof (h_denom_pub))) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify a denomination key with this 
subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   TALER_donau_offline_denomination_revoke_sign (&h_denom_pub,
+//                                                 &master_priv,
+//                                                 &master_sig);
+//   output_operation (OP_REVOKE_DENOMINATION,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_data_auto ("h_denom_pub",
+//                                                   &h_denom_pub),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + 1);
+// }
+
+
+// /**
+//  * Revoke signkey.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the hash of the denomination key to revoke
+//  */
+// static void
+// do_revoke_signkey (char *const *args)
+// {
+//   struct DONAU_DonauPublicKeyP donau_pub;
+//   struct TALER_MasterSignatureP master_sig;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, refusing revocation\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (GNUNET_OK !=
+//         GNUNET_STRINGS_string_to_data (args[0],
+//                                        strlen (args[0]),
+//                                        &donau_pub,
+//                                        sizeof (donau_pub))) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify an donau signing key with this 
subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   TALER_donau_offline_signkey_revoke_sign (&donau_pub,
+//                                            &master_priv,
+//                                            &master_sig);
+//   output_operation (OP_REVOKE_SIGNKEY,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_data_auto ("donau_pub",
+//                                                   &donau_pub),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + 1);
+// }
+
+
+// /**
+//  * Add auditor.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the auditor's public key, args[1] the auditor's
+//  *        API base URL, and args[2] the auditor's name.
+//  */
+// static void
+// do_add_auditor (char *const *args)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   struct TALER_AuditorPublicKeyP auditor_pub;
+//   struct GNUNET_TIME_Timestamp now;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, not adding auditor\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (GNUNET_OK !=
+//         GNUNET_STRINGS_string_to_data (args[0],
+//                                        strlen (args[0]),
+//                                        &auditor_pub,
+//                                        sizeof (auditor_pub))) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify an auditor public key as first argument 
for this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+
+//   if ( (NULL == args[1]) ||
+//        (0 != strncmp ("http",
+//                       args[1],
+//                       strlen ("http"))) ||
+//        (NULL == args[2]) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify an auditor URI and auditor name as 2nd 
and 3rd arguments to this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   now = GNUNET_TIME_timestamp_get ();
+//   TALER_donau_offline_auditor_add_sign (&auditor_pub,
+//                                         args[1],
+//                                         now,
+//                                         &master_priv,
+//                                         &master_sig);
+//   output_operation (OP_ENABLE_AUDITOR,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_string ("auditor_url",
+//                                                args[1]),
+//                       GNUNET_JSON_pack_string ("auditor_name",
+//                                                args[2]),
+//                       GNUNET_JSON_pack_timestamp ("validity_start",
+//                                                   now),
+//                       GNUNET_JSON_pack_data_auto ("auditor_pub",
+//                                                   &auditor_pub),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + 3);
+// }
+
+
+// /**
+//  * Disable auditor account.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the hash of the denomination key to revoke
+//  */
+// static void
+// do_del_auditor (char *const *args)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   struct TALER_AuditorPublicKeyP auditor_pub;
+//   struct GNUNET_TIME_Timestamp now;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, not deleting auditor 
account\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (GNUNET_OK !=
+//         GNUNET_STRINGS_string_to_data (args[0],
+//                                        strlen (args[0]),
+//                                        &auditor_pub,
+//                                        sizeof (auditor_pub))) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify an auditor public key as first argument 
for this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   now = GNUNET_TIME_timestamp_get ();
+//   TALER_donau_offline_auditor_del_sign (&auditor_pub,
+//                                         now,
+//                                         &master_priv,
+//                                         &master_sig);
+//   output_operation (OP_DISABLE_AUDITOR,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_data_auto ("auditor_pub",
+//                                                   &auditor_pub),
+//                       GNUNET_JSON_pack_timestamp ("validity_end",
+//                                                   now),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + 1);
+// }
+
+
+// /**
+//  * Parse account restriction.
+//  *
+//  * @param args the array of command-line arguments to process next
+//  * @param[in,out] restrictions JSON array to update
+//  * @return -1 on error, otherwise number of arguments from @a args that 
were used
+//  */
+// static int
+// parse_restriction (char *const *args,
+//                    json_t *restrictions)
+// {
+//   if (NULL == args[0])
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Restriction TYPE argument missing\n");
+//     return -1;
+//   }
+//   if (0 == strcmp (args[0],
+//                    "deny"))
+//   {
+//     GNUNET_assert (0 ==
+//                    json_array_append_new (
+//                      restrictions,
+//                      GNUNET_JSON_PACK (
+//                        GNUNET_JSON_pack_string ("type",
+//                                                 "deny"))));
+//     return 1;
+//   }
+//   if (0 == strcmp (args[0],
+//                    "regex"))
+//   {
+//     json_t *i18n;
+//     json_error_t err;
+
+//     if ( (NULL == args[1]) ||
+//          (NULL == args[2]) ||
+//          (NULL == args[3]) )
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Mandatory arguments for restriction of type `regex' 
missing (REGEX, HINT, HINT-I18 required)\n");
+//       return -1;
+//     }
+//     {
+//       regex_t ex;
+
+//       if (0 != regcomp (&ex,
+//                         args[1],
+//                         REG_NOSUB | REG_EXTENDED))
+//       {
+//         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                     "Invalid regular expression `%s'\n",
+//                     args[1]);
+//         return -1;
+//       }
+//       regfree (&ex);
+//     }
+
+//     i18n = json_loads (args[3],
+//                        JSON_REJECT_DUPLICATES,
+//                        &err);
+//     if (NULL == i18n)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid JSON for restriction of type `regex': `%s` at 
%d\n",
+//                   args[3],
+//                   err.position);
+//       return -1;
+//     }
+//     GNUNET_assert (0 ==
+//                    json_array_append_new (
+//                      restrictions,
+//                      GNUNET_JSON_PACK (
+//                        GNUNET_JSON_pack_string ("type",
+//                                                 "regex"),
+//                        GNUNET_JSON_pack_string ("regex",
+//                                                 args[1]),
+//                        GNUNET_JSON_pack_string ("human_hint",
+//                                                 args[2]),
+//                        GNUNET_JSON_pack_object_steal ("human_hint_i18n",
+//                                                       i18n)
+//                        )));
+//     return 4;
+//   }
+//   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//               "Restriction TYPE `%s' unsupported\n",
+//               args[0]);
+//   return -1;
+// }
+
+
+// /**
+//  * Add wire account.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the hash of the denomination key to revoke
+//  */
+// static void
+// do_add_wire (char *const *args)
+// {
+//   struct TALER_MasterSignatureP master_sig_add;
+//   struct TALER_MasterSignatureP master_sig_wire;
+//   struct GNUNET_TIME_Timestamp now;
+//   const char *conversion_url = NULL;
+//   json_t *debit_restrictions;
+//   json_t *credit_restrictions;
+//   unsigned int num_args = 1;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, not adding wire 
account\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if (NULL == args[0])
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify a payto://-URI with this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   {
+//     char *msg = TALER_payto_validate (args[0]);
+
+//     if (NULL != msg)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "payto URI is malformed: %s\n",
+//                   msg);
+//       GNUNET_free (msg);
+//       test_shutdown ();
+//       global_ret = EXIT_INVALIDARGUMENT;
+//       return;
+//     }
+//   }
+//   now = GNUNET_TIME_timestamp_get ();
+//   {
+//     char *wire_method;
+
+//     wire_method = TALER_payto_get_method (args[0]);
+//     if (NULL == wire_method)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "payto:// URI `%s' is malformed\n",
+//                   args[0]);
+//       global_ret = EXIT_INVALIDARGUMENT;
+//       test_shutdown ();
+//       return;
+//     }
+//     GNUNET_free (wire_method);
+//   }
+//   debit_restrictions = json_array ();
+//   GNUNET_assert (NULL != debit_restrictions);
+//   credit_restrictions = json_array ();
+//   GNUNET_assert (NULL != credit_restrictions);
+//   while (NULL != args[num_args])
+//   {
+//     if (0 == strcmp (args[num_args],
+//                      "conversion-url"))
+//     {
+//       num_args++;
+//       conversion_url = args[num_args];
+//       if (NULL == conversion_url)
+//       {
+//         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                     "'conversion-url' requires an argument\n");
+//         global_ret = EXIT_INVALIDARGUMENT;
+//         test_shutdown ();
+//         json_decref (debit_restrictions);
+//         json_decref (credit_restrictions);
+//         return;
+//       }
+//       num_args++;
+//       continue;
+//     }
+//     if (0 == strcmp (args[num_args],
+//                      "credit-restriction"))
+//     {
+//       int iret;
+
+//       num_args++;
+//       iret = parse_restriction (&args[num_args],
+//                                 credit_restrictions);
+//       if (iret <= 0)
+//       {
+//         global_ret = EXIT_INVALIDARGUMENT;
+//         test_shutdown ();
+//         json_decref (debit_restrictions);
+//         json_decref (credit_restrictions);
+//         return;
+//       }
+//       num_args += iret;
+//       continue;
+//     }
+//     if (0 == strcmp (args[num_args],
+//                      "debit-restriction"))
+//     {
+//       int iret;
+
+//       num_args++;
+//       iret = parse_restriction (&args[num_args],
+//                                 debit_restrictions);
+//       if (iret <= 0)
+//       {
+//         global_ret = EXIT_INVALIDARGUMENT;
+//         test_shutdown ();
+//         json_decref (debit_restrictions);
+//         json_decref (credit_restrictions);
+//         return;
+//       }
+//       num_args += iret;
+//       continue;
+//     }
+//     break;
+//   }
+//   TALER_donau_offline_wire_add_sign (args[0],
+//                                      conversion_url,
+//                                      debit_restrictions,
+//                                      credit_restrictions,
+//                                      now,
+//                                      &master_priv,
+//                                      &master_sig_add);
+//   TALER_donau_wire_signature_make (args[0],
+//                                    conversion_url,
+//                                    debit_restrictions,
+//                                    credit_restrictions,
+//                                    &master_priv,
+//                                    &master_sig_wire);
+//   output_operation (OP_ENABLE_WIRE,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_string ("payto_uri",
+//                                                args[0]),
+//                       GNUNET_JSON_pack_array_steal ("debit_restrictions",
+//                                                     debit_restrictions),
+//                       GNUNET_JSON_pack_array_steal ("credit_restrictions",
+//                                                     credit_restrictions),
+//                       GNUNET_JSON_pack_allow_null (
+//                         GNUNET_JSON_pack_string ("conversion_url",
+//                                                  conversion_url)),
+//                       GNUNET_JSON_pack_timestamp ("validity_start",
+//                                                   now),
+//                       GNUNET_JSON_pack_data_auto ("master_sig_add",
+//                                                   &master_sig_add),
+//                       GNUNET_JSON_pack_data_auto ("master_sig_wire",
+//                                                   &master_sig_wire)));
+//   next (args + num_args);
+// }
+
+
+// /**
+//  * Disable wire account.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the hash of the denomination key to revoke
+//  */
+// static void
+// do_del_wire (char *const *args)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   struct GNUNET_TIME_Timestamp now;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, not deleting wire 
account\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if (NULL == args[0])
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify a payto://-URI with this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   now = GNUNET_TIME_timestamp_get ();
+//   TALER_donau_offline_wire_del_sign (args[0],
+//                                      now,
+//                                      &master_priv,
+//                                      &master_sig);
+//   output_operation (OP_DISABLE_WIRE,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_string ("payto_uri",
+//                                                args[0]),
+//                       GNUNET_JSON_pack_timestamp ("validity_end",
+//                                                   now),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + 1);
+// }
+
+
+// /**
+//  * Set wire fees for the given year.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the year, args[1] the wire method, args[2] the 
wire fee and args[3]
+//  *        the closing fee.
+//  */
+// static void
+// do_set_wire_fee (char *const *args)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   char dummy;
+//   unsigned int year;
+//   struct TALER_WireFeeSet fees;
+//   struct GNUNET_TIME_Timestamp start_time;
+//   struct GNUNET_TIME_Timestamp end_time;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, not setting wire fee\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (NULL == args[1]) ||
+//        (NULL == args[2]) ||
+//        (NULL == args[3]) ||
+//        ( (1 != sscanf (args[0],
+//                        "%u%c",
+//                        &year,
+//                        &dummy)) &&
+//          (0 != strcasecmp ("now",
+//                            args[0])) ) ||
+//        (GNUNET_OK !=
+//         TALER_string_to_amount (args[2],
+//                                 &fees.wire)) ||
+//        (GNUNET_OK !=
+//         TALER_string_to_amount (args[3],
+//                                 &fees.closing)) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must use YEAR, METHOD, WIRE-FEE, and CLOSING-FEE as 
arguments for this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (0 == strcasecmp ("now",
+//                        args[0]))
+//     year = GNUNET_TIME_get_current_year ();
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   start_time = GNUNET_TIME_absolute_to_timestamp (
+//     GNUNET_TIME_year_to_time (year));
+//   end_time = GNUNET_TIME_absolute_to_timestamp (
+//     GNUNET_TIME_year_to_time (year + 1));
+
+//   TALER_donau_offline_wire_fee_sign (args[1],
+//                                      start_time,
+//                                      end_time,
+//                                      &fees,
+//                                      &master_priv,
+//                                      &master_sig);
+//   output_operation (OP_SET_WIRE_FEE,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_string ("wire_method",
+//                                                args[1]),
+//                       GNUNET_JSON_pack_timestamp ("start_time",
+//                                                   start_time),
+//                       GNUNET_JSON_pack_timestamp ("end_time",
+//                                                   end_time),
+//                       TALER_JSON_pack_amount ("wire_fee",
+//                                               &fees.wire),
+//                       TALER_JSON_pack_amount ("closing_fee",
+//                                               &fees.closing),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + 4);
+// }
+
+
+// /**
+//  * Set global fees for the given year.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the year, args[1] the history fee, args[2]
+//  *        the account fee and args[3] the purse fee. These are followed by 
args[4] purse timeout,
+//  *        args[5] history expiration. Last is args[6] the (free) purse 
account limit.
+//  */
+// static void
+// do_set_global_fee (char *const *args)
+// {
+//   struct TALER_MasterSignatureP master_sig;
+//   char dummy;
+//   unsigned int year;
+//   struct TALER_GlobalFeeSet fees;
+//   struct GNUNET_TIME_Relative purse_timeout;
+//   struct GNUNET_TIME_Relative history_expiration;
+//   unsigned int purse_account_limit;
+//   struct GNUNET_TIME_Timestamp start_time;
+//   struct GNUNET_TIME_Timestamp end_time;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, not setting global 
fee\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (NULL == args[1]) ||
+//        (NULL == args[2]) ||
+//        (NULL == args[3]) ||
+//        (NULL == args[4]) ||
+//        (NULL == args[5]) ||
+//        (NULL == args[6]) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must use YEAR, HISTORY-FEE, ACCOUNT-FEE, PURSE-FEE, 
PURSE-TIMEOUT, HISTORY-EXPIRATION and PURSE-ACCOUNT-LIMIT as arguments for this 
subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if ( (1 != sscanf (args[0],
+//                      "%u%c",
+//                      &year,
+//                      &dummy)) &&
+//        (0 != strcasecmp ("now",
+//                          args[0])) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid YEAR given for 'global-fee' subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if ( (GNUNET_OK !=
+//         TALER_string_to_amount (args[1],
+//                                 &fees.history)) ||
+//        (GNUNET_OK !=
+//         TALER_string_to_amount (args[2],
+//                                 &fees.account)) ||
+//        (GNUNET_OK !=
+//         TALER_string_to_amount (args[3],
+//                                 &fees.purse)) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid amount given for 'global-fee' subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if ( (GNUNET_OK !=
+//         GNUNET_STRINGS_fancy_time_to_relative (args[4],
+//                                                &purse_timeout)) ||
+//        (GNUNET_OK !=
+//         GNUNET_STRINGS_fancy_time_to_relative (args[5],
+//                                                &history_expiration)) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid delay given for 'global-fee' subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (1 != sscanf (args[6],
+//                    "%u%c",
+//                    &purse_account_limit,
+//                    &dummy))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid purse account limit given for 'global-fee' 
subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (0 == strcasecmp ("now",
+//                        args[0]))
+//     year = GNUNET_TIME_get_current_year ();
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   start_time = GNUNET_TIME_absolute_to_timestamp (
+//     GNUNET_TIME_year_to_time (year));
+//   end_time = GNUNET_TIME_absolute_to_timestamp (
+//     GNUNET_TIME_year_to_time (year + 1));
+
+//   TALER_donau_offline_global_fee_sign (start_time,
+//                                        end_time,
+//                                        &fees,
+//                                        purse_timeout,
+//                                        history_expiration,
+//                                        (uint32_t) purse_account_limit,
+//                                        &master_priv,
+//                                        &master_sig);
+//   output_operation (OP_SET_GLOBAL_FEE,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_timestamp ("start_time",
+//                                                   start_time),
+//                       GNUNET_JSON_pack_timestamp ("end_time",
+//                                                   end_time),
+//                       TALER_JSON_pack_amount ("history_fee",
+//                                               &fees.history),
+//                       TALER_JSON_pack_amount ("account_fee",
+//                                               &fees.account),
+//                       TALER_JSON_pack_amount ("purse_fee",
+//                                               &fees.purse),
+//                       GNUNET_JSON_pack_time_rel ("purse_timeout",
+//                                                  purse_timeout),
+//                       GNUNET_JSON_pack_time_rel ("history_expiration",
+//                                                  history_expiration),
+//                       GNUNET_JSON_pack_uint64 ("purse_account_limit",
+//                                                (uint32_t) 
purse_account_limit),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + 7);
+// }
+
+
+// /**
+//  * Drain profits from donau's escrow account to
+//  * regular donau account.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the amount,
+//  *        args[1] must be the section of the escrow account to drain
+//  *        args[2] must be the payto://-URI of the target account
+//  */
+// static void
+// do_drain (char *const *args)
+// {
+//   struct TALER_WireTransferIdentifierRawP wtid;
+//   struct GNUNET_TIME_Timestamp date;
+//   struct TALER_Amount amount;
+//   const char *account_section;
+//   const char *payto_uri;
+//   struct TALER_MasterSignatureP master_sig;
+//   char *err;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, refusing drain\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (NULL == args[1]) ||
+//        (NULL == args[2]) ||
+//        (GNUNET_OK !=
+//         TALER_string_to_amount (args[0],
+//                                 &amount)) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Drain requires an amount, section name and target 
payto://-URI as arguments\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (NULL == args[1]) ||
+//        (NULL == args[2]) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Drain requires an amount, section name and target 
payto://-URI as arguments\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (GNUNET_OK !=
+//       TALER_string_to_amount (args[0],
+//                               &amount))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid amount `%s' specified for drain\n",
+//                 args[0]);
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   account_section = args[1];
+//   payto_uri = args[2];
+//   err = TALER_payto_validate (payto_uri);
+//   if (NULL != err)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid payto://-URI `%s' specified for drain: %s\n",
+//                 payto_uri,
+//                 err);
+//     GNUNET_free (err);
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+//                               &wtid,
+//                               sizeof (wtid));
+//   date = GNUNET_TIME_timestamp_get ();
+//   TALER_donau_offline_profit_drain_sign (&wtid,
+//                                          date,
+//                                          &amount,
+//                                          account_section,
+//                                          payto_uri,
+//                                          &master_priv,
+//                                          &master_sig);
+//   output_operation (OP_DRAIN_PROFITS,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_data_auto ("wtid",
+//                                                   &wtid),
+//                       GNUNET_JSON_pack_string ("account_section",
+//                                                account_section),
+//                       GNUNET_JSON_pack_string ("payto_uri",
+//                                                payto_uri),
+//                       TALER_JSON_pack_amount ("amount",
+//                                               &amount),
+//                       GNUNET_JSON_pack_timestamp ("date",
+//                                                   date),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + 3);
+// }
+
+
+// /**
+//  * Add partner.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the partner's master public key, args[1] the 
partner's
+//  *        API base URL, args[2] the wad fee, args[3] the wad frequency, and
+//  *        args[4] the year (including possibly 'now')
+//  */
+// static void
+// do_add_partner (char *const *args)
+// {
+//   struct TALER_MasterPublicKeyP partner_pub;
+//   struct GNUNET_TIME_Timestamp start_date;
+//   struct GNUNET_TIME_Timestamp end_date;
+//   struct GNUNET_TIME_Relative wad_frequency;
+//   struct TALER_Amount wad_fee;
+//   const char *partner_base_url;
+//   struct TALER_MasterSignatureP master_sig;
+//   char dummy;
+//   unsigned int year;
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, not adding partner\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (GNUNET_OK !=
+//         GNUNET_STRINGS_string_to_data (args[0],
+//                                        strlen (args[0]),
+//                                        &partner_pub,
+//                                        sizeof (partner_pub))) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify the partner master public key as first 
argument for this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if ( (NULL == args[1]) ||
+//        (0 != strncmp ("http",
+//                       args[1],
+//                       strlen ("http"))) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify the partner's base URL as the 2nd 
argument to this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   partner_base_url = args[1];
+//   if ( (NULL == args[2]) ||
+//        (GNUNET_OK !=
+//         TALER_string_to_amount (args[2],
+//                                 &wad_fee)) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid amount `%s' specified for wad fee of partner\n",
+//                 args[2]);
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if ( (NULL == args[3]) ||
+//        (GNUNET_OK !=
+//         GNUNET_STRINGS_fancy_time_to_relative (args[3],
+//                                                &wad_frequency)) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid wad frequency `%s' specified for add partner\n",
+//                 args[3]);
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if ( (NULL == args[4]) ||
+//        ( (1 != sscanf (args[4],
+//                        "%u%c",
+//                        &year,
+//                        &dummy)) &&
+//          (0 != strcasecmp ("now",
+//                            args[4])) ) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid year `%s' specified for add partner\n",
+//                 args[4]);
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (0 == strcasecmp ("now",
+//                        args[4]))
+//     year = GNUNET_TIME_get_current_year ();
+//   start_date = GNUNET_TIME_absolute_to_timestamp (
+//     GNUNET_TIME_year_to_time (year));
+//   end_date = GNUNET_TIME_absolute_to_timestamp (
+//     GNUNET_TIME_year_to_time (year + 1));
+
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   TALER_donau_offline_partner_details_sign (&partner_pub,
+//                                             start_date,
+//                                             end_date,
+//                                             wad_frequency,
+//                                             &wad_fee,
+//                                             partner_base_url,
+//                                             &master_priv,
+//                                             &master_sig);
+//   output_operation (OP_ADD_PARTNER,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_string ("partner_base_url",
+//                                                partner_base_url),
+//                       GNUNET_JSON_pack_time_rel ("wad_frequency",
+//                                                  wad_frequency),
+//                       GNUNET_JSON_pack_timestamp ("start_date",
+//                                                   start_date),
+//                       GNUNET_JSON_pack_timestamp ("end_date",
+//                                                   end_date),
+//                       GNUNET_JSON_pack_data_auto ("partner_pub",
+//                                                   &partner_pub),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + 5);
+// }
+
+
+// /**
+//  * Enable or disable AML staff.
+//  *
+//  * @param is_active true to enable, false to disable
+//  * @param args the array of command-line arguments to process next; args[0] 
must be the AML staff's public key, args[1] the AML staff's legal name, and if 
@a is_active then args[2] rw (read write) or ro (read only)
+//  */
+// static void
+// do_set_aml_staff (bool is_active,
+//                   char *const *args)
+// {
+//   struct TALER_AmlOfficerPublicKeyP officer_pub;
+//   const char *officer_name;
+//   bool read_only;
+//   struct TALER_MasterSignatureP master_sig;
+//   struct GNUNET_TIME_Timestamp now
+//     = GNUNET_TIME_timestamp_get ();
+
+//   if (NULL != in)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Downloaded data was not consumed, not updating AML staff 
status\n");
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   if ( (NULL == args[0]) ||
+//        (GNUNET_OK !=
+//         GNUNET_STRINGS_string_to_data (args[0],
+//                                        strlen (args[0]),
+//                                        &officer_pub,
+//                                        sizeof (officer_pub))) )
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify the AML officer's public key as first 
argument for this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   if (NULL == args[1])
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must specify the officer's legal name as the 2nd 
argument to this subcommand\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+//   officer_name = args[1];
+//   if (is_active)
+//   {
+//     if ( (NULL == args[2]) ||
+//          ( (0 != strcmp (args[2],
+//                          "ro")) &&
+//            (0 != strcmp (args[2],
+//                          "rw")) ) )
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "You must specify 'ro' or 'rw' (and not `%s') for the 
access level\n",
+//                   args[2]);
+//       test_shutdown ();
+//       global_ret = EXIT_INVALIDARGUMENT;
+//       return;
+//     }
+//     read_only = (0 == strcmp (args[2],
+//                               "ro"));
+//   }
+//   else
+//   {
+//     read_only = true;
+//   }
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   TALER_donau_offline_aml_officer_status_sign (&officer_pub,
+//                                                officer_name,
+//                                                now,
+//                                                is_active,
+//                                                read_only,
+//                                                &master_priv,
+//                                                &master_sig);
+//   output_operation (OP_UPDATE_AML_STAFF,
+//                     GNUNET_JSON_PACK (
+//                       GNUNET_JSON_pack_string ("officer_name",
+//                                                officer_name),
+//                       GNUNET_JSON_pack_timestamp ("change_date",
+//                                                   now),
+//                       GNUNET_JSON_pack_bool ("is_active",
+//                                              is_active),
+//                       GNUNET_JSON_pack_bool ("read_only",
+//                                              read_only),
+//                       GNUNET_JSON_pack_data_auto ("officer_pub",
+//                                                   &officer_pub),
+//                       GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                   &master_sig)));
+//   next (args + (is_active ? 3 : 2));
+// }
+
+
+// /**
+//  * Disable AML staff.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the AML staff's public key, args[1] the AML 
staff's legal name, args[2] rw (read write) or ro (read only)
+//  */
+// static void
+// disable_aml_staff (char *const *args)
+// {
+//   do_set_aml_staff (false,
+//                     args);
+// }
+
+
+// /**
+//  * Enable AML staff.
+//  *
+//  * @param args the array of command-line arguments to process next;
+//  *        args[0] must be the AML staff's public key, args[1] the AML 
staff's legal name, args[2] rw (read write) or ro (read only)
+//  */
+// static void
+// enable_aml_staff (char *const *args)
+// {
+//   do_set_aml_staff (true,
+//                     args);
+// }
+
+
+// /**
+//  * Function called with information about future keys.  Dumps the JSON 
output
+//  * (on success), either into an internal buffer or to stdout (depending on
+//  * whether there are subsequent commands).
+//  *
+//  * @param cls closure with the `char **` remaining args
+//  * @param mgr response data
+//  */
+// static void
+// download_cb (void *cls,
+//              const struct DONAU_ManagementGetKeysResponse *mgr)
+// {
+//   char *const *args = cls;
+//   const struct DONAU_HttpResponse *hr = &mgr->hr;
+
+//   mgkh = NULL;
+//   switch (hr->http_status)
+//   {
+//   case MHD_HTTP_OK:
+//     break;
+//   default:
+//     if (0 != hr->http_status)
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Failed to download keys from `%s': %s (HTTP status: 
%u/%u)\n",
+//                   CFG_donau_url,
+//                   hr->hint,
+//                   hr->http_status,
+//                   (unsigned int) hr->ec);
+//     else
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Failed to download keys from `%s' (no HTTP response)\n",
+//                   CFG_donau_url);
+//     test_shutdown ();
+//     global_ret = EXIT_FAILURE;
+//     return;
+//   }
+//   in = GNUNET_JSON_PACK (
+//     GNUNET_JSON_pack_string ("operation",
+//                              OP_INPUT_KEYS),
+//     GNUNET_JSON_pack_object_incref ("arguments",
+//                                     (json_t *) hr->reply));
+//   if (NULL == args[0])
+//   {
+//     json_dumpf (in,
+//                 stdout,
+//                 JSON_INDENT (2));
+//     json_decref (in);
+//     in = NULL;
+//   }
+//   next (args);
+// }
+
+
+// /**
+//  * Download future keys.
+//  *
+//  * @param args the array of command-line arguments to process next
+//  */
+// static void
+// do_download (char *const *args)
+// {
+//   if ( (NULL == CFG_donau_url) &&
+//        (GNUNET_OK !=
+//         GNUNET_CONFIGURATION_get_value_string (kcfg,
+//                                                "donau",
+//                                                "BASE_URL",
+//                                                &CFG_donau_url)) )
+//   {
+//     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+//                                "donau",
+//                                "BASE_URL");
+//     test_shutdown ();
+//     global_ret = EXIT_NOTCONFIGURED;
+//     return;
+//   }
+//   mgkh = DONAU_get_management_keys (ctx,
+//                                     CFG_donau_url,
+//                                     &download_cb,
+//                                     (void *) args);
+// }
+
+
+// /**
+//  * Check that the security module keys are the same as before.  If we had no
+//  * keys in store before, remember them (Trust On First Use).
+//  *
+//  * @param secmset security module keys
+//  * @return #GNUNET_OK if keys match with what we have in store
+//  *         #GNUNET_NO if we had nothing in store but now do
+//  *         #GNUNET_SYSERR if keys changed from what we remember or other 
error
+//  */
+// static enum GNUNET_GenericReturnValue
+// tofu_check (const struct TALER_SecurityModulePublicKeySetP *secmset)
+// {
+//   char *fn;
+//   struct TALER_SecurityModulePublicKeySetP oldset;
+//   ssize_t ret;
+
+//   if (GNUNET_OK !=
+//       GNUNET_CONFIGURATION_get_value_filename (kcfg,
+//                                                "donau-offline",
+//                                                "SECM_TOFU_FILE",
+//                                                &fn))
+//   {
+//     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+//                                "donau-offline",
+//                                "SECM_TOFU_FILE");
+//     return GNUNET_SYSERR;
+//   }
+//   if (GNUNET_OK ==
+//       GNUNET_DISK_file_test (fn))
+//   {
+//     ret = GNUNET_DISK_fn_read (fn,
+//                                &oldset,
+//                                sizeof (oldset));
+//     if (GNUNET_SYSERR != ret)
+//     {
+//       if (ret != sizeof (oldset))
+//       {
+//         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                     "File `%s' corrupt\n",
+//                     fn);
+//         GNUNET_free (fn);
+//         return GNUNET_SYSERR;
+//       }
+//       /* TOFU check */
+//       if (0 != memcmp (&oldset,
+//                        secmset,
+//                        sizeof (*secmset)))
+//       {
+//         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                     "Fatal: security module keys changed (file `%s')!\n",
+//                     fn);
+//         GNUNET_free (fn);
+//         return GNUNET_SYSERR;
+//       }
+//       GNUNET_free (fn);
+//       return GNUNET_OK;
+//     }
+//   }
+
+//   {
+//     char *key;
+
+//     /* check against SECMOD-keys pinned in configuration */
+//     if (GNUNET_OK ==
+//         GNUNET_CONFIGURATION_get_value_string (kcfg,
+//                                                "donau-offline",
+//                                                "SECM_ESIGN_PUBKEY",
+//                                                &key))
+//     {
+//       struct TALER_SecurityModulePublicKeyP k;
+
+//       if (GNUNET_OK !=
+//           GNUNET_STRINGS_string_to_data (key,
+//                                          strlen (key),
+//                                          &k,
+//                                          sizeof (k)))
+//       {
+//         GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+//                                    "donau-offline",
+//                                    "SECM_ESIGN_PUBKEY",
+//                                    "key malformed");
+//         GNUNET_free (key);
+//         GNUNET_free (fn);
+//         return GNUNET_SYSERR;
+//       }
+//       GNUNET_free (key);
+//       if (0 !=
+//           GNUNET_memcmp (&k,
+//                          &secmset->eddsa))
+//       {
+//         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                     "ESIGN security module key does not match 
SECM_ESIGN_PUBKEY in configuration\n");
+//         GNUNET_free (fn);
+//         return GNUNET_SYSERR;
+//       }
+//     }
+//     if (GNUNET_OK ==
+//         GNUNET_CONFIGURATION_get_value_string (kcfg,
+//                                                "donau-offline",
+//                                                "SECM_DENOM_PUBKEY",
+//                                                &key))
+//     {
+//       struct TALER_SecurityModulePublicKeyP k;
+
+//       if (GNUNET_OK !=
+//           GNUNET_STRINGS_string_to_data (key,
+//                                          strlen (key),
+//                                          &k,
+//                                          sizeof (k)))
+//       {
+//         GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+//                                    "donau-offline",
+//                                    "SECM_DENOM_PUBKEY",
+//                                    "key malformed");
+//         GNUNET_free (key);
+//         GNUNET_free (fn);
+//         return GNUNET_SYSERR;
+//       }
+//       GNUNET_free (key);
+//       if (0 !=
+//           GNUNET_memcmp (&k,
+//                          &secmset->rsa))
+//       {
+//         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                     "DENOM security module key does not match 
SECM_DENOM_PUBKEY in configuration\n");
+//         GNUNET_free (fn);
+//         return GNUNET_SYSERR;
+//       }
+//     }
+//     if (GNUNET_OK ==
+//         GNUNET_CONFIGURATION_get_value_string (kcfg,
+//                                                "donau-offline",
+//                                                "SECM_DENOM_CS_PUBKEY",
+//                                                &key))
+//     {
+//       struct TALER_SecurityModulePublicKeyP k;
+
+//       if (GNUNET_OK !=
+//           GNUNET_STRINGS_string_to_data (key,
+//                                          strlen (key),
+//                                          &k,
+//                                          sizeof (k)))
+//       {
+//         GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+//                                    "donau-offline",
+//                                    "SECM_DENOM_CS_PUBKEY",
+//                                    "key malformed");
+//         GNUNET_free (key);
+//         GNUNET_free (fn);
+//         return GNUNET_SYSERR;
+//       }
+//       GNUNET_free (key);
+//       if (0 !=
+//           GNUNET_memcmp (&k,
+//                          &secmset->cs))
+//       {
+//         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                     "DENOM security module key does not match 
SECM_DENOM_CS_PUBKEY in configuration\n");
+//         GNUNET_free (fn);
+//         return GNUNET_SYSERR;
+//       }
+//     }
+//   }
+//   if (GNUNET_OK !=
+//       GNUNET_DISK_directory_create_for_file (fn))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Failed create directory to store key material in file 
`%s'\n",
+//                 fn);
+//     GNUNET_free (fn);
+//     return GNUNET_SYSERR;
+//   }
+//   /* persist keys for future runs */
+//   if (GNUNET_OK !=
+//       GNUNET_DISK_fn_write (fn,
+//                             secmset,
+//                             sizeof (oldset),
+//                             GNUNET_DISK_PERM_USER_READ))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Failed to store key material in file `%s'\n",
+//                 fn);
+//     GNUNET_free (fn);
+//     return GNUNET_SYSERR;
+//   }
+//   GNUNET_free (fn);
+//   return GNUNET_NO;
+// }
+
+
+// /**
+//  * Output @a signkeys for human consumption.
+//  *
+//  * @param secm_pub security module public key used to sign the denominations
+//  * @param signkeys keys to output
+//  * @return #GNUNET_OK on success
+//  */
+// static enum GNUNET_GenericReturnValue
+// show_signkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
+//                const json_t *signkeys)
+// {
+//   size_t index;
+//   json_t *value;
+
+//   json_array_foreach (signkeys, index, value) {
+//     const char *err_name;
+//     unsigned int err_line;
+//     struct DONAU_DonauPublicKeyP donau_pub;
+//     struct TALER_SecurityModuleSignatureP secm_sig;
+//     struct GNUNET_TIME_Timestamp start_time;
+//     struct GNUNET_TIME_Timestamp sign_end;
+//     struct GNUNET_TIME_Timestamp legal_end;
+//     struct GNUNET_TIME_Relative duration;
+//     struct GNUNET_JSON_Specification spec[] = {
+//       GNUNET_JSON_spec_timestamp ("stamp_start",
+//                                   &start_time),
+//       GNUNET_JSON_spec_timestamp ("stamp_expire",
+//                                   &sign_end),
+//       GNUNET_JSON_spec_timestamp ("stamp_end",
+//                                   &legal_end),
+//       GNUNET_JSON_spec_fixed_auto ("key",
+//                                    &donau_pub),
+//       GNUNET_JSON_spec_fixed_auto ("signkey_secmod_sig",
+//                                    &secm_sig),
+//       GNUNET_JSON_spec_end ()
+//     };
+
+//     if (GNUNET_OK !=
+//         GNUNET_JSON_parse (value,
+//                            spec,
+//                            &err_name,
+//                            &err_line))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid input for signing key to 'show': %s#%u at %u 
(skipping)\n",
+//                   err_name,
+//                   err_line,
+//                   (unsigned int) index);
+//       json_dumpf (value,
+//                   stderr,
+//                   JSON_INDENT (2));
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return GNUNET_SYSERR;
+//     }
+//     duration = GNUNET_TIME_absolute_get_difference (start_time.abs_time,
+//                                                     sign_end.abs_time);
+//     if (GNUNET_OK !=
+//         TALER_donau_secmod_eddsa_verify (&donau_pub,
+//                                          start_time,
+//                                          duration,
+//                                          secm_pub,
+//                                          &secm_sig))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid security module signature for signing key %s 
(aborting)\n",
+//                   TALER_B2S (&donau_pub));
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return GNUNET_SYSERR;
+//     }
+//     {
+//       char *legal_end_s;
+
+//       legal_end_s = GNUNET_strdup (
+//         GNUNET_TIME_timestamp2s (legal_end));
+//       printf ("DONAU-KEY %s starting at %s (used for: %s, legal end: %s)\n",
+//               TALER_B2S (&donau_pub),
+//               GNUNET_TIME_timestamp2s (start_time),
+//               GNUNET_TIME_relative2s (duration,
+//                                       false),
+//               legal_end_s);
+//       GNUNET_free (legal_end_s);
+//     }
+//   }
+//   return GNUNET_OK;
+// }
+
+
+// /**
+//  * Output @a denomkeys for human consumption.
+//  *
+//  * @param secm_pub_rsa security module public key used to sign the RSA 
denominations
+//  * @param secm_pub_cs security module public key used to sign the CS 
denominations
+//  * @param denomkeys keys to output
+//  * @return #GNUNET_OK on success
+//  */
+// static enum GNUNET_GenericReturnValue
+// show_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub_rsa,
+//                 const struct TALER_SecurityModulePublicKeyP *secm_pub_cs,
+//                 const json_t *denomkeys)
+// {
+//   size_t index;
+//   json_t *value;
+
+//   json_array_foreach (denomkeys, index, value) {
+//     const char *err_name;
+//     unsigned int err_line;
+//     const char *section_name;
+//     struct TALER_DenominationPublicKey denom_pub;
+//     struct GNUNET_TIME_Timestamp stamp_start;
+//     struct GNUNET_TIME_Timestamp stamp_expire_withdraw;
+//     struct GNUNET_TIME_Timestamp stamp_expire_deposit;
+//     struct GNUNET_TIME_Timestamp stamp_expire_legal;
+//     struct TALER_Amount coin_value;
+//     struct TALER_DenomFeeSet fees;
+//     struct TALER_SecurityModuleSignatureP secm_sig;
+//     struct GNUNET_JSON_Specification spec[] = {
+//       GNUNET_JSON_spec_string ("section_name",
+//                                &section_name),
+//       TALER_JSON_spec_denom_pub ("denom_pub",
+//                                  &denom_pub),
+//       TALER_JSON_spec_amount ("value",
+//                               currency,
+//                               &coin_value),
+//       TALER_JSON_SPEC_DENOM_FEES ("fee",
+//                                   currency,
+//                                   &fees),
+//       GNUNET_JSON_spec_timestamp ("stamp_start",
+//                                   &stamp_start),
+//       GNUNET_JSON_spec_timestamp ("stamp_expire_withdraw",
+//                                   &stamp_expire_withdraw),
+//       GNUNET_JSON_spec_timestamp ("stamp_expire_deposit",
+//                                   &stamp_expire_deposit),
+//       GNUNET_JSON_spec_timestamp ("stamp_expire_legal",
+//                                   &stamp_expire_legal),
+//       GNUNET_JSON_spec_fixed_auto ("denom_secmod_sig",
+//                                    &secm_sig),
+//       GNUNET_JSON_spec_end ()
+//     };
+//     struct GNUNET_TIME_Relative duration;
+//     struct TALER_DenominationHashP h_denom_pub;
+//     enum GNUNET_GenericReturnValue ok;
+
+//     if (GNUNET_OK !=
+//         GNUNET_JSON_parse (value,
+//                            spec,
+//                            &err_name,
+//                            &err_line))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid input for denomination key to 'show': %s#%u at 
%u (skipping)\n",
+//                   err_name,
+//                   err_line,
+//                   (unsigned int) index);
+//       json_dumpf (value,
+//                   stderr,
+//                   JSON_INDENT (2));
+//       GNUNET_JSON_parse_free (spec);
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return GNUNET_SYSERR;
+//     }
+//     duration = GNUNET_TIME_absolute_get_difference (
+//       stamp_start.abs_time,
+//       stamp_expire_withdraw.abs_time);
+//     TALER_denom_pub_hash (&denom_pub,
+//                           &h_denom_pub);
+//     switch (denom_pub.cipher)
+//     {
+//     case TALER_DENOMINATION_RSA:
+//       {
+//         struct TALER_RsaPubHashP h_rsa;
+
+//         TALER_rsa_pub_hash (denom_pub.details.rsa_public_key,
+//                             &h_rsa);
+//         ok = TALER_donau_secmod_rsa_verify (&h_rsa,
+//                                             section_name,
+//                                             stamp_start,
+//                                             duration,
+//                                             secm_pub_rsa,
+//                                             &secm_sig);
+//       }
+//       break;
+//     case TALER_DENOMINATION_CS:
+//       {
+//         struct TALER_CsPubHashP h_cs;
+
+//         TALER_cs_pub_hash (&denom_pub.details.cs_public_key,
+//                            &h_cs);
+//         ok = TALER_donau_secmod_cs_verify (&h_cs,
+//                                            section_name,
+//                                            stamp_start,
+//                                            duration,
+//                                            secm_pub_cs,
+//                                            &secm_sig);
+//       }
+//       break;
+//     default:
+//       GNUNET_break (0);
+//       ok = GNUNET_SYSERR;
+//       break;
+//     }
+//     if (GNUNET_OK != ok)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid security module signature for denomination key 
%s (aborting)\n",
+//                   GNUNET_h2s (&h_denom_pub.hash));
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return GNUNET_SYSERR;
+//     }
+
+//     {
+//       char *withdraw_fee_s;
+//       char *deposit_fee_s;
+//       char *refresh_fee_s;
+//       char *refund_fee_s;
+//       char *deposit_s;
+//       char *legal_s;
+
+//       withdraw_fee_s = TALER_amount_to_string (&fees.withdraw);
+//       deposit_fee_s = TALER_amount_to_string (&fees.deposit);
+//       refresh_fee_s = TALER_amount_to_string (&fees.refresh);
+//       refund_fee_s = TALER_amount_to_string (&fees.refund);
+//       deposit_s = GNUNET_strdup (
+//         GNUNET_TIME_timestamp2s (stamp_expire_deposit));
+//       legal_s = GNUNET_strdup (
+//         GNUNET_TIME_timestamp2s (stamp_expire_legal));
+
+//       printf (
+//         "DENOMINATION-KEY(%s) %s of value %s starting at %s "
+//         "(used for: %s, deposit until: %s legal end: %s) with fees 
%s/%s/%s/%s\n",
+//         section_name,
+//         TALER_B2S (&h_denom_pub),
+//         TALER_amount2s (&coin_value),
+//         GNUNET_TIME_timestamp2s (stamp_start),
+//         GNUNET_TIME_relative2s (duration,
+//                                 false),
+//         deposit_s,
+//         legal_s,
+//         withdraw_fee_s,
+//         deposit_fee_s,
+//         refresh_fee_s,
+//         refund_fee_s);
+//       GNUNET_free (withdraw_fee_s);
+//       GNUNET_free (deposit_fee_s);
+//       GNUNET_free (refresh_fee_s);
+//       GNUNET_free (refund_fee_s);
+//       GNUNET_free (deposit_s);
+//       GNUNET_free (legal_s);
+//     }
+
+//     GNUNET_JSON_parse_free (spec);
+//   }
+//   return GNUNET_OK;
+// }
+
+
+// /**
+//  * Parse the input of donau keys for the 'show' and 'sign' commands.
+//  *
+//  * @param command_name name of the command, for logging
+//  * @return NULL on error, otherwise the keys details to be free'd by caller
+//  */
+// static json_t *
+// parse_keys_input (const char *command_name)
+// {
+//   const char *op_str;
+//   json_t *keys;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_json ("arguments",
+//                            &keys),
+//     GNUNET_JSON_spec_string ("operation",
+//                              &op_str),
+//     GNUNET_JSON_spec_end ()
+//   };
+//   const char *err_name;
+//   unsigned int err_line;
+
+//   if (NULL == in)
+//   {
+//     json_error_t err;
+
+//     in = json_loadf (stdin,
+//                      JSON_REJECT_DUPLICATES,
+//                      &err);
+//     if (NULL == in)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Failed to read JSON input: %s at %d:%s (offset: %d)\n",
+//                   err.text,
+//                   err.line,
+//                   err.source,
+//                   err.position);
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return NULL;
+//     }
+//   }
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (in,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to '%s': %s#%u (skipping)\n",
+//                 command_name,
+//                 err_name,
+//                 err_line);
+//     json_dumpf (in,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     return NULL;
+//   }
+//   if (0 != strcmp (op_str,
+//                    OP_INPUT_KEYS))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to '%s' : operation is `%s', expected 
`%s'\n",
+//                 command_name,
+//                 op_str,
+//                 OP_INPUT_KEYS);
+//     GNUNET_JSON_parse_free (spec);
+//     return NULL;
+//   }
+//   json_decref (in);
+//   in = NULL;
+//   return keys;
+// }
+
+
+// /**
+//  * Show future keys.
+//  *
+//  * @param args the array of command-line arguments to process next
+//  */
+// static void
+// do_show (char *const *args)
+// {
+//   json_t *keys;
+//   const char *err_name;
+//   unsigned int err_line;
+//   const json_t *denomkeys;
+//   const json_t *signkeys;
+//   struct TALER_MasterPublicKeyP mpub;
+//   struct TALER_SecurityModulePublicKeySetP secmset;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_array_const ("future_denoms",
+//                                   &denomkeys),
+//     GNUNET_JSON_spec_array_const ("future_signkeys",
+//                                   &signkeys),
+//     GNUNET_JSON_spec_fixed_auto ("master_pub",
+//                                  &mpub),
+//     GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
+//                                  &secmset.rsa),
+//     GNUNET_JSON_spec_fixed_auto ("denom_secmod_cs_public_key",
+//                                  &secmset.cs),
+//     GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
+//                                  &secmset.eddsa),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   keys = parse_keys_input ("show");
+//   if (NULL == keys)
+//     return;
+
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//     return;
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (keys,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to 'show': %s #%u (skipping)\n",
+//                 err_name,
+//                 err_line);
+//     json_dumpf (in,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     json_decref (keys);
+//     return;
+//   }
+//   if (0 !=
+//       GNUNET_memcmp (&master_pub,
+//                      &mpub))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Fatal: donau uses different master key!\n");
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     json_decref (keys);
+//     return;
+//   }
+//   if (GNUNET_SYSERR ==
+//       tofu_check (&secmset))
+//   {
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     json_decref (keys);
+//     return;
+//   }
+//   if ( (GNUNET_OK !=
+//         show_signkeys (&secmset.eddsa,
+//                        signkeys)) ||
+//        (GNUNET_OK !=
+//         show_denomkeys (&secmset.rsa,
+//                         &secmset.cs,
+//                         denomkeys)) )
+//   {
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     json_decref (keys);
+//     return;
+//   }
+//   json_decref (keys);
+//   next (args);
+// }
+
+
+// /**
+//  * Sign @a signkeys with offline key.
+//  *
+//  * @param secm_pub security module public key used to sign the denominations
+//  * @param signkeys keys to output
+//  * @param[in,out] result array where to output the signatures
+//  * @return #GNUNET_OK on success
+//  */
+// static enum GNUNET_GenericReturnValue
+// sign_signkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
+//                const json_t *signkeys,
+//                json_t *result)
+// {
+//   size_t index;
+//   json_t *value;
+
+//   json_array_foreach (signkeys, index, value) {
+//     const char *err_name;
+//     unsigned int err_line;
+//     struct DONAU_DonauPublicKeyP donau_pub;
+//     struct TALER_SecurityModuleSignatureP secm_sig;
+//     struct GNUNET_TIME_Timestamp start_time;
+//     struct GNUNET_TIME_Timestamp sign_end;
+//     struct GNUNET_TIME_Timestamp legal_end;
+//     struct GNUNET_TIME_Relative duration;
+//     struct GNUNET_JSON_Specification spec[] = {
+//       GNUNET_JSON_spec_timestamp ("stamp_start",
+//                                   &start_time),
+//       GNUNET_JSON_spec_timestamp ("stamp_expire",
+//                                   &sign_end),
+//       GNUNET_JSON_spec_timestamp ("stamp_end",
+//                                   &legal_end),
+//       GNUNET_JSON_spec_fixed_auto ("key",
+//                                    &donau_pub),
+//       GNUNET_JSON_spec_fixed_auto ("signkey_secmod_sig",
+//                                    &secm_sig),
+//       GNUNET_JSON_spec_end ()
+//     };
+
+//     if (GNUNET_OK !=
+//         GNUNET_JSON_parse (value,
+//                            spec,
+//                            &err_name,
+//                            &err_line))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid input for signing key to 'show': %s #%u at %u 
(skipping)\n",
+//                   err_name,
+//                   err_line,
+//                   (unsigned int) index);
+//       json_dumpf (value,
+//                   stderr,
+//                   JSON_INDENT (2));
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return GNUNET_SYSERR;
+//     }
+
+//     duration = GNUNET_TIME_absolute_get_difference (start_time.abs_time,
+//                                                     sign_end.abs_time);
+//     if (GNUNET_OK !=
+//         TALER_donau_secmod_eddsa_verify (&donau_pub,
+//                                          start_time,
+//                                          duration,
+//                                          secm_pub,
+//                                          &secm_sig))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid security module signature for signing key %s 
(aborting)\n",
+//                   TALER_B2S (&donau_pub));
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       GNUNET_JSON_parse_free (spec);
+//       return GNUNET_SYSERR;
+//     }
+//     {
+//       struct TALER_MasterSignatureP master_sig;
+
+//       TALER_donau_offline_signkey_validity_sign (&donau_pub,
+//                                                  start_time,
+//                                                  sign_end,
+//                                                  legal_end,
+//                                                  &master_priv,
+//                                                  &master_sig);
+//       GNUNET_assert (0 ==
+//                      json_array_append_new (
+//                        result,
+//                        GNUNET_JSON_PACK (
+//                          GNUNET_JSON_pack_data_auto ("donau_pub",
+//                                                      &donau_pub),
+//                          GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                      &master_sig))));
+//     }
+//     GNUNET_JSON_parse_free (spec);
+//   }
+//   return GNUNET_OK;
+// }
+
+
+// /**
+//  * Looks up the AGE_RESTRICTED setting for a denomination in the config and
+//  * returns the age restriction (mask) accordingly.
+//  *
+//  * @param section_name Section in the configuration for the particular
+//  *    denomination.
+//  */
+// static struct TALER_AgeMask
+// load_age_mask (const char*section_name)
+// {
+//   static const struct TALER_AgeMask null_mask = {0};
+//   enum GNUNET_GenericReturnValue ret;
+
+//   if (! ar_enabled)
+//     return null_mask;
+
+//   if (GNUNET_OK != (GNUNET_CONFIGURATION_have_value (
+//                       kcfg,
+//                       section_name,
+//                       "AGE_RESTRICTED")))
+//     return null_mask;
+
+//   ret = GNUNET_CONFIGURATION_get_value_yesno (kcfg,
+//                                               section_name,
+//                                               "AGE_RESTRICTED");
+//   if (GNUNET_SYSERR == ret)
+//     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+//                                section_name,
+//                                "AGE_RESTRICTED",
+//                                "Value must be YES or NO\n");
+//   if (GNUNET_YES == ret)
+//     return ar_config.mask;
+
+//   return null_mask;
+// }
+
+
+// /**
+//  * Sign @a denomkeys with offline key.
+//  *
+//  * @param secm_pub_rsa security module public key used to sign the RSA 
denominations
+//  * @param secm_pub_cs security module public key used to sign the CS 
denominations
+//  * @param denomkeys keys to output
+//  * @param[in,out] result array where to output the signatures
+//  * @return #GNUNET_OK on success
+//  */
+// static enum GNUNET_GenericReturnValue
+// sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub_rsa,
+//                 const struct TALER_SecurityModulePublicKeyP *secm_pub_cs,
+//                 const json_t *denomkeys,
+//                 json_t *result)
+// {
+//   size_t index;
+//   json_t *value;
+
+//   json_array_foreach (denomkeys, index, value) {
+//     const char *err_name;
+//     unsigned int err_line;
+//     const char *section_name;
+//     struct TALER_DenominationPublicKey denom_pub;
+//     struct GNUNET_TIME_Timestamp stamp_start;
+//     struct GNUNET_TIME_Timestamp stamp_expire_withdraw;
+//     struct GNUNET_TIME_Timestamp stamp_expire_deposit;
+//     struct GNUNET_TIME_Timestamp stamp_expire_legal;
+//     struct TALER_Amount coin_value;
+//     struct TALER_DenomFeeSet fees;
+//     struct TALER_SecurityModuleSignatureP secm_sig;
+//     struct GNUNET_JSON_Specification spec[] = {
+//       GNUNET_JSON_spec_string ("section_name",
+//                                &section_name),
+//       TALER_JSON_spec_denom_pub ("denom_pub",
+//                                  &denom_pub),
+//       TALER_JSON_spec_amount ("value",
+//                               currency,
+//                               &coin_value),
+//       TALER_JSON_SPEC_DENOM_FEES ("fee",
+//                                   currency,
+//                                   &fees),
+//       GNUNET_JSON_spec_timestamp ("stamp_start",
+//                                   &stamp_start),
+//       GNUNET_JSON_spec_timestamp ("stamp_expire_withdraw",
+//                                   &stamp_expire_withdraw),
+//       GNUNET_JSON_spec_timestamp ("stamp_expire_deposit",
+//                                   &stamp_expire_deposit),
+//       GNUNET_JSON_spec_timestamp ("stamp_expire_legal",
+//                                   &stamp_expire_legal),
+//       GNUNET_JSON_spec_fixed_auto ("denom_secmod_sig",
+//                                    &secm_sig),
+//       GNUNET_JSON_spec_end ()
+//     };
+//     struct GNUNET_TIME_Relative duration;
+//     struct TALER_DenominationHashP h_denom_pub;
+
+//     if (GNUNET_OK !=
+//         GNUNET_JSON_parse (value,
+//                            spec,
+//                            &err_name,
+//                            &err_line))
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid input for denomination key to 'sign': %s #%u at 
%u (skipping)\n",
+//                   err_name,
+//                   err_line,
+//                   (unsigned int) index);
+//       json_dumpf (value,
+//                   stderr,
+//                   JSON_INDENT (2));
+//       GNUNET_JSON_parse_free (spec);
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       return GNUNET_SYSERR;
+//     }
+//     duration = GNUNET_TIME_absolute_get_difference (
+//       stamp_start.abs_time,
+//       stamp_expire_withdraw.abs_time);
+
+//     /* Load the age mask, if applicable to this denomination */
+//     denom_pub.age_mask = load_age_mask (section_name);
+
+//     TALER_denom_pub_hash (&denom_pub,
+//                           &h_denom_pub);
+//     switch (denom_pub.cipher)
+//     {
+//     case TALER_DENOMINATION_RSA:
+//       {
+//         struct TALER_RsaPubHashP h_rsa;
+
+//         TALER_rsa_pub_hash (denom_pub.details.rsa_public_key,
+//                             &h_rsa);
+//         if (GNUNET_OK !=
+//             TALER_donau_secmod_rsa_verify (&h_rsa,
+//                                            section_name,
+//                                            stamp_start,
+//                                            duration,
+//                                            secm_pub_rsa,
+//                                            &secm_sig))
+//         {
+//           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                       "Invalid security module signature for denomination 
key %s (aborting)\n",
+//                       GNUNET_h2s (&h_denom_pub.hash));
+//           global_ret = EXIT_FAILURE;
+//           test_shutdown ();
+//           GNUNET_JSON_parse_free (spec);
+//           return GNUNET_SYSERR;
+//         }
+//       }
+//       break;
+//     case TALER_DENOMINATION_CS:
+//       {
+//         struct TALER_CsPubHashP h_cs;
+
+//         TALER_cs_pub_hash (&denom_pub.details.cs_public_key,
+//                            &h_cs);
+//         if (GNUNET_OK !=
+//             TALER_donau_secmod_cs_verify (&h_cs,
+//                                           section_name,
+//                                           stamp_start,
+//                                           duration,
+//                                           secm_pub_cs,
+//                                           &secm_sig))
+//         {
+//           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                       "Invalid security module signature for denomination 
key %s (aborting)\n",
+//                       GNUNET_h2s (&h_denom_pub.hash));
+//           global_ret = EXIT_FAILURE;
+//           test_shutdown ();
+//           GNUNET_JSON_parse_free (spec);
+//           return GNUNET_SYSERR;
+//         }
+//       }
+//       break;
+//     default:
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       GNUNET_JSON_parse_free (spec);
+//       return GNUNET_SYSERR;
+//     }
+
+//     {
+//       struct TALER_MasterSignatureP master_sig;
+
+//       TALER_donau_offline_denom_validity_sign (&h_denom_pub,
+//                                                stamp_start,
+//                                                stamp_expire_withdraw,
+//                                                stamp_expire_deposit,
+//                                                stamp_expire_legal,
+//                                                &coin_value,
+//                                                &fees,
+//                                                &master_priv,
+//                                                &master_sig);
+//       GNUNET_assert (0 ==
+//                      json_array_append_new (
+//                        result,
+//                        GNUNET_JSON_PACK (
+//                          GNUNET_JSON_pack_data_auto ("h_denom_pub",
+//                                                      &h_denom_pub),
+//                          GNUNET_JSON_pack_data_auto ("master_sig",
+//                                                      &master_sig))));
+//     }
+//     GNUNET_JSON_parse_free (spec);
+//   }
+//   return GNUNET_OK;
+// }
+
+
+// /**
+//  * Sign future keys.
+//  *
+//  * @param args the array of command-line arguments to process next
+//  */
+// static void
+// do_sign (char *const *args)
+// {
+//   json_t *keys;
+//   const char *err_name;
+//   unsigned int err_line;
+//   const json_t *denomkeys;
+//   const json_t *signkeys;
+//   struct TALER_MasterPublicKeyP mpub;
+//   struct TALER_SecurityModulePublicKeySetP secmset;
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_array_const ("future_denoms",
+//                                   &denomkeys),
+//     GNUNET_JSON_spec_array_const ("future_signkeys",
+//                                   &signkeys),
+//     GNUNET_JSON_spec_fixed_auto ("master_pub",
+//                                  &mpub),
+//     GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
+//                                  &secmset.rsa),
+//     GNUNET_JSON_spec_fixed_auto ("denom_secmod_cs_public_key",
+//                                  &secmset.cs),
+//     GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
+//                                  &secmset.eddsa),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   keys = parse_keys_input ("sign");
+//   if (NULL == keys)
+//     return;
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//   {
+//     json_decref (keys);
+//     return;
+//   }
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (keys,
+//                          spec,
+//                          &err_name,
+//                          &err_line))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Invalid input to 'sign' : %s #%u (skipping)\n",
+//                 err_name,
+//                 err_line);
+//     json_dumpf (in,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     json_decref (keys);
+//     return;
+//   }
+//   if (0 !=
+//       GNUNET_memcmp (&master_pub,
+//                      &mpub))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Fatal: donau uses different master key!\n");
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     json_decref (keys);
+//     return;
+//   }
+//   if (GNUNET_SYSERR ==
+//       tofu_check (&secmset))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Fatal: security module keys changed!\n");
+//     global_ret = EXIT_FAILURE;
+//     test_shutdown ();
+//     json_decref (keys);
+//     return;
+//   }
+//   {
+//     json_t *signkey_sig_array = json_array ();
+//     json_t *denomkey_sig_array = json_array ();
+
+//     GNUNET_assert (NULL != signkey_sig_array);
+//     GNUNET_assert (NULL != denomkey_sig_array);
+//     if ( (GNUNET_OK !=
+//           sign_signkeys (&secmset.eddsa,
+//                          signkeys,
+//                          signkey_sig_array)) ||
+//          (GNUNET_OK !=
+//           sign_denomkeys (&secmset.rsa,
+//                           &secmset.cs,
+//                           denomkeys,
+//                           denomkey_sig_array)) )
+//     {
+//       global_ret = EXIT_FAILURE;
+//       test_shutdown ();
+//       json_decref (signkey_sig_array);
+//       json_decref (denomkey_sig_array);
+//       json_decref (keys);
+//       return;
+//     }
+
+//     output_operation (OP_UPLOAD_SIGS,
+//                       GNUNET_JSON_PACK (
+//                         GNUNET_JSON_pack_array_steal ("denom_sigs",
+//                                                       denomkey_sig_array),
+//                         GNUNET_JSON_pack_array_steal ("signkey_sigs",
+//                                                       signkey_sig_array)));
+//   }
+//   json_decref (keys);
+//   next (args);
+// }
+
+
+// /**
+//  * Setup and output offline signing key.
+//  *
+//  * @param args the array of command-line arguments to process next
+//  */
+// static void
+// do_setup (char *const *args)
+// {
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_YES))
+//   {
+//     global_ret = EXIT_NOPERMISSION;
+//     return;
+//   }
+//   if (NULL != *args)
+//   {
+//     output_operation (OP_SETUP,
+//                       GNUNET_JSON_PACK (
+//                         GNUNET_JSON_pack_data_auto ("donau_offline_pub",
+//                                                     &master_pub)));
+//   }
+
+//   else
+//   {
+//     char *pub_s;
+
+//     pub_s = GNUNET_STRINGS_data_to_string_alloc (&master_pub,
+//                                                  sizeof (master_pub));
+//     fprintf (stdout,
+//              "%s\n",
+//              pub_s);
+//     GNUNET_free (pub_s);
+//   }
+//   if ( (NULL != *args) &&
+//        (0 == strcmp (*args,
+//                      "-")) )
+//     args++;
+//   next (args);
+// }
+
+
+// /**
+//  * Print the current extensions as configured
+//  *
+//  * @param args the array of command-line arguments to process next
+//  */
+// static void
+// do_extensions_show (char *const *args)
+// {
+//   const struct TALER_Extensions *it;
+//   json_t *exts = json_object ();
+//   json_t *obj;
+
+//   GNUNET_assert (NULL != exts);
+//   for (it = TALER_extensions_get_head ();
+//        NULL != it && NULL != it->extension;
+//        it = it->next)
+//   {
+//     const struct TALER_Extension *extension = it->extension;
+//     int ret;
+
+//     ret = json_object_set_new (exts,
+//                                extension->name,
+//                                extension->manifest (extension));
+//     GNUNET_assert (-1 != ret);
+//   }
+
+//   obj = GNUNET_JSON_PACK (
+//     GNUNET_JSON_pack_object_steal ("extensions",
+//                                    exts));
+//   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+//               "%s\n",
+//               json_dumps (obj,
+//                           JSON_INDENT (2)));
+//   json_decref (obj);
+//   next (args);
+// }
+
+
+// /**
+//  * Sign the configurations of the enabled extensions
+//  */
+// static void
+// do_extensions_sign (char *const *args)
+// {
+//   json_t *extensions = json_object ();
+//   struct TALER_ExtensionManifestsHashP h_manifests;
+//   struct TALER_MasterSignatureP sig;
+//   const struct TALER_Extensions *it;
+//   bool found = false;
+//   json_t *obj;
+
+//   GNUNET_assert (NULL != extensions);
+//   for (it = TALER_extensions_get_head ();
+//        NULL != it && NULL != it->extension;
+//        it = it->next)
+//   {
+//     const struct TALER_Extension *ext = it->extension;
+//     GNUNET_assert (ext);
+
+//     found = true;
+
+//     GNUNET_assert (0 ==
+//                    json_object_set_new (extensions,
+//                                         ext->name,
+//                                         ext->manifest (ext)));
+//   }
+
+//   if (! found)
+//     return;
+
+//   if (GNUNET_OK !=
+//       TALER_JSON_extensions_manifests_hash (extensions,
+//                                             &h_manifests))
+//   {
+//     json_decref (extensions);
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "error while hashing manifest for extensions\n");
+//     return;
+//   }
+
+//   if (GNUNET_OK !=
+//       load_offline_key (GNUNET_NO))
+//   {
+//     json_decref (extensions);
+//     return;
+//   }
+
+//   TALER_donau_offline_extension_manifests_hash_sign (&h_manifests,
+//                                                      &master_priv,
+//                                                      &sig);
+//   obj = GNUNET_JSON_PACK (
+//     GNUNET_JSON_pack_object_steal ("extensions",
+//                                    extensions),
+//     GNUNET_JSON_pack_data_auto (
+//       "extensions_sig",
+//       &sig));
+
+//   output_operation (OP_EXTENSIONS,
+//                     obj);
+//   next (args);
+// }
+
+
+// /**
+//  * Dispatch @a args in the @a cmds array.
+//  *
+//  * @param args arguments with subcommand to dispatch
+//  * @param cmds array of possible subcommands to call
+//  */
+// static void
+// cmd_handler (char *const *args,
+//              const struct SubCommand *cmds)
+// {
+//   nxt = NULL;
+//   for (unsigned int i = 0; NULL != cmds[i].name; i++)
+//   {
+//     if (0 == strcasecmp (cmds[i].name,
+//                          args[0]))
+//     {
+//       cmds[i].cb (&args[1]);
+//       return;
+//     }
+//   }
+
+//   if (0 != strcasecmp ("help",
+//                        args[0]))
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+//                 "Unexpected command `%s'\n",
+//                 args[0]);
+//     global_ret = EXIT_INVALIDARGUMENT;
+//   }
+
+//   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+//               "Supported subcommands:\n");
+//   for (unsigned int i = 0; NULL != cmds[i].name; i++)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+//                 "- %s: %s\n",
+//                 cmds[i].name,
+//                 cmds[i].help);
+//   }
+//   json_decref (out);
+//   out = NULL;
+//   GNUNET_SCHEDULER_shutdown ();
+// }
+
+
+// static void
+// do_work_extensions (char *const *args)
+// {
+//   struct SubCommand cmds[] = {
+//     {
+//       .name = "show",
+//       .help =
+//         "show the extensions in the Taler-config and their configured 
parameters",
+//       .cb = &do_extensions_show
+//     },
+//     {
+//       .name = "sign",
+//       .help =
+//         "sign the configuration of the extensions and publish it with the 
donau",
+//       .cb = &do_extensions_sign
+//     },
+//     {
+//       .name = NULL,
+//     }
+//   };
+
+//   if (NULL == args[0])
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "You must provide a subcommand: `show` or `sign`.\n");
+//     test_shutdown ();
+//     global_ret = EXIT_INVALIDARGUMENT;
+//     return;
+//   }
+
+//   cmd_handler (args, cmds);
+// }
+
+
+// static void
+// work (void *cls)
+// {
+//   char *const *args = cls;
+//   struct SubCommand cmds[] = {
+//     {
+//       .name = "setup",
+//       .help =
+//         "initialize offline key signing material and display public offline 
key",
+//       .cb = &do_setup
+//     },
+//     {
+//       .name = "download",
+//       .help =
+//         "obtain future public keys from donau (to be performed online!)",
+//       .cb = &do_download
+//     },
+//     {
+//       .name = "show",
+//       .help =
+//         "display future public keys from donau for human review (pass '-' 
as argument to disable consuming input)",
+//       .cb = &do_show
+//     },
+//     {
+//       .name = "sign",
+//       .help = "sign all future public keys from the input",
+//       .cb = &do_sign
+//     },
+//     {
+//       .name = "revoke-denomination",
+//       .help =
+//         "revoke denomination key (hash of public key must be given as 
argument)",
+//       .cb = &do_revoke_denomination_key
+//     },
+//     {
+//       .name = "revoke-signkey",
+//       .help =
+//         "revoke donau online signing key (public key must be given as 
argument)",
+//       .cb = &do_revoke_signkey
+//     },
+//     {
+//       .name = "enable-auditor",
+//       .help =
+//         "enable auditor for the donau (auditor-public key, auditor-URI and 
auditor-name must be given as arguments)",
+//       .cb = &do_add_auditor
+//     },
+//     {
+//       .name = "disable-auditor",
+//       .help =
+//         "disable auditor at the donau (auditor-public key must be given as 
argument)",
+//       .cb = &do_del_auditor
+//     },
+//     {
+//       .name = "enable-account",
+//       .help =
+//         "enable wire account of the donau (payto-URI must be given as 
argument; for optional argument see man page)",
+//       .cb = &do_add_wire
+//     },
+//     {
+//       .name = "disable-account",
+//       .help =
+//         "disable wire account of the donau (payto-URI must be given as 
argument)",
+//       .cb = &do_del_wire
+//     },
+//     {
+//       .name = "wire-fee",
+//       .help =
+//         "sign wire fees for the given year (year, wire method, wire fee, 
and closing fee must be given as arguments)",
+//       .cb = &do_set_wire_fee
+//     },
+//     {
+//       .name = "global-fee",
+//       .help =
+//         "sign global fees for the given year (year, history fee, account 
fee, purse fee, purse timeout, history expiration and the maximum number of 
free purses per account must be given as arguments)",
+//       .cb = &do_set_global_fee
+//     },
+//     {
+//       .name = "drain",
+//       .help =
+//         "drain profits from donau escrow account to regular donau operator 
account (amount, debit account configuration section and credit account 
payto://-URI must be given as arguments)",
+//       .cb = &do_drain
+//     },
+//     {
+//       .name = "add-partner",
+//       .help =
+//         "add partner donau for P2P wad transfers (partner master public 
key, partner base URL, wad fee, wad frequency and validity year must be given 
as arguments)",
+//       .cb = &do_add_partner
+//     },
+//     {
+//       .name = "aml-enable",
+//       .help =
+//         "enable AML staff member (staff member public key, legal name and 
rw (read write) or ro (read only) must be given as arguments)",
+//       .cb = &enable_aml_staff
+//     },
+//     {
+//       .name = "aml-disable",
+//       .help =
+//         "disable AML staff member (staff member public key and legal name 
must be given as arguments)",
+//       .cb = &disable_aml_staff
+//     },
+//     {
+//       .name = "upload",
+//       .help =
+//         "upload operation result to donau (to be performed online!)",
+//       .cb = &do_upload
+//     },
+//     {
+//       .name = "extensions",
+//       .help = "subcommands for extension handling",
+//       .cb = &do_work_extensions
+//     },
+//     /* list terminator */
+//     {
+//       .name = NULL,
+//     }
+//   };
+//   (void) cls;
+
+//   cmd_handler (args, cmds);
+// }
+
+
+// /**
+//  * Main function that will be run.
+//  *
+//  * @param cls closure
+//  * @param args remaining command-line arguments
+//  * @param cfgfile name of the configuration file used (for saving, can be 
NULL!)
+//  * @param cfg configuration
+//  */
+// static void
+// run (void *cls,
+//      char *const *args,
+//      const char *cfgfile,
+//      const struct GNUNET_CONFIGURATION_Handle *cfg)
+// {
+//   (void) cls;
+//   (void) cfgfile;
+//   kcfg = cfg;
+
+//   /* load extensions */
+//   GNUNET_assert (GNUNET_OK ==
+//                  TALER_extensions_init (kcfg));
+
+//   /* setup age restriction, if applicable */
+//   {
+//     const struct TALER_AgeRestrictionConfig *arc;
+
+//     if (NULL !=
+//         (arc = TALER_extensions_get_age_restriction_config ()))
+//     {
+//       ar_config  = *arc;
+//       ar_enabled = true;
+//     }
+//   }
+
+
+//   if (GNUNET_OK !=
+//       TALER_config_get_currency (kcfg,
+//                                  &currency))
+//   {
+//     global_ret = EXIT_NOTCONFIGURED;
+//     return;
+//   }
+
+//   ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
+//                           &rc);
+//   rc = GNUNET_CURL_gnunet_rc_create (ctx);
+//   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+//                                  NULL);
+//   next (args);
+// }
+
+
+// /**
+//  * The main function of the taler-donau-offline tool.  This tool is used to
+//  * create the signing and denomination keys for the donau.  It uses the
+//  * long-term offline private key and generates signatures with it. It also
+//  * supports online operations with the donau to download its input data and
+//  * to upload its results. Those online operations should be performed on
+//  * another machine in production!
+//  *
+//  * @param argc number of arguments from the command line
+//  * @param argv command line arguments
+//  * @return 0 ok, 1 on error
+//  */
 int
 main (int argc,
       char *const *argv)
@@ -5405,18 +5405,18 @@ main (int argc,
   /* force linker to link against libtalerutil; if we do
      not do this, the linker may "optimize" libtalerutil
      away and skip #TALER_OS_init(), which we do need */
-  (void) TALER_project_data_default ();
+  // (void) TALER_project_data_default ();
   if (GNUNET_OK !=
       GNUNET_STRINGS_get_utf8_args (argc, argv,
                                     &argc, &argv))
     return EXIT_INVALIDARGUMENT;
-  TALER_OS_init ();
-  ret = GNUNET_PROGRAM_run (
-    argc, argv,
-    "taler-donau-offline",
-    gettext_noop ("Operations for offline signing for a Taler donau"),
-    options,
-    &run, NULL);
+  // TALER_OS_init ();
+  // ret = GNUNET_PROGRAM_run (
+  //   argc, argv,
+  //   "taler-donau-offline",
+  //   gettext_noop ("Operations for offline signing for a Taler donau"),
+  //   options,
+  //   &run, NULL);
   GNUNET_free_nz ((void *) argv);
   if (GNUNET_SYSERR == ret)
     return EXIT_INVALIDARGUMENT;
diff --git a/src/include/donau_service.h b/src/include/donau_service.h
index 2d73fc1..86a58a4 100644
--- a/src/include/donau_service.h
+++ b/src/include/donau_service.h
@@ -26,9 +26,8 @@
 
 #include <jansson.h>
 #include "taler_util.h"
-#include "taler_donau_util.h"
+#include "donau_util.h"
 #include "taler/taler_error_codes.h"
-#include "taler_kyclogic_lib.h"
 #include <gnunet/gnunet_curl_lib.h>
 
 
@@ -428,33 +427,33 @@ DONAU_get_signing_key_info (
 /* ********************* POST / issue receipt  *********************** */
 
 
-/**
- * @brief Type including Parameters to create blinded signature
- */
-struct TALER_BlindedUniqueDonationIdentifier
-{
-  /**
-   * Type of the sign blinded message
-   */
-  enum TALER_DenominationCipher cipher;
+// /**
+//  * @brief Type including Parameters to create blinded signature
+//  */
+// struct TALER_BlindedUniqueDonationIdentifier
+// {
+//   /**
+//    * Type of the sign blinded message
+//    */
+//   enum TALER_DenominationCipher cipher;
 
-  /**
-   * Details, depending on @e cipher.
-   */
-  union
-  {
-    /**
-     * If we use #TALER_DENOMINATION_CS in @a cipher.
-     */
-    struct TALER_BlindedCsPlanchet cs_blinded_donor;
+//   /**
+//    * Details, depending on @e cipher.
+//    */
+//   union
+//   {
+//     /**
+//      * If we use #TALER_DENOMINATION_CS in @a cipher.
+//      */
+//     struct TALER_BlindedCsPlanchet cs_blinded_donor;
 
-    /**
-     * If we use #TALER_DENOMINATION_RSA in @a cipher.
-     */
-    struct TALER_BlindedRsaPlanchet rsa_blinded_donor;
+//     /**
+//      * If we use #TALER_DENOMINATION_RSA in @a cipher.
+//      */
+//     struct TALER_BlindedRsaPlanchet rsa_blinded_donor;
 
-  } details;
-};
+//   } details;
+// };
 
 /**
  * @brief A Batch Submit Handle
@@ -543,15 +542,15 @@ typedef void
  * @return a handle for this request; NULL if the inputs are invalid (i.e.
  *         signatures fail to verify).  In this case, the callback is not 
called.
  */
-struct DONAU_BatchIssueReceiptHandle *
-DONAU_charity_issue_receipt (
-  struct GNUNET_CURL_Context *ctx,
-  const char *url,
-  const struct DONAU_CharityPrivateKeyP *charity_priv,
-  unsigned int num_bkp,
-  const struct TALER_BlindedUniqueDonationIdentifierKeyPair bkp[static 
num_bkp],
-  DONAU_BatchIssueReceiptsCallback cb,
-  void *cb_cls);
+// struct DONAU_BatchIssueReceiptHandle *
+// DONAU_charity_issue_receipt (
+//   struct GNUNET_CURL_Context *ctx,
+//   const char *url,
+//   const struct DONAU_CharityPrivateKeyP *charity_priv,
+//   unsigned int num_bkp,
+//   const struct TALER_BlindedUniqueDonationIdentifierKeyPair bkp[static 
num_bkp],
+//   DONAU_BatchIssueReceiptsCallback cb,
+//   void *cb_cls);
 
 /**
  * Cancel a batch issue receipt request. This function cannot be used
@@ -711,43 +710,43 @@ DONAU_donor_receipts_to_statement_cancel (
 struct DONAU_CsRBatchIssueHandle;
 
 
-/**
- * Details about a response for a CS R request.
- */
-struct DONAU_CsRBatchIssueResponse
-{
-  /**
-   * HTTP response data.
-   */
-  struct DONAU_HttpResponse hr;
-
-  /**
-   * Details about the response.
-   */
-  union
-  {
-    /**
-     * Details if the status is #MHD_HTTP_OK.
-     */
-    struct
-    {
-      /**
-       * Values contributed by the donau for the
-       * respective coin's batch-issue operation.
-       */
-      struct TALER_DonauBatchIssueValues alg_values;
-    } ok;
-
-    /**
-     * Details if the status is #MHD_HTTP_GONE.
-     */
-    struct
-    {
-      /* TODO: returning full details is not implemented */
-    } gone;
-
-  } details;
-};
+// /**
+//  * Details about a response for a CS R request.
+//  */
+// struct DONAU_CsRBatchIssueResponse
+// {
+//   /**
+//    * HTTP response data.
+//    */
+//   struct DONAU_HttpResponse hr;
+
+//   /**
+//    * Details about the response.
+//    */
+//   union
+//   {
+//     /**
+//      * Details if the status is #MHD_HTTP_OK.
+//      */
+//     struct
+//     {
+//       /**
+//        * Values contributed by the donau for the
+//        * respective coin's batch-issue operation.
+//        */
+//       struct TALER_DonauBatchIssueValues alg_values;
+//     } ok;
+
+//     /**
+//      * Details if the status is #MHD_HTTP_GONE.
+//      */
+//     struct
+//     {
+//       /* TODO: returning full details is not implemented */
+//     } gone;
+
+//   } details;
+// };
 
 
 /**
@@ -757,10 +756,10 @@ struct DONAU_CsRBatchIssueResponse
  * @param cls closure
  * @param csrr response details
  */
-typedef void
-(*DONAU_CsRBatchIssueCallback) (
-  void *cls,
-  const struct DONAU_CsRBatchIssueResponse *csrr);
+// typedef void
+// (*DONAU_CsRBatchIssueCallback) (
+//   void *cls,
+//   const struct DONAU_CsRBatchIssueResponse *csrr);
 
 
 /**
@@ -776,14 +775,14 @@ typedef void
  *         if the inputs are invalid (i.e.donation unit key not with this 
donau).
  *         In this case, the callback is not called.
  */
-struct DONAU_CsRBatchIssueHandle *
-DONAU_csr_batch_issue (
-  struct GNUNET_CURL_Context *curl_ctx,
-  const char *donau_url,
-  const struct DONAU_DonationUnitPublicKey *pk,
-  const struct TALER_CsNonce *nonce,
-  DONAU_CsRBatchIssueCallback res_cb,
-  void *res_cb_cls);
+// struct DONAU_CsRBatchIssueHandle *
+// DONAU_csr_batch_issue (
+//   struct GNUNET_CURL_Context *curl_ctx,
+//   const char *donau_url,
+//   const struct DONAU_DonationUnitPublicKey *pk,
+//   const struct TALER_CsNonce *nonce,
+//   DONAU_CsRBatchIssueCallback res_cb,
+//   void *res_cb_cls);
 
 
 /**
@@ -793,9 +792,9 @@ DONAU_csr_batch_issue (
  *
  * @param csrh the batch-issue handle
  */
-void
-DONAU_csr_batch_issue_cancel (
-  struct DONAU_CsRBatchIssueHandle *csrh);
+// void
+// DONAU_csr_batch_issue_cancel (
+//   struct DONAU_CsRBatchIssueHandle *csrh);
 
 
 /* ********************* GET /charities/ *********************** */
@@ -818,12 +817,12 @@ struct CharitySummary
   /**
    * Max donation amout for this charitiy and year.
    */
-  struct TALER_Amount amount;
+  // struct TALER_Amount amount;
 
   /**
    * Current donation amount for this charity and year.
    */
-  struct TALER_Amount amount;
+  // struct TALER_Amount amount;
 
 };
 
@@ -920,9 +919,9 @@ DONAU_charities_get (
  *
  * @param rgh the charity request handle
  */
-void
-DONAU_charities_get_cancel (
-  struct DONAU_charitiesGetHandle *rgh);
+// void
+// DONAU_charities_get_cancel (
+//   struct DONAU_charitiesGetHandle *rgh);
 
 
 /* ********************* GET /charities/$CHARITY_ID *********************** */
@@ -1059,9 +1058,9 @@ DONAU_charity_get (
  *
  * @param rgh the charity request handle
  */
-void
-DONAU_charity_get_cancel (
-  struct DONAU_charityGetHandle *rgh);
+// void
+// DONAU_charity_get_cancel (
+//   struct DONAU_charityGetHandle *rgh);
 
 
 /* ********************* POST /charities/ *********************** */
@@ -1160,14 +1159,14 @@ typedef void
  * @return a handle for this request; NULL if the inputs are invalid (i.e.
  *         signatures fail to verify).  In this case, the callback is not 
called.
  */
-struct DONAU_CharityPostHandle *
-DONAU_charity_post (
-  struct GNUNET_CURL_Context *ctx,
-  const char *url,
-  const charityRequest charity_req,
-  const struct DONAU_BearerToken bearer,
-  DONAU_PostCharityResponseCallback cb,
-  void *cb_cls);
+// struct DONAU_CharityPostHandle *
+// DONAU_charity_post (
+//   struct GNUNET_CURL_Context *ctx,
+//   const char *url,
+//   const charityRequest charity_req,
+//   const struct DONAU_BearerToken bearer,
+//   DONAU_PostCharityResponseCallback cb,
+//   void *cb_cls);
 
 /**
  * Cancel a charity Post request. This function cannot be used
@@ -1175,9 +1174,9 @@ DONAU_charity_post (
  *
  * @param rgh the charity post handle
  */
-void
-DONAU_charity_post_cancel (
-  struct DONAU_charityPostHandle *rgh);
+// void
+// DONAU_charity_post_cancel (
+//   struct DONAU_charityPostHandle *rgh);
 
 /* ********************* PATCH /charities/$CHARITY_ID *********************** 
*/
 
@@ -1245,9 +1244,9 @@ DONAU_charity_patch (
  *
  * @param rgh the charity patch handle
  */
-void
-DONAU_charity_patch_cancel (
-  struct DONAU_charityPatchHandle *rgh);
+// void
+// DONAU_charity_patch_cancel (
+//   struct DONAU_charityPatchHandle *rgh);
 
 
 /* ********************* DELETE /charities/$CHARITY_ID *********************** 
*/
@@ -1318,3 +1317,5 @@ DONAU_charity_delete (
 void
 DONAU_charity_post_delete (
   struct DONAU_CharityDeleteHandle *rgh);
+
+#endif
\ No newline at end of file
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 8035ae6..1b2fe8c 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -1,128 +1,35 @@
 # This Makefile.am is in the public domain
 
 AM_CPPFLAGS = \
-  -I$(top_srcdir)/src/include \
-  $(LIBGCRYPT_CFLAGS) \
-  $(POSTGRESQL_CPPFLAGS)
+       -I$(top_srcdir)/src/include \
+       $(LIBGCRYPT_CFLAGS) \
+       $(POSTGRESQL_CPPFLAGS)
 
 if USE_COVERAGE
-  AM_CFLAGS = --coverage -O0
-  XLIB = -lgcov
+       AM_CFLAGS = --coverage -O0
+       XLIB = -lgcov
 endif
 
 
 # Libraries
 
 lib_LTLIBRARIES = \
-  libtalerauditor.la \
-  libtalerdonau.la
+       libtalerdonau.la
 
 libtalerdonau_la_LDFLAGS = \
-  -version-info 5:0:0 \
-  -no-undefined
-libtalerdonau_la_SOURCES = \
-  donau_api_add_aml_decision.c \
-  donau_api_age_withdraw.c \
-  donau_api_age_withdraw_reveal.c \
-  donau_api_auditor_add_denomination.c \
-  donau_api_batch_deposit.c \
-  donau_api_batch_withdraw.c \
-  donau_api_batch_withdraw2.c \
-  donau_api_curl_defaults.c donau_api_curl_defaults.h \
-  donau_api_common.c donau_api_common.h \
-  donau_api_contracts_get.c \
-  donau_api_csr_melt.c \
-  donau_api_csr_withdraw.c \
-  donau_api_handle.c donau_api_handle.h \
-  donau_api_deposits_get.c \
-  donau_api_kyc_check.c \
-  donau_api_kyc_proof.c \
-  donau_api_kyc_wallet.c \
-  donau_api_link.c \
-  donau_api_lookup_aml_decision.c \
-  donau_api_lookup_aml_decisions.c \
-  donau_api_management_add_partner.c \
-  donau_api_management_auditor_disable.c \
-  donau_api_management_auditor_enable.c \
-  donau_api_management_drain_profits.c \
-  donau_api_management_get_keys.c \
-  donau_api_management_post_keys.c \
-  donau_api_management_post_extensions.c \
-  donau_api_management_revoke_denomination_key.c \
-  donau_api_management_revoke_signing_key.c \
-  donau_api_management_set_global_fee.c \
-  donau_api_management_set_wire_fee.c \
-  donau_api_management_update_aml_officer.c \
-  donau_api_management_wire_disable.c \
-  donau_api_management_wire_enable.c \
-  donau_api_melt.c \
-  donau_api_purse_create_with_deposit.c \
-  donau_api_purse_create_with_merge.c \
-  donau_api_purse_delete.c \
-  donau_api_purse_deposit.c \
-  donau_api_purse_merge.c \
-  donau_api_purses_get.c \
-  donau_api_recoup.c \
-  donau_api_recoup_refresh.c \
-  donau_api_refresh_common.c donau_api_refresh_common.h \
-  donau_api_refreshes_reveal.c \
-  donau_api_refund.c \
-  donau_api_reserves_attest.c \
-  donau_api_reserves_close.c \
-  donau_api_reserves_get.c \
-  donau_api_reserves_get_attestable.c \
-  donau_api_reserves_history.c \
-  donau_api_reserves_open.c \
-  donau_api_reserves_status.c \
-  donau_api_stefan.c \
-  donau_api_transfers_get.c \
-  donau_api_withdraw.c \
-  donau_api_withdraw2.c
-libtalerdonau_la_LIBADD = \
-  libtalerauditor.la \
-  $(top_builddir)/src/json/libtalerjson.la \
-  $(top_builddir)/src/kyclogic/libtalerkyclogic.la \
-  $(top_builddir)/src/curl/libtalercurl.la \
-  $(top_builddir)/src/util/libtalerdonauutil.la \
-  $(top_builddir)/src/extensions/libtalerextensions.la \
-  -lgnunetcurl \
-  -lgnunetjson \
-  -lgnunetutil \
-  -ljansson \
-  $(LIBGNURLCURL_LIBS) \
-  $(XLIB)
-
-libtalerauditor_la_LDFLAGS = \
-  -version-info 0:0:0 \
-  -no-undefined
-libtalerauditor_la_SOURCES = \
-  auditor_api_curl_defaults.c auditor_api_curl_defaults.h \
-  auditor_api_get_config.c \
-  auditor_api_deposit_confirmation.c \
-  auditor_api_donaus.c
-libtalerauditor_la_LIBADD = \
-  $(top_builddir)/src/curl/libtalercurl.la \
-  $(top_builddir)/src/json/libtalerjson.la \
-  $(top_builddir)/src/util/libtalerdonauutil.la \
-  -lgnunetcurl \
-  -lgnunetjson \
-  -lgnunetutil \
-  -ljansson \
-  -lm \
-  $(LIBGNURLCURL_LIBS) \
-  $(XLIB)
-
-
-check_PROGRAMS = \
- test_stefan
-
-TESTS = \
- $(check_PROGRAMS)
+       -version-info 5:0:0 \
+       -no-undefined
 
+libtalerdonau_la_SOURCES = \
+       donau_api_charities_open.c      
 
-test_stefan_SOURCES = \
-  test_stefan.c
-test_stefan_LDADD = \
-  $(top_builddir)/src/lib/libtalerdonau.la \
-  $(top_builddir)/src/util/libtalerdonauutil.la \
-  -lgnunetutil
+# maybe need libtalercurl
+libtalerdonau_la_LIBADD = \
+       $(top_builddir)/src/json/libtalerjson.la \
+       $(top_builddir)/src/util/libtalerdonauutil.la \
+       -lgnunetcurl \
+       -lgnunetjson \
+       -lgnunetutil \
+       -ljansson \
+       $(LIBGNURLCURL_LIBS) \
+       $(XLIB)
diff --git a/src/lib/donau_api_charities_open.c 
b/src/lib/donau_api_charities_open.c
index f2509d8..57baa11 100644
--- a/src/lib/donau_api_charities_open.c
+++ b/src/lib/donau_api_charities_open.c
@@ -25,7 +25,7 @@
 #include <gnunet/gnunet_util_lib.h>
 #include <gnunet/gnunet_json_lib.h>
 #include <gnunet/gnunet_curl_lib.h>
-#include "taler_donau_service.h"
+#include "donau_service.h"
 #include "taler/taler_json_lib.h"
 #include "donau_api_common.h"
 #include "donau_api_handle.h"
@@ -63,66 +63,66 @@ struct CoinData
 /**
  * @brief A /reserves/$RID/open Handle
  */
-struct DONAU_ReservesOpenHandle
-{
-
-  /**
-   * The keys of the donau this request handle will use
-   */
-  struct DONAU_Keys *keys;
-
-  /**
-   * The url for this request.
-   */
-  char *url;
-
-  /**
-   * Handle for the request.
-   */
-  struct GNUNET_CURL_Job *job;
-
-  /**
-   * Context for #TEH_curl_easy_post(). Keeps the data that must
-   * persist for Curl to make the upload.
-   */
-  struct TALER_CURL_PostContext post_ctx;
-
-  /**
-   * Function to call with the result.
-   */
-  DONAU_ReservesOpenCallback cb;
-
-  /**
-   * Closure for @a cb.
-   */
-  void *cb_cls;
-
-  /**
-   * Information we keep per coin to validate the reply.
-   */
-  struct CoinData *coins;
-
-  /**
-   * Length of the @e coins array.
-   */
-  unsigned int num_coins;
-
-  /**
-   * Public key of the reserve we are querying.
-   */
-  struct TALER_ReservePublicKeyP reserve_pub;
-
-  /**
-   * Our signature.
-   */
-  struct TALER_ReserveSignatureP reserve_sig;
-
-  /**
-   * When did we make the request.
-   */
-  struct GNUNET_TIME_Timestamp ts;
-
-};
+// struct DONAU_ReservesOpenHandle
+// {
+
+//   /**
+//    * The keys of the donau this request handle will use
+//    */
+//   struct DONAU_Keys *keys;
+
+//   /**
+//    * The url for this request.
+//    */
+//   char *url;
+
+//   /**
+//    * Handle for the request.
+//    */
+//   struct GNUNET_CURL_Job *job;
+
+//   /**
+//    * Context for #TEH_curl_easy_post(). Keeps the data that must
+//    * persist for Curl to make the upload.
+//    */
+//   struct TALER_CURL_PostContext post_ctx;
+
+//   /**
+//    * Function to call with the result.
+//    */
+//   DONAU_ReservesOpenCallback cb;
+
+//   /**
+//    * Closure for @a cb.
+//    */
+//   void *cb_cls;
+
+//   /**
+//    * Information we keep per coin to validate the reply.
+//    */
+//   struct CoinData *coins;
+
+//   /**
+//    * Length of the @e coins array.
+//    */
+//   unsigned int num_coins;
+
+//   /**
+//    * Public key of the reserve we are querying.
+//    */
+//   struct TALER_ReservePublicKeyP reserve_pub;
+
+//   /**
+//    * Our signature.
+//    */
+//   struct TALER_ReserveSignatureP reserve_sig;
+
+//   /**
+//    * When did we make the request.
+//    */
+//   struct GNUNET_TIME_Timestamp ts;
+
+// };
 
 
 /**
@@ -133,459 +133,459 @@ struct DONAU_ReservesOpenHandle
  * @param j JSON response
  * @return #GNUNET_OK on success
  */
-static enum GNUNET_GenericReturnValue
-handle_reserves_open_ok (struct DONAU_ReservesOpenHandle *roh,
-                         const json_t *j)
-{
-  struct DONAU_ReserveOpenResult rs = {
-    .hr.reply = j,
-    .hr.http_status = MHD_HTTP_OK,
-  };
-  struct GNUNET_JSON_Specification spec[] = {
-    TALER_JSON_spec_amount_any ("open_cost",
-                                &rs.details.ok.open_cost),
-    GNUNET_JSON_spec_timestamp ("reserve_expiration",
-                                &rs.details.ok.expiration_time),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (j,
-                         spec,
-                         NULL,
-                         NULL))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  roh->cb (roh->cb_cls,
-           &rs);
-  roh->cb = NULL;
-  GNUNET_JSON_parse_free (spec);
-  return GNUNET_OK;
-}
-
-
-/**
- * We received an #MHD_HTTP_PAYMENT_REQUIRED open code. Handle the JSON
- * response.
- *
- * @param roh handle of the request
- * @param j JSON response
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-handle_reserves_open_pr (struct DONAU_ReservesOpenHandle *roh,
-                         const json_t *j)
-{
-  struct DONAU_ReserveOpenResult rs = {
-    .hr.reply = j,
-    .hr.http_status = MHD_HTTP_PAYMENT_REQUIRED,
-  };
-  struct GNUNET_JSON_Specification spec[] = {
-    TALER_JSON_spec_amount_any ("open_cost",
-                                &rs.details.payment_required.open_cost),
-    GNUNET_JSON_spec_timestamp ("reserve_expiration",
-                                &rs.details.payment_required.expiration_time),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (j,
-                         spec,
-                         NULL,
-                         NULL))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  roh->cb (roh->cb_cls,
-           &rs);
-  roh->cb = NULL;
-  GNUNET_JSON_parse_free (spec);
-  return GNUNET_OK;
-}
-
-
-/**
- * We received an #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS open code. Handle 
the JSON
- * response.
- *
- * @param roh handle of the request
- * @param j JSON response
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-handle_reserves_open_kyc (struct DONAU_ReservesOpenHandle *roh,
-                          const json_t *j)
-{
-  struct DONAU_ReserveOpenResult rs = {
-    .hr.reply = j,
-    .hr.http_status = MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
-  };
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_fixed_auto (
-      "h_payto",
-      &rs.details.unavailable_for_legal_reasons.h_payto),
-    GNUNET_JSON_spec_uint64 (
-      "requirement_row",
-      &rs.details.unavailable_for_legal_reasons.requirement_row),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (j,
-                         spec,
-                         NULL,
-                         NULL))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  roh->cb (roh->cb_cls,
-           &rs);
-  roh->cb = NULL;
-  GNUNET_JSON_parse_free (spec);
-  return GNUNET_OK;
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /reserves/$RID/open request.
- *
- * @param cls the `struct DONAU_ReservesOpenHandle`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_reserves_open_finished (void *cls,
-                               long response_code,
-                               const void *response)
-{
-  struct DONAU_ReservesOpenHandle *roh = cls;
-  const json_t *j = response;
-  struct DONAU_ReserveOpenResult rs = {
-    .hr.reply = j,
-    .hr.http_status = (unsigned int) response_code
-  };
-
-  roh->job = NULL;
-  switch (response_code)
-  {
-  case 0:
-    rs.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
-    break;
-  case MHD_HTTP_OK:
-    if (GNUNET_OK !=
-        handle_reserves_open_ok (roh,
-                                 j))
-    {
-      GNUNET_break_op (0);
-      rs.hr.http_status = 0;
-      rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
-    }
-    break;
-  case MHD_HTTP_BAD_REQUEST:
-    /* This should never happen, either us or the donau is buggy
-       (or API version conflict); just pass JSON reply to the application */
-    GNUNET_break (0);
-    json_dumpf (j,
-                stderr,
-                JSON_INDENT (2));
-    rs.hr.ec = TALER_JSON_get_error_code (j);
-    rs.hr.hint = TALER_JSON_get_error_hint (j);
-    break;
-  case MHD_HTTP_PAYMENT_REQUIRED:
-    if (GNUNET_OK !=
-        handle_reserves_open_pr (roh,
-                                 j))
-    {
-      GNUNET_break_op (0);
-      rs.hr.http_status = 0;
-      rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
-    }
-    break;
-  case MHD_HTTP_FORBIDDEN:
-    /* This should never happen, either us or the donau is buggy
-       (or API version conflict); just pass JSON reply to the application */
-    GNUNET_break (0);
-    rs.hr.ec = TALER_JSON_get_error_code (j);
-    rs.hr.hint = TALER_JSON_get_error_hint (j);
-    break;
-  case MHD_HTTP_NOT_FOUND:
-    /* Nothing really to verify, this should never
-       happen, we should pass the JSON reply to the application */
-    rs.hr.ec = TALER_JSON_get_error_code (j);
-    rs.hr.hint = TALER_JSON_get_error_hint (j);
-    break;
-  case MHD_HTTP_CONFLICT:
-    {
-      const struct CoinData *cd = NULL;
-      struct TALER_CoinSpendPublicKeyP coin_pub;
-      const struct DONAU_DenomPublicKey *dk;
-      struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_fixed_auto ("coin_pub",
-                                     &coin_pub),
-        GNUNET_JSON_spec_end ()
-      };
-
-      if (GNUNET_OK !=
-          GNUNET_JSON_parse (j,
-                             spec,
-                             NULL,
-                             NULL))
-      {
-        GNUNET_break_op (0);
-        rs.hr.http_status = 0;
-        rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
-        break;
-      }
-      for (unsigned int i = 0; i<roh->num_coins; i++)
-      {
-        const struct CoinData *cdi = &roh->coins[i];
-
-        if (0 == GNUNET_memcmp (&coin_pub,
-                                &cdi->coin_pub))
-        {
-          cd = cdi;
-          break;
-        }
-      }
-      if (NULL == cd)
-      {
-        GNUNET_break_op (0);
-        rs.hr.http_status = 0;
-        rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
-        break;
-      }
-      dk = DONAU_get_denomination_key_by_hash (roh->keys,
-                                               &cd->h_denom_pub);
-      if (NULL == dk)
-      {
-        GNUNET_break_op (0);
-        rs.hr.http_status = 0;
-        rs.hr.ec = TALER_EC_GENERIC_CLIENT_INTERNAL_ERROR;
-        break;
-      }
-      if (GNUNET_OK !=
-          DONAU_check_coin_conflict_ (roh->keys,
-                                      j,
-                                      dk,
-                                      &coin_pub,
-                                      &cd->coin_sig,
-                                      &cd->contribution))
-      {
-        GNUNET_break_op (0);
-        rs.hr.http_status = 0;
-        rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
-        break;
-      }
-      rs.hr.ec = TALER_JSON_get_error_code (j);
-      rs.hr.hint = TALER_JSON_get_error_hint (j);
-      break;
-    }
-  case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
-    if (GNUNET_OK !=
-        handle_reserves_open_kyc (roh,
-                                  j))
-    {
-      GNUNET_break_op (0);
-      rs.hr.http_status = 0;
-      rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
-    }
-    break;
-  case MHD_HTTP_INTERNAL_SERVER_ERROR:
-    /* Server had an internal issue; we should retry, but this API
-       leaves this to the application */
-    rs.hr.ec = TALER_JSON_get_error_code (j);
-    rs.hr.hint = TALER_JSON_get_error_hint (j);
-    break;
-  default:
-    /* unexpected response code */
-    GNUNET_break_op (0);
-    rs.hr.ec = TALER_JSON_get_error_code (j);
-    rs.hr.hint = TALER_JSON_get_error_hint (j);
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unexpected response code %u/%d for reserves open\n",
-                (unsigned int) response_code,
-                (int) rs.hr.ec);
-    break;
-  }
-  if (NULL != roh->cb)
-  {
-    roh->cb (roh->cb_cls,
-             &rs);
-    roh->cb = NULL;
-  }
-  DONAU_reserves_open_cancel (roh);
-}
-
-
-struct DONAU_ReservesOpenHandle *
-DONAU_reserves_open (
-  struct GNUNET_CURL_Context *ctx,
-  const char *url,
-  struct DONAU_Keys *keys,
-  const struct TALER_ReservePrivateKeyP *reserve_priv,
-  const struct TALER_Amount *reserve_contribution,
-  unsigned int coin_payments_length,
-  const struct DONAU_PurseDeposit coin_payments[
-    static coin_payments_length],
-  struct GNUNET_TIME_Timestamp expiration_time,
-  uint32_t min_purses,
-  DONAU_ReservesOpenCallback cb,
-  void *cb_cls)
-{
-  struct DONAU_ReservesOpenHandle *roh;
-  CURL *eh;
-  char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
-  json_t *cpa;
-
-  roh = GNUNET_new (struct DONAU_ReservesOpenHandle);
-  roh->cb = cb;
-  roh->cb_cls = cb_cls;
-  roh->ts = GNUNET_TIME_timestamp_get ();
-  GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
-                                      &roh->reserve_pub.eddsa_pub);
-  {
-    char pub_str[sizeof (struct TALER_ReservePublicKeyP) * 2];
-    char *end;
-
-    end = GNUNET_STRINGS_data_to_string (
-      &roh->reserve_pub,
-      sizeof (roh->reserve_pub),
-      pub_str,
-      sizeof (pub_str));
-    *end = '\0';
-    GNUNET_snprintf (arg_str,
-                     sizeof (arg_str),
-                     "reserves/%s/open",
-                     pub_str);
-  }
-  roh->url = TALER_url_join (url,
-                             arg_str,
-                             NULL);
-  if (NULL == roh->url)
-  {
-    GNUNET_free (roh);
-    return NULL;
-  }
-  eh = DONAU_curl_easy_get_ (roh->url);
-  if (NULL == eh)
-  {
-    GNUNET_break (0);
-    GNUNET_free (roh->url);
-    GNUNET_free (roh);
-    return NULL;
-  }
-  TALER_wallet_reserve_open_sign (reserve_contribution,
-                                  roh->ts,
-                                  expiration_time,
-                                  min_purses,
-                                  reserve_priv,
-                                  &roh->reserve_sig);
-  roh->coins = GNUNET_new_array (coin_payments_length,
-                                 struct CoinData);
-  cpa = json_array ();
-  GNUNET_assert (NULL != cpa);
-  for (unsigned int i = 0; i<coin_payments_length; i++)
-  {
-    const struct DONAU_PurseDeposit *pd = &coin_payments[i];
-    const struct TALER_AgeCommitmentProof *acp = pd->age_commitment_proof;
-    struct TALER_AgeCommitmentHash ahac;
-    struct TALER_AgeCommitmentHash *achp = NULL;
-    struct CoinData *cd = &roh->coins[i];
-    json_t *cp;
-
-    cd->contribution = pd->amount;
-    cd->h_denom_pub = pd->h_denom_pub;
-    if (NULL != acp)
-    {
-      TALER_age_commitment_hash (&acp->commitment,
-                                 &ahac);
-      achp = &ahac;
-    }
-    TALER_wallet_reserve_open_deposit_sign (&pd->amount,
-                                            &roh->reserve_sig,
-                                            &pd->coin_priv,
-                                            &cd->coin_sig);
-    GNUNET_CRYPTO_eddsa_key_get_public (&pd->coin_priv.eddsa_priv,
-                                        &cd->coin_pub.eddsa_pub);
-
-    cp = GNUNET_JSON_PACK (
-      GNUNET_JSON_pack_allow_null (
-        GNUNET_JSON_pack_data_auto ("h_age_commitment",
-                                    achp)),
-      TALER_JSON_pack_amount ("amount",
-                              &pd->amount),
-      GNUNET_JSON_pack_data_auto ("denom_pub_hash",
-                                  &pd->h_denom_pub),
-      TALER_JSON_pack_denom_sig ("ub_sig",
-                                 &pd->denom_sig),
-      GNUNET_JSON_pack_data_auto ("coin_pub",
-                                  &cd->coin_pub),
-      GNUNET_JSON_pack_data_auto ("coin_sig",
-                                  &cd->coin_sig));
-    GNUNET_assert (0 ==
-                   json_array_append_new (cpa,
-                                          cp));
-  }
-  {
-    json_t *open_obj = GNUNET_JSON_PACK (
-      GNUNET_JSON_pack_timestamp ("request_timestamp",
-                                  roh->ts),
-      GNUNET_JSON_pack_timestamp ("reserve_expiration",
-                                  expiration_time),
-      GNUNET_JSON_pack_array_steal ("payments",
-                                    cpa),
-      TALER_JSON_pack_amount ("reserve_payment",
-                              reserve_contribution),
-      GNUNET_JSON_pack_uint64 ("purse_limit",
-                               min_purses),
-      GNUNET_JSON_pack_data_auto ("reserve_sig",
-                                  &roh->reserve_sig));
-
-    if (GNUNET_OK !=
-        TALER_curl_easy_post (&roh->post_ctx,
-                              eh,
-                              open_obj))
-    {
-      GNUNET_break (0);
-      curl_easy_cleanup (eh);
-      json_decref (open_obj);
-      GNUNET_free (roh->coins);
-      GNUNET_free (roh->url);
-      GNUNET_free (roh);
-      return NULL;
-    }
-    json_decref (open_obj);
-  }
-  roh->keys = DONAU_keys_incref (keys);
-  roh->job = GNUNET_CURL_job_add2 (ctx,
-                                   eh,
-                                   roh->post_ctx.headers,
-                                   &handle_reserves_open_finished,
-                                   roh);
-  return roh;
-}
-
-
-void
-DONAU_reserves_open_cancel (
-  struct DONAU_ReservesOpenHandle *roh)
-{
-  if (NULL != roh->job)
-  {
-    GNUNET_CURL_job_cancel (roh->job);
-    roh->job = NULL;
-  }
-  TALER_curl_easy_post_finished (&roh->post_ctx);
-  GNUNET_free (roh->coins);
-  GNUNET_free (roh->url);
-  DONAU_keys_decref (roh->keys);
-  GNUNET_free (roh);
-}
+// static enum GNUNET_GenericReturnValue
+// handle_reserves_open_ok (struct DONAU_ReservesOpenHandle *roh,
+//                          const json_t *j)
+// {
+//   struct DONAU_ReserveOpenResult rs = {
+//     .hr.reply = j,
+//     .hr.http_status = MHD_HTTP_OK,
+//   };
+//   struct GNUNET_JSON_Specification spec[] = {
+//     TALER_JSON_spec_amount_any ("open_cost",
+//                                 &rs.details.ok.open_cost),
+//     GNUNET_JSON_spec_timestamp ("reserve_expiration",
+//                                 &rs.details.ok.expiration_time),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (j,
+//                          spec,
+//                          NULL,
+//                          NULL))
+//   {
+//     GNUNET_break_op (0);
+//     return GNUNET_SYSERR;
+//   }
+//   roh->cb (roh->cb_cls,
+//            &rs);
+//   roh->cb = NULL;
+//   GNUNET_JSON_parse_free (spec);
+//   return GNUNET_OK;
+// }
+
+
+// /**
+//  * We received an #MHD_HTTP_PAYMENT_REQUIRED open code. Handle the JSON
+//  * response.
+//  *
+//  * @param roh handle of the request
+//  * @param j JSON response
+//  * @return #GNUNET_OK on success
+//  */
+// static enum GNUNET_GenericReturnValue
+// handle_reserves_open_pr (struct DONAU_ReservesOpenHandle *roh,
+//                          const json_t *j)
+// {
+//   struct DONAU_ReserveOpenResult rs = {
+//     .hr.reply = j,
+//     .hr.http_status = MHD_HTTP_PAYMENT_REQUIRED,
+//   };
+//   struct GNUNET_JSON_Specification spec[] = {
+//     TALER_JSON_spec_amount_any ("open_cost",
+//                                 &rs.details.payment_required.open_cost),
+//     GNUNET_JSON_spec_timestamp ("reserve_expiration",
+//                                 
&rs.details.payment_required.expiration_time),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (j,
+//                          spec,
+//                          NULL,
+//                          NULL))
+//   {
+//     GNUNET_break_op (0);
+//     return GNUNET_SYSERR;
+//   }
+//   roh->cb (roh->cb_cls,
+//            &rs);
+//   roh->cb = NULL;
+//   GNUNET_JSON_parse_free (spec);
+//   return GNUNET_OK;
+// }
+
+
+// /**
+//  * We received an #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS open code. Handle 
the JSON
+//  * response.
+//  *
+//  * @param roh handle of the request
+//  * @param j JSON response
+//  * @return #GNUNET_OK on success
+//  */
+// static enum GNUNET_GenericReturnValue
+// handle_reserves_open_kyc (struct DONAU_ReservesOpenHandle *roh,
+//                           const json_t *j)
+// {
+//   struct DONAU_ReserveOpenResult rs = {
+//     .hr.reply = j,
+//     .hr.http_status = MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
+//   };
+//   struct GNUNET_JSON_Specification spec[] = {
+//     GNUNET_JSON_spec_fixed_auto (
+//       "h_payto",
+//       &rs.details.unavailable_for_legal_reasons.h_payto),
+//     GNUNET_JSON_spec_uint64 (
+//       "requirement_row",
+//       &rs.details.unavailable_for_legal_reasons.requirement_row),
+//     GNUNET_JSON_spec_end ()
+//   };
+
+//   if (GNUNET_OK !=
+//       GNUNET_JSON_parse (j,
+//                          spec,
+//                          NULL,
+//                          NULL))
+//   {
+//     GNUNET_break_op (0);
+//     return GNUNET_SYSERR;
+//   }
+//   roh->cb (roh->cb_cls,
+//            &rs);
+//   roh->cb = NULL;
+//   GNUNET_JSON_parse_free (spec);
+//   return GNUNET_OK;
+// }
+
+
+// /**
+//  * Function called when we're done processing the
+//  * HTTP /reserves/$RID/open request.
+//  *
+//  * @param cls the `struct DONAU_ReservesOpenHandle`
+//  * @param response_code HTTP response code, 0 on error
+//  * @param response parsed JSON result, NULL on error
+//  */
+// static void
+// handle_reserves_open_finished (void *cls,
+//                                long response_code,
+//                                const void *response)
+// {
+//   struct DONAU_ReservesOpenHandle *roh = cls;
+//   const json_t *j = response;
+//   struct DONAU_ReserveOpenResult rs = {
+//     .hr.reply = j,
+//     .hr.http_status = (unsigned int) response_code
+//   };
+
+//   roh->job = NULL;
+//   switch (response_code)
+//   {
+//   case 0:
+//     rs.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+//     break;
+//   case MHD_HTTP_OK:
+//     if (GNUNET_OK !=
+//         handle_reserves_open_ok (roh,
+//                                  j))
+//     {
+//       GNUNET_break_op (0);
+//       rs.hr.http_status = 0;
+//       rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+//     }
+//     break;
+//   case MHD_HTTP_BAD_REQUEST:
+//     /* This should never happen, either us or the donau is buggy
+//        (or API version conflict); just pass JSON reply to the application */
+//     GNUNET_break (0);
+//     json_dumpf (j,
+//                 stderr,
+//                 JSON_INDENT (2));
+//     rs.hr.ec = TALER_JSON_get_error_code (j);
+//     rs.hr.hint = TALER_JSON_get_error_hint (j);
+//     break;
+//   case MHD_HTTP_PAYMENT_REQUIRED:
+//     if (GNUNET_OK !=
+//         handle_reserves_open_pr (roh,
+//                                  j))
+//     {
+//       GNUNET_break_op (0);
+//       rs.hr.http_status = 0;
+//       rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+//     }
+//     break;
+//   case MHD_HTTP_FORBIDDEN:
+//     /* This should never happen, either us or the donau is buggy
+//        (or API version conflict); just pass JSON reply to the application */
+//     GNUNET_break (0);
+//     rs.hr.ec = TALER_JSON_get_error_code (j);
+//     rs.hr.hint = TALER_JSON_get_error_hint (j);
+//     break;
+//   case MHD_HTTP_NOT_FOUND:
+//     /* Nothing really to verify, this should never
+//        happen, we should pass the JSON reply to the application */
+//     rs.hr.ec = TALER_JSON_get_error_code (j);
+//     rs.hr.hint = TALER_JSON_get_error_hint (j);
+//     break;
+//   case MHD_HTTP_CONFLICT:
+//     {
+//       const struct CoinData *cd = NULL;
+//       struct TALER_CoinSpendPublicKeyP coin_pub;
+//       const struct DONAU_DenomPublicKey *dk;
+//       struct GNUNET_JSON_Specification spec[] = {
+//         GNUNET_JSON_spec_fixed_auto ("coin_pub",
+//                                      &coin_pub),
+//         GNUNET_JSON_spec_end ()
+//       };
+
+//       if (GNUNET_OK !=
+//           GNUNET_JSON_parse (j,
+//                              spec,
+//                              NULL,
+//                              NULL))
+//       {
+//         GNUNET_break_op (0);
+//         rs.hr.http_status = 0;
+//         rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+//         break;
+//       }
+//       for (unsigned int i = 0; i<roh->num_coins; i++)
+//       {
+//         const struct CoinData *cdi = &roh->coins[i];
+
+//         if (0 == GNUNET_memcmp (&coin_pub,
+//                                 &cdi->coin_pub))
+//         {
+//           cd = cdi;
+//           break;
+//         }
+//       }
+//       if (NULL == cd)
+//       {
+//         GNUNET_break_op (0);
+//         rs.hr.http_status = 0;
+//         rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+//         break;
+//       }
+//       dk = DONAU_get_denomination_key_by_hash (roh->keys,
+//                                                &cd->h_denom_pub);
+//       if (NULL == dk)
+//       {
+//         GNUNET_break_op (0);
+//         rs.hr.http_status = 0;
+//         rs.hr.ec = TALER_EC_GENERIC_CLIENT_INTERNAL_ERROR;
+//         break;
+//       }
+//       if (GNUNET_OK !=
+//           DONAU_check_coin_conflict_ (roh->keys,
+//                                       j,
+//                                       dk,
+//                                       &coin_pub,
+//                                       &cd->coin_sig,
+//                                       &cd->contribution))
+//       {
+//         GNUNET_break_op (0);
+//         rs.hr.http_status = 0;
+//         rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+//         break;
+//       }
+//       rs.hr.ec = TALER_JSON_get_error_code (j);
+//       rs.hr.hint = TALER_JSON_get_error_hint (j);
+//       break;
+//     }
+//   case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
+//     if (GNUNET_OK !=
+//         handle_reserves_open_kyc (roh,
+//                                   j))
+//     {
+//       GNUNET_break_op (0);
+//       rs.hr.http_status = 0;
+//       rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+//     }
+//     break;
+//   case MHD_HTTP_INTERNAL_SERVER_ERROR:
+//     /* Server had an internal issue; we should retry, but this API
+//        leaves this to the application */
+//     rs.hr.ec = TALER_JSON_get_error_code (j);
+//     rs.hr.hint = TALER_JSON_get_error_hint (j);
+//     break;
+//   default:
+//     /* unexpected response code */
+//     GNUNET_break_op (0);
+//     rs.hr.ec = TALER_JSON_get_error_code (j);
+//     rs.hr.hint = TALER_JSON_get_error_hint (j);
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Unexpected response code %u/%d for reserves open\n",
+//                 (unsigned int) response_code,
+//                 (int) rs.hr.ec);
+//     break;
+//   }
+//   if (NULL != roh->cb)
+//   {
+//     roh->cb (roh->cb_cls,
+//              &rs);
+//     roh->cb = NULL;
+//   }
+//   DONAU_reserves_open_cancel (roh);
+// }
+
+
+// struct DONAU_ReservesOpenHandle *
+// DONAU_reserves_open (
+//   struct GNUNET_CURL_Context *ctx,
+//   const char *url,
+//   struct DONAU_Keys *keys,
+//   const struct TALER_ReservePrivateKeyP *reserve_priv,
+//   const struct TALER_Amount *reserve_contribution,
+//   unsigned int coin_payments_length,
+//   const struct DONAU_PurseDeposit coin_payments[
+//     static coin_payments_length],
+//   struct GNUNET_TIME_Timestamp expiration_time,
+//   uint32_t min_purses,
+//   DONAU_ReservesOpenCallback cb,
+//   void *cb_cls)
+// {
+//   struct DONAU_ReservesOpenHandle *roh;
+//   CURL *eh;
+//   char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
+//   json_t *cpa;
+
+//   roh = GNUNET_new (struct DONAU_ReservesOpenHandle);
+//   roh->cb = cb;
+//   roh->cb_cls = cb_cls;
+//   roh->ts = GNUNET_TIME_timestamp_get ();
+//   GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
+//                                       &roh->reserve_pub.eddsa_pub);
+//   {
+//     char pub_str[sizeof (struct TALER_ReservePublicKeyP) * 2];
+//     char *end;
+
+//     end = GNUNET_STRINGS_data_to_string (
+//       &roh->reserve_pub,
+//       sizeof (roh->reserve_pub),
+//       pub_str,
+//       sizeof (pub_str));
+//     *end = '\0';
+//     GNUNET_snprintf (arg_str,
+//                      sizeof (arg_str),
+//                      "reserves/%s/open",
+//                      pub_str);
+//   }
+//   roh->url = TALER_url_join (url,
+//                              arg_str,
+//                              NULL);
+//   if (NULL == roh->url)
+//   {
+//     GNUNET_free (roh);
+//     return NULL;
+//   }
+//   eh = DONAU_curl_easy_get_ (roh->url);
+//   if (NULL == eh)
+//   {
+//     GNUNET_break (0);
+//     GNUNET_free (roh->url);
+//     GNUNET_free (roh);
+//     return NULL;
+//   }
+//   TALER_wallet_reserve_open_sign (reserve_contribution,
+//                                   roh->ts,
+//                                   expiration_time,
+//                                   min_purses,
+//                                   reserve_priv,
+//                                   &roh->reserve_sig);
+//   roh->coins = GNUNET_new_array (coin_payments_length,
+//                                  struct CoinData);
+//   cpa = json_array ();
+//   GNUNET_assert (NULL != cpa);
+//   for (unsigned int i = 0; i<coin_payments_length; i++)
+//   {
+//     const struct DONAU_PurseDeposit *pd = &coin_payments[i];
+//     const struct TALER_AgeCommitmentProof *acp = pd->age_commitment_proof;
+//     struct TALER_AgeCommitmentHash ahac;
+//     struct TALER_AgeCommitmentHash *achp = NULL;
+//     struct CoinData *cd = &roh->coins[i];
+//     json_t *cp;
+
+//     cd->contribution = pd->amount;
+//     cd->h_denom_pub = pd->h_denom_pub;
+//     if (NULL != acp)
+//     {
+//       TALER_age_commitment_hash (&acp->commitment,
+//                                  &ahac);
+//       achp = &ahac;
+//     }
+//     TALER_wallet_reserve_open_deposit_sign (&pd->amount,
+//                                             &roh->reserve_sig,
+//                                             &pd->coin_priv,
+//                                             &cd->coin_sig);
+//     GNUNET_CRYPTO_eddsa_key_get_public (&pd->coin_priv.eddsa_priv,
+//                                         &cd->coin_pub.eddsa_pub);
+
+//     cp = GNUNET_JSON_PACK (
+//       GNUNET_JSON_pack_allow_null (
+//         GNUNET_JSON_pack_data_auto ("h_age_commitment",
+//                                     achp)),
+//       TALER_JSON_pack_amount ("amount",
+//                               &pd->amount),
+//       GNUNET_JSON_pack_data_auto ("denom_pub_hash",
+//                                   &pd->h_denom_pub),
+//       TALER_JSON_pack_denom_sig ("ub_sig",
+//                                  &pd->denom_sig),
+//       GNUNET_JSON_pack_data_auto ("coin_pub",
+//                                   &cd->coin_pub),
+//       GNUNET_JSON_pack_data_auto ("coin_sig",
+//                                   &cd->coin_sig));
+//     GNUNET_assert (0 ==
+//                    json_array_append_new (cpa,
+//                                           cp));
+//   }
+//   {
+//     json_t *open_obj = GNUNET_JSON_PACK (
+//       GNUNET_JSON_pack_timestamp ("request_timestamp",
+//                                   roh->ts),
+//       GNUNET_JSON_pack_timestamp ("reserve_expiration",
+//                                   expiration_time),
+//       GNUNET_JSON_pack_array_steal ("payments",
+//                                     cpa),
+//       TALER_JSON_pack_amount ("reserve_payment",
+//                               reserve_contribution),
+//       GNUNET_JSON_pack_uint64 ("purse_limit",
+//                                min_purses),
+//       GNUNET_JSON_pack_data_auto ("reserve_sig",
+//                                   &roh->reserve_sig));
+
+//     if (GNUNET_OK !=
+//         TALER_curl_easy_post (&roh->post_ctx,
+//                               eh,
+//                               open_obj))
+//     {
+//       GNUNET_break (0);
+//       curl_easy_cleanup (eh);
+//       json_decref (open_obj);
+//       GNUNET_free (roh->coins);
+//       GNUNET_free (roh->url);
+//       GNUNET_free (roh);
+//       return NULL;
+//     }
+//     json_decref (open_obj);
+//   }
+//   roh->keys = DONAU_keys_incref (keys);
+//   roh->job = GNUNET_CURL_job_add2 (ctx,
+//                                    eh,
+//                                    roh->post_ctx.headers,
+//                                    &handle_reserves_open_finished,
+//                                    roh);
+//   return roh;
+// }
+
+
+// void
+// DONAU_reserves_open_cancel (
+//   struct DONAU_ReservesOpenHandle *roh)
+// {
+//   if (NULL != roh->job)
+//   {
+//     GNUNET_CURL_job_cancel (roh->job);
+//     roh->job = NULL;
+//   }
+//   TALER_curl_easy_post_finished (&roh->post_ctx);
+//   GNUNET_free (roh->coins);
+//   GNUNET_free (roh->url);
+//   DONAU_keys_decref (roh->keys);
+//   GNUNET_free (roh);
+// }
 
 
 /* end of donau_api_reserves_open.c */
diff --git a/src/lib/donau_api_common.h b/src/lib/donau_api_common.h
index 12f1941..99e96a5 100644
--- a/src/lib/donau_api_common.h
+++ b/src/lib/donau_api_common.h
@@ -23,7 +23,7 @@
 #define DONAU_API_COMMON_H
 
 #include "taler/taler_json_lib.h"
-#include "taler_donau_service.h"
+#include "donau_service.h"
 
 
 /**
@@ -174,14 +174,14 @@ DONAU_check_coin_signature_conflict_ (
  * @param required balance required on the coin for the operation
  * @return #GNUNET_OK if @a proof holds
  */
-enum GNUNET_GenericReturnValue
-DONAU_check_coin_conflict_ (
-  const struct DONAU_Keys *keys,
-  const json_t *proof,
-  const struct DONAU_DenomPublicKey *dk,
-  const struct TALER_CoinSpendPublicKeyP *coin_pub,
-  const struct TALER_CoinSpendSignatureP *coin_sig,
-  const struct TALER_Amount *required);
+// enum GNUNET_GenericReturnValue
+// DONAU_check_coin_conflict_ (
+//   const struct DONAU_Keys *keys,
+//   const json_t *proof,
+//   const struct DONAU_DenomPublicKey *dk,
+//   const struct TALER_CoinSpendPublicKeyP *coin_pub,
+//   const struct TALER_CoinSpendSignatureP *coin_sig,
+//   const struct TALER_Amount *required);
 
 
 /**
@@ -190,7 +190,7 @@ DONAU_check_coin_conflict_ (
  * @param keys keys to search
  * @param[out] min set to the smallest amount
  * @return #GNUNET_SYSERR if there are no denominations in @a keys
-
+*/
 enum GNUNET_GenericReturnValue
 DONAU_get_min_denomination_ (
   const struct DONAU_Keys *keys,
@@ -207,13 +207,13 @@ DONAU_get_min_denomination_ (
  * @param dki denomination of the coin
  * @return #GNUNET_OK if signatures are OK, #GNUNET_SYSERR if not
  */
-enum GNUNET_GenericReturnValue
-DONAU_verify_deposit_signature_ (
-  const struct DONAU_DepositContractDetail *dcd,
-  const struct TALER_ExtensionPolicyHashP *ech,
-  const struct TALER_CharityWireHashP *h_wire,
-  const struct DONAU_CoinDepositDetail *cdd,
-  const struct DONAU_DenomPublicKey *dki);
+// enum GNUNET_GenericReturnValue
+// DONAU_verify_deposit_signature_ (
+//   const struct DONAU_DepositContractDetail *dcd,
+//   const struct TALER_ExtensionPolicyHashP *ech,
+//   const struct TALER_CharityWireHashP *h_wire,
+//   const struct DONAU_CoinDepositDetail *cdd,
+//   const struct DONAU_DenomPublicKey *dki);
 
 
 #endif
diff --git a/src/lib/donau_api_handle.h b/src/lib/donau_api_handle.h
index bf251e9..ba1cc96 100644
--- a/src/lib/donau_api_handle.h
+++ b/src/lib/donau_api_handle.h
@@ -23,10 +23,9 @@
 #define DONAU_API_HANDLE_H
 
 #include <gnunet/gnunet_curl_lib.h>
-#include "taler_auditor_service.h"
-#include "taler_donau_service.h"
+#include "donau_service.h"
 #include "taler_util.h"
-#include "taler_curl_lib.h"
+// #include "taler_curl_lib.h"
 
 
 /**

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]