diff options
Diffstat (limited to 'src/bank-lib/taler-exchange-wire-gateway-client.c')
-rw-r--r-- | src/bank-lib/taler-exchange-wire-gateway-client.c | 748 |
1 files changed, 748 insertions, 0 deletions
diff --git a/src/bank-lib/taler-exchange-wire-gateway-client.c b/src/bank-lib/taler-exchange-wire-gateway-client.c new file mode 100644 index 000000000..c10b4ddde --- /dev/null +++ b/src/bank-lib/taler-exchange-wire-gateway-client.c | |||
@@ -0,0 +1,748 @@ | |||
1 | /* | ||
2 | This file is part of TALER | ||
3 | Copyright (C) 2017-2020 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-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; | ||
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 | do_shutdown (void *cls) | ||
118 | { | ||
119 | (void) cls; | ||
120 | if (NULL != op) | ||
121 | { | ||
122 | TALER_BANK_admin_add_incoming_cancel (op); | ||
123 | op = NULL; | ||
124 | } | ||
125 | if (NULL != chh) | ||
126 | { | ||
127 | TALER_BANK_credit_history_cancel (chh); | ||
128 | chh = NULL; | ||
129 | } | ||
130 | if (NULL != dhh) | ||
131 | { | ||
132 | TALER_BANK_debit_history_cancel (dhh); | ||
133 | dhh = NULL; | ||
134 | } | ||
135 | if (NULL != eh) | ||
136 | { | ||
137 | TALER_BANK_transfer_cancel (eh); | ||
138 | eh = NULL; | ||
139 | } | ||
140 | if (NULL != ctx) | ||
141 | { | ||
142 | GNUNET_CURL_fini (ctx); | ||
143 | ctx = NULL; | ||
144 | } | ||
145 | if (NULL != rc) | ||
146 | { | ||
147 | GNUNET_CURL_gnunet_rc_destroy (rc); | ||
148 | rc = NULL; | ||
149 | } | ||
150 | TALER_BANK_auth_free (&auth); | ||
151 | } | ||
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 int | ||
169 | 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 | if (MHD_HTTP_OK != http_status) | ||
179 | { | ||
180 | if ( (MHD_HTTP_NO_CONTENT != http_status) || | ||
181 | (TALER_EC_NONE != ec) || | ||
182 | (NULL == details) ) | ||
183 | { | ||
184 | fprintf (stderr, | ||
185 | "Failed to obtain credit history: %u/%d\n", | ||
186 | http_status, | ||
187 | ec); | ||
188 | if (NULL != json) | ||
189 | json_dumpf (json, | ||
190 | stderr, | ||
191 | JSON_INDENT (2)); | ||
192 | global_ret = 2; | ||
193 | GNUNET_SCHEDULER_shutdown (); | ||
194 | return GNUNET_NO; | ||
195 | } | ||
196 | fprintf (stdout, | ||
197 | "End of transactions list.\n"); | ||
198 | global_ret = 0; | ||
199 | GNUNET_SCHEDULER_shutdown (); | ||
200 | return GNUNET_NO; | ||
201 | } | ||
202 | |||
203 | /* If credit/debit accounts were specified, use as a filter */ | ||
204 | if ( (NULL != credit_account) && | ||
205 | (0 != strcasecmp (credit_account, | ||
206 | details->credit_account_url) ) ) | ||
207 | return GNUNET_OK; | ||
208 | if ( (NULL != debit_account) && | ||
209 | (0 != strcasecmp (debit_account, | ||
210 | details->debit_account_url) ) ) | ||
211 | return GNUNET_OK; | ||
212 | |||
213 | fprintf (stdout, | ||
214 | "%llu: %s->%s (%s) over %s at %s\n", | ||
215 | (unsigned long long) serial_id, | ||
216 | details->debit_account_url, | ||
217 | details->credit_account_url, | ||
218 | TALER_B2S (&details->reserve_pub), | ||
219 | TALER_amount2s (&details->amount), | ||
220 | GNUNET_STRINGS_absolute_time_to_string (details->execution_date)); | ||
221 | return GNUNET_OK; | ||
222 | } | ||
223 | |||
224 | |||
225 | /** | ||
226 | * Ask the bank the list of transactions for the bank account | ||
227 | * mentioned in the config section given by the user. | ||
228 | */ | ||
229 | static void | ||
230 | execute_credit_history (void) | ||
231 | { | ||
232 | if (NULL != subject) | ||
233 | { | ||
234 | fprintf (stderr, | ||
235 | "Specifying subject is not supported when inspecting credit history\n"); | ||
236 | GNUNET_SCHEDULER_shutdown (); | ||
237 | return; | ||
238 | } | ||
239 | chh = TALER_BANK_credit_history (ctx, | ||
240 | &auth, | ||
241 | start_row, | ||
242 | -10, | ||
243 | &credit_history_cb, | ||
244 | NULL); | ||
245 | if (NULL == chh) | ||
246 | { | ||
247 | fprintf (stderr, | ||
248 | "Could not request the credit transaction history.\n"); | ||
249 | GNUNET_SCHEDULER_shutdown (); | ||
250 | return; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | |||
255 | /** | ||
256 | * Function with the debit debit transaction history. | ||
257 | * | ||
258 | * @param cls closure | ||
259 | * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request | ||
260 | * 0 if the bank's reply is bogus (fails to follow the protocol), | ||
261 | * #MHD_HTTP_NO_CONTENT if there are no more results; on success the | ||
262 | * last callback is always of this status (even if `abs(num_results)` were | ||
263 | * already returned). | ||
264 | * @param ec detailed error code | ||
265 | * @param serial_id monotonically increasing counter corresponding to the transaction | ||
266 | * @param details details about the wire transfer | ||
267 | * @param json detailed response from the HTTPD, or NULL if reply was not in JSON | ||
268 | * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration | ||
269 | */ | ||
270 | static int | ||
271 | debit_history_cb (void *cls, | ||
272 | unsigned int http_status, | ||
273 | enum TALER_ErrorCode ec, | ||
274 | uint64_t serial_id, | ||
275 | const struct TALER_BANK_DebitDetails *details, | ||
276 | const json_t *json) | ||
277 | { | ||
278 | (void) cls; | ||
279 | |||
280 | if (MHD_HTTP_OK != http_status) | ||
281 | { | ||
282 | if ( (MHD_HTTP_NO_CONTENT != http_status) || | ||
283 | (TALER_EC_NONE != ec) || | ||
284 | (NULL == details) ) | ||
285 | { | ||
286 | fprintf (stderr, | ||
287 | "Failed to obtain debit history: %u/%d\n", | ||
288 | http_status, | ||
289 | ec); | ||
290 | if (NULL != json) | ||
291 | json_dumpf (json, | ||
292 | stderr, | ||
293 | JSON_INDENT (2)); | ||
294 | global_ret = 2; | ||
295 | GNUNET_SCHEDULER_shutdown (); | ||
296 | return GNUNET_NO; | ||
297 | } | ||
298 | fprintf (stdout, | ||
299 | "End of transactions list.\n"); | ||
300 | global_ret = 0; | ||
301 | GNUNET_SCHEDULER_shutdown (); | ||
302 | return GNUNET_NO; | ||
303 | } | ||
304 | |||
305 | /* If credit/debit accounts were specified, use as a filter */ | ||
306 | if ( (NULL != credit_account) && | ||
307 | (0 != strcasecmp (credit_account, | ||
308 | details->credit_account_url) ) ) | ||
309 | return GNUNET_OK; | ||
310 | if ( (NULL != debit_account) && | ||
311 | (0 != strcasecmp (debit_account, | ||
312 | details->debit_account_url) ) ) | ||
313 | return GNUNET_OK; | ||
314 | |||
315 | fprintf (stdout, | ||
316 | "%llu: %s->%s (%s) over %s at %s\n", | ||
317 | (unsigned long long) serial_id, | ||
318 | details->debit_account_url, | ||
319 | details->credit_account_url, | ||
320 | TALER_B2S (&details->wtid), | ||
321 | TALER_amount2s (&details->amount), | ||
322 | GNUNET_STRINGS_absolute_time_to_string (details->execution_date)); | ||
323 | return GNUNET_OK; | ||
324 | } | ||
325 | |||
326 | |||
327 | /** | ||
328 | * Ask the bank the list of transactions for the bank account | ||
329 | * mentioned in the config section given by the user. | ||
330 | */ | ||
331 | static void | ||
332 | execute_debit_history (void) | ||
333 | { | ||
334 | if (NULL != subject) | ||
335 | { | ||
336 | fprintf (stderr, | ||
337 | "Specifying subject is not supported when inspecting debit history\n"); | ||
338 | GNUNET_SCHEDULER_shutdown (); | ||
339 | return; | ||
340 | } | ||
341 | dhh = TALER_BANK_debit_history (ctx, | ||
342 | &auth, | ||
343 | start_row, | ||
344 | -10, | ||
345 | &debit_history_cb, | ||
346 | NULL); | ||
347 | if (NULL == dhh) | ||
348 | { | ||
349 | fprintf (stderr, | ||
350 | "Could not request the debit transaction history.\n"); | ||
351 | GNUNET_SCHEDULER_shutdown (); | ||
352 | return; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | |||
357 | /** | ||
358 | * Callback that processes the outcome of a wire transfer | ||
359 | * execution. | ||
360 | * | ||
361 | * @param cls closure | ||
362 | * @param response_code HTTP status code | ||
363 | * @param ec taler error code | ||
364 | * @param row_id unique ID of the wire transfer in the bank's records | ||
365 | * @param timestamp when did the transaction go into effect | ||
366 | */ | ||
367 | static void | ||
368 | confirmation_cb (void *cls, | ||
369 | unsigned int response_code, | ||
370 | enum TALER_ErrorCode ec, | ||
371 | uint64_t row_id, | ||
372 | struct GNUNET_TIME_Absolute timestamp) | ||
373 | { | ||
374 | (void) cls; | ||
375 | eh = NULL; | ||
376 | if (MHD_HTTP_OK != response_code) | ||
377 | { | ||
378 | fprintf (stderr, | ||
379 | "The wire transfer didn't execute correctly (%u/%d).\n", | ||
380 | response_code, | ||
381 | ec); | ||
382 | GNUNET_SCHEDULER_shutdown (); | ||
383 | return; | ||
384 | } | ||
385 | |||
386 | fprintf (stdout, | ||
387 | "Wire transfer #%llu executed successfully at %s.\n", | ||
388 | (unsigned long long) row_id, | ||
389 | GNUNET_STRINGS_absolute_time_to_string (timestamp)); | ||
390 | global_ret = 0; | ||
391 | GNUNET_SCHEDULER_shutdown (); | ||
392 | } | ||
393 | |||
394 | |||
395 | /** | ||
396 | * Ask the bank to execute a wire transfer. | ||
397 | */ | ||
398 | static void | ||
399 | execute_wire_transfer (void) | ||
400 | { | ||
401 | struct TALER_WireTransferIdentifierRawP wtid; | ||
402 | void *buf; | ||
403 | size_t buf_size; | ||
404 | char *params; | ||
405 | |||
406 | if (NULL != debit_account) | ||
407 | { | ||
408 | fprintf (stderr, | ||
409 | "Invalid option -C specified, conflicts with -D\n"); | ||
410 | GNUNET_SCHEDULER_shutdown (); | ||
411 | return; | ||
412 | } | ||
413 | |||
414 | // See if subject was given as a payto-parameter. | ||
415 | if (NULL == subject) | ||
416 | subject = TALER_payto_get_subject (credit_account); | ||
417 | if (NULL != subject) | ||
418 | { | ||
419 | if (GNUNET_OK != | ||
420 | GNUNET_STRINGS_string_to_data (subject, | ||
421 | strlen (subject), | ||
422 | &wtid, | ||
423 | sizeof (wtid))) | ||
424 | { | ||
425 | fprintf (stderr, | ||
426 | "Error: wire transfer subject must be a WTID\n"); | ||
427 | return; | ||
428 | } | ||
429 | GNUNET_SCHEDULER_shutdown (); | ||
430 | return; | ||
431 | } | ||
432 | else | ||
433 | { | ||
434 | /* pick one at random */ | ||
435 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, | ||
436 | &wtid, | ||
437 | sizeof (wtid)); | ||
438 | } | ||
439 | params = strchr (credit_account, | ||
440 | (unsigned char) '&'); | ||
441 | if (NULL != params) | ||
442 | *params = '\0'; | ||
443 | TALER_BANK_prepare_transfer (credit_account, | ||
444 | &amount, | ||
445 | "http://exchange.example.com/", | ||
446 | &wtid, | ||
447 | &buf, | ||
448 | &buf_size); | ||
449 | eh = TALER_BANK_transfer (ctx, | ||
450 | &auth, | ||
451 | buf, | ||
452 | buf_size, | ||
453 | &confirmation_cb, | ||
454 | NULL); | ||
455 | if (NULL == eh) | ||
456 | { | ||
457 | fprintf (stderr, | ||
458 | "Could not execute the wire transfer\n"); | ||
459 | GNUNET_SCHEDULER_shutdown (); | ||
460 | return; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | |||
465 | /** | ||
466 | * Function called with the result of the operation. | ||
467 | * | ||
468 | * @param cls closure | ||
469 | * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request | ||
470 | * 0 if the bank's reply is bogus (fails to follow the protocol) | ||
471 | * @param ec detailed error code | ||
472 | * @param serial_id unique ID of the wire transfer in the bank's records; UINT64_MAX on error | ||
473 | * @param timestamp timestamp when the transaction got settled at the bank. | ||
474 | * @param json detailed response from the HTTPD, or NULL if reply was not in JSON | ||
475 | */ | ||
476 | static void | ||
477 | res_cb (void *cls, | ||
478 | unsigned int http_status, | ||
479 | enum TALER_ErrorCode ec, | ||
480 | uint64_t serial_id, | ||
481 | struct GNUNET_TIME_Absolute timestamp, | ||
482 | const json_t *json) | ||
483 | { | ||
484 | (void) cls; | ||
485 | (void) timestamp; | ||
486 | op = NULL; | ||
487 | switch (ec) | ||
488 | { | ||
489 | case TALER_EC_NONE: | ||
490 | global_ret = 0; | ||
491 | fprintf (stdout, | ||
492 | "%llu\n", | ||
493 | (unsigned long long) serial_id); | ||
494 | break; | ||
495 | default: | ||
496 | fprintf (stderr, | ||
497 | "Operation failed with status code %u/%u\n", | ||
498 | (unsigned int) ec, | ||
499 | http_status); | ||
500 | if (NULL != json) | ||
501 | json_dumpf (json, | ||
502 | stderr, | ||
503 | JSON_INDENT (2)); | ||
504 | break; | ||
505 | } | ||
506 | GNUNET_SCHEDULER_shutdown (); | ||
507 | } | ||
508 | |||
509 | |||
510 | /** | ||
511 | * Ask the bank to execute a wire transfer to the exchange. | ||
512 | */ | ||
513 | static void | ||
514 | execute_admin_transfer (void) | ||
515 | { | ||
516 | struct TALER_ReservePublicKeyP reserve_pub; | ||
517 | |||
518 | if (NULL != subject) | ||
519 | { | ||
520 | if (GNUNET_OK != | ||
521 | GNUNET_STRINGS_string_to_data (subject, | ||
522 | strlen (subject), | ||
523 | &reserve_pub, | ||
524 | sizeof (reserve_pub))) | ||
525 | { | ||
526 | fprintf (stderr, | ||
527 | "Error: wire transfer subject must be a reserve public key\n"); | ||
528 | return; | ||
529 | } | ||
530 | } | ||
531 | else | ||
532 | { | ||
533 | /* pick one that is kind-of well-formed at random */ | ||
534 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, | ||
535 | &reserve_pub, | ||
536 | sizeof (reserve_pub)); | ||
537 | } | ||
538 | op = TALER_BANK_admin_add_incoming (ctx, | ||
539 | &auth, | ||
540 | &reserve_pub, | ||
541 | &amount, | ||
542 | credit_account, | ||
543 | &res_cb, | ||
544 | NULL); | ||
545 | if (NULL == op) | ||
546 | { | ||
547 | fprintf (stderr, | ||
548 | "Could not execute the wire transfer to the exchange\n"); | ||
549 | GNUNET_SCHEDULER_shutdown (); | ||
550 | return; | ||
551 | } | ||
552 | } | ||
553 | |||
554 | |||
555 | /** | ||
556 | * Main function that will be run. | ||
557 | * | ||
558 | * @param cls closure | ||
559 | * @param args remaining command-line arguments | ||
560 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
561 | * @param cfg configuration | ||
562 | */ | ||
563 | static void | ||
564 | run (void *cls, | ||
565 | char *const *args, | ||
566 | const char *cfgfile, | ||
567 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
568 | { | ||
569 | (void) cls; | ||
570 | (void) args; | ||
571 | (void) cfgfile; | ||
572 | (void) cfg; | ||
573 | |||
574 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | ||
575 | NULL); | ||
576 | ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, | ||
577 | &rc); | ||
578 | GNUNET_assert (NULL != ctx); | ||
579 | rc = GNUNET_CURL_gnunet_rc_create (ctx); | ||
580 | if (NULL != account_section) | ||
581 | { | ||
582 | if ( (NULL != auth.wire_gateway_url) || | ||
583 | (NULL != auth.details.basic.username) || | ||
584 | (NULL != auth.details.basic.password) ) | ||
585 | { | ||
586 | fprintf (stderr, | ||
587 | "Conflicting authentication options provided. Please only use one method.\n"); | ||
588 | GNUNET_SCHEDULER_shutdown (); | ||
589 | return; | ||
590 | } | ||
591 | if (GNUNET_OK != | ||
592 | TALER_BANK_auth_parse_cfg (cfg, | ||
593 | account_section, | ||
594 | &auth)) | ||
595 | { | ||
596 | fprintf (stderr, | ||
597 | "Authentication information not found in configuration section `%s'\n", | ||
598 | account_section); | ||
599 | GNUNET_SCHEDULER_shutdown (); | ||
600 | return; | ||
601 | } | ||
602 | } | ||
603 | else | ||
604 | { | ||
605 | if ( (NULL != auth.wire_gateway_url) && | ||
606 | (NULL != auth.details.basic.username) && | ||
607 | (NULL != auth.details.basic.password) ) | ||
608 | { | ||
609 | auth.method = TALER_BANK_AUTH_BASIC; | ||
610 | } | ||
611 | else if (NULL == auth.wire_gateway_url) | ||
612 | { | ||
613 | fprintf (stderr, | ||
614 | "No account specified (use -b or -s options).\n"); | ||
615 | GNUNET_SCHEDULER_shutdown (); | ||
616 | return; | ||
617 | } | ||
618 | } | ||
619 | if ( (GNUNET_YES == incoming_history) && | ||
620 | (GNUNET_YES == outgoing_history) ) | ||
621 | { | ||
622 | fprintf (stderr, | ||
623 | "Please specify only -i or -o, but not both.\n"); | ||
624 | GNUNET_SCHEDULER_shutdown (); | ||
625 | return; | ||
626 | } | ||
627 | if (GNUNET_YES == incoming_history) | ||
628 | { | ||
629 | execute_credit_history (); | ||
630 | return; | ||
631 | } | ||
632 | if (GNUNET_YES == outgoing_history) | ||
633 | { | ||
634 | execute_debit_history (); | ||
635 | return; | ||
636 | } | ||
637 | if (NULL != credit_account) | ||
638 | { | ||
639 | execute_wire_transfer (); | ||
640 | return; | ||
641 | } | ||
642 | if (NULL != debit_account) | ||
643 | { | ||
644 | execute_admin_transfer (); | ||
645 | return; | ||
646 | } | ||
647 | |||
648 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
649 | "No operation specified.\n"); | ||
650 | global_ret = 0; | ||
651 | GNUNET_SCHEDULER_shutdown (); | ||
652 | } | ||
653 | |||
654 | |||
655 | /** | ||
656 | * The main function of the taler-bank-transfer tool | ||
657 | * | ||
658 | * @param argc number of arguments from the command line | ||
659 | * @param argv command line arguments | ||
660 | * @return 0 ok, 1 on error | ||
661 | */ | ||
662 | int | ||
663 | main (int argc, | ||
664 | char *const *argv) | ||
665 | { | ||
666 | const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
667 | TALER_getopt_get_amount ('a', | ||
668 | "amount", | ||
669 | "VALUE", | ||
670 | "value to transfer", | ||
671 | &amount), | ||
672 | GNUNET_GETOPT_option_string ('b', | ||
673 | "bank", | ||
674 | "URL", | ||
675 | "Wire gateway URL to use to talk to the bank", | ||
676 | &auth.wire_gateway_url), | ||
677 | GNUNET_GETOPT_option_string ('C', | ||
678 | "credit", | ||
679 | "ACCOUNT", | ||
680 | "payto URI of the bank account to credit (when making outgoing transfers)", | ||
681 | &credit_account), | ||
682 | GNUNET_GETOPT_option_string ('D', | ||
683 | "debit", | ||
684 | "PAYTO-URL", | ||
685 | "payto URI of the bank account to debit (when making incoming transfers)", | ||
686 | &debit_account), | ||
687 | GNUNET_GETOPT_option_flag ('i', | ||
688 | "credit-history", | ||
689 | "Ask to get a list of 10 incoming transactions.", | ||
690 | &incoming_history), | ||
691 | GNUNET_GETOPT_option_flag ('o', | ||
692 | "debit-history", | ||
693 | "Ask to get a list of 10 outgoing transactions.", | ||
694 | &outgoing_history), | ||
695 | GNUNET_GETOPT_option_string ('p', | ||
696 | "pass", | ||
697 | "PASSPHRASE", | ||
698 | "passphrase to use for authentication", | ||
699 | &auth.details.basic.password), | ||
700 | GNUNET_GETOPT_option_string ('s', | ||
701 | "section", | ||
702 | "ACCOUNT-SECTION", | ||
703 | "Which config section has the credentials to access the bank. Conflicts with -b -u and -p options.\n", | ||
704 | &account_section), | ||
705 | GNUNET_GETOPT_option_string ('S', | ||
706 | "subject", | ||
707 | "SUBJECT", | ||
708 | "specifies the wire transfer subject", | ||
709 | &subject), | ||
710 | GNUNET_GETOPT_option_string ('u', | ||
711 | "user", | ||
712 | "USERNAME", | ||
713 | "username to use for authentication", | ||
714 | &auth.details.basic.username), | ||
715 | GNUNET_GETOPT_option_ulong ('w', | ||
716 | "since-when", | ||
717 | "ROW", | ||
718 | "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.", | ||
719 | &start_row), | ||
720 | GNUNET_GETOPT_OPTION_END | ||
721 | }; | ||
722 | enum GNUNET_GenericReturnValue ret; | ||
723 | |||
724 | /* force linker to link against libtalerutil; if we do | ||
725 | not do this, the linker may "optimize" libtalerutil | ||
726 | away and skip #TALER_OS_init(), which we do need */ | ||
727 | (void) TALER_project_data_default (); | ||
728 | if (GNUNET_OK != | ||
729 | GNUNET_STRINGS_get_utf8_args (argc, argv, | ||
730 | &argc, &argv)) | ||
731 | return 4; | ||
732 | global_ret = 1; | ||
733 | ret = GNUNET_PROGRAM_run ( | ||
734 | argc, argv, | ||
735 | "taler-wire-gateway-client", | ||
736 | gettext_noop ("Client tool of the Taler Wire Gateway"), | ||
737 | options, | ||
738 | &run, NULL); | ||
739 | GNUNET_free_nz ((void *) argv); | ||
740 | if (GNUNET_SYSERR == ret) | ||
741 | return 3; | ||
742 | if (GNUNET_NO == ret) | ||
743 | return 0; | ||
744 | return global_ret; | ||
745 | } | ||
746 | |||
747 | |||
748 | /* end taler-wire-gateway-client.c */ | ||