gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: merge taler-wire and taler-bank-


From: gnunet
Subject: [taler-exchange] branch master updated: merge taler-wire and taler-bank-transfer tools, they are very related and otherwise duplicate lots of logic; also enable both credit and debit histories to be shown
Date: Sat, 07 Mar 2020 12:23:34 +0100

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

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 20a7d8fc merge taler-wire and taler-bank-transfer tools, they are very 
related and otherwise duplicate lots of logic; also enable both credit and 
debit histories to be shown
20a7d8fc is described below

commit 20a7d8fc081c71d83d77b39c681dbfd9337aa97a
Author: Christian Grothoff <address@hidden>
AuthorDate: Sat Mar 7 12:23:32 2020 +0100

    merge taler-wire and taler-bank-transfer tools, they are very related and 
otherwise duplicate lots of logic; also enable both credit and debit histories 
to be shown
---
 src/bank-lib/taler-bank-transfer.c         | 598 ++++++++++++++++++++++++++---
 src/exchange-tools/Makefile.am             |  11 +-
 src/exchange-tools/taler-exchange-dbinit.c |  10 +-
 src/exchange-tools/taler-wire.c            | 402 -------------------
 4 files changed, 544 insertions(+), 477 deletions(-)

diff --git a/src/bank-lib/taler-bank-transfer.c 
b/src/bank-lib/taler-bank-transfer.c
index 82fafbed..4b2a06fc 100644
--- a/src/bank-lib/taler-bank-transfer.c
+++ b/src/bank-lib/taler-bank-transfer.c
@@ -24,6 +24,18 @@
 #include <jansson.h>
 #include "taler_bank_service.h"
 
+/**
+ * If set to #GNUNET_YES, then we'll ask the bank for a list
+ * of incoming transactions from the account.
+ */
+static int incoming_history;
+
+/**
+ * If set to #GNUNET_YES, then we'll ask the bank for a list
+ * of outgoing transactions from the account.
+ */
+static int outgoing_history;
+
 /**
  * Amount to transfer.
  */
@@ -34,28 +46,56 @@ static struct TALER_Amount amount;
  */
 static char *credit_account;
 
+/**
+ * Debit account payto://-URI.
+ */
+static char *debit_account;
+
 /**
  * Wire transfer subject.
  */
 static char *subject;
 
+/**
+ * Which config section has the credentials to access the bank.
+ */
+static char *account_section;
+
+/**
+ * Starting row.
+ */
+static unsigned long long start_row;
+
 /**
  * Authentication data.
  */
-static struct TALER_BANK_AuthenticationData auth = {
-  .method = TALER_BANK_AUTH_BASIC
-};
+static struct TALER_BANK_AuthenticationData auth;
 
 /**
  * Return value from main().
  */
-static int global_ret;
+static int global_ret = 1;
 
 /**
  * Main execution context for the main loop.
  */
 static struct GNUNET_CURL_Context *ctx;
 
+/**
+ * Handle to ongoing credit history operation.
+ */
+static struct TALER_BANK_CreditHistoryHandle *chh;
+
+/**
+ * Handle to ongoing debit history operation.
+ */
+static struct TALER_BANK_DebitHistoryHandle *dhh;
+
+/**
+ * Handle for executing the wire transfer.
+ */
+static struct TALER_BANK_TransferHandle *eh;
+
 /**
  * Handle to access the exchange.
  */
@@ -82,6 +122,21 @@ do_shutdown (void *cls)
     TALER_BANK_admin_add_incoming_cancel (op);
     op = NULL;
   }
+  if (NULL != chh)
+  {
+    TALER_BANK_credit_history_cancel (chh);
+    chh = NULL;
+  }
+  if (NULL != dhh)
+  {
+    TALER_BANK_debit_history_cancel (dhh);
+    dhh = NULL;
+  }
+  if (NULL != eh)
+  {
+    TALER_BANK_transfer_cancel (eh);
+    eh = NULL;
+  }
   if (NULL != ctx)
   {
     GNUNET_CURL_fini (ctx);
@@ -92,6 +147,308 @@ do_shutdown (void *cls)
     GNUNET_CURL_gnunet_rc_destroy (rc);
     rc = NULL;
   }
