summaryrefslogtreecommitdiff
path: root/src/exchange-tools/taler-wire.c
blob: 1aba95c3435b96b7ea0571fe1e48f1fe9531e9b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
/*
  This file is part of TALER
  Copyright (C) 2014-2018 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 performing wire transfers.
 * @author Marcello Stanisci
 * @author Christian Grothoff
 */

#include <platform.h>
#include <gnunet/gnunet_util_lib.h>
#include <taler/taler_util.h>
#include <taler/taler_wire_lib.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.
 */
int history;

/**
 * If set to GNUNET_YES, then we'll ask the bank to execute a
 * wire transfer.
 */
int transfer;

/**
 * Name of the wire plugin to use with the bank.
 */
char *plugin_name;

/**
 * Global return code.
 */
unsigned int global_ret = 0;

/**
 * Base32 encoding of a transaction ID.  When asking the
 * bank for a transaction history, all the results will
 * have a transaction ID settled *after* this one.
 */
char *since_when;

/**
 * Which config section has the credentials to access the bank.
 */
char *account_section; 

/**
 * Binary version of the 'since-when' CLI option.
 */
void *since_when_bin;

/**
 * Wire plugin handle.
 */
struct TALER_WIRE_Plugin *plugin_handle;


/**
 * Callback used to process ONE entry in the transaction
 * history returned by the bank.
 * @param cls closure
 * @param ec taler error code
 * @param dir direction of the transfer
 * @param row_off identification of the position at
 *        which we are querying
 * @param row_off_size number of bytes in @a row_off
 * @param details details about the wire transfer
 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to
 *         abort iteration
 */
int
cb (void *cls,
    enum TALER_ErrorCode ec,
    enum TALER_BANK_Direction dir,
    const void *row_off,
    size_t row_off_size,
    const struct TALER_WIRE_TransferDetails *details)
{
  char *row_off_enc;

  row_off_enc = GNUNET_STRINGS_data_to_string_alloc (row_off,
                                                     row_off_size);

  fprintf (stdout,
           "History of transactions:\n");

  /* Give more details on screen (??) */
  fprintf (stdout,
           "%s\n",
           row_off_enc);

  GNUNET_free (row_off_enc);

  return GNUNET_SYSERR;
}

/**
 * Ask the bank to execute a wire transfer.
 */
void
execute_wire_transfer ()
{}

/**
 * Ask the bank the list of transactions for the bank account
 * mentioned in the config section given by the user.
 */
void
execute_history ()
{
  size_t bin_len = (strlen (since_when) * 5) / 8;

  if (NULL == since_when)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Missing since-when option\n");
    global_ret = 1;
    return;
  }

  since_when_bin = GNUNET_malloc (bin_len);
    GNUNET_assert
      (GNUNET_OK == GNUNET_STRINGS_string_to_data
        (since_when,
         strlen (since_when),
         since_when_bin,
         bin_len));

  if (NULL == plugin_handle->get_history
      (plugin_handle->cls,
       account_section,
       TALER_BANK_DIRECTION_BOTH,
       since_when_bin,
       bin_len,
       10,
       cb,
       NULL));
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Could not request the transaction history.\n");
    global_ret = 1;
    return;
  }
    
}

/**
 * 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)
{
  if (NULL == account_section)
  {
    global_ret = 1;
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "The ACCOUNT-SECTION is mandatory.\n");
    return;
  }

  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string
      (cfg,
       account_section,
       "plugin",
       &plugin_name))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Could not find the 'plugin' value under %s\n",
                account_section);
    global_ret = 1;
    return;
  }

  plugin_handle = TALER_WIRE_plugin_load (cfg,
                                          plugin_name);
  if (NULL == plugin_handle)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Could not load the wire plugin\n");
    global_ret = 1;
    return;
  }

  if (GNUNET_YES == history)
    execute_history ();
  else
    execute_wire_transfer ();
}

/**
 * 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",
                               "Wire plugin to use",
                               &history),

    GNUNET_GETOPT_option_flag ('t',
                               "transfer",
                               "Execute a wire transfer.",
                               &transfer),

    GNUNET_GETOPT_option_string ('w',
                                 "since-when",
                                 "SW",
                                 "When asking the bank for"
                                 " transactions history, this"
                                 " option commands that all the"
                                 " results should have IDs settled"
                                 " after SW",
                                 &since_when),

    GNUNET_GETOPT_option_string ('s',
                                 "section",
                                 "ACCOUNT-SECTION",
                                 "Which config section has the"
                                 " credentials to access the"
                                 " bank.\n",
                                 &account_section),

    GNUNET_GETOPT_OPTION_END
  };

  GNUNET_assert
    (GNUNET_OK == GNUNET_log_setup ("taler-wire",
                                    NULL,
                                    NULL)); /* filename */

  if (GNUNET_OK != GNUNET_PROGRAM_run
      (argc,
       argv,
       "taler-wire",
       "Perform wire transfers using plugin PLUGIN",
       options,
       &run,
       NULL))
    return 1;

  return global_ret;
}