missing definition
[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   if (ret < 0)
105     return GNUNET_SYSERR;
106   ret = fprintf(outfile, "select max(topology_uid) from topology into @temp_topology;\n");
107   if (ret >= 0)
108     return GNUNET_OK;
109   return GNUNET_SYSERR;
110 }
111
112 /*
113  * Records a connection between two peers in the current topology
114  *
115  * @param first one side of the connection
116  * @param second other side of the connection
117  *
118  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
119  */
120 int
121 add_extended_topology (const struct GNUNET_PeerIdentity *first, const struct GNUNET_PeerIdentity *second)
122 {
123   int ret;
124   if (outfile == NULL)
125     return GNUNET_SYSERR;
126
127   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));
128   if (ret < 0)
129     return GNUNET_SYSERR;
130   ret = fprintf(extended_topology_outfile, "%s);\n", GNUNET_h2s_full(&second->hashPubKey));
131
132   if (ret >= 0)
133     return GNUNET_OK;
134   return GNUNET_SYSERR;
135 }
136
137
138 /*
139  * Inserts the specified trial into the dhttests.trials table
140  *
141  * @param trialuid return the trialuid of the newly inserted trial
142  * @param num_nodes how many nodes are in the trial
143  * @param topology integer representing topology for this trial
144  * @param blacklist_topology integer representing blacklist topology for this trial
145  * @param connect_topology integer representing connect topology for this trial
146  * @param connect_topology_option integer representing connect topology option
147  * @param connect_topology_option_modifier float to modify connect option
148  * @param topology_percentage percentage modifier for certain topologies
149  * @param topology_probability probability modifier for certain topologies
150  * @param puts number of puts to perform
151  * @param gets number of gets to perform
152  * @param concurrent number of concurrent requests
153  * @param settle_time time to wait between creating topology and starting testing
154  * @param num_rounds number of times to repeat the trial
155  * @param malicious_getters number of malicious GET peers in the trial
156  * @param malicious_putters number of malicious PUT peers in the trial
157  * @param malicious_droppers number of malicious DROP peers in the trial
158  * @param malicious_get_frequency how often malicious gets are sent
159  * @param malicious_put_frequency how often malicious puts are sent
160  * @param stop_closest stop forwarding PUTs if closest node found
161  * @param stop_found stop forwarding GETs if data found
162  * @param strict_kademlia test used kademlia routing algorithm
163  * @param gets_succeeded how many gets did the test driver report success on
164  * @param message string to put into DB for this trial
165  *
166  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
167  */
168 int add_trial (unsigned long long *trialuid, unsigned int num_nodes, unsigned int topology,
169                unsigned int blacklist_topology, unsigned int connect_topology,
170                unsigned int connect_topology_option, float connect_topology_option_modifier,
171                float topology_percentage, float topology_probability,
172                unsigned int puts, unsigned int gets, unsigned int concurrent, unsigned int settle_time,
173                unsigned int num_rounds, unsigned int malicious_getters, unsigned int malicious_putters,
174                unsigned int malicious_droppers, unsigned int malicious_get_frequency,
175                unsigned int malicious_put_frequency, unsigned int stop_closest, unsigned int stop_found,
176                unsigned int strict_kademlia, unsigned int gets_succeeded,
177                char *message)
178 {
179   int ret;
180   if (trialuid != NULL)
181     *trialuid = 0;
182   if (outfile == NULL)
183     return GNUNET_SYSERR;
184
185   ret = fprintf(outfile, "INSERT INTO trials "
186                          "(starttime, numnodes, topology,"
187                            "blacklist_topology, connect_topology, connect_topology_option,"
188                            "connect_topology_option_modifier, topology_percentage, topology_probability,"
189                            "puts, gets, "
190                            "concurrent, settle_time, num_rounds, malicious_getters,"
191                            "malicious_putters, malicious_droppers, malicious_get_frequency,"
192                            "malicious_put_frequency, stop_closest, stop_found, strict_kademlia, "
193                            "gets_succeeded, message) "
194                            "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",
195                            get_sql_time(), num_nodes, topology,
196                            blacklist_topology, connect_topology,
197                            connect_topology_option, connect_topology_option_modifier,
198                            topology_percentage, topology_probability,
199                            puts, gets, concurrent, settle_time,
200                            num_rounds, malicious_getters, malicious_putters,
201                            malicious_droppers, malicious_get_frequency, malicious_put_frequency,
202                            stop_closest, stop_found, strict_kademlia, gets_succeeded, message);
203
204   if (ret < 0)
205     return GNUNET_SYSERR;
206
207   ret = fprintf(outfile, "SELECT MAX( trialuid ) FROM trials into @temp_trial;\n");
208
209   if (ret >= 0)
210     return GNUNET_OK;
211   else
212     return GNUNET_SYSERR;
213 }
214
215
216 /*
217  * Inserts the specified stats into the dhttests.generic_stats table
218  *
219  * @param peer the peer inserting the statistic
220  * @param name the name of the statistic
221  * @param section the section of the statistic
222  * @param value the value of the statistic
223  *
224  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
225  */
226 int
227 add_generic_stat (const struct GNUNET_PeerIdentity *peer,
228                   const char *name,
229                   const char *section, uint64_t value)
230 {
231   if (outfile == NULL)
232     return GNUNET_SYSERR;
233
234   if (peer != NULL)
235     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);
236
237   return GNUNET_OK;
238 }
239
240
241 /*
242  * Inserts the specified stats into the dhttests.node_statistics table
243  *
244  * @param peer the peer inserting the statistic
245  * @param route_requests route requests seen
246  * @param route_forwards route requests forwarded
247  * @param result_requests route result requests seen
248  * @param client_requests client requests initiated
249  * @param result_forwards route results forwarded
250  * @param gets get requests handled
251  * @param puts put requests handle
252  * @param data_inserts data inserted at this node
253  * @param find_peer_requests find peer requests seen
254  * @param find_peers_started find peer requests initiated at this node
255  * @param gets_started get requests initiated at this node
256  * @param puts_started put requests initiated at this node
257  * @param find_peer_responses_received find peer responses received locally
258  * @param get_responses_received get responses received locally
259  * @param find_peer_responses_sent find peer responses sent from this node
260  * @param get_responses_sent get responses sent from this node
261  *
262  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
263  */
264 int
265 add_stat (const struct GNUNET_PeerIdentity *peer, unsigned int route_requests,
266           unsigned int route_forwards, unsigned int result_requests,
267           unsigned int client_requests, unsigned int result_forwards,
268           unsigned int gets, unsigned int puts,
269           unsigned int data_inserts, unsigned int find_peer_requests,
270           unsigned int find_peers_started, unsigned int gets_started,
271           unsigned int puts_started, unsigned int find_peer_responses_received,
272           unsigned int get_responses_received, unsigned int find_peer_responses_sent,
273           unsigned int get_responses_sent)
274 {
275   int ret;
276   if (outfile == NULL)
277     return GNUNET_SYSERR;
278
279   if (peer != NULL)
280     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",
281                                 GNUNET_h2s_full(&peer->hashPubKey),
282                                 route_requests, route_forwards, result_requests,
283                                 client_requests, result_forwards, gets, puts,
284                                 data_inserts, find_peer_requests, find_peers_started,
285                                 gets_started, puts_started, find_peer_responses_received,
286                                 get_responses_received, find_peer_responses_sent,
287                                 get_responses_sent);
288
289   else
290     return GNUNET_SYSERR;
291
292   if (ret >= 0)
293     return GNUNET_OK;
294   else
295     return GNUNET_SYSERR;
296 }
297 /*
298  * Inserts the specified dhtkey into the dhttests.dhtkeys table,
299  * stores return value of dhttests.dhtkeys.dhtkeyuid into dhtkeyuid
300  *
301  * @param dhtkeyuid return value
302  * @param dhtkey hashcode of key to insert
303  *
304  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
305  */
306 int
307 add_dhtkey (unsigned long long *dhtkeyuid, const GNUNET_HashCode * dhtkey)
308 {
309   int ret;
310   if (dhtkeyuid != NULL)
311     *dhtkeyuid = 0;
312
313   if ((dhtkey_outfile == NULL) || (dhtkey == NULL))
314     return GNUNET_SYSERR;
315
316   ret = fprintf(dhtkey_outfile, "TRIALUID\t%s\n", GNUNET_h2s_full(dhtkey));
317
318   if (ret >= 0)
319     return GNUNET_OK;
320   else
321     return GNUNET_SYSERR;
322 }
323
324 /*
325  * Inserts the specified node into the dhttests.nodes table
326  *
327  * @param nodeuid the inserted node uid
328  * @param node the node to insert
329  *
330  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
331  */
332 int
333 add_node (unsigned long long *nodeuid, struct GNUNET_PeerIdentity * node)
334 {
335   int ret;
336
337   if ((node == NULL) || (node_outfile == NULL))
338     return GNUNET_SYSERR;
339
340   ret = fprintf(node_outfile, "TRIALUID\t%s\n", GNUNET_h2s_full(&node->hashPubKey));
341
342   if (ret >= 0)
343     return GNUNET_OK;
344   return GNUNET_SYSERR;
345 }
346
347 /*
348  * Update dhttests.trials table with current server time as end time
349  *
350  * @param trialuid trial to update
351  * @param gets_succeeded how many gets did the testcase report as successful
352  *
353  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
354  */
355 int
356 update_trials (unsigned long long trialuid,
357                unsigned int gets_succeeded)
358 {
359   int ret;
360 #if DEBUG_DHTLOG
361   if (trialuid != current_trial)
362     {
363       fprintf (stderr,
364                _("Trialuid to update is not equal to current_trial\n"));
365     }
366 #endif
367
368   if (outfile == NULL)
369     return GNUNET_SYSERR;
370
371   ret = fprintf(outfile, "update trials set endtime=\"%s\", gets_succeeded=%u where trialuid = @temp_trial;\n", get_sql_time(), gets_succeeded);
372
373   if (ret >= 0)
374     return GNUNET_OK;
375   else
376     return GNUNET_SYSERR;
377 }
378
379
380 /*
381  * Update dhttests.nodes table setting the identified
382  * node as a malicious dropper.
383  *
384  * @param peer the peer that was set to be malicious
385  *
386  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
387  */
388 int
389 set_malicious (struct GNUNET_PeerIdentity *peer)
390 {
391   int ret;
392
393   if (outfile == NULL)
394     return GNUNET_SYSERR;
395
396   ret = fprintf(outfile, "update nodes set malicious_dropper = 1 where trialuid = @temp_trial and nodeid = \"%s\";\n", GNUNET_h2s_full(&peer->hashPubKey));
397
398   if (ret >= 0)
399     return GNUNET_OK;
400   else
401     return GNUNET_SYSERR;
402 }
403
404
405 /*
406  * Update dhttests.trials table with total connections information
407  *
408  * @param trialuid the trialuid to update
409  * @param totalConnections the number of connections
410  *
411  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
412  */
413 int
414 add_connections (unsigned long long trialuid, unsigned int totalConnections)
415 {
416   int ret;
417 #if DEBUG_DHTLOG
418   if (trialuid != current_trial)
419     {
420       fprintf (stderr,
421                _("Trialuid to update is not equal to current_trial(!)(?)\n"));
422     }
423 #endif
424   if (outfile == NULL)
425     return GNUNET_SYSERR;
426
427   ret = fprintf(outfile, "update trials set totalConnections = %u where trialuid = @temp_trial;\n", totalConnections);
428
429   if (ret >= 0)
430     return GNUNET_OK;
431   else
432     return GNUNET_SYSERR;
433 }
434
435
436 /*
437  * Update dhttests.topology table with total connections information
438  *
439  * @param connections the number of connections
440  *
441  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
442  */
443 int
444 update_topology (unsigned int connections)
445 {
446   int ret;
447   if (outfile == NULL)
448     return GNUNET_SYSERR;
449
450   ret = fprintf(outfile, "update topology set connections = %u where topology_uid = @temp_topology;\n", connections);
451   topology_count++;
452   if (ret >= 0)
453     return GNUNET_OK;
454   else
455     return GNUNET_SYSERR;
456 }
457
458 /*
459  * Inserts the specified query into the dhttests.queries table
460  *
461  * @param sqlqueruid inserted query uid
462  * @param queryid dht query id
463  * @param type type of the query
464  * @param hops number of hops query traveled
465  * @param succeeded whether or not query was successful
466  * @param node the node the query hit
467  * @param key the key of the query
468  *
469  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
470  */
471 int
472 add_query (unsigned long long *sqlqueryuid, unsigned long long queryid,
473            unsigned int type, unsigned int hops, int succeeded,
474            const struct GNUNET_PeerIdentity * node, const GNUNET_HashCode * key)
475 {
476   int ret;
477
478   if ((outfile == NULL) || (node == NULL) || (key == NULL))
479     return GNUNET_SYSERR;
480
481   if (sqlqueryuid != NULL)
482     *sqlqueryuid = 0;
483
484   ret = fprintf(query_outfile, "TRIALUID\t%s\t", GNUNET_h2s_full(key));
485
486   if (ret < 0)
487     return GNUNET_SYSERR;
488
489   ret = fprintf(query_outfile, "%s\t%llu\t%u\t%u\t%u\n", GNUNET_h2s_full(&node->hashPubKey), queryid, type, hops, succeeded);
490
491   if (ret >= 0)
492     return GNUNET_OK;
493   else
494     return GNUNET_SYSERR;
495 }
496
497 /*
498  * Inserts the specified route information into the dhttests.routes table
499  *
500  * @param sqlqueruid inserted query uid
501  * @param queryid dht query id
502  * @param type type of the query
503  * @param hops number of hops query traveled
504  * @param succeeded whether or not query was successful
505  * @param node the node the query hit
506  * @param key the key of the query
507  * @param from_node the node that sent the message to node
508  * @param to_node next node to forward message to
509  *
510  * @return GNUNET_OK on success, GNUNET_SYSERR on failure.
511  */
512 int
513 add_route (unsigned long long *sqlqueryuid, unsigned long long queryid,
514            unsigned int type, unsigned int hops,
515            int succeeded, const struct GNUNET_PeerIdentity * node,
516            const GNUNET_HashCode * key, const struct GNUNET_PeerIdentity * from_node,
517            const struct GNUNET_PeerIdentity * to_node)
518 {
519   int ret;
520
521   if ((outfile == NULL) || (node == NULL) || (key == NULL))
522     return GNUNET_SYSERR;
523
524   if (sqlqueryuid != NULL)
525     *sqlqueryuid = 0;
526
527   ret = fprintf(route_outfile, "TRIALUID\t%s\t", GNUNET_h2s_full(key));
528   if (ret < 0)
529     return GNUNET_SYSERR;
530
531   ret = fprintf(route_outfile, "%s\t", GNUNET_h2s_full(&node->hashPubKey));
532   if (ret < 0)
533     return GNUNET_SYSERR;
534   if (from_node == NULL)
535     ret = fprintf(route_outfile, "0\t");
536   else
537     ret = fprintf(route_outfile, "%s\t", GNUNET_h2s_full(&from_node->hashPubKey));
538   if (ret < 0)
539     return GNUNET_SYSERR;
540
541   if (to_node == NULL)
542     ret = fprintf(route_outfile, "0\t%llu\t%u\t%u\t%d\n", queryid, type, hops, succeeded);
543   else
544     ret = fprintf(route_outfile, "%s\t%llu\t%u\t%u\t%d\n", GNUNET_h2s_full(&to_node->hashPubKey), queryid, type, hops, succeeded);
545
546   if (ret >= 0)
547     return GNUNET_OK;
548   else
549     return GNUNET_SYSERR;
550 }
551
552 /*
553  * Provides the dhtlog api
554  *
555  * @param c the configuration to use to connect to a server
556  *
557  * @return the handle to the server, or NULL on error
558  */
559 void *
560 libgnunet_plugin_dhtlog_mysql_dump_load_init (void * cls)
561 {
562   struct GNUNET_DHTLOG_Plugin *plugin = cls;
563   char *outfile_name;
564   char *outfile_path;
565   char *fn;
566   int dirwarn;
567
568   cfg = plugin->cfg;
569   max_varchar_len = 255;
570
571   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MySQL (DUMP) DHT Logger: initializing\n");
572
573   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (plugin->cfg,
574                                                          "MYSQLDUMP", "PATH",
575                                                          &outfile_path))
576     {
577       outfile_path = GNUNET_strdup("");
578     }
579
580   GNUNET_asprintf (&outfile_name,
581                    "%s%s-%d",
582                    outfile_path,
583                    "mysqldump",
584                    getpid());
585
586   fn = GNUNET_STRINGS_filename_expand (outfile_name);
587
588   if (fn == NULL)
589     {
590       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
591       GNUNET_free(outfile_path);
592       GNUNET_free(outfile_name);
593       return NULL;
594     }
595
596   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
597   outfile = FOPEN (fn, "w");
598
599   if (outfile == NULL)
600     {
601       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
602       if (dirwarn)
603         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
604                     _("Failed to create or access directory for log file `%s'\n"),
605                     fn);
606       GNUNET_free(outfile_path);
607       GNUNET_free(outfile_name);
608       GNUNET_free (fn);
609       return NULL;
610     }
611
612   GNUNET_asprintf (&outfile_name,
613                    "%s%s-%d",
614                    outfile_path,
615                    "mysqldump_nodes",
616                    getpid());
617
618   fn = GNUNET_STRINGS_filename_expand (outfile_name);
619
620   if (fn == NULL)
621     {
622       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
623       GNUNET_free(outfile_path);
624       GNUNET_free(outfile_name);
625       return NULL;
626     }
627
628   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
629   node_outfile = FOPEN (fn, "w");
630
631   if (node_outfile == NULL)
632     {
633       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
634       if (dirwarn)
635         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
636                     _("Failed to create or access directory for log file `%s'\n"),
637                     fn);
638       GNUNET_free(outfile_path);
639       GNUNET_free(outfile_name);
640       GNUNET_free (fn);
641       return NULL;
642     }
643
644   GNUNET_asprintf (&outfile_name,
645                    "%s%s-%d",
646                    outfile_path,
647                    "mysqldump_routes",
648                    getpid());
649
650   fn = GNUNET_STRINGS_filename_expand (outfile_name);
651
652   if (fn == NULL)
653     {
654       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
655       GNUNET_free(outfile_path);
656       GNUNET_free(outfile_name);
657       return NULL;
658     }
659
660   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
661   route_outfile = FOPEN (fn, "w");
662
663   if (route_outfile == NULL)
664     {
665       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
666       if (dirwarn)
667         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
668                     _("Failed to create or access directory for log file `%s'\n"),
669                     fn);
670       GNUNET_free(outfile_path);
671       GNUNET_free(outfile_name);
672       GNUNET_free (fn);
673       return NULL;
674     }
675
676   GNUNET_asprintf (&outfile_name,
677                    "%s%s-%d",
678                    outfile_path,
679                    "mysqldump_queries",
680                    getpid());
681
682   fn = GNUNET_STRINGS_filename_expand (outfile_name);
683
684   if (fn == NULL)
685     {
686       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
687       GNUNET_free(outfile_path);
688       GNUNET_free(outfile_name);
689       return NULL;
690     }
691
692   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
693   query_outfile = FOPEN (fn, "w");
694
695   if (query_outfile == NULL)
696     {
697       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
698       if (dirwarn)
699         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
700                     _("Failed to create or access directory for log file `%s'\n"),
701                     fn);
702       GNUNET_free(outfile_path);
703       GNUNET_free(outfile_name);
704       GNUNET_free (fn);
705       return NULL;
706     }
707
708   GNUNET_asprintf (&outfile_name,
709                    "%s%s-%d",
710                    outfile_path,
711                    "mysqldump_stats",
712                    getpid());
713
714   fn = GNUNET_STRINGS_filename_expand (outfile_name);
715
716   if (fn == NULL)
717     {
718       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
719       GNUNET_free(outfile_path);
720       GNUNET_free(outfile_name);
721       return NULL;
722     }
723
724   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
725   stat_outfile = FOPEN (fn, "w");
726
727   if (stat_outfile == NULL)
728     {
729       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
730       if (dirwarn)
731         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
732                     _("Failed to create or access directory for log file `%s'\n"),
733                     fn);
734       GNUNET_free(outfile_path);
735       GNUNET_free(outfile_name);
736       GNUNET_free (fn);
737       return NULL;
738     }
739
740   GNUNET_asprintf (&outfile_name,
741                    "%s%s-%d",
742                    outfile_path,
743                    "mysqldump_generic_stats",
744                    getpid());
745
746   fn = GNUNET_STRINGS_filename_expand (outfile_name);
747
748   if (fn == NULL)
749     {
750       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
751       GNUNET_free(outfile_path);
752       GNUNET_free(outfile_name);
753       return NULL;
754     }
755
756   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
757   generic_stat_outfile = FOPEN (fn, "w");
758
759   if (generic_stat_outfile == NULL)
760     {
761       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
762       if (dirwarn)
763         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
764                     _("Failed to create or access directory for log file `%s'\n"),
765                     fn);
766       GNUNET_free(outfile_path);
767       GNUNET_free(outfile_name);
768       GNUNET_free (fn);
769       return NULL;
770     }
771
772   GNUNET_asprintf (&outfile_name,
773                    "%s%s-%d",
774                    outfile_path,
775                    "mysqldump_dhtkey",
776                    getpid());
777
778   fn = GNUNET_STRINGS_filename_expand (outfile_name);
779
780   if (fn == NULL)
781     {
782       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
783       GNUNET_free(outfile_path);
784       GNUNET_free(outfile_name);
785       return NULL;
786     }
787
788   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
789   dhtkey_outfile = FOPEN (fn, "w");
790
791   if (dhtkey_outfile == NULL)
792     {
793       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
794       if (dirwarn)
795         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
796                     _("Failed to create or access directory for log file `%s'\n"),
797                     fn);
798       GNUNET_free(outfile_path);
799       GNUNET_free(outfile_name);
800       GNUNET_free (fn);
801       return NULL;
802     }
803
804   GNUNET_asprintf (&outfile_name,
805                    "%s%s-%d",
806                    outfile_path,
807                    "mysqldump_extended_topology",
808                    getpid());
809
810   fn = GNUNET_STRINGS_filename_expand (outfile_name);
811
812   if (fn == NULL)
813     {
814       GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to get full path for `%s'\n"), outfile_name);
815       GNUNET_free(outfile_path);
816       GNUNET_free(outfile_name);
817       return NULL;
818     }
819
820   dirwarn = (GNUNET_OK !=  GNUNET_DISK_directory_create_for_file (fn));
821   extended_topology_outfile = FOPEN (fn, "w");
822
823   if (extended_topology_outfile == NULL)
824     {
825       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", fn);
826       if (dirwarn)
827         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
828                     _("Failed to create or access directory for log file `%s'\n"),
829                     fn);
830       GNUNET_free(outfile_path);
831       GNUNET_free(outfile_name);
832       GNUNET_free (fn);
833       return NULL;
834     }
835
836   GNUNET_free (outfile_path);
837   GNUNET_free (outfile_name);
838   GNUNET_free (fn);
839
840   GNUNET_assert(plugin->dhtlog_api == NULL);
841   plugin->dhtlog_api = GNUNET_malloc(sizeof(struct GNUNET_DHTLOG_Handle));
842   plugin->dhtlog_api->insert_trial = &add_trial;
843   plugin->dhtlog_api->insert_stat = &add_stat;
844   plugin->dhtlog_api->insert_query = &add_query;
845   plugin->dhtlog_api->update_trial = &update_trials;
846   plugin->dhtlog_api->insert_route = &add_route;
847   plugin->dhtlog_api->insert_node = &add_node;
848   plugin->dhtlog_api->insert_dhtkey = &add_dhtkey;
849   plugin->dhtlog_api->update_connections = &add_connections;
850   plugin->dhtlog_api->insert_topology = &add_topology;
851   plugin->dhtlog_api->insert_extended_topology = &add_extended_topology;
852   plugin->dhtlog_api->update_topology = &update_topology;
853   plugin->dhtlog_api->set_malicious = &set_malicious;
854   plugin->dhtlog_api->add_generic_stat = &add_generic_stat;
855
856   return plugin;
857 }
858
859 /**
860  * Shutdown the plugin.
861  */
862 void *
863 libgnunet_plugin_dhtlog_mysql_dump_load_done (void * cls)
864 {
865   struct GNUNET_DHTLOG_Handle *dhtlog_api = cls;
866   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
867               "MySQL DHT Logger: database shutdown\n");
868   GNUNET_assert(dhtlog_api != NULL);
869
870   fclose(outfile);
871   fclose(node_outfile);
872   fclose(query_outfile);
873   fclose(route_outfile);
874   fclose(stat_outfile);
875   fclose(generic_stat_outfile);
876   fclose(extended_topology_outfile);
877   GNUNET_free(dhtlog_api);
878   return NULL;
879 }
880
881 /* end of plugin_dhtlog_mysql_dump_load.c */