LCOV - code coverage report
Current view: top level - bank-lib - taler-exchange-wire-gateway-client.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 144 276 52.2 %
Date: 2025-06-22 12:09:43 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2017-2023 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify it under the
       6             :   terms of the GNU General Public License as published by the Free Software
       7             :   Foundation; either version 3, or (at your option) any later version.
       8             : 
       9             :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10             :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11             :   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12             : 
      13             :   You should have received a copy of the GNU General Public License along with
      14             :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15             : */
      16             : /**
      17             :  * @file taler-exchange-wire-gateway-client.c
      18             :  * @brief Execute wire transfer.
      19             :  * @author Christian Grothoff
      20             :  */
      21             : #include "taler/platform.h"
      22             : #include <gnunet/gnunet_util_lib.h>
      23             : #include <gnunet/gnunet_json_lib.h>
      24             : #include <jansson.h>
      25             : #include <microhttpd.h>
      26             : #include "taler/taler_bank_service.h"
      27             : 
      28             : /**
      29             :  * If set to #GNUNET_YES, then we'll ask the bank for a list
      30             :  * of incoming transactions from the account.
      31             :  */
      32             : static int incoming_history;
      33             : 
      34             : /**
      35             :  * If set to #GNUNET_YES, then we'll ask the bank for a list
      36             :  * of outgoing transactions from the account.
      37             :  */
      38             : static int outgoing_history;
      39             : 
      40             : /**
      41             :  * Amount to transfer.
      42             :  */
      43             : static struct TALER_Amount amount;
      44             : 
      45             : /**
      46             :  * Credit account payto://-URI.
      47             :  */
      48             : static struct TALER_FullPayto credit_account;
      49             : 
      50             : /**
      51             :  * Debit account payto://-URI.
      52             :  */
      53             : static struct TALER_FullPayto debit_account;
      54             : 
      55             : /**
      56             :  * Wire transfer subject.
      57             :  */
      58             : static char *subject;
      59             : 
      60             : /**
      61             :  * Which config section has the credentials to access the bank.
      62             :  */
      63             : static char *account_section;
      64             : 
      65             : /**
      66             :  * Starting row.
      67             :  */
      68             : static unsigned long long start_row = UINT64_MAX;
      69             : 
      70             : /**
      71             :  * Authentication data.
      72             :  */
      73             : static struct TALER_BANK_AuthenticationData auth;
      74             : 
      75             : /**
      76             :  * Return value from main().
      77             :  */
      78             : static int global_ret = 1;
      79             : 
      80             : /**
      81             :  * Main execution context for the main loop.
      82             :  */
      83             : static struct GNUNET_CURL_Context *ctx;
      84             : 
      85             : /**
      86             :  * Handle to ongoing credit history operation.
      87             :  */
      88             : static struct TALER_BANK_CreditHistoryHandle *chh;
      89             : 
      90             : /**
      91             :  * Handle to ongoing debit history operation.
      92             :  */
      93             : static struct TALER_BANK_DebitHistoryHandle *dhh;
      94             : 
      95             : /**
      96             :  * Handle for executing the wire transfer.
      97             :  */
      98             : static struct TALER_BANK_TransferHandle *eh;
      99             : 
     100             : /**
     101             :  * Handle to access the exchange.
     102             :  */
     103             : static struct TALER_BANK_AdminAddIncomingHandle *op;
     104             : 
     105             : /**
     106             :  * Context for running the CURL event loop.
     107             :  */
     108             : static struct GNUNET_CURL_RescheduleContext *rc;
     109             : 
     110             : 
     111             : /**
     112             :  * Function run when the test terminates (good or bad).
     113             :  * Cleans up our state.
     114             :  *
     115             :  * @param cls NULL
     116             :  */
     117             : static void
     118           4 : do_shutdown (void *cls)
     119             : {
     120             :   (void) cls;
     121           4 :   if (NULL != op)
     122             :   {
     123           0 :     TALER_BANK_admin_add_incoming_cancel (op);
     124           0 :     op = NULL;
     125             :   }
     126           4 :   if (NULL != chh)
     127             :   {
     128           0 :     TALER_BANK_credit_history_cancel (chh);
     129           0 :     chh = NULL;
     130             :   }
     131           4 :   if (NULL != dhh)
     132             :   {
     133           0 :     TALER_BANK_debit_history_cancel (dhh);
     134           0 :     dhh = NULL;
     135             :   }
     136           4 :   if (NULL != eh)
     137             :   {
     138           0 :     TALER_BANK_transfer_cancel (eh);
     139           0 :     eh = NULL;
     140             :   }
     141           4 :   if (NULL != ctx)
     142             :   {
     143           4 :     GNUNET_CURL_fini (ctx);
     144           4 :     ctx = NULL;
     145             :   }
     146           4 :   if (NULL != rc)
     147             :   {
     148           4 :     GNUNET_CURL_gnunet_rc_destroy (rc);
     149           4 :     rc = NULL;
     150             :   }
     151           4 :   TALER_BANK_auth_free (&auth);
     152           4 : }
     153             : 
     154             : 
     155             : /**
     156             :  * Callback used to process the transaction
     157             :  * history returned by the bank.
     158             :  *
     159             :  * @param cls closure
     160             :  * @param reply response we got from the bank
     161             :  */
     162             : static void
     163           1 : credit_history_cb (void *cls,
     164             :                    const struct TALER_BANK_CreditHistoryResponse *reply)
     165             : {
     166             :   (void) cls;
     167             : 
     168           1 :   chh = NULL;
     169           1 :   switch (reply->http_status)
     170             :   {
     171           0 :   case 0:
     172           0 :     fprintf (stderr,
     173             :              "Failed to obtain HTTP reply from `%s'\n",
     174             :              auth.wire_gateway_url);
     175           0 :     global_ret = 2;
     176           0 :     break;
     177           0 :   case MHD_HTTP_NO_CONTENT:
     178           0 :     fprintf (stdout,
     179             :              "No transactions.\n");
     180           0 :     global_ret = 0;
     181           0 :     break;
     182           1 :   case MHD_HTTP_OK:
     183           2 :     for (unsigned int i = 0; i<reply->details.ok.details_length; i++)
     184             :     {
     185           1 :       const struct TALER_BANK_CreditDetails *cd =
     186           1 :         &reply->details.ok.details[i];
     187             : 
     188             :       /* If credit/debit accounts were specified, use as a filter */
     189           1 :       if ( (NULL != credit_account.full_payto) &&
     190           0 :            (0 != TALER_full_payto_cmp (credit_account,
     191             :                                        reply->details.ok.credit_account_uri) ) )
     192           0 :         continue;
     193           1 :       if ( (NULL != debit_account.full_payto) &&
     194           0 :            (0 != TALER_full_payto_cmp (debit_account,
     195             :                                        cd->debit_account_uri) ) )
     196           0 :         continue;
     197           1 :       switch (cd->type)
     198             :       {
     199           1 :       case TALER_BANK_CT_RESERVE:
     200           1 :         fprintf (stdout,
     201             :                  "%llu: %s->%s (%s) over %s at %s\n",
     202           1 :                  (unsigned long long) cd->serial_id,
     203           1 :                  cd->debit_account_uri.full_payto,
     204           1 :                  reply->details.ok.credit_account_uri.full_payto,
     205           1 :                  TALER_B2S (&cd->details.reserve.reserve_pub),
     206             :                  TALER_amount2s (&cd->amount),
     207             :                  GNUNET_TIME_timestamp2s (cd->execution_date));
     208           1 :         break;
     209           0 :       case TALER_BANK_CT_KYCAUTH:
     210           0 :         fprintf (stdout,
     211             :                  "%llu: %s->%s (KYC:%s) over %s at %s\n",
     212           0 :                  (unsigned long long) cd->serial_id,
     213           0 :                  cd->debit_account_uri.full_payto,
     214           0 :                  reply->details.ok.credit_account_uri.full_payto,
     215           0 :                  TALER_B2S (&cd->details.kycauth.account_pub),
     216             :                  TALER_amount2s (&cd->amount),
     217             :                  GNUNET_TIME_timestamp2s (cd->execution_date));
     218           0 :         break;
     219           0 :       case TALER_BANK_CT_WAD:
     220           0 :         GNUNET_break (0); // FIXME-#7271 (support wad payments)
     221           0 :         break;
     222             :       }
     223             :     }
     224           1 :     global_ret = 0;
     225           1 :     break;
     226           0 :   default:
     227           0 :     fprintf (stderr,
     228             :              "Failed to obtain credit history from `%s': HTTP status %u (%s)\n",
     229             :              auth.wire_gateway_url,
     230           0 :              reply->http_status,
     231           0 :              TALER_ErrorCode_get_hint (reply->ec));
     232           0 :     if (NULL != reply->response)
     233           0 :       json_dumpf (reply->response,
     234             :                   stderr,
     235             :                   JSON_INDENT (2));
     236           0 :     global_ret = 2;
     237           0 :     break;
     238             :   }
     239           1 :   GNUNET_SCHEDULER_shutdown ();
     240           1 : }
     241             : 
     242             : 
     243             : /**
     244             :  * Ask the bank the list of transactions for the bank account
     245             :  * mentioned in the config section given by the user.
     246             :  */
     247             : static void
     248           1 : execute_credit_history (void)
     249             : {
     250           1 :   if (NULL != subject)
     251             :   {
     252           0 :     fprintf (stderr,
     253             :              "Specifying subject is not supported when inspecting credit history\n");
     254           0 :     GNUNET_SCHEDULER_shutdown ();
     255           0 :     return;
     256             :   }
     257           2 :   chh = TALER_BANK_credit_history (ctx,
     258             :                                    &auth,
     259             :                                    start_row,
     260             :                                    -10,
     261           1 :                                    GNUNET_TIME_UNIT_ZERO,
     262             :                                    &credit_history_cb,
     263             :                                    NULL);
     264           1 :   if (NULL == chh)
     265             :   {
     266           0 :     fprintf (stderr,
     267             :              "Could not request the credit transaction history.\n");
     268           0 :     GNUNET_SCHEDULER_shutdown ();
     269           0 :     return;
     270             :   }
     271             : }
     272             : 
     273             : 
     274             : /**
     275             :  * Function with the debit transaction history.
     276             :  *
     277             :  * @param cls closure
     278             :  * @param reply response details
     279             :  */
     280             : static void
     281           1 : debit_history_cb (void *cls,
     282             :                   const struct TALER_BANK_DebitHistoryResponse *reply)
     283             : {
     284             :   (void) cls;
     285             : 
     286           1 :   dhh = NULL;
     287           1 :   switch (reply->http_status)
     288             :   {
     289           0 :   case 0:
     290           0 :     fprintf (stderr,
     291             :              "Failed to obtain HTTP reply from `%s'\n",
     292             :              auth.wire_gateway_url);
     293           0 :     global_ret = 2;
     294           0 :     break;
     295           0 :   case MHD_HTTP_NO_CONTENT:
     296           0 :     fprintf (stdout,
     297             :              "No transactions.\n");
     298           0 :     global_ret = 0;
     299           0 :     break;
     300           1 :   case MHD_HTTP_OK:
     301           2 :     for (unsigned int i = 0; i<reply->details.ok.details_length; i++)
     302             :     {
     303           1 :       const struct TALER_BANK_DebitDetails *dd =
     304           1 :         &reply->details.ok.details[i];
     305             : 
     306             :       /* If credit/debit accounts were specified, use as a filter */
     307           1 :       if ( (NULL != credit_account.full_payto) &&
     308           0 :            (0 != TALER_full_payto_cmp (credit_account,
     309             :                                        dd->credit_account_uri) ) )
     310           0 :         continue;
     311           1 :       if ( (NULL != debit_account.full_payto) &&
     312           0 :            (0 != TALER_full_payto_cmp (debit_account,
     313             :                                        reply->details.ok.debit_account_uri) ) )
     314           0 :         continue;
     315           1 :       fprintf (stdout,
     316             :                "%llu: %s->%s (%s) over %s at %s\n",
     317           1 :                (unsigned long long) dd->serial_id,
     318           1 :                reply->details.ok.debit_account_uri.full_payto,
     319           1 :                dd->credit_account_uri.full_payto,
     320           1 :                TALER_B2S (&dd->wtid),
     321             :                TALER_amount2s (&dd->amount),
     322             :                GNUNET_TIME_timestamp2s (dd->execution_date));
     323             :     }
     324           1 :     global_ret = 0;
     325           1 :     break;
     326           0 :   default:
     327           0 :     fprintf (stderr,
     328             :              "Failed to obtain debit history from `%s': HTTP status %u (%s)\n",
     329             :              auth.wire_gateway_url,
     330           0 :              reply->http_status,
     331           0 :              TALER_ErrorCode_get_hint (reply->ec));
     332           0 :     if (NULL != reply->response)
     333           0 :       json_dumpf (reply->response,
     334             :                   stderr,
     335             :                   JSON_INDENT (2));
     336           0 :     global_ret = 2;
     337           0 :     break;
     338             :   }
     339           1 :   GNUNET_SCHEDULER_shutdown ();
     340           1 : }
     341             : 
     342             : 
     343             : /**
     344             :  * Ask the bank the list of transactions for the bank account
     345             :  * mentioned in the config section given by the user.
     346             :  */
     347             : static void
     348           1 : execute_debit_history (void)
     349             : {
     350           1 :   if (NULL != subject)
     351             :   {
     352           0 :     fprintf (stderr,
     353             :              "Specifying subject is not supported when inspecting debit history\n");
     354           0 :     GNUNET_SCHEDULER_shutdown ();
     355           0 :     return;
     356             :   }
     357           2 :   dhh = TALER_BANK_debit_history (ctx,
     358             :                                   &auth,
     359             :                                   start_row,
     360             :                                   -10,
     361           1 :                                   GNUNET_TIME_UNIT_ZERO,
     362             :                                   &debit_history_cb,
     363             :                                   NULL);
     364           1 :   if (NULL == dhh)
     365             :   {
     366           0 :     fprintf (stderr,
     367             :              "Could not request the debit transaction history.\n");
     368           0 :     GNUNET_SCHEDULER_shutdown ();
     369           0 :     return;
     370             :   }
     371             : }
     372             : 
     373             : 
     374             : /**
     375             :  * Callback that processes the outcome of a wire transfer
     376             :  * execution.
     377             :  *
     378             :  * @param cls closure
     379             :  * @param tr response details
     380             :  */
     381             : static void
     382           1 : confirmation_cb (void *cls,
     383             :                  const struct TALER_BANK_TransferResponse *tr)
     384             : {
     385             :   (void) cls;
     386           1 :   eh = NULL;
     387           1 :   if (MHD_HTTP_OK != tr->http_status)
     388             :   {
     389           0 :     fprintf (stderr,
     390             :              "The wire transfer didn't execute correctly (%u/%d).\n",
     391           0 :              tr->http_status,
     392           0 :              tr->ec);
     393           0 :     GNUNET_SCHEDULER_shutdown ();
     394           0 :     return;
     395             :   }
     396             : 
     397           1 :   fprintf (stdout,
     398             :            "Wire transfer #%llu executed successfully at %s.\n",
     399           1 :            (unsigned long long) tr->details.ok.row_id,
     400             :            GNUNET_TIME_timestamp2s (tr->details.ok.timestamp));
     401           1 :   global_ret = 0;
     402           1 :   GNUNET_SCHEDULER_shutdown ();
     403             : }
     404             : 
     405             : 
     406             : /**
     407             :  * Ask the bank to execute a wire transfer.
     408             :  */
     409             : static void
     410           1 : execute_wire_transfer (void)
     411             : {
     412             :   struct TALER_WireTransferIdentifierRawP wtid;
     413             :   void *buf;
     414             :   size_t buf_size;
     415             :   char *params;
     416             : 
     417           1 :   if (NULL != debit_account.full_payto)
     418             :   {
     419           0 :     fprintf (stderr,
     420             :              "Invalid option -C specified, conflicts with -D\n");
     421           0 :     GNUNET_SCHEDULER_shutdown ();
     422           0 :     return;
     423             :   }
     424             : 
     425             :   /* See if subject was given as a payto-parameter. */
     426           1 :   if (NULL == subject)
     427           0 :     subject = TALER_payto_get_subject (credit_account);
     428           1 :   if (NULL != subject)
     429             :   {
     430           1 :     if (GNUNET_OK !=
     431           1 :         GNUNET_STRINGS_string_to_data (subject,
     432             :                                        strlen (subject),
     433             :                                        &wtid,
     434             :                                        sizeof (wtid)))
     435             :     {
     436           0 :       fprintf (stderr,
     437             :                "Error: wire transfer subject must be a WTID\n");
     438           0 :       GNUNET_SCHEDULER_shutdown ();
     439           0 :       return;
     440             :     }
     441             :   }
     442             :   else
     443             :   {
     444             :     /* pick one at random */
     445           0 :     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
     446             :                                 &wtid,
     447             :                                 sizeof (wtid));
     448             :   }
     449           1 :   params = strchr (credit_account.full_payto,
     450             :                    (unsigned char) '&');
     451           1 :   if (NULL != params)
     452           0 :     *params = '\0';
     453           1 :   TALER_BANK_prepare_transfer (credit_account,
     454             :                                &amount,
     455             :                                "http://exchange.example.com/",
     456             :                                &wtid,
     457             :                                &buf,
     458             :                                &buf_size);
     459           1 :   eh = TALER_BANK_transfer (ctx,
     460             :                             &auth,
     461             :                             buf,
     462             :                             buf_size,
     463             :                             &confirmation_cb,
     464             :                             NULL);
     465           1 :   GNUNET_free (buf);
     466           1 :   if (NULL == eh)
     467             :   {
     468           0 :     fprintf (stderr,
     469             :              "Could not execute the wire transfer\n");
     470           0 :     GNUNET_SCHEDULER_shutdown ();
     471           0 :     return;
     472             :   }
     473             : }
     474             : 
     475             : 
     476             : /**
     477             :  * Function called with the result of the operation.
     478             :  *
     479             :  * @param cls closure
     480             :  * @param air response details
     481             :  */
     482             : static void
     483           1 : res_cb (void *cls,
     484             :         const struct TALER_BANK_AdminAddIncomingResponse *air)
     485             : {
     486             :   (void) cls;
     487           1 :   op = NULL;
     488           1 :   switch (air->http_status)
     489             :   {
     490           1 :   case MHD_HTTP_OK:
     491           1 :     global_ret = 0;
     492           1 :     fprintf (stdout,
     493             :              "%llu\n",
     494           1 :              (unsigned long long) air->details.ok.serial_id);
     495           1 :     break;
     496           0 :   default:
     497           0 :     fprintf (stderr,
     498             :              "Operation failed with status code %u/%u\n",
     499           0 :              (unsigned int) air->ec,
     500           0 :              air->http_status);
     501           0 :     if (NULL != air->response)
     502           0 :       json_dumpf (air->response,
     503             :                   stderr,
     504             :                   JSON_INDENT (2));
     505           0 :     break;
     506             :   }
     507           1 :   GNUNET_SCHEDULER_shutdown ();
     508           1 : }
     509             : 
     510             : 
     511             : /**
     512             :  * Ask the bank to execute a wire transfer to the exchange.
     513             :  */
     514             : static void
     515           1 : execute_admin_transfer (void)
     516             : {
     517             :   struct TALER_ReservePublicKeyP reserve_pub;
     518             : 
     519           1 :   if (NULL != subject)
     520             :   {
     521           1 :     if (GNUNET_OK !=
     522           1 :         GNUNET_STRINGS_string_to_data (subject,
     523             :                                        strlen (subject),
     524             :                                        &reserve_pub,
     525             :                                        sizeof (reserve_pub)))
     526             :     {
     527           0 :       fprintf (stderr,
     528             :                "Error: wire transfer subject must be a reserve public key\n");
     529           0 :       return;
     530             :     }
     531             :   }
     532             :   else
     533             :   {
     534             :     /* pick one that is kind-of well-formed at random */
     535           0 :     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
     536             :                                 &reserve_pub,
     537             :                                 sizeof (reserve_pub));
     538             :   }
     539           1 :   op = TALER_BANK_admin_add_incoming (ctx,
     540             :                                       &auth,
     541             :                                       &reserve_pub,
     542             :                                       &amount,
     543             :                                       debit_account,
     544             :                                       &res_cb,
     545             :                                       NULL);
     546           1 :   if (NULL == op)
     547             :   {
     548           0 :     fprintf (stderr,
     549             :              "Could not execute the wire transfer to the exchange\n");
     550           0 :     GNUNET_SCHEDULER_shutdown ();
     551           0 :     return;
     552             :   }
     553             : }
     554             : 
     555             : 
     556             : /**
     557             :  * Main function that will be run.
     558             :  *
     559             :  * @param cls closure
     560             :  * @param args remaining command-line arguments
     561             :  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
     562             :  * @param cfg configuration
     563             :  */
     564             : static void
     565           4 : run (void *cls,
     566             :      char *const *args,
     567             :      const char *cfgfile,
     568             :      const struct GNUNET_CONFIGURATION_Handle *cfg)
     569             : {
     570             :   (void) cls;
     571             :   (void) args;
     572             :   (void) cfgfile;
     573             :   (void) cfg;
     574             : 
     575           4 :   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
     576             :                                  NULL);
     577           4 :   ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
     578             :                           &rc);
     579           4 :   GNUNET_assert (NULL != ctx);
     580           4 :   rc = GNUNET_CURL_gnunet_rc_create (ctx);
     581           4 :   if (NULL != account_section)
     582             :   {
     583           0 :     if (0 != strncasecmp ("exchange-accountcredentials-",
     584             :                           account_section,
     585             :                           strlen ("exchange-accountcredentials-")))
     586             :     {
     587           0 :       fprintf (stderr,
     588             :                "Error: invalid section specified, must begin with `%s`\n",
     589             :                "exchange-accountcredentials-");
     590           0 :       GNUNET_SCHEDULER_shutdown ();
     591           0 :       return;
     592             :     }
     593           0 :     if ( (NULL != auth.wire_gateway_url) ||
     594           0 :          (NULL != auth.details.basic.username) ||
     595           0 :          (NULL != auth.details.basic.password) )
     596             :     {
     597           0 :       fprintf (stderr,
     598             :                "Error: Conflicting authentication options provided. Please only use one method.\n");
     599           0 :       GNUNET_SCHEDULER_shutdown ();
     600           0 :       return;
     601             :     }
     602           0 :     if (GNUNET_OK !=
     603           0 :         TALER_BANK_auth_parse_cfg (cfg,
     604             :                                    account_section,
     605             :                                    &auth))
     606             :     {
     607           0 :       fprintf (stderr,
     608             :                "Error: Authentication information not found in configuration section `%s'\n",
     609             :                account_section);
     610           0 :       GNUNET_SCHEDULER_shutdown ();
     611           0 :       return;
     612             :     }
     613             :   }
     614             :   else
     615             :   {
     616           4 :     if ( (NULL != auth.wire_gateway_url) &&
     617           4 :          (NULL != auth.details.basic.username) &&
     618           0 :          (NULL != auth.details.basic.password) )
     619             :     {
     620           0 :       auth.method = TALER_BANK_AUTH_BASIC;
     621             :     }
     622           4 :     else if ( (NULL != auth.wire_gateway_url) &&
     623           4 :               (NULL != auth.details.bearer.token) )
     624             :     {
     625           0 :       auth.method = TALER_BANK_AUTH_BEARER;
     626             :     }
     627             : 
     628           4 :     else if (NULL == auth.wire_gateway_url)
     629             :     {
     630           0 :       fprintf (stderr,
     631             :                "Error: No account specified (use -b or -s options).\n");
     632           0 :       GNUNET_SCHEDULER_shutdown ();
     633           0 :       return;
     634             :     }
     635             :   }
     636           4 :   if ( (NULL == auth.wire_gateway_url) ||
     637           4 :        (0 == strlen (auth.wire_gateway_url)) ||
     638           4 :        (0 != strncasecmp ("http",
     639           4 :                           auth.wire_gateway_url,
     640             :                           strlen ("http"))) )
     641             :   {
     642           0 :     fprintf (stderr,
     643             :              "Error: Invalid wire gateway URL `%s' configured.\n",
     644             :              auth.wire_gateway_url);
     645           0 :     GNUNET_SCHEDULER_shutdown ();
     646           0 :     return;
     647             :   }
     648           4 :   if ( (GNUNET_YES == incoming_history) &&
     649           1 :        (GNUNET_YES == outgoing_history) )
     650             :   {
     651           0 :     fprintf (stderr,
     652             :              "Error: Please specify only -i or -o, but not both.\n");
     653           0 :     GNUNET_SCHEDULER_shutdown ();
     654           0 :     return;
     655             :   }
     656           4 :   if (GNUNET_YES == incoming_history)
     657             :   {
     658           1 :     execute_credit_history ();
     659           1 :     return;
     660             :   }
     661           3 :   if (GNUNET_YES == outgoing_history)
     662             :   {
     663           1 :     execute_debit_history ();
     664           1 :     return;
     665             :   }
     666           2 :   if (NULL != credit_account.full_payto)
     667             :   {
     668           1 :     execute_wire_transfer ();
     669           1 :     return;
     670             :   }
     671           1 :   if (NULL != debit_account.full_payto)
     672             :   {
     673           1 :     execute_admin_transfer ();
     674           1 :     return;
     675             :   }
     676             : 
     677           0 :   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     678             :               "No operation specified.\n");
     679           0 :   global_ret = 0;
     680           0 :   GNUNET_SCHEDULER_shutdown ();
     681             : }
     682             : 
     683             : 
     684             : /**
     685             :  * The main function of the taler-exchange-wire-gateway-client
     686             :  *
     687             :  * @param argc number of arguments from the command line
     688             :  * @param argv command line arguments
     689             :  * @return 0 ok, 1 on error
     690             :  */
     691             : int
     692           4 : main (int argc,
     693             :       char *const *argv)
     694             : {
     695           4 :   const struct GNUNET_GETOPT_CommandLineOption options[] = {
     696           4 :     TALER_getopt_get_amount ('a',
     697             :                              "amount",
     698             :                              "VALUE",
     699             :                              "value to transfer",
     700             :                              &amount),
     701           4 :     GNUNET_GETOPT_option_string ('b',
     702             :                                  "bank",
     703             :                                  "URL",
     704             :                                  "Wire gateway URL to use to talk to the bank",
     705             :                                  &auth.wire_gateway_url),
     706           4 :     GNUNET_GETOPT_option_string ('C',
     707             :                                  "credit",
     708             :                                  "ACCOUNT",
     709             :                                  "payto URI of the bank account to credit (when making outgoing transfers)",
     710             :                                  &credit_account.full_payto),
     711           4 :     GNUNET_GETOPT_option_string ('D',
     712             :                                  "debit",
     713             :                                  "PAYTO-URL",
     714             :                                  "payto URI of the bank account to debit (when making incoming transfers)",
     715             :                                  &debit_account.full_payto),
     716           4 :     GNUNET_GETOPT_option_flag ('i',
     717             :                                "credit-history",
     718             :                                "Ask to get a list of 10 incoming transactions.",
     719             :                                &incoming_history),
     720           4 :     GNUNET_GETOPT_option_flag ('o',
     721             :                                "debit-history",
     722             :                                "Ask to get a list of 10 outgoing transactions.",
     723             :                                &outgoing_history),
     724           4 :     GNUNET_GETOPT_option_string ('p',
     725             :                                  "pass",
     726             :                                  "PASSPHRASE",
     727             :                                  "passphrase to use for authentication",
     728             :                                  &auth.details.basic.password),
     729           4 :     GNUNET_GETOPT_option_string ('s',
     730             :                                  "section",
     731             :                                  "ACCOUNT-SECTION",
     732             :                                  "Which config section has the credentials to access the bank. Conflicts with -b -u and -p options.\n",
     733             :                                  &account_section),
     734           4 :     GNUNET_GETOPT_option_string ('S',
     735             :                                  "subject",
     736             :                                  "SUBJECT",
     737             :                                  "specifies the wire transfer subject",
     738             :                                  &subject),
     739           4 :     GNUNET_GETOPT_option_string ('u',
     740             :                                  "user",
     741             :                                  "USERNAME",
     742             :                                  "username to use for authentication",
     743             :                                  &auth.details.basic.username),
     744           4 :     GNUNET_GETOPT_option_ulong ('w',
     745             :                                 "since-when",
     746             :                                 "ROW",
     747             :                                 "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.",
     748             :                                 &start_row),
     749             :     GNUNET_GETOPT_OPTION_END
     750             :   };
     751             :   enum GNUNET_GenericReturnValue ret;
     752             : 
     753           4 :   global_ret = 1;
     754           4 :   ret = GNUNET_PROGRAM_run (
     755             :     TALER_EXCHANGE_project_data (),
     756             :     argc, argv,
     757             :     "taler-wire-gateway-client",
     758             :     gettext_noop ("Client tool of the Taler Wire Gateway"),
     759             :     options,
     760             :     &run, NULL);
     761           4 :   if (GNUNET_SYSERR == ret)
     762           0 :     return 3;
     763           4 :   if (GNUNET_NO == ret)
     764           0 :     return 0;
     765           4 :   return global_ret;
     766             : }
     767             : 
     768             : 
     769             : /* end taler-wire-gateway-client.c */

Generated by: LCOV version 1.16