wrong types
[oweals/gnunet.git] / src / dht / plugin_dhtlog_mysql_dump_load.c
1 /*
2      This file is part of GNUnet.
3      (C) 2006 - 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file src/dht/plugin_dhtlog_mysql_dump_load.c
23  * @brief MySQL logging plugin to record DHT operations to MySQL server,
24  *        but write all queries to file instead of the actual server
25  *        so that they can be imported later.  Since the first attempt
26  *        (writing out SQL queries) seemed rather time consuming on insert,
27  *        this plugin writes out tab separated values instead.
28  *
29  * @author Nathan Evans
30  *
31  * Database: MySQL
32  */
33
34 #include "platform.h"
35 #include "gnunet_util_lib.h"
36 #include "dhtlog.h"
37
38
39 #define DEBUG_DHTLOG GNUNET_NO
40
41 /**
42  * Maximum number of supported parameters for a prepared
43  * statement.  Increase if needed.
44  */
45 #define MAX_PARAM 32
46
47
48 static unsigned long max_varchar_len;
49
50 /**
51  * The configuration the DHT service is running with
52  */
53 static const struct GNUNET_CONFIGURATION_Handle *cfg;
54
55 #define DATE_STR_SIZE 50
56
57 static unsigned int topology_count;
58
59 /**
60  * File(s) to dump all sql statements to.
61  */
62 FILE *outfile;
63 FILE *generic_stat_outfile;
64 FILE *stat_outfile;
65 FILE *node_outfile;
66 FILE *query_outfile;
67 FILE *route_outfile;
68 FILE *dhtkey_outfile;
69 FILE *extended_topology_outfile;
70
71 static char *
72 get_sql_time()
73 {
74   static char date[DATE_STR_SIZE];
75   time_t timetmp;
76   struct tm *tmptr;
77
78   time (&timetmp);
79   memset (date, 0, DATE_STR_SIZE);
80   tmptr = localtime (&timetmp);
81   if (NULL != tmptr)
82     strftime (date, DATE_STR_SIZE, "%Y-%m-%d %H:%M:%S", tmptr);
83   else
84     strcpy (date, "");
85
86   return date;
87 }
88
89 /*
90  * Records the current topology (number of connections, time, trial)
91  *
92  * @param num_connections how many connections are in the topology
93  *
94  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
95  */
96 int
97 add_topology (int num_connections)
98 {
99   int ret;
100   if (outfile == NULL)
101     return GNUNET_SYSERR;
102
103   ret = fprintf(outfile, "insert into topology (trialuid, date, connections) values (@temp_trial, \"%s\", %d);\n", get_sql_time(), num_connections);
104   ret = fprintf(outfile, "select max(topology_uid) from topology into @temp_topology;\n");
105   if (ret >= 0)
106     return GNUNET_OK;
107   return GNUNET_SYSERR;
108 }
109
110 /*
111  * Records a connection between two peers in the current topology
112  *
113  * @param first one side of the connection
114  * @param second other side of the connection
115  *
116  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
117  */
118 int
119 add_extended_topology (const struct GNUNET_PeerIdentity *first, const struct GNUNET_PeerIdentity *second)
120 {
121   int ret;
122   if (outfile == NULL)
123     return GNUNET_SYSERR;
124
125   ret = fprintf(extended_topology_outfile, "insert into extended_topology (topology_uid, uid_first, uid_second) values (%u, %s,", topology_count, GNUNET_h2s_full(&first->hashPubKey));
126   ret = fprintf(extended_topology_outfile, "%s);\n", GNUNET_h2s_full(&second->hashPubKey));
127
128   if (ret >= 0)
129     return GNUNET_OK;
130   return GNUNET_SYSERR;
131 }
132
133
134 /*
135  * Inserts the specified trial into the dhttests.trials table
136  *
137  * @param trialuid return the trialuid of the newly inserted trial
138  * @param num_nodes how many nodes are in the trial
139  * @param topology integer representing topology for this trial
140  * @param blacklist_topology integer representing blacklist topology for this trial
141  * @param connect_topology integer representing connect topology for this trial
142  * @param connect_topology_option integer representing connect topology option
143  * @param connect_topology_option_modifier float to modify connect option
144  * @param topology_percentage percentage modifier for certain topologies
145  * @param topology_probability probability modifier for certain topologies
146  * @param puts number of puts to perform
147  * @param gets number of gets to perform
148  * @param concurrent number of concurrent requests
149  * @param settle_time time to wait between creating topology and starting testing
150  * @param num_rounds number of times to repeat the trial
151  * @param malicious_getters number of malicious GET peers in the trial
152  * @param malicious_putters number of malicious PUT peers in the trial
153  * @param malicious_droppers number of malicious DROP peers in the trial
154  * @param malicious_get_frequency how often malicious gets are sent
155  * @param malicious_put_frequency how often malicious puts are sent
156  * @param stop_closest stop forwarding PUTs if closest node found
157  * @param stop_found stop forwarding GETs if data found
158  * @param strict_kademlia test used kademlia routing algorithm
159  * @param gets_succeeded how many gets did the test driver report success on
160  * @param message string to put into DB for this trial
161  *
162  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
163  */
164 int add_trial (unsigned long long *trialuid, unsigned int num_nodes, unsigned int topology,
165                unsigned int blacklist_topology, unsigned int connect_topology,
166                unsigned int connect_topology_option, float connect_topology_option_modifier,
167                float topology_percentage, float topology_probability,
168                unsigned int puts, unsigned int gets, unsigned int concurrent, unsigned int settle_time,
169                unsigned int num_rounds, unsigned int malicious_getters, unsigned int malicious_putters,
170                unsigned int malicious_droppers, unsigned int malicious_get_frequency,
171                unsigned int malicious_put_frequency, unsigned int stop_closest, unsigned int stop_found,
172                unsigned int strict_kademlia, unsigned int gets_succeeded,
173                char *message)
174 {
175   int ret;
176   if (trialuid != NULL)
177     *trialuid = 0;
178   if (outfile == NULL)
179     return GNUNET_SYSERR;
180
181   ret = fprintf(outfile, "INSERT INTO trials "
182                          "(starttime, numnodes, topology,"
183                            "blacklist_topology, connect_topology, connect_topology_option,"
184                            "connect_topology_option_modifier, topology_percentage, topology_probability,"
185                            "puts, gets, "
186                            "concurrent, settle_time, num_rounds, malicious_getters,"
187                            "malicious_putters, malicious_droppers, malicious_get_frequency,"
188                            "malicious_put_frequency, stop_closest, stop_found, strict_kademlia, "
189                            "gets_succeeded, message) "
190                            "VALUES (\"%s\", %u, %u, %u, %u, %u, %f, %f, %f, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, \"%s\");\n",
191                            get_sql_time(), num_nodes, topology,
192                            blacklist_topology, connect_topology,
193                            connect_topology_option, connect_topology_option_modifier,
194                            topology_percentage, topology_probability,
195                            puts, gets, concurrent, settle_time,
196                            num_rounds, malicious_getters, malicious_putters,
197                            malicious_droppers, malicious_get_frequency, malicious_put_frequency,
198                            stop_closest, stop_found, strict_kademlia, gets_succeeded, message);
199
200   ret = fprintf(outfile, "SELECT MAX( trialuid ) FROM trials into @temp_trial;\n");
201
202   if (ret >= 0)
203     return GNUNET_OK;
204   return GNUNET_SYSERR;
205 }
206
207
208 /*
209  * Inserts the specified stats into the dhttests.generic_stats table
210  *
211  * @param peer the peer inserting the statistic
212  * @param name the name of the statistic
213  * @param section the section of the statistic
214  * @param value the value of the statistic
215  *
216  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
217  */
218 int
219 add_generic_stat (const struct GNUNET_PeerIdentity *peer,
220                   const char *name,
221                   const char *section, uint64_t value)
222 {
223   if (outfile == NULL)
224     return GNUNET_SYSERR;
225
226   if (peer != NULL)
227     fprintf(generic_stat_outfile, "TRIALUID\t%s\t%s\t%s\t%llu\n", GNUNET_h2s_full(&peer->hashPubKey), section, name, (unsigned long long)value);
228
229   return GNUNET_OK;
230 }
231
232
233 /*
234  * Inserts the specified stats into the dhttests.node_statistics table
235  *
236  * @param peer the peer inserting the statistic
237  * @param route_requests route requests seen
238  * @param route_forwards route requests forwarded
239  * @param result_requests route result requests seen
240  * @param client_requests client requests initiated
241  * @param result_forwards route results forwarded
242  * @param gets get requests handled
243  * @param puts put requests handle
244  * @param data_inserts data inserted at this node
245  * @param find_peer_requests find peer requests seen
246  * @param find_peers_started find peer requests initiated at this node
247  * @param gets_started get requests initiated at this node
248  * @param puts_started put requests initiated at this node
249  * @param find_peer_responses_received find peer responses received locally
250  * @param get_responses_received get responses received locally
251  * @param find_peer_responses_sent find peer responses sent from this node
252  * @param get_responses_sent get responses sent from this node
253  *
254  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
255  */
256 int
257 add_stat (const struct GNUNET_PeerIdentity *peer, unsigned int route_requests,
258           unsigned int route_forwards, unsigned int result_requests,
259           unsigned int client_requests, unsigned int result_forwards,
260           unsigned int gets, unsigned int puts,
261           unsigned int data_inserts, unsigned int find_peer_requests,
262           unsigned int find_peers_started, unsigned int gets_started,
263           unsigned int puts_started, unsigned int find_peer_responses_received,
264           unsigned int get_responses_received, unsigned int find_peer_responses_sent,
265           unsigned int get_responses_sent)
266 {
267   int ret;
268   if (outfile == NULL)
269     return GNUNET_SYSERR;
270
271   if (peer != NULL)
272     ret = fprintf(stat_outfile, "TRIALUID\t%s\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\n",
273                                 GNUNET_h2s_full(&peer->hashPubKey),
274                                 route_requests, route_forwards, result_requests,
275                                 client_requests, result_forwards, gets, puts,
276                                 data_inserts, find_peer_requests, find_peers_started,
277                                 gets_started, puts_started, find_peer_responses_received,
278                                 get_responses_received, find_peer_responses_sent,
279                                 get_responses_sent);
280
281   if (ret < 0)
282     return GNUNET_SYSERR;
283
284   return GNUNET_OK;
285 }
286 /*
287  * Inserts the specified dhtkey into the dhttests.dhtkeys table,
288  * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid
289  *
290  * @param dhtkeyuid return value
291  * @param dhtkey hashcode of key to insert
292  *
293  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
294  */
295 int
296 add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey)
297 {
298   int ret;
299   if (dhtkeyuid != NULL)
300     *dhtkeyuid = 0;
301
302   if (dhtkey_outfile == NULL)
303     return GNUNET_SYSERR;
304
305   if (dhtkey != NULL)
306     ret = fprintf(dhtkey_outfile, "TRIALUID\t%s\n", GNUNET_h2s_full(dhtkey));
307
308   if (ret >= 0)
309     return GNUNET_OK;
310   return GNUNET_SYSERR;
311 }
312
313 /*
314  * Inserts the specified node into the dhttests.nodes table
315  *
316  * @param nodeuid the inserted node uid
317  * @param node the node to insert
318  *
319  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
320  */
321 int
322 add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node)
323 {
324   int ret;
325
326   if ((node == NULL) || (node_outfile == NULL))
327     return GNUNET_SYSERR;
328
329   ret = fprintf(node_outfile, "TRIALUID\t%s\n", GNUNET_h2s_full(&node->hashPubKey));
330
331   if (ret >= 0)
332     return GNUNET_OK;
333   return GNUNET_SYSERR;
334 }
335
336 /*
337  * Update dhttests.trials table with current server time as end time
338  *
339  * @param trialuid trial to update
340  * @param gets_succeeded how many gets did the testcase report as successful
341  *
342  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
343  */
344 int
345 update_trials (unsigned long long trialuid,
346                unsigned int gets_succeeded)
347 {
348   int ret;
349 #if DEBUG_DHTLOG
350   if (trialuid != current_trial)
351     {
352       fprintf (stderr,
353                _("Trialuid to update is not equal to current_trial\n"));
354     }
355 #endif
356
357   if (outfile == NULL)
358     return GNUNET_SYSERR;
359
360   ret = fprintf(outfile, "update trials set endtime=\"%s\", gets_succeeded=%u where trialuid = @temp_trial;\n", get_sql_time(), gets_succeeded);
361
362   if (ret >= 0)
363     return GNUNET_OK;
364   else
365     return GNUNET_SYSERR;
366 }
367
368
369 /*
370  * Update dhttests.nodes table setting the identified
371  * node as a malicious dropper.
372  *
373  * @param peer the peer that was set to be malicious
374  *
375  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
376  */
377 int
378 set_malicious (struct GNUNET_PeerIdentity *peer)
379 {
380   int ret;
381
382   if (outfile == NULL)
383     return GNUNET_SYSERR;
384
385   ret = fprintf(outfile, "update nodes set malicious_dropper = 1 where trialuid = @temp_trial and nodeid = \"%s\";\n", GNUNET_h2s_full(&peer->hashPubKey));
386
387   if (ret >= 0)
388     return GNUNET_OK;
389   else
390     return GNUNET_SYSERR;
391 }
392
393
394 /*
395  * Update dhttests.trials table with total connections information
396  *
397  * @param trialuid the trialuid to update
398  * @param totalConnections the number of connections
399  *
400  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
401  */
402 int
403 add_connections (unsigned long long trialuid, unsigned int totalConnections)
404 {
405   int ret;
406 #if DEBUG_DHTLOG
407   if (trialuid != current_trial)
408     {
409       fprintf (stderr,
410                _("Trialuid to update is not equal to current_trial(!)(?)\n"));
411     }
412 #endif
413   if (outfile == NULL)
414     return GNUNET_SYSERR;
415
416   ret = fprintf(outfile, "update trials set totalConnections = %u where trialuid = @temp_trial;\n", totalConnections);
417
418   if (ret >= 0)
419     return GNUNET_OK;
420   else
421     return GNUNET_SYSERR;
422 }
423
424
425 /*
426  * Update dhttests.topology table with total connections information
427  *
428  * @param connections the number of connections
429  *
430  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
431  */
432 int
433 update_topology (unsigned int connections)
434 {
435   int ret;
436   if (outfile == NULL)
437     return GNUNET_SYSERR;
438
439   ret = fprintf(outfile, "update topology set connections = %u where topology_uid = @temp_topology;\n", connections);
440   topology_count++;
441   if (ret >= 0)
442     return GNUNET_OK;
443   else
444     return GNUNET_SYSERR;
445 }
446
447 /*
448  * Inserts the specified query into the dhttests.queries table
449  *
450  * @param sqlqueruid inserted query uid
451  * @param queryid dht query id
452  * @param type type of the query
453  * @param hops number of hops query traveled
454  * @param succeeded whether or not query was successful
455  * @param node the node the query hit
456  * @param key the key of the query
457  *
458  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
459  */
460 int
461 add_query (unsigned long long *sqlqueryuid, unsigned long long queryid,
462            unsigned int type, unsigned int hops, int succeeded,
463            const struct GNUNET_PeerIdentity * node, const GNUNET_HashCode * key)
464 {
465   int ret;
466
467   if ((outfile == NULL) || (node == NULL) || (key == NULL))
468     return GNUNET_SYSERR;
469
470   if (sqlqueryuid != NULL)
471     *sqlqueryuid = 0;
472
473   ret = fprintf(query_outfile, "TRIALUID\t%s\t", GNUNET_h2s_full(key));
474   ret = fprintf(query_outfile, "%s\t%llu\t%u\t%u\t%u\n", GNUNET_h2s_full(&node->hashPubKey), queryid, type, hops, succeeded);
475
476   if (ret >= 0)
477     return GNUNET_OK;
478   else
479     return GNUNET_SYSERR;
480 }
481
482 /*
483  * Inserts the specified route information into the dhttests.routes table
484  *
485  * @param sqlqueruid inserted query uid
486  * @param queryid dht query id
487  * @param type type of the query
488  * @param hops number of hops query traveled
489  * @param succeeded whether or not query was successful
490  * @param node the node the query hit
491  * @param key the key of the query
492  * @param from_node the node that sent the message to node
493  * @param to_node next node to forward message to
494  *
495  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
496  */
497 int
498 add_route (unsigned long long *sqlqueryuid, unsigned long long queryid,
499            unsigned int type, unsigned int hops,
500            int succeeded, const struct GNUNET_PeerIdentity * node,
501            const GNUNET_HashCode * key, const struct GNUNET_PeerIdentity * from_node,
502            const struct GNUNET_PeerIdentity * to_node)
503 {
504   int ret;
505
506   if ((outfile == NULL) || (node == NULL) || (key == NULL))
507     return GNUNET_SYSERR;
508
509   if (sqlqueryuid != NULL)
510     *sqlqueryuid = 0;
511
512   ret = fprintf(route_outfile, "TRIALUID\t%s\t", GNUNET_h2s_full(key));
513   ret = fprintf(route_outfile, "%s\t", GNUNET_h2s_full(&node->hashPubKey));
514   if (from_node == NULL)
515     ret = fprintf(route_outfile, "0\t");
516   else
517     ret = fprintf(route_outfile, "%s\t", GNUNET_h2s_full(&from_node->hashPubKey));
518
519   if (to_node == NULL)
520     ret = fprintf(route_outfile, "0\t%llu\t%u\t%u\t%d\n", queryid, type, hops, succeeded);
521   else
522     ret = fprintf(route_outfile, "%s\t%llu\t%u\t%u\t%d\n", GNUNET_h2s_full(&to_node->hashPubKey), queryid, type, hops, succeeded);
523
524   if (ret >= 0)
525     return GNUNET_OK;
526   else
527     return GNUNET_SYSERR;
528 }
529
530 /*
531  * Provides the dhtlog api
532  *
533  * @param c the configuration to use to connect to a server
534  *
535  * @return the handle to the server, or NULL on error
536  */
537 void *
538 libgnunet_plugin_dhtlog_mysql_dump_load_init (void * cls)
539 {
540   struct GNUNET_DHTLOG_Plugin *plugin = cls;
541   char *outfile_name;
542   char *outfile_path;
543   char *fn;
544   int dirwarn;
545
546   cfg = plugin->cfg;
547   max_varchar_len = 255;
548
549   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL (DUMP) DHT Logger: initializing\n");
550
551   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
552                                                          "MYSQLDUMP", "PATH",
553                                                          &outfile_path))
554     {
555       outfile_path = GNUNET_strdup("");
556     }
557
558   GNUNET_asprintf (&outfile_name,
559                    "%s%s-%d",
560                    outfile_path,
561                    "mysqldump",
562                    getpid());
563
564   fn = GNUNET_STRINGS_filename_expand (outfile_name);
565
566   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
567   outfile = FOPEN (fn, "w");
568
569   if (outfile == NULL)
570     {
571       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
572       if (dirwarn)
573         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
574                     _("Failed to create or access directory for log file `%s'\n"),
575                     fn);
576       GNUNET_free(outfile_path);
577       GNUNET_free(outfile_name);
578       GNUNET_free (fn);
579       return NULL;
580     }
581
582   GNUNET_asprintf (&outfile_name,
583                    "%s%s-%d",
584                    outfile_path,
585                    "mysqldump_nodes",
586                    getpid());
587
588   fn = GNUNET_STRINGS_filename_expand (outfile_name);
589
590   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
591   node_outfile = FOPEN (fn, "w");
592
593   if (node_outfile == NULL)
594     {
595       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
596       if (dirwarn)
597         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
598                     _("Failed to create or access directory for log file `%s'\n"),
599                     fn);
600       GNUNET_free(outfile_path);
601       GNUNET_free(outfile_name);
602       GNUNET_free (fn);
603       return NULL;
604     }
605
606   GNUNET_asprintf (&outfile_name,
607                    "%s%s-%d",
608                    outfile_path,
609                    "mysqldump_routes",
610                    getpid());
611
612   fn = GNUNET_STRINGS_filename_expand (outfile_name);
613
614   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
615   route_outfile = FOPEN (fn, "w");
616
617   if (route_outfile == NULL)
618     {
619       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
620       if (dirwarn)
621         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
622                     _("Failed to create or access directory for log file `%s'\n"),
623                     fn);
624       GNUNET_free(outfile_path);
625       GNUNET_free(outfile_name);
626       GNUNET_free (fn);
627       return NULL;
628     }
629
630   GNUNET_asprintf (&outfile_name,
631                    "%s%s-%d",
632                    outfile_path,
633                    "mysqldump_queries",
634                    getpid());
635
636   fn = GNUNET_STRINGS_filename_expand (outfile_name);
637
638   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
639   query_outfile = FOPEN (fn, "w");
640
641   if (query_outfile == NULL)
642     {
643       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
644       if (dirwarn)
645         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
646                     _("Failed to create or access directory for log file `%s'\n"),
647                     fn);
648       GNUNET_free(outfile_path);
649       GNUNET_free(outfile_name);
650       GNUNET_free (fn);
651       return NULL;
652     }
653
654   GNUNET_asprintf (&outfile_name,
655                    "%s%s-%d",
656                    outfile_path,
657                    "mysqldump_stats",
658                    getpid());
659
660   fn = GNUNET_STRINGS_filename_expand (outfile_name);
661
662   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
663   stat_outfile = FOPEN (fn, "w");
664
665   if (stat_outfile == NULL)
666     {
667       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
668       if (dirwarn)
669         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
670                     _("Failed to create or access directory for log file `%s'\n"),
671                     fn);
672       GNUNET_free(outfile_path);
673       GNUNET_free(outfile_name);
674       GNUNET_free (fn);
675       return NULL;
676     }
677
678   GNUNET_asprintf (&outfile_name,
679                    "%s%s-%d",
680                    outfile_path,
681                    "mysqldump_generic_stats",
682                    getpid());
683
684   fn = GNUNET_STRINGS_filename_expand (outfile_name);
685
686   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
687   generic_stat_outfile = FOPEN (fn, "w");
688
689   if (generic_stat_outfile == NULL)
690     {
691       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
692       if (dirwarn)
693         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
694                     _("Failed to create or access directory for log file `%s'\n"),
695                     fn);
696       GNUNET_free(outfile_path);
697       GNUNET_free(outfile_name);
698       GNUNET_free (fn);
699       return NULL;
700     }
701
702   GNUNET_asprintf (&outfile_name,
703                    "%s%s-%d",
704                    outfile_path,
705                    "mysqldump_dhtkey",
706                    getpid());
707
708   fn = GNUNET_STRINGS_filename_expand (outfile_name);
709
710   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
711   dhtkey_outfile = FOPEN (fn, "w");
712
713   if (dhtkey_outfile == NULL)
714     {
715       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
716       if (dirwarn)
717         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
718                     _("Failed to create or access directory for log file `%s'\n"),
719                     fn);
720       GNUNET_free(outfile_path);
721       GNUNET_free(outfile_name);
722       GNUNET_free (fn);
723       return NULL;
724     }
725
726   GNUNET_asprintf (&outfile_name,
727                    "%s%s-%d",
728                    outfile_path,
729                    "mysqldump_extended_topology",
730                    getpid());
731
732   fn = GNUNET_STRINGS_filename_expand (outfile_name);
733
734   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
735   extended_topology_outfile = FOPEN (fn, "w");
736
737   if (extended_topology_outfile == NULL)
738     {
739       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
740       if (dirwarn)
741         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
742                     _("Failed to create or access directory for log file `%s'\n"),
743                     fn);
744       GNUNET_free(outfile_path);
745       GNUNET_free(outfile_name);
746       GNUNET_free (fn);
747       return NULL;
748     }
749
750   GNUNET_free (outfile_path);
751   GNUNET_free (outfile_name);
752   GNUNET_free (fn);
753
754   GNUNET_assert(plugin->dhtlog_api == NULL);
755   plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
756   plugin->dhtlog_api->insert_trial = &add_trial;
757   plugin->dhtlog_api->insert_stat = &add_stat;
758   plugin->dhtlog_api->insert_query = &add_query;
759   plugin->dhtlog_api->update_trial = &update_trials;
760   plugin->dhtlog_api->insert_route = &add_route;
761   plugin->dhtlog_api->insert_node = &add_node;
762   plugin->dhtlog_api->insert_dhtkey = &add_dhtkey;
763   plugin->dhtlog_api->update_connections = &add_connections;
764   plugin->dhtlog_api->insert_topology = &add_topology;
765   plugin->dhtlog_api->insert_extended_topology = &add_extended_topology;
766   plugin->dhtlog_api->update_topology = &update_topology;
767   plugin->dhtlog_api->set_malicious = &set_malicious;
768   plugin->dhtlog_api->add_generic_stat = &add_generic_stat;
769
770   return plugin;
771 }
772
773 /**
774  * Shutdown the plugin.
775  */
776 void *
777 libgnunet_plugin_dhtlog_mysql_dump_load_done (void * cls)
778 {
779   struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
780   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
781               "MySQL DHT Logger: database shutdown\n");
782   GNUNET_assert(dhtlog_api != NULL);
783
784   fclose(outfile);
785   fclose(node_outfile);
786   fclose(query_outfile);
787   fclose(route_outfile);
788   fclose(stat_outfile);
789   fclose(generic_stat_outfile);
790   fclose(extended_topology_outfile);
791   GNUNET_free(dhtlog_api);
792   return NULL;
793 }
794
795 /* end of plugin_dhtlog_mysql_dump_load.c */