LCOV - code coverage report
Current view: top level - bank-lib - taler-exchange-wire-gateway-client.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 130 234 55.6 %
Date: 2021-08-30 06:43:37 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14