aboutsummaryrefslogtreecommitdiff
path: root/src/datastore/gnunet-datastore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datastore/gnunet-datastore.c')
-rw-r--r--src/datastore/gnunet-datastore.c508
1 files changed, 0 insertions, 508 deletions
diff --git a/src/datastore/gnunet-datastore.c b/src/datastore/gnunet-datastore.c
deleted file mode 100644
index 5901cce54..000000000
--- a/src/datastore/gnunet-datastore.c
+++ /dev/null
@@ -1,508 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010, 2013 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file datastore/gnunet-datastore.c
23 * @brief tool to manipulate datastores
24 * @author Christian Grothoff
25 */
26#include <inttypes.h>
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_datastore_service.h"
30
31GNUNET_NETWORK_STRUCT_BEGIN
32
33struct DataRecord
34{
35 /**
36 * Number of bytes in the item (NBO).
37 */
38 uint32_t size GNUNET_PACKED;
39
40 /**
41 * Type of the item (NBO) (actually an enum GNUNET_BLOCK_Type)
42 */
43 uint32_t type GNUNET_PACKED;
44
45 /**
46 * Priority of the item (NBO).
47 */
48 uint32_t priority GNUNET_PACKED;
49
50 /**
51 * Desired anonymity level (NBO).
52 */
53 uint32_t anonymity GNUNET_PACKED;
54
55 /**
56 * Desired replication level (NBO).
57 */
58 uint32_t replication GNUNET_PACKED;
59
60 /**
61 * Expiration time (NBO).
62 */
63 struct GNUNET_TIME_AbsoluteNBO expiration;
64
65 /**
66 * Key under which the item can be found.
67 */
68 struct GNUNET_HashCode key;
69};
70GNUNET_NETWORK_STRUCT_END
71
72
73/**
74 * Length of our magic header.
75 */
76static const size_t MAGIC_LEN = 16;
77
78/**
79 * Magic header bytes.
80 */
81static const uint8_t MAGIC_BYTES[16] = "GNUNETDATASTORE1";
82
83/**
84 * Dump the database.
85 */
86static int dump;
87
88/**
89 * Insert into the database.
90 */
91static int insert;
92
93/**
94 * Dump file name.
95 */
96static char *file_name;
97
98/**
99 * Dump file handle.
100 */
101static struct GNUNET_DISK_FileHandle *file_handle;
102
103/**
104 * Global return value.
105 */
106static int ret;
107
108/**
109 * Handle for datastore.
110 */
111static struct GNUNET_DATASTORE_Handle *datastore;
112
113/**
114 * Current operation.
115 */
116static struct GNUNET_DATASTORE_QueueEntry *qe;
117
118/**
119 * Record count.
120 */
121static uint64_t record_count;
122
123
124static void
125do_shutdown (void *cls)
126{
127 if (NULL != qe)
128 GNUNET_DATASTORE_cancel (qe);
129 if (NULL != datastore)
130 GNUNET_DATASTORE_disconnect (datastore, GNUNET_NO);
131 if (NULL != file_handle)
132 GNUNET_DISK_file_close (file_handle);
133}
134
135
136/**
137 * Begin dumping the database.
138 */
139static void
140start_dump (void);
141
142
143/**
144 * Begin inserting into the database.
145 */
146static void
147start_insert (void);
148
149
150/**
151 * Perform next GET operation.
152 */
153static void
154do_get (const uint64_t next_uid);
155
156
157/**
158 * Process a datum that was stored in the datastore.
159 *
160 * @param cls closure
161 * @param key key for the content
162 * @param size number of bytes in data
163 * @param data content stored
164 * @param type type of the content
165 * @param priority priority of the content
166 * @param anonymity anonymity-level for the content
167 * @param replication replication-level for the content
168 * @param expiration expiration time for the content
169 * @param uid unique identifier for the datum;
170 * maybe 0 if no unique identifier is available
171 */
172static void
173get_cb (void *cls,
174 const struct GNUNET_HashCode *key,
175 size_t size,
176 const void *data,
177 enum GNUNET_BLOCK_Type type,
178 uint32_t priority,
179 uint32_t anonymity,
180 uint32_t replication,
181 struct GNUNET_TIME_Absolute expiration,
182 uint64_t uid)
183{
184 qe = NULL;
185 if (NULL == key)
186 {
187 fprintf (stderr, _ ("Dumped %" PRIu64 " records\n"), record_count);
188 GNUNET_DISK_file_close (file_handle);
189 file_handle = NULL;
190 if (insert)
191 start_insert ();
192 else
193 {
194 ret = 0;
195 GNUNET_SCHEDULER_shutdown ();
196 }
197 return;
198 }
199
200 struct DataRecord dr;
201 dr.size = htonl ((uint32_t) size);
202 dr.type = htonl (type);
203 dr.priority = htonl (priority);
204 dr.anonymity = htonl (anonymity);
205 dr.replication = htonl (replication);
206 dr.expiration = GNUNET_TIME_absolute_hton (expiration);
207 dr.key = *key;
208
209 ssize_t len;
210 len = GNUNET_DISK_file_write (file_handle, &dr, sizeof(dr));
211 if (sizeof(dr) != len)
212 {
213 fprintf (stderr,
214 _ ("Short write to file: %zd bytes expecting %zd\n"),
215 len,
216 sizeof(dr));
217 ret = 1;
218 GNUNET_SCHEDULER_shutdown ();
219 return;
220 }
221
222 len = GNUNET_DISK_file_write (file_handle, data, size);
223 if (size != len)
224 {
225 fprintf (stderr,
226 _ ("Short write to file: %zd bytes expecting %zd\n"),
227 len,
228 size);
229 ret = 1;
230 GNUNET_SCHEDULER_shutdown ();
231 return;
232 }
233
234 record_count++;
235 do_get (uid + 1);
236}
237
238
239/**
240 * Perform next GET operation.
241 */
242static void
243do_get (const uint64_t next_uid)
244{
245 GNUNET_assert (NULL == qe);
246 qe = GNUNET_DATASTORE_get_key (datastore,
247 next_uid,
248 false /* random */,
249 NULL /* key */,
250 GNUNET_BLOCK_TYPE_ANY,
251 0 /* queue_priority */,
252 1 /* max_queue_size */,
253 &get_cb,
254 NULL /* proc_cls */);
255 if (NULL == qe)
256 {
257 fprintf (stderr, _ ("Error queueing datastore GET operation\n"));
258 ret = 1;
259 GNUNET_SCHEDULER_shutdown ();
260 }
261}
262
263
264/**
265 * Begin dumping the database.
266 */
267static void
268start_dump ()
269{
270 record_count = 0;
271
272 if (NULL != file_name)
273 {
274 file_handle = GNUNET_DISK_file_open (file_name,
275 GNUNET_DISK_OPEN_WRITE
276 | GNUNET_DISK_OPEN_TRUNCATE
277 | GNUNET_DISK_OPEN_CREATE,
278 GNUNET_DISK_PERM_USER_READ
279 | GNUNET_DISK_PERM_USER_WRITE);
280 if (NULL == file_handle)
281 {
282 fprintf (stderr, _ ("Unable to open dump file: %s\n"), file_name);
283 ret = 1;
284 GNUNET_SCHEDULER_shutdown ();
285 return;
286 }
287 }
288 else
289 {
290 file_handle = GNUNET_DISK_get_handle_from_int_fd (STDOUT_FILENO);
291 }
292 GNUNET_DISK_file_write (file_handle, MAGIC_BYTES, MAGIC_LEN);
293 do_get (0);
294}
295
296
297/**
298 * Continuation called to notify client about result of the
299 * operation.
300 *
301 * @param cls closure
302 * @param success GNUNET_SYSERR on failure (including timeout/queue drop)
303 * GNUNET_NO if content was already there
304 * GNUNET_YES (or other positive value) on success
305 * @param min_expiration minimum expiration time required for 0-priority content to be stored
306 * by the datacache at this time, zero for unknown, forever if we have no
307 * space for 0-priority content
308 * @param msg NULL on success, otherwise an error message
309 */
310static void
311put_cb (void *cls,
312 int32_t success,
313 struct GNUNET_TIME_Absolute min_expiration,
314 const char *msg)
315{
316 qe = NULL;
317 if (GNUNET_SYSERR == success)
318 {
319 fprintf (stderr, _ ("Failed to store item: %s, aborting\n"), msg);
320 ret = 1;
321 GNUNET_SCHEDULER_shutdown ();
322 return;
323 }
324
325 struct DataRecord dr;
326 ssize_t len;
327
328 len = GNUNET_DISK_file_read (file_handle, &dr, sizeof(dr));
329 if (0 == len)
330 {
331 fprintf (stderr, _ ("Inserted %" PRIu64 " records\n"), record_count);
332 ret = 0;
333 GNUNET_SCHEDULER_shutdown ();
334 return;
335 }
336 else if (sizeof(dr) != len)
337 {
338 fprintf (stderr,
339 _ ("Short read from file: %zd bytes expecting %zd\n"),
340 len,
341 sizeof(dr));
342 ret = 1;
343 GNUNET_SCHEDULER_shutdown ();
344 return;
345 }
346
347 const size_t size = ntohl (dr.size);
348 uint8_t data[size];
349 len = GNUNET_DISK_file_read (file_handle, data, size);
350 if (size != len)
351 {
352 fprintf (stderr,
353 _ ("Short read from file: %zd bytes expecting %zd\n"),
354 len,
355 size);
356 ret = 1;
357 GNUNET_SCHEDULER_shutdown ();
358 return;
359 }
360
361 record_count++;
362 qe = GNUNET_DATASTORE_put (datastore,
363 0,
364 &dr.key,
365 size,
366 data,
367 ntohl (dr.type),
368 ntohl (dr.priority),
369 ntohl (dr.anonymity),
370 ntohl (dr.replication),
371 GNUNET_TIME_absolute_ntoh (dr.expiration),
372 0,
373 1,
374 &put_cb,
375 NULL);
376 if (NULL == qe)
377 {
378 fprintf (stderr, _ ("Error queueing datastore PUT operation\n"));
379 ret = 1;
380 GNUNET_SCHEDULER_shutdown ();
381 }
382}
383
384
385/**
386 * Begin inserting into the database.
387 */
388static void
389start_insert ()
390{
391 record_count = 0;
392
393 if (NULL != file_name)
394 {
395 file_handle = GNUNET_DISK_file_open (file_name,
396 GNUNET_DISK_OPEN_READ,
397 GNUNET_DISK_PERM_NONE);
398 if (NULL == file_handle)
399 {
400 fprintf (stderr, _ ("Unable to open dump file: %s\n"), file_name);
401 ret = 1;
402 GNUNET_SCHEDULER_shutdown ();
403 return;
404 }
405 }
406 else
407 {
408 file_handle = GNUNET_DISK_get_handle_from_int_fd (STDIN_FILENO);
409 }
410
411 uint8_t buf[MAGIC_LEN];
412 ssize_t len;
413
414 len = GNUNET_DISK_file_read (file_handle, buf, MAGIC_LEN);
415 if ((len != MAGIC_LEN) || (0 != memcmp (buf, MAGIC_BYTES, MAGIC_LEN)))
416 {
417 fprintf (stderr, _ ("Input file is not of a supported format\n"));
418 return;
419 }
420 put_cb (NULL, GNUNET_YES, GNUNET_TIME_UNIT_ZERO_ABS, NULL);
421}
422
423
424/**
425 * Main function that will be run by the scheduler.
426 *
427 * @param cls closure
428 * @param args remaining command-line arguments
429 * @param cfgfile name of the configuration file used
430 * @param cfg configuration
431 */
432static void
433run (void *cls,
434 char *const *args,
435 const char *cfgfile,
436 const struct GNUNET_CONFIGURATION_Handle *cfg)
437{
438 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
439 datastore = GNUNET_DATASTORE_connect (cfg);
440 if (NULL == datastore)
441 {
442 fprintf (stderr, _ ("Failed connecting to the datastore.\n"));
443 ret = 1;
444 GNUNET_SCHEDULER_shutdown ();
445 return;
446 }
447 if (dump)
448 start_dump ();
449 else if (insert)
450 start_insert ();
451 else
452 {
453 fprintf (stderr,
454 _ ("Please choose at least one operation: %s, %s\n"),
455 "dump",
456 "insert");
457 ret = 1;
458 GNUNET_SCHEDULER_shutdown ();
459 }
460}
461
462
463/**
464 * The main function to manipulate datastores.
465 *
466 * @param argc number of arguments from the command line
467 * @param argv command line arguments
468 * @return 0 ok, 1 on error
469 */
470int
471main (int argc, char *const *argv)
472{
473 struct GNUNET_GETOPT_CommandLineOption options[] =
474 { GNUNET_GETOPT_option_flag ('d',
475 "dump",
476 gettext_noop (
477 "Dump all records from the datastore"),
478 &dump),
479 GNUNET_GETOPT_option_flag ('i',
480 "insert",
481 gettext_noop (
482 "Insert records into the datastore"),
483 &insert),
484 GNUNET_GETOPT_option_filename ('f',
485 "file",
486 "FILENAME",
487 gettext_noop ("File to dump or insert"),
488 &file_name),
489 GNUNET_GETOPT_OPTION_END };
490
491 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
492 return 2;
493
494 if (GNUNET_OK !=
495 GNUNET_PROGRAM_run (argc,
496 argv,
497 "gnunet-datastore",
498 gettext_noop ("Manipulate GNUnet datastore"),
499 options,
500 &run,
501 NULL))
502 ret = 1;
503 GNUNET_free_nz ((void *) argv);
504 return ret;
505}
506
507
508/* end of gnunet-datastore.c */