/* This file is part of TALER Copyright (C) 2014, 2015 GNUnet e.V. 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 */ /** * @file taler-exchange-reservemod.c * @brief Modify reserves. Allows manipulation of reserve balances. * @author Florian Dold * @author Benedikt Mueller */ #include "platform.h" #include #include #include #include "taler_exchangedb_plugin.h" /** * Director of the exchange, containing the keys. */ static char *exchange_directory; /** * Our DB plugin. */ static struct TALER_EXCHANGEDB_Plugin *plugin; /** * Public key of the reserve as a string. */ static char *reserve_pub_str; /** * Amount to add as a string. */ static char *add_str; /** * Details about the sender account in JSON format. */ static char *sender_details; /** * Details about the wire transfer in JSON format. */ static char *transfer_details; /** * Return value from main(). */ static int global_ret; /** * Run the database transaction. * * @param reserve_pub public key of the reserve to use * @param add_value value to add * @param jdetails JSON details about sender * @param tdetails JSON details about transfer * @return #GNUNET_OK on success, #GNUNET_SYSERR on hard error, * #GNUNET_NO if record exists */ static int run_transaction (const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_Amount *add_value, json_t *jdetails, json_t *tdetails) { int ret; struct TALER_EXCHANGEDB_Session *session; session = plugin->get_session (plugin->cls); if (NULL == session) { fprintf (stderr, "Failed to initialize DB session\n"); return GNUNET_SYSERR; } /* FIXME: maybe allow passing timestamp via command-line? */ ret = plugin->reserves_in_insert (plugin->cls, session, reserve_pub, add_value, GNUNET_TIME_absolute_get (), jdetails, tdetails); if (GNUNET_SYSERR == ret) { fprintf (stderr, "Failed to update reserve.\n"); } if (GNUNET_NO == ret) { fprintf (stderr, "Record exists, reserve not updated.\n"); } return ret; } /** * 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) { struct TALER_Amount add_value; json_t *jdetails; json_t *tdetails; json_error_t error; struct TALER_ReservePublicKeyP reserve_pub; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "exchange", "KEYDIR", &exchange_directory)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "exchange", "KEYDIR"); global_ret = 1; return; } if ((NULL == reserve_pub_str) || (GNUNET_OK != GNUNET_STRINGS_string_to_data (reserve_pub_str, strlen (reserve_pub_str), &reserve_pub, sizeof (struct TALER_ReservePublicKeyP)))) { fprintf (stderr, "Parsing reserve key invalid\n"); global_ret = 1; return; } if ( (NULL == add_str) || (GNUNET_OK != TALER_string_to_amount (add_str, &add_value)) ) { fprintf (stderr, "Failed to parse currency amount `%s'\n", add_str); global_ret = 1; return; } if (NULL == sender_details) { fprintf (stderr, "No sender details given (sender required)\n"); global_ret = 1; return; } jdetails = json_loads (sender_details, JSON_REJECT_DUPLICATES, &error); if (NULL == jdetails) { fprintf (stderr, "Failed to parse JSON transaction details `%s': %s (%s)\n", sender_details, error.text, error.source); global_ret = 1; return; } if (NULL == transfer_details) { fprintf (stderr, "No transfer details given (justification required)\n"); global_ret = 1; json_decref (jdetails); return; } tdetails = json_loads (transfer_details, JSON_REJECT_DUPLICATES, &error); if (NULL == tdetails) { fprintf (stderr, "Failed to parse JSON transaction details `%s': %s (%s)\n", transfer_details, error.text, error.source); global_ret = 1; json_decref (jdetails); return; } if (NULL == (plugin = TALER_EXCHANGEDB_plugin_load (cfg))) { fprintf (stderr, "Failed to initialize database plugin.\n"); global_ret = 1; return; } if (GNUNET_SYSERR == run_transaction (&reserve_pub, &add_value, jdetails, tdetails)) global_ret = 1; TALER_EXCHANGEDB_plugin_unload (plugin); json_decref (jdetails); json_decref (tdetails); } /** * The main function of the reservemod tool * * @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) { const struct GNUNET_GETOPT_CommandLineOption options[] = { {'a', "add", "DENOM", "value to add", 1, &GNUNET_GETOPT_set_string, &add_str}, {'s', "sender", "JSON", "details about the sender's bank account", 1, &GNUNET_GETOPT_set_string, &sender_details}, {'t', "transfer", "JSON", "details that uniquely identify the bank transfer", 1, &GNUNET_GETOPT_set_string, &transfer_details}, GNUNET_GETOPT_OPTION_HELP ("Deposit funds into a Taler reserve"), {'R', "reserve", "KEY", "reserve (public key) to modify", 1, &GNUNET_GETOPT_set_string, &reserve_pub_str}, GNUNET_GETOPT_OPTION_END }; GNUNET_assert (GNUNET_OK == GNUNET_log_setup ("taler-exchange-reservemod", "WARNING", NULL)); if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "taler-exchange-reservemod", "Deposit funds into a Taler reserve", options, &run, NULL)) return 1; return global_ret; } /* end taler-exchange-reservemod.c */