+  TALER_BANK_auth_free (&auth);
+}
+
+
+/**
+ * Callback used to process ONE entry in the transaction
+ * history returned by the bank.
+ *
+ * @param cls closure
+ * @param http_status HTTP status code from server
+ * @param ec taler error code
+ * @param serial_id identification of the position at
+ *        which we are returning data
+ * @param details details about the wire transfer
+ * @param json original full response from server
+ * @return #GNUNET_OK to continue, #GNUNET_SYSERR to
+ *         abort iteration
+ */
+static int
+credit_history_cb (void *cls,
+                   unsigned int http_status,
+                   enum TALER_ErrorCode ec,
+                   uint64_t serial_id,
+                   const struct TALER_BANK_CreditDetails *details,
+                   const json_t *json)
+{
+  (void) cls;
+
+  if (MHD_HTTP_OK != http_status)
+  {
+    if ( (MHD_HTTP_NO_CONTENT != http_status) ||
+         (TALER_EC_NONE != ec) ||
+         (NULL == details) )
+    {
+      fprintf (stderr,
+               "Failed to obtain credit history: %u/%d\n",
+               http_status,
+               ec);
+      if (NULL != json)
+        json_dumpf (json,
+                    stderr,
+                    JSON_INDENT (2));
+      global_ret = 2;
+      GNUNET_SCHEDULER_shutdown ();
+      return GNUNET_NO;
+    }
+    fprintf (stdout,
+             "End of transactions list.\n");
+    global_ret = 0;
+    GNUNET_SCHEDULER_shutdown ();
+    return GNUNET_NO;
+  }
+
+  /* If credit/debit accounts were specified, use as a filter */
+  if ( (NULL != credit_account) &&
+       (0 != strcasecmp (credit_account,
+                         details->credit_account_url) ) )
+    return GNUNET_OK;
+  if ( (NULL != debit_account) &&
+       (0 != strcasecmp (debit_account,
+                         details->debit_account_url) ) )
+    return GNUNET_OK;
+
+  fprintf (stdout,
+           "%llu: %s->%s (%s) over %s at %s\n",
+           (unsigned long long) serial_id,
+           details->debit_account_url,
+           details->credit_account_url,
+           TALER_B2S (&details->reserve_pub),
+           TALER_amount2s (&details->amount),
+           GNUNET_STRINGS_absolute_time_to_string (details->execution_date));
+  return GNUNET_OK;
+}
+
+
+/**
+ * Ask the bank the list of transactions for the bank account
+ * mentioned in the config section given by the user.
+ */
+static void
+execute_credit_history ()
+{
+  if (NULL != subject)
+  {
+    fprintf (stderr,
+             "Specifying subject is not supported when inspecting credit 
history\n");
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  chh = TALER_BANK_credit_history (ctx,
+                                   &auth,
+                                   start_row,
+                                   -10,
+                                   &credit_history_cb,
+                                   NULL);
+  if (NULL == chh)
+  {
+    fprintf (stderr,
+             "Could not request the credit transaction history.\n");
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+}
+
+
+/**
+ * Function with the debit debit transaction history.
+ *
+ * @param cls closure
+ * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful 
status request
+ *                    0 if the bank's reply is bogus (fails to follow the 
protocol),
+ *                    #MHD_HTTP_NO_CONTENT if there are no more results; on 
success the
+ *                    last callback is always of this status (even if 
`abs(num_results)` were
+ *                    already returned).
+ * @param ec detailed error code
+ * @param serial_id monotonically increasing counter corresponding to the 
transaction
+ * @param details details about the wire transfer
+ * @param json detailed response from the HTTPD, or NULL if reply was not in 
JSON
+ * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
+ */
+static int
+debit_history_cb (void *cls,
+                  unsigned int http_status,
+                  enum TALER_ErrorCode ec,
+                  uint64_t serial_id,
+                  const struct TALER_BANK_DebitDetails *details,
+                  const json_t *json)
+{
+  (void) cls;
+
+  if (MHD_HTTP_OK != http_status)
+  {
+    if ( (MHD_HTTP_NO_CONTENT != http_status) ||
+         (TALER_EC_NONE != ec) ||
+         (NULL == details) )
+    {
+      fprintf (stderr,
+               "Failed to obtain debit history: %u/%d\n",
+               http_status,
+               ec);
+      if (NULL != json)
+        json_dumpf (json,
+                    stderr,
+                    JSON_INDENT (2));
+      global_ret = 2;
+      GNUNET_SCHEDULER_shutdown ();
+      return GNUNET_NO;
+    }
+    fprintf (stdout,
+             "End of transactions list.\n");
+    global_ret = 0;
+    GNUNET_SCHEDULER_shutdown ();
+    return GNUNET_NO;
+  }
+
+  /* If credit/debit accounts were specified, use as a filter */
+  if ( (NULL != credit_account) &&
+       (0 != strcasecmp (credit_account,
+                         details->credit_account_url) ) )
+    return GNUNET_OK;
+  if ( (NULL != debit_account) &&
+       (0 != strcasecmp (debit_account,
+                         details->debit_account_url) ) )
+    return GNUNET_OK;
+
+  fprintf (stdout,
+           "%llu: %s->%s (%s) over %s at %s\n",
+           (unsigned long long) serial_id,
+           details->debit_account_url,
+           details->credit_account_url,
+           TALER_B2S (&details->wtid),
+           TALER_amount2s (&details->amount),
+           GNUNET_STRINGS_absolute_time_to_string (details->execution_date));
+  return GNUNET_OK;
+}
+
+
+/**
+ * Ask the bank the list of transactions for the bank account
+ * mentioned in the config section given by the user.
+ */
+static void
+execute_debit_history ()
+{
+  if (NULL != subject)
+  {
+    fprintf (stderr,
+             "Specifying subject is not supported when inspecting debit 
history\n");
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  dhh = TALER_BANK_debit_history (ctx,
+                                  &auth,
+                                  start_row,
+                                  -10,
+                                  &debit_history_cb,
+                                  NULL);
+  if (NULL == dhh)
+  {
+    fprintf (stderr,
+             "Could not request the debit transaction history.\n");
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+}
+
+
+/**
+ * Callback that processes the outcome of a wire transfer
+ * execution.
+ *
+ * @param cls closure
+ * @param response_code HTTP status code
+ * @param ec taler error code
+ * @param row_id unique ID of the wire transfer in the bank's records
+ * @param timestamp when did the transaction go into effect
+ */
+static void
+confirmation_cb (void *cls,
+                 unsigned int response_code,
+                 enum TALER_ErrorCode ec,
+                 uint64_t row_id,
+                 struct GNUNET_TIME_Absolute timestamp)
+{
+  (void) cls;
+  if (MHD_HTTP_OK != response_code)
+  {
+    fprintf (stderr,
+             "The wire transfer didn't execute correctly (%u/%d).\n",
+             response_code,
+             ec);
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+
+  fprintf (stdout,
+           "Wire transfer #%llu executed successfully at %s.\n",
+           (unsigned long long) row_id,
+           GNUNET_STRINGS_absolute_time_to_string (timestamp));
+  global_ret = 0;
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * Ask the bank to execute a wire transfer.
+ */
+static void
+execute_wire_transfer ()
+{
+  struct TALER_WireTransferIdentifierRawP wtid;
+  void *buf;
+  size_t buf_size;
+
+  if (NULL != debit_account)
+  {
+    fprintf (stderr,
+             "Invalid option -C specified, conflicts with -D\n");
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (NULL != subject)
+  {
+    if (GNUNET_OK !=
+        GNUNET_STRINGS_string_to_data (subject,
+                                       strlen (subject),
+                                       &wtid,
+                                       sizeof (wtid)))
+    {
+      fprintf (stderr,
+               "Error: wire transfer subject must be a WTID\n");
+      return;
+    }
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  else
+  {
+    /* pick one at random */
+    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+                                &wtid,
+                                sizeof (wtid));
+  }
+  TALER_BANK_prepare_transfer (credit_account,
+                               &amount,
+                               "http://exchange.example.com/";,
+                               &wtid,
+                               &buf,
+                               &buf_size);
+  eh = TALER_BANK_transfer (ctx,
+                            &auth,
+                            buf,
+                            buf_size,
+                            &confirmation_cb,
+                            NULL);
+  if (NULL == eh)
+  {
+    fprintf (stderr,
+             "Could not execute the wire transfer\n");
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
 }
 
 
@@ -140,6 +497,51 @@ res_cb (void *cls,
 }
 
 
+/**
+ * Ask the bank to execute a wire transfer to the exchange.
+ */
+static void
+execute_admin_transfer ()
+{
+  struct TALER_ReservePublicKeyP reserve_pub;
+
+  if (NULL != subject)
+  {
+    if (GNUNET_OK !=
+        GNUNET_STRINGS_string_to_data (subject,
+                                       strlen (subject),
+                                       &reserve_pub,
+                                       sizeof (reserve_pub)))
+    {
+      fprintf (stderr,
+               "Error: wire transfer subject must be a reserve public key\n");
+      return;
+    }
+  }
+  else
+  {
+    /* pick one that is kind-of well-formed at random */
+    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+                                &reserve_pub,
+                                sizeof (reserve_pub));
+  }
+  op = TALER_BANK_admin_add_incoming (ctx,
+                                      &auth,
+                                      &reserve_pub,
+                                      &amount,
+                                      credit_account,
+                                      &res_cb,
+                                      NULL);
+  if (NULL == op)
+  {
+    fprintf (stderr,
+             "Could not execute the wire transfer to the exchange\n");
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+}
+
+
 /**
  * Main function that will be run.
  *
@@ -154,39 +556,89 @@ run (void *cls,
      const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  struct TALER_ReservePublicKeyP reserve_pub;
-
   (void) cls;
   (void) args;
   (void) cfgfile;
   (void) cfg;
-  if (GNUNET_OK !=
-      GNUNET_STRINGS_string_to_data (subject,
-                                     strlen (subject),
-                                     &reserve_pub,
-                                     sizeof (reserve_pub)))
-  {
-    fprintf (stderr,
-             "Error: wire transfer subject must be a reserve public key\n");
-    return;
-  }
 
+  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+                                 NULL);
   ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
                           &rc);
   GNUNET_assert (NULL != ctx);
   rc = GNUNET_CURL_gnunet_rc_create (ctx);
-
-  op = TALER_BANK_admin_add_incoming (ctx,
-                                      &auth,
-                                      &reserve_pub,
-                                      &amount,
-                                      credit_account,
-                                      &res_cb,
-                                      NULL);
-  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
-                                 NULL);
-  if (NULL == op)
+  if (NULL != account_section)
+  {
+    if ( (NULL != auth.wire_gateway_url) ||
+         (NULL != auth.details.basic.username) ||
+         (NULL != auth.details.basic.password) )
+    {
+      fprintf (stderr,
+               "Conflicting authentication options provided. Please only use 
one method.\n");
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+    if (GNUNET_OK !=
+        TALER_BANK_auth_parse_cfg (cfg,
+                                   account_section,
+                                   &auth))
+    {
+      fprintf (stderr,
+               "Authentication information not found in configuration section 
`%s'\n",
+               account_section);
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+  }
+  else
+  {
+    if ( (NULL != auth.wire_gateway_url) &&
+         (NULL != auth.details.basic.username) &&
+         (NULL != auth.details.basic.password) )
+    {
+      auth.method = TALER_BANK_AUTH_BASIC;
+    }
+    else if (NULL == auth.wire_gateway_url)
+    {
+      fprintf (stderr,
+               "No account specified (use -b or -s options).\n");
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+  }
+  if ( (GNUNET_YES == incoming_history) &&
+       (GNUNET_YES == incoming_history) )
+  {
+    fprintf (stderr,
+             "Please specify only -i or -o, but not both.\n");
     GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (GNUNET_YES == incoming_history)
+  {
+    execute_credit_history ();
+    return;
+  }
+  if (GNUNET_YES == outgoing_history)
+  {
+    execute_debit_history ();
+    return;
+  }
+  if (NULL != credit_account)
+  {
+    execute_wire_transfer ();
+    return;
+  }
+  if (NULL != debit_account)
+  {
+    execute_admin_transfer ();
+    return;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "No operation specified.\n");
+  global_ret = 0;
+  GNUNET_SCHEDULER_shutdown ();
 }
 
 
@@ -198,46 +650,64 @@ run (void *cls,
  * @return 0 ok, 1 on error
  */
 int
-main (int argc, char *const *argv)
+main (int argc,
+      char *const *argv)
 {
   const struct GNUNET_GETOPT_CommandLineOption options[] = {
-    GNUNET_GETOPT_option_mandatory
-      (TALER_getopt_get_amount ('a',
-                                "amount",
-                                "VALUE",
-                                "value to transfer",
-                                &amount)),
-    GNUNET_GETOPT_option_mandatory
-      (GNUNET_GETOPT_option_string ('b',
-                                    "bank",
-                                    "URL",
-                                    "Wire gateway URL to use to talk to the 
bank",
-                                    &auth.wire_gateway_url)),
+    TALER_getopt_get_amount ('a',
+                             "amount",
+                             "VALUE",
+                             "value to transfer",
+                             &amount),
+    GNUNET_GETOPT_option_string ('b',
+                                 "bank",
+                                 "URL",
+                                 "Wire gateway URL to use to talk to the bank",
+                                 &auth.wire_gateway_url),
     GNUNET_GETOPT_option_help ("Deposit funds into a Taler reserve"),
-    GNUNET_GETOPT_option_mandatory
-      (GNUNET_GETOPT_option_string ('C',
-                                    "credit",
-                                    "ACCOUNT",
-                                    "payto URI of the bank account to credit",
-                                    &credit_account)),
-    GNUNET_GETOPT_option_mandatory
-      (GNUNET_GETOPT_option_string ('s',
-                                    "subject",
-                                    "STRING",
-                                    "specifies the wire transfer subject (must 
be a reserve public key)",
-                                    &subject)),
-    GNUNET_GETOPT_option_mandatory
-      (GNUNET_GETOPT_option_string ('u',
-                                    "user",
-                                    "USERNAME",
-                                    "username to use for authentication",
-                                    &auth.details.basic.username)),
-    GNUNET_GETOPT_option_mandatory
-      (GNUNET_GETOPT_option_string ('p',
-                                    "pass",
-                                    "PASSPHRASE",
-                                    "passphrase to use for authentication",
-                                    &auth.details.basic.password)),
+    GNUNET_GETOPT_option_string ('C',
+                                 "credit",
+                                 "ACCOUNT",
+                                 "payto URI of the bank account to credit 
(when making outgoing transfers)",
+                                 &credit_account),
+    GNUNET_GETOPT_option_string ('D',
+                                 "debit",
+                                 "PAYTO-URL",
+                                 "payto URI of the bank account to debit (when 
making incoming transfers)",
+                                 &debit_account),
+    GNUNET_GETOPT_option_flag ('i',
+                               "credit-history",
+                               "Ask to get a list of 10 incoming 
transactions.",
+                               &incoming_history),
+    GNUNET_GETOPT_option_flag ('o',
+                               "debit-history",
+                               "Ask to get a list of 10 outgoing 
transactions.",
+                               &outgoing_history),
+    GNUNET_GETOPT_option_string ('p',
+                                 "pass",
+                                 "PASSPHRASE",
+                                 "passphrase to use for authentication",
+                                 &auth.details.basic.password),
+    GNUNET_GETOPT_option_string ('s',
+                                 "section",
+                                 "ACCOUNT-SECTION",
+                                 "Which config section has the credentials to 
access the bank. Conflicts with -b -u and -p options.\n",
+                                 &account_section),
+    GNUNET_GETOPT_option_string ('S',
+                                 "subject",
+                                 "SUBJECT",
+                                 "specifies the wire transfer subject",
+                                 &subject),
+    GNUNET_GETOPT_option_string ('u',
+                                 "user",
+                                 "USERNAME",
+                                 "username to use for authentication",
+                                 &auth.details.basic.username),
+    GNUNET_GETOPT_option_ulong ('w',
+                                "since-when",
+                                "ROW",
+                                "When asking the bank for transactions 
history, this option commands that all the results should have IDs settled 
after SW.  If not given, then the 10 youngest transactions are returned.",
+                                &start_row),
     GNUNET_GETOPT_OPTION_END
   };
 
diff --git a/src/exchange-tools/Makefile.am b/src/exchange-tools/Makefile.am
index b08cea68..c86faf58 100644
--- a/src/exchange-tools/Makefile.am
+++ b/src/exchange-tools/Makefile.am
@@ -15,16 +15,7 @@ bin_PROGRAMS = \
   taler-exchange-keyup \
   taler-exchange-keycheck \
   taler-exchange-wire \
-  taler-exchange-dbinit \
-  taler-wire
-
-taler_wire_SOURCES = \
-  taler-wire.c
-taler_wire_LDADD = \
-  $(top_builddir)/src/util/libtalerutil.la \
-  $(top_builddir)/src/bank-lib/libtalerbank.la \
-  -lgnunetcurl \
-  -lgnunetutil
+  taler-exchange-dbinit
 
 taler_exchange_keyup_SOURCES = \
   taler-exchange-keyup.c
diff --git a/src/exchange-tools/taler-exchange-dbinit.c 
b/src/exchange-tools/taler-exchange-dbinit.c
index d7c21ad9..d10b2ebc 100644
--- a/src/exchange-tools/taler-exchange-dbinit.c
+++ b/src/exchange-tools/taler-exchange-dbinit.c
@@ -66,7 +66,13 @@ run (void *cls,
     return;
   }
   if (reset_db)
-    (void) plugin->drop_tables (plugin->cls);
+  {
+    if (GNUNET_OK != plugin->drop_tables (plugin->cls))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Could not drop tables. 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))
   {
@@ -79,8 +85,10 @@ run (void *cls,
   if (gc_db)
   {
     if (GNUNET_SYSERR == plugin->gc (plugin->cls))
+    {
       fprintf (stderr,
                "Garbage collection failed!\n");
+    }
   }
   TALER_EXCHANGEDB_plugin_unload (plugin);
 }
diff --git a/src/exchange-tools/taler-wire.c b/src/exchange-tools/taler-wire.c
deleted file mode 100644
index d5a915a9..00000000
--- a/src/exchange-tools/taler-wire.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
-  This file is part of TALER
-  Copyright (C) 2014--2019 Taler Systems SA
-
-  TALER is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as
-  published by the Free Software Foundation; either version 3,
-  or (at your option) any later version.
-
-  TALER is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public
-  License along with TALER; see the file COPYING.  If not,
-  see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-wire.c
- * @brief Utility for performing wire transfers.
- * @author Marcello Stanisci
- * @author Christian Grothoff
- */
-#include <platform.h>
-#include <gnunet/gnunet_util_lib.h>
-#include "taler_util.h"
-#include "taler_bank_service.h"
-
-/**
- * If set to #GNUNET_YES, then we'll ask the bank for a list
- * of transactions from the account mentioned in the config
- * section.
- */
-static int history;
-
-/**
- * If set to #GNUNET_YES, then we'll ask the bank to execute a
- * wire transfer.
- */
-static int transfer;
-
-/**
- * Global return code.
- */
-static unsigned int global_ret = 1;
-
-/**
- * When a wire transfer is being performed, this value
- * specifies the amount to transfer.
- */
-static struct TALER_Amount amount;
-
-/**
- * Starting row.
- */
-static unsigned long long start_row;
-
-/**
- * Which config section has the credentials to access the bank.
- */
-static char *account_section;
-
-/**
- * URL identifying the account that is going to receive the
- * wire transfer.
- */
-static char *destination_account_url;
-
-/**
- * Handle for executing the wire transfer.
- */
-static struct TALER_BANK_TransferHandle *eh;
-
-/**
- * Handle to ongoing history operation.
- */
-static struct TALER_BANK_CreditHistoryHandle *hh;
-
-/**
- * For authentication.
- */
-static struct TALER_BANK_AuthenticationData auth;
-
-/**
- * Handle to the context for interacting with the bank.
- */
-static struct GNUNET_CURL_Context *ctx;
-
-/**
- * Scheduler context for running the @e ctx.
- */
-static struct GNUNET_CURL_RescheduleContext *rc;
-
-
-/**
- * Callback used to process ONE entry in the transaction
- * history returned by the bank.
- *
- * @param cls closure
- * @param http_status HTTP status code from server
- * @param ec taler error code
- * @param serial_id identification of the position at
- *        which we are returning data
- * @param details details about the wire transfer
- * @param json original full response from server
- * @return #GNUNET_OK to continue, #GNUNET_SYSERR to
- *         abort iteration
- */
-static int
-history_cb (void *cls,
-            unsigned int http_status,
-            enum TALER_ErrorCode ec,
-            uint64_t serial_id,
-            const struct TALER_BANK_CreditDetails *details,
-            const json_t *json)
-{
-  (void) cls;
-  (void) ec;
-  (void) http_status;
-  (void) json;
-  if (NULL == details)
-  {
-    fprintf (stdout,
-             "End of transactions list.\n");
-    global_ret = 0;
-    GNUNET_SCHEDULER_shutdown ();
-    return GNUNET_NO;
-  }
-
-  fprintf (stdout,
-           "%llu: %s->%s (%s) over %s at %s\n",
-           (unsigned long long) serial_id,
-           details->debit_account_url,
-           details->credit_account_url,
-           TALER_B2S (&details->reserve_pub),
-           TALER_amount2s (&details->amount),
-           GNUNET_STRINGS_absolute_time_to_string (details->execution_date));
-  return GNUNET_OK;
-}
-
-
-/**
- * Callback that processes the outcome of a wire transfer
- * execution.
- *
- * @param cls closure
- * @param response_code HTTP status code
- * @param ec taler error code
- * @param row_id unique ID of the wire transfer in the bank's records
- * @param timestamp when did the transaction go into effect
- */
-static void
-confirmation_cb (void *cls,
-                 unsigned int response_code,
-                 enum TALER_ErrorCode ec,
-                 uint64_t row_id,
-                 struct GNUNET_TIME_Absolute timestamp)
-{
-  (void) cls;
-  if (MHD_HTTP_OK != response_code)
-  {
-    fprintf (stderr,
-             "The wire transfer didn't execute correctly (%d).\n",
-             ec);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-
-  fprintf (stdout,
-           "Wire transfer #%llu executed successfully at %s.\n",
-           (unsigned long long) row_id,
-           GNUNET_STRINGS_absolute_time_to_string (timestamp));
-  global_ret = 0;
-  GNUNET_SCHEDULER_shutdown ();
-}
-
-
-/**
- * Ask the bank to execute a wire transfer.
- */
-static void
-execute_wire_transfer ()
-{
-  struct TALER_WireTransferIdentifierRawP wtid;
-  void *buf;
-  size_t buf_size;
-
-  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
-                              &wtid,
-                              sizeof (wtid));
-  TALER_BANK_prepare_transfer (destination_account_url,
-                               &amount,
-                               "http://exchange.example.com/";,
-                               &wtid,
-                               &buf,
-                               &buf_size);
-  eh = TALER_BANK_transfer (ctx,
-                            &auth,
-                            buf,
-                            buf_size,
-                            &confirmation_cb,
-                            NULL);
-  if (NULL == eh)
-  {
-    fprintf (stderr,
-             "Could not execute the wire transfer\n");
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-}
-
-
-/**
- * Ask the bank the list of transactions for the bank account
- * mentioned in the config section given by the user.
- */
-static void
-execute_history ()
-{
-  hh = TALER_BANK_credit_history (ctx,
-                                  &auth,
-                                  start_row,
-                                  -10,
-                                  &history_cb,
-                                  NULL);
-  if (NULL == hh)
-  {
-    fprintf (stderr,
-             "Could not request the transaction history.\n");
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-}
-
-
-/**
- * Gets executed upon shutdown.  Main duty is wire-plugin unloading.
- *
- * @param cls closure.
- */
-static void
-do_shutdown (void *cls)
-{
-  (void) cls;
-  if (NULL != ctx)
-  {
-    GNUNET_CURL_fini (ctx);
-    ctx = NULL;
-  }
-  if (NULL != rc)
-  {
-    GNUNET_CURL_gnunet_rc_destroy (rc);
-    rc = NULL;
-  }
-  if (NULL != hh)
-  {
-    TALER_BANK_credit_history_cancel (hh);
-    hh = NULL;
-  }
-  if (NULL != eh)
-  {
-    TALER_BANK_transfer_cancel (eh);
-    eh = NULL;
-  }
-  TALER_BANK_auth_free (&auth);
-}
-
-
-/**
- * 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) args;
-  (void) cfgfile;
-  if (NULL == account_section)
-  {
-    fprintf (stderr,
-             "The option: -s ACCOUNT-SECTION, is mandatory.\n");
-    return;
-  }
-  if (GNUNET_OK !=
-      TALER_BANK_auth_parse_cfg (cfg,
-                                 account_section,
-                                 &auth))
-  {
-    fprintf (stderr,
-             "Authentication information not found in configuration section 
`%s'\n",
-             account_section);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-
-
-  if (GNUNET_YES == history)
-    execute_history ();
-  else if (GNUNET_YES == transfer)
-    execute_wire_transfer ();
-  else
-    fprintf (stderr,
-             "Please give either --history/-H or --transfer/t\n");
-
-  ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
-                          &rc);
-  rc = GNUNET_CURL_gnunet_rc_create (ctx);
-  if (NULL == ctx)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
-                                 NULL);
-}
-
-
-/**
- * Main function of taler-wire.  This tool is used to command the
- * execution of wire transfers from the command line.  Its main
- * purpose is to test whether the bank and exchange can speak the
- * same protocol of a certain wire plugin.
- *
- * @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)
-{
-  struct GNUNET_GETOPT_CommandLineOption options[] = {
-    GNUNET_GETOPT_option_flag ('H',
-                               "history",
-                               "Ask to get a list of 10 transactions.",
-                               &history),
-    GNUNET_GETOPT_option_flag ('t',
-                               "transfer",
-                               "Execute a wire transfer.",
-                               &transfer),
-    GNUNET_GETOPT_option_ulong ('w',
-                                "since-when",
-                                "SW",
-                                "When asking the bank for"
-                                " transactions history, this"
-                                " option commands that all the"
-                                " results should have IDs settled"
-                                " after SW.  If not given, then"
-                                " the 10 youngest transactions"
-                                " are returned.",
-                                &start_row),
-    GNUNET_GETOPT_option_mandatory
-      (GNUNET_GETOPT_option_string ('s',
-                                    "section",
-                                    "ACCOUNT-SECTION",
-                                    "Which config section has the credentials 
to access the bank.  Mandatory.\n",
-                                    &account_section)),
-    GNUNET_GETOPT_option_mandatory
-      (TALER_getopt_get_amount ('a',
-                                "amount",
-                                "AMOUNT",
-                                "Specify the amount to transfer.",
-                                &amount)),
-    GNUNET_GETOPT_option_mandatory
-      (GNUNET_GETOPT_option_string ('d',
-                                    "destination",
-                                    "PAYTO-URL",
-                                    "Destination account for the wire 
transfer.",
-                                    &destination_account_url)),
-    GNUNET_GETOPT_OPTION_END
-  };
-  int ret;
-
-  GNUNET_assert
-    (GNUNET_OK == GNUNET_log_setup ("taler-wire",
-                                    "WARNING",
-                                    NULL)); /* filename */
-  ret = GNUNET_PROGRAM_run
-          (argc,
-          argv,
-          "taler-wire",
-          "CLI bank client.",
-          options,
-          &run,
-          NULL);
-  if (GNUNET_OK != ret)
-    return ret;
-  return global_ret;
-}
-
-
-/* end of taler-wire.c */

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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