diff options
Diffstat (limited to 'src/mint/taler-mint-reservemod.c')
-rw-r--r-- | src/mint/taler-mint-reservemod.c | 215 |
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 | |||
31 | static char *mintdir; | ||
32 | static struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub; | ||
33 | static struct GNUNET_CONFIGURATION_Handle *kcfg; | ||
34 | static 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 | */ | ||
46 | int | ||
47 | reservemod_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 | */ | ||
140 | int | ||
141 | main (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 | |||