aboutsummaryrefslogtreecommitdiff
path: root/src/mint/taler-mint-reservemod.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mint/taler-mint-reservemod.c')
-rw-r--r--src/mint/taler-mint-reservemod.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/mint/taler-mint-reservemod.c b/src/mint/taler-mint-reservemod.c
new file mode 100644
index 000000000..3dd94f84b
--- /dev/null
+++ b/src/mint/taler-mint-reservemod.c
@@ -0,0 +1,215 @@
1/*
2 This file is part of TALER
3 (C) 2014 Christian Grothoff (and other contributing authors)
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, If not, see <http://www.gnu.org/licenses/>
15*/
16
17/**
18 * @file taler-mint-reservemod.c
19 * @brief Modify reserves.
20 * @author Florian Dold
21 * @author Benedikt Mueller
22 */
23
24#include "platform.h"
25#include <gnunet/gnunet_util_lib.h>
26#include <libpq-fe.h>
27#include "taler_util.h"
28#include "taler_signatures.h"
29#include "mint.h"
30
31static char *mintdir;
32static struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub;
33static struct GNUNET_CONFIGURATION_Handle *kcfg;
34static PGconn *db_conn;
35
36
37
38/**
39 * Create a new or add to existing reserve.
40 * Fails if currencies do not match.
41 *
42 * @param denom denomination to add
43 *
44 * @return ...
45 */
46int
47reservemod_add (struct TALER_Amount denom)
48{
49 PGresult *result;
50 {
51 const void *param_values[] = { reserve_pub };
52 int param_lengths[] = {sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)};
53 int param_formats[] = {1};
54 result = PQexecParams (db_conn,
55 "select balance_value, balance_fraction, balance_currency from reserves where reserve_pub=$1 limit 1;",
56 1, NULL, (const char * const *) param_values, param_lengths, param_formats, 1);
57 }
58
59 if (PGRES_TUPLES_OK != PQresultStatus (result))
60 {
61 fprintf (stderr, "Select failed: %s\n", PQresultErrorMessage (result));
62 return GNUNET_SYSERR;
63 }
64 if (0 == PQntuples (result))
65 {
66 struct GNUNET_TIME_AbsoluteNBO exnbo;
67 exnbo = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add ( GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_YEARS));
68
69 uint32_t value = htonl (denom.value);
70 uint32_t fraction = htonl (denom.fraction);
71 const void *param_values[] = {
72 reserve_pub,
73 &value,
74 &fraction,
75 denom.currency,
76 &exnbo};
77 int param_lengths[] = {32, 4, 4, strlen(denom.currency), 8};
78 int param_formats[] = {1, 1, 1, 1, 1};
79 result = PQexecParams (db_conn,
80 "insert into reserves (reserve_pub, balance_value, balance_fraction, balance_currency, "
81 " expiration_date )"
82 "values ($1,$2,$3,$4,$5);",
83 5, NULL, (const char **) param_values, param_lengths, param_formats, 1);
84
85 if (PGRES_COMMAND_OK != PQresultStatus (result))
86 {
87 fprintf (stderr, "Insert failed: %s\n", PQresultErrorMessage (result));
88 return GNUNET_SYSERR;
89 }
90 }
91 else
92 {
93 struct TALER_Amount old_denom;
94 struct TALER_Amount new_denom;
95 struct TALER_AmountNBO new_denom_nbo;
96 int denom_indices[] = {0, 1, 2};
97 int param_lengths[] = {4, 4, 32};
98 int param_formats[] = {1, 1, 1};
99 const void *param_values[] = {
100 &new_denom_nbo.value,
101 &new_denom_nbo.fraction,
102 reserve_pub
103 };
104
105 GNUNET_assert (GNUNET_OK == TALER_TALER_DB_extract_amount (result, 0, denom_indices, &old_denom));
106 new_denom = TALER_amount_add (old_denom, denom);
107 new_denom_nbo = TALER_amount_hton (new_denom);
108 result = PQexecParams (db_conn,
109 "UPDATE reserves "
110 "SET balance_value = $1, balance_fraction = $2, "
111 " status_sig = NULL, status_sign_pub = NULL "
112 "WHERE reserve_pub = $3 ",
113 3, NULL, (const char **) param_values, param_lengths, param_formats, 1);
114
115 if (PGRES_COMMAND_OK != PQresultStatus (result))
116 {
117 fprintf (stderr, "Update failed: %s\n", PQresultErrorMessage (result));
118 return GNUNET_SYSERR;
119 }
120
121 if (0 != strcmp ("1", PQcmdTuples (result)))
122 {
123 fprintf (stderr, "Update failed (updated '%s' tupes instead of '1')\n",
124 PQcmdTuples (result));
125 return GNUNET_SYSERR;
126 }
127
128 }
129 return GNUNET_OK;
130}
131
132
133/**
134 * The main function of the reservemod tool
135 *
136 * @param argc number of arguments from the command line
137 * @param argv command line arguments
138 * @return 0 ok, 1 on error
139 */
140int
141main (int argc, char *const *argv)
142{
143 static char *reserve_pub_str;
144 static char *add_str;
145 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
146 GNUNET_GETOPT_OPTION_HELP ("gnunet-mint-keyup OPTIONS"),
147 {'d', "mint-dir", "DIR",
148 "mint directory with keys to update", 1,
149 &GNUNET_GETOPT_set_filename, &mintdir},
150 {'R', "reserve", "KEY",
151 "reserve (public key) to modify", 1,
152 &GNUNET_GETOPT_set_string, &reserve_pub_str},
153 {'a', "add", "DENOM",
154 "value to add", 1,
155 &GNUNET_GETOPT_set_string, &add_str},
156 GNUNET_GETOPT_OPTION_END
157 };
158 char *TALER_MINT_db_connection_cfg_str;
159
160 GNUNET_assert (GNUNET_OK == GNUNET_log_setup ("taler-mint-keycheck", "WARNING", NULL));
161
162 if (GNUNET_GETOPT_run ("taler-mint-keyup", options, argc, argv) < 0)
163 return 1;
164 if (NULL == mintdir)
165 {
166 fprintf (stderr, "mint directory not given\n");
167 return 1;
168 }
169
170 reserve_pub = GNUNET_new (struct GNUNET_CRYPTO_EddsaPublicKey);
171 if ((NULL == reserve_pub_str) ||
172 (GNUNET_OK != GNUNET_STRINGS_string_to_data (reserve_pub_str,
173 strlen (reserve_pub_str),
174 reserve_pub,
175 sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))))
176 {
177 fprintf (stderr, "reserve key invalid\n");
178 return 1;
179 }
180
181 kcfg = TALER_MINT_config_load (mintdir);
182 if (NULL == kcfg)
183 {
184 fprintf (stderr, "can't load mint configuration\n");
185 return 1;
186 }
187 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (kcfg, "mint", "db", &TALER_MINT_db_connection_cfg_str))
188 {
189 fprintf (stderr, "db configuration string not found\n");
190 return 42;
191 }
192 db_conn = PQconnectdb (TALER_MINT_db_connection_cfg_str);
193 if (CONNECTION_OK != PQstatus (db_conn))
194 {
195 fprintf (stderr, "db connection failed: %s\n", PQerrorMessage (db_conn));
196 return 1;
197 }
198
199 if (NULL != add_str)
200 {
201 struct TALER_Amount add_value;
202 if (GNUNET_OK != TALER_string_to_amount (add_str, &add_value))
203 {
204 fprintf (stderr, "could not read value\n");
205 return 1;
206 }
207 if (GNUNET_OK != reservemod_add (add_value))
208 {
209 fprintf (stderr, "adding value failed\n");
210 return 1;
211 }
212 }
213 return 0;
214}
215