aboutsummaryrefslogtreecommitdiff
path: root/src/services/gnunet-service-dht-dbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/services/gnunet-service-dht-dbus.c')
-rw-r--r--src/services/gnunet-service-dht-dbus.c612
1 files changed, 612 insertions, 0 deletions
diff --git a/src/services/gnunet-service-dht-dbus.c b/src/services/gnunet-service-dht-dbus.c
new file mode 100644
index 0000000..4b47be7
--- /dev/null
+++ b/src/services/gnunet-service-dht-dbus.c
@@ -0,0 +1,612 @@
1#include "config.h"
2
3#include <gnunet/platform.h>
4#include <gnunet/gnunet_common.h>
5#include <gnunet/gnunet_configuration_lib.h>
6#include <gnunet/gnunet_getopt_lib.h>
7#include <gnunet/gnunet_strings_lib.h>
8#include <gnunet/gnunet_program_lib.h>
9#include <gnunet/gnunet_dht_service.h>
10
11#include "gnunet_dbus_lib.h"
12#include "gnunet_dht_dbus_lib.h"
13#include "gnunet_block_dbus_lib.h"
14#include "gnunet_time_dbus_lib.h"
15
16#define LOG(kind, ...) GNUNET_log_from (kind, "dht-dbus", __VA_ARGS__)
17
18struct GetRequest
19{
20 struct GNUNET_DBUS_Client *client;
21 struct GNUNET_DHT_GetHandle *handle;
22 bool pretty;
23};
24
25struct ClientData
26{
27 struct GNUNET_DBUS_ObjectIterator *gets_front;
28 struct GNUNET_DBUS_ObjectIterator *gets_back;
29 struct GNUNET_DHT_Handle *dht_handle;
30};
31
32static struct GNUNET_DBUS_Service *gbl_dht_service;
33static struct GNUNET_DBUS_Interface *gbl_dht_interface;
34static struct GNUNET_DBUS_Method *gbl_dht_put_method;
35static struct GNUNET_DBUS_Method *gbl_dht_get_start_method;
36static struct GNUNET_DBUS_Object *gbl_dht_get_object;
37static struct GNUNET_DBUS_Interface *gbl_dht_get_request_interface;
38static struct GNUNET_DBUS_Method
39 *gbl_dht_get_request_filter_known_results_method;
40static struct GNUNET_DBUS_Method *gbl_dht_get_request_stop_method;
41static struct GNUNET_DBUS_Signal *gbl_dht_get_request_result_signal;
42
43static void
44put_return (
45 void *cls,
46 int success)
47{
48 struct GNUNET_DBUS_MethodContext *mc =
49 (struct GNUNET_DBUS_MethodContext *)cls;
50 unsigned msg_serial = dbus_message_get_serial (mc->message);
51 LOG (GNUNET_ERROR_TYPE_DEBUG,
52 "Received reply from DHT. Method call id %u\n",
53 msg_serial);
54 DBusMessage *reply;
55 switch (success)
56 {
57 case GNUNET_OK:
58 reply = GNUNET_DBUS_method_context_create_reply (mc);
59 break;
60 case GNUNET_NO:
61 reply = dbus_message_new_error (
62 mc->message,
63 DBUS_ERROR_FAILED,
64 "DHT service timed out.");
65 break;
66 case GNUNET_SYSERR:
67 reply = dbus_message_new_error (
68 mc->message,
69 DBUS_ERROR_FAILED,
70 "DHT DBus proxy was disconnected from DHT service.");
71 break;
72 default:
73 reply = dbus_message_new_error_printf (
74 mc->message,
75 DBUS_ERROR_FAILED,
76 "Unabled to interpret response from DHT service."
77 "Service returned code %d.",
78 success);
79 };
80
81 GNUNET_DBUS_method_context_send_reply (mc, reply);
82 GNUNET_DBUS_method_context_unref (mc);
83 LOG (GNUNET_ERROR_TYPE_DEBUG,
84 "Received reply from DHT. Method call id %u\n",
85 msg_serial);
86};
87
88static void
89put (
90 struct GNUNET_DBUS_MethodContext *mc)
91{
92 struct GNUNET_HashCode key;
93 uint32_t desired_replication_level;
94 enum GNUNET_DHT_RouteOption options;
95 enum GNUNET_BLOCK_Type type;
96 int size;
97 const void *data;
98 struct GNUNET_TIME_Absolute expiry;
99
100 unsigned msg_serial = dbus_message_get_serial (mc->message);
101 LOG (GNUNET_ERROR_TYPE_DEBUG,
102 "Recieved put from dbus. Method call id %u\n",
103 msg_serial);
104
105 DBusMessage *message = mc->message;
106 DBusMessageIter iter;
107 dbus_message_iter_init (message, &iter);
108
109 DBusMessage *reply = NULL;
110 reply = reply ? reply : GNUNET_DBUS_pop_hashcode (
111 message, &iter,
112 "key",
113 &key);
114 reply = reply ? reply : GNUNET_DBUS_pop_uint32 (
115 message, &iter,
116 "desired_replication_level",
117 &desired_replication_level);
118 reply = reply ? reply : GNUNET_DHT_DBUS_pop_route_option (
119 message, &iter,
120 "options",
121 &options);
122 reply = reply ? reply : GNUNET_BLOCK_DBUS_pop_type (
123 message, &iter,
124 "type",
125 &type);
126 reply = reply ? reply : GNUNET_DBUS_pop_byte_array (
127 message, &iter,
128 "data",
129 (const unsigned char **)&data, &size);
130 reply = reply ? reply : GNUNET_TIME_DBUS_pop_absolute (
131 message, &iter,
132 "expiry",
133 &expiry);
134 if (reply)
135 {
136 GNUNET_DBUS_method_context_send_reply (mc, reply);
137 return;
138 };
139
140 GNUNET_DBUS_method_context_ref (mc);
141 struct ClientData *cd = GNUNET_DBUS_client_get_data (mc->client);
142 struct GNUNET_DHT_Handle *handle = cd->dht_handle;
143
144 GNUNET_DHT_put (
145 handle,
146 &key,
147 desired_replication_level,
148 options,
149 type,
150 size,
151 data,
152 expiry,
153 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100),
154 put_return,
155 mc);
156
157 LOG (
158 GNUNET_ERROR_TYPE_DEBUG,
159 "Forwarded put to dht. Method call id %u\n",
160 msg_serial);
161};
162
163static void
164get_filter_known_results (
165 struct GNUNET_DBUS_MethodContext *mc)
166{
167 struct GNUNET_HashCode *results;
168 size_t results_len;
169
170 DBusMessage *message = mc->message;
171 DBusMessageIter iter;
172 DBusMessageIter iter_sub;
173 dbus_message_iter_init (message, &iter);
174
175 DBusMessage *reply = NULL;
176 reply = GNUNET_DBUS_pop_enter_array (message, &iter, &iter_sub,
177 "results",
178 &results_len);
179 if (reply)
180 {
181 GNUNET_DBUS_method_context_send_reply (mc, reply);
182 return ;
183 };
184
185 results = GNUNET_malloc (sizeof (struct GNUNET_HashCode) * results_len);
186 size_t i;
187 for (i = 0; i < results_len && ! results ; i++)
188 reply = GNUNET_DBUS_pop_hashcode (message, &iter_sub,
189 "result",
190 results + i);
191 if(reply)
192 {
193 GNUNET_free (results);
194 GNUNET_DBUS_method_context_send_reply (mc, reply);
195 return;
196 };
197
198 struct GetRequest *get_request = GNUNET_DBUS_object_get_data (mc->object);
199 struct GNUNET_DHT_GetHandle *handle = get_request->handle;
200
201 GNUNET_DHT_get_filter_known_results (handle, (unsigned)results_len, results);
202 GNUNET_free (results);
203
204 reply = GNUNET_DBUS_method_context_create_reply (mc);
205 GNUNET_DBUS_method_context_send_reply (mc, reply);
206}
207
208static void
209get_stop (
210 struct GNUNET_DBUS_MethodContext *mc)
211{
212 struct GNUNET_DBUS_Object *object = mc->object;
213 struct GetRequest *get_request = GNUNET_DBUS_object_get_data (object);
214 struct GNUNET_DHT_GetHandle *handle = get_request->handle;
215
216 GNUNET_DHT_get_stop (handle);
217
218 struct GNUNET_DBUS_ObjectIterator *obj_it =
219 GNUNET_DBUS_object_iterate_subobjects (gbl_dht_get_object);
220 while (obj_it)
221 {
222 if (obj_it->object == object)
223 {
224 GNUNET_DBUS_object_remove_subobject (gbl_dht_get_object, obj_it);
225 break;
226 }
227 obj_it = obj_it->next;
228 };
229 if (obj_it)
230 {
231 GNUNET_DBUS_client_unref (get_request->client);
232 GNUNET_free (get_request);
233 }
234 else
235 {
236 LOG (GNUNET_ERROR_TYPE_WARNING,
237 "Tried to stop request that does not exist\n");
238 LOG (GNUNET_ERROR_TYPE_WARNING,
239 " name == %s\n",
240 GNUNET_DBUS_object_get_name (object));
241 }
242
243 DBusMessage *reply = GNUNET_DBUS_method_context_create_reply (mc);
244 GNUNET_DBUS_method_context_send_reply (mc, reply);
245}
246
247static void
248get_iter_return (
249 void *cls,
250 struct GNUNET_TIME_Absolute expiry,
251 const struct GNUNET_HashCode *key,
252 const struct GNUNET_PeerIdentity *get_path,
253 unsigned get_path_len,
254 const struct GNUNET_PeerIdentity *put_path,
255 unsigned put_path_len,
256 enum GNUNET_BLOCK_Type type,
257 size_t size,
258 const void *data)
259{
260 unsigned i;
261 struct GNUNET_DBUS_Object *request_object = (struct GNUNET_DBUS_Object *)cls;
262 struct GetRequest *get_request =
263 (struct GetRequest *)GNUNET_DBUS_object_get_data (request_object);
264 struct GNUNET_DBUS_Client *client = get_request->client;
265 struct GNUNET_DBUS_ObjectPath *path = GNUNET_DBUS_object_path_create (
266 gbl_dht_service,
267 gbl_dht_get_object,
268 request_object,
269 NULL);
270
271 DBusMessage *message = GNUNET_DBUS_signal_spawn_unicast (
272 gbl_dht_get_request_result_signal,
273 path,
274 gbl_dht_get_request_interface,
275 client,
276 get_request->pretty);
277
278 GNUNET_DBUS_object_path_unref (path);
279
280 DBusMessageIter message_iter;
281 DBusMessageIter message_iter_sub;
282 dbus_message_iter_init_append (message, &message_iter);
283
284 GNUNET_TIME_DBUS_push_absolute (message, &message_iter, &expiry);
285 GNUNET_DBUS_push_hashcode (message, &message_iter, key);
286 GNUNET_DBUS_push_open_array (message, &message_iter, &message_iter_sub,
287 GNUNET_DBUS_SIGNATURE_PEER_IDENTITY);
288 for (i = 0; i < get_path_len; i++)
289 {
290 GNUNET_DBUS_push_peer_identity (message, &message_iter_sub, get_path + i);
291 }
292 GNUNET_DBUS_push_close_array (message, &message_iter, &message_iter_sub);
293 GNUNET_DBUS_push_open_array (message, &message_iter, &message_iter_sub,
294 GNUNET_DBUS_SIGNATURE_PEER_IDENTITY);
295 for (i = 0; i < put_path_len; i++)
296 {
297 GNUNET_DBUS_push_peer_identity (message, &message_iter_sub, put_path + i);
298 }
299 GNUNET_DBUS_push_close_array (message, &message_iter, &message_iter_sub);
300 GNUNET_BLOCK_DBUS_push_type (message, &message_iter, &type);
301 GNUNET_DBUS_push_byte_array (message, &message_iter, data, size);
302
303 GNUNET_DBUS_service_send (gbl_dht_service, message);
304}
305
306static void
307get_start (
308 struct GNUNET_DBUS_MethodContext *mc)
309{
310 enum GNUNET_BLOCK_Type type;
311 struct GNUNET_HashCode key;
312 uint32_t desired_replication_level;
313 enum GNUNET_DHT_RouteOption options;
314
315 unsigned msg_serial = dbus_message_get_serial (mc->message);
316 LOG (GNUNET_ERROR_TYPE_DEBUG, "Recieved get_start from dbus. Method call id %u\n", msg_serial);
317
318 DBusMessage *message = mc->message;
319 DBusMessageIter iter;
320 dbus_message_iter_init (message, &iter);
321
322 DBusMessage *reply = NULL;
323 reply = reply ? reply : GNUNET_BLOCK_DBUS_pop_type (
324 message, &iter,
325 "type",
326 &type);
327 reply = reply ? reply : GNUNET_DBUS_pop_hashcode (
328 message, &iter,
329 "key",
330 &key);
331 reply = reply ? reply : GNUNET_DBUS_pop_uint32 (
332 message, &iter,
333 "desired_replication_level",
334 &desired_replication_level);
335 reply = reply ? reply : GNUNET_DHT_DBUS_pop_route_option (
336 message, &iter,
337 "options",
338 &options);
339 if (reply)
340 {
341 GNUNET_DBUS_method_context_send_reply (mc, reply);
342 return;
343 };
344 //if (GNUNET_DBUS_message_get_pretty_encoded (message))
345 //GNUNET_DBUS_client_set_prefers_pretty_encodings (mc->client, true);
346
347 GNUNET_DBUS_method_context_ref (mc);
348 struct ClientData *cd = GNUNET_DBUS_client_get_data (mc->client);
349 struct GNUNET_DHT_Handle *handle = cd->dht_handle;
350
351 struct GetRequest *get_request = GNUNET_new (struct GetRequest);
352 get_request->client = mc->client;
353 GNUNET_DBUS_client_ref (mc->client);
354 get_request->pretty = GNUNET_DBUS_message_get_pretty (message);
355
356 struct GNUNET_DBUS_Object *request_object =
357 GNUNET_DBUS_object_create_uniquely_named_subobject (gbl_dht_get_object,
358 get_request);
359 GNUNET_DBUS_object_add_interface (request_object,
360 GNUNET_DBUS_interface_introspectable ());
361 GNUNET_DBUS_object_add_interface (request_object,
362 gbl_dht_get_request_interface);
363
364 struct GNUNET_DBUS_ObjectPath *path =
365 GNUNET_DBUS_object_path_create (gbl_dht_service,
366 gbl_dht_get_object,
367 request_object,
368 NULL);
369
370 reply = GNUNET_DBUS_method_context_create_reply (mc);
371 DBusMessageIter reply_iter;
372 dbus_message_iter_init_append (reply, &reply_iter);
373 GNUNET_DBUS_push_object_path (reply, &reply_iter, path);
374 GNUNET_DBUS_method_context_send_reply (mc, reply);
375
376 struct GNUNET_DBUS_ObjectIterator *obj_it =
377 GNUNET_new (struct GNUNET_DBUS_ObjectIterator);
378 obj_it->object = request_object;
379 GNUNET_CONTAINER_DLL_insert (cd->gets_front,
380 cd->gets_back,
381 obj_it);
382
383 get_request->handle = GNUNET_DHT_get_start (
384 handle,
385 type,
386 &key,
387 desired_replication_level,
388 options,
389 NULL,
390 0,
391 get_iter_return,
392 request_object);
393};
394
395static void
396client_connects (
397 struct GNUNET_DBUS_Service *service,
398 struct GNUNET_DBUS_Client *client)
399{
400 LOG (GNUNET_ERROR_TYPE_DEBUG,
401 "Creating dht client for %s\n",
402 GNUNET_DBUS_client_get_unique_name (client));
403 const struct GNUNET_CONFIGURATION_Handle *cfg =
404 GNUNET_DBUS_service_get_config (service);
405 struct ClientData *cd = GNUNET_new (struct ClientData);
406 cd->dht_handle = GNUNET_DHT_connect (cfg, 32);
407 cd->gets_front = NULL;
408 cd->gets_back = NULL;
409 GNUNET_DBUS_client_set_data (client, cd);
410 LOG (GNUNET_ERROR_TYPE_DEBUG,
411 "Finished creating DHT client for %s\n",
412 GNUNET_DBUS_client_get_unique_name (client));
413};
414
415static void
416client_disconnects (
417 struct GNUNET_DBUS_Service *service,
418 struct GNUNET_DBUS_Client *client)
419{
420 struct ClientData *cd = GNUNET_DBUS_client_get_data (client);
421 struct GNUNET_DBUS_ObjectIterator *obj_it = cd->gets_front;
422 while (obj_it)
423 {
424 struct GNUNET_DBUS_ObjectIterator *next = obj_it->next;
425 struct GNUNET_DBUS_Object *object = obj_it->object;
426 struct GetRequest *request = GNUNET_DBUS_object_get_data (object);
427
428 GNUNET_DHT_get_stop (request->handle);
429 GNUNET_free (request);
430 GNUNET_DBUS_object_remove_subobject (gbl_dht_get_object, obj_it);
431 GNUNET_free (obj_it);
432 obj_it = next;
433 };
434 GNUNET_DHT_disconnect (cd->dht_handle);
435 GNUNET_free (cd);
436};
437
438static void
439shutdown_task (
440 void *cls,
441 const struct GNUNET_SCHEDULER_TaskContext *tc)
442{
443 (void)cls;
444 (void)tc;
445
446 GNUNET_DBUS_service_unref (gbl_dht_service);
447
448 LOG (GNUNET_ERROR_TYPE_INFO, "Exiting.\n");
449};
450
451static void
452run (
453 void *cls,
454 char *const *args,
455 const char *configfile,
456 const struct GNUNET_CONFIGURATION_Handle *cfg)
457{
458 LOG (GNUNET_ERROR_TYPE_DEBUG, "Running.\n");
459
460 gbl_dht_service = GNUNET_DBUS_service_create (cfg, "dht");
461 if (! gbl_dht_service)
462 {
463 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create dht service.\n");
464 GNUNET_abort_ ();
465 };
466 GNUNET_DBUS_service_set_client_handlers (gbl_dht_service,
467 client_connects,
468 client_disconnects);
469
470 struct GNUNET_DBUS_Object *root_object =
471 GNUNET_DBUS_service_get_root_object (gbl_dht_service);
472
473 gbl_dht_interface = GNUNET_DBUS_interface_create ("gnu.gnunet.dht");
474 GNUNET_DBUS_object_add_interface (root_object,
475 GNUNET_DBUS_interface_introspectable ());
476 GNUNET_DBUS_object_add_interface (root_object,
477 gbl_dht_interface);
478
479 gbl_dht_put_method = GNUNET_DBUS_method_create ("put", put);
480 GNUNET_DBUS_interface_add_method (gbl_dht_interface, gbl_dht_put_method);
481 GNUNET_DBUS_method_add_arg (gbl_dht_put_method,
482 "key",
483 GNUNET_DBUS_SIGNATURE_HASHCODE);
484 GNUNET_DBUS_method_add_arg (gbl_dht_put_method,
485 "desired_replication_level",
486 GNUNET_DBUS_SIGNATURE_UINT32);
487 GNUNET_DBUS_method_add_arg (gbl_dht_put_method,
488 "options",
489 GNUNET_DHT_DBUS_SIGNATURE_ROUTE_OPTION);
490 GNUNET_DBUS_method_add_arg (gbl_dht_put_method,
491 "type",
492 GNUNET_BLOCK_DBUS_SIGNATURE_TYPE);
493 GNUNET_DBUS_method_add_arg (gbl_dht_put_method,
494 "data",
495 GNUNET_DBUS_SIGNATURE_ARRAY (
496 GNUNET_DBUS_SIGNATURE_BYTE));
497 GNUNET_DBUS_method_add_arg (gbl_dht_put_method,
498 "expiry",
499 GNUNET_TIME_DBUS_SIGNATURE_ABSOLUTE);
500
501 gbl_dht_get_start_method = GNUNET_DBUS_method_create ("get_start",
502 get_start);
503 GNUNET_DBUS_interface_add_method (gbl_dht_interface,
504 gbl_dht_get_start_method);
505 GNUNET_DBUS_method_add_arg (gbl_dht_get_start_method,
506 "type",
507 GNUNET_BLOCK_DBUS_SIGNATURE_TYPE);
508 GNUNET_DBUS_method_add_arg (gbl_dht_get_start_method,
509 "key",
510 GNUNET_DBUS_SIGNATURE_HASHCODE);
511 GNUNET_DBUS_method_add_arg (gbl_dht_get_start_method,
512 "desired_replication_level",
513 GNUNET_DBUS_SIGNATURE_UINT32);
514 GNUNET_DBUS_method_add_arg (gbl_dht_get_start_method,
515 "options",
516 GNUNET_DHT_DBUS_SIGNATURE_ROUTE_OPTION);
517 GNUNET_DBUS_method_add_return_arg (gbl_dht_get_start_method,
518 "request_object",
519 GNUNET_DBUS_SIGNATURE_OBJECT_PATH);
520
521 gbl_dht_get_object = GNUNET_DBUS_object_create ("get", NULL);
522 GNUNET_DBUS_object_add_subobject (root_object, gbl_dht_get_object);
523 GNUNET_DBUS_object_add_interface (gbl_dht_get_object,
524 GNUNET_DBUS_interface_introspectable ());
525
526 gbl_dht_get_request_interface =
527 GNUNET_DBUS_interface_create ("gnu.gnunet.dht.get");
528
529 gbl_dht_get_request_filter_known_results_method =
530 GNUNET_DBUS_method_create ("filter_known_results",
531 get_filter_known_results);
532 GNUNET_DBUS_interface_add_method (
533 gbl_dht_get_request_interface,
534 gbl_dht_get_request_filter_known_results_method);
535 GNUNET_DBUS_method_add_arg (gbl_dht_get_request_filter_known_results_method,
536 "results",
537 GNUNET_DBUS_SIGNATURE_ARRAY (
538 GNUNET_DBUS_SIGNATURE_HASHCODE));
539
540 gbl_dht_get_request_stop_method = GNUNET_DBUS_method_create ("stop",
541 get_stop);
542 GNUNET_DBUS_interface_add_method (gbl_dht_get_request_interface,
543 gbl_dht_get_request_stop_method);
544
545 gbl_dht_get_request_result_signal = GNUNET_DBUS_signal_create ("result");
546 GNUNET_DBUS_interface_add_signal (gbl_dht_get_request_interface,
547 gbl_dht_get_request_result_signal);
548 GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal,
549 "expiry",
550 GNUNET_TIME_DBUS_SIGNATURE_ABSOLUTE);
551 GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal,
552 "key",
553 GNUNET_DBUS_SIGNATURE_HASHCODE);
554 GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal,
555 "get_path",
556 GNUNET_DBUS_SIGNATURE_ARRAY (
557 GNUNET_DBUS_SIGNATURE_PEER_IDENTITY));
558 GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal,
559 "put_path",
560 GNUNET_DBUS_SIGNATURE_ARRAY (
561 GNUNET_DBUS_SIGNATURE_PEER_IDENTITY));
562 GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal,
563 "type",
564 GNUNET_BLOCK_DBUS_SIGNATURE_TYPE);
565 GNUNET_DBUS_signal_add_arg (gbl_dht_get_request_result_signal,
566 "data",
567 GNUNET_DBUS_SIGNATURE_ARRAY (
568 GNUNET_DBUS_SIGNATURE_BYTE));
569
570 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
571 shutdown_task, NULL);
572};
573
574int
575main (
576 int argc,
577 char *const *argv)
578{
579 int ret;
580
581 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
582 GNUNET_GETOPT_OPTION_END
583 };
584 static const char bin_name[] = "gnunet-service-dht-dbus [OPTIONS]";
585 static const char bin_help[] = gettext_noop ("DBus proxy for gnunet-service-dht");
586
587 ret = GNUNET_log_setup ("gnunet-service-dht-dbus", "DEBUG", NULL);
588 if (GNUNET_OK != ret)
589 {
590 fprintf (stderr, "ERROR: Failed to setup logging. GNUNET_log_setup returned %d\n", ret);
591 return 1;
592 }
593
594 ret = GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv);
595 if (GNUNET_OK != ret)
596 {
597 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to parse command line options. GNUNET_STRINGS_get_utf8_args returned %d\n", ret);
598 return 1;
599 };
600
601 ret = GNUNET_PROGRAM_run (argc, argv, bin_name, bin_help, options, run, NULL);
602 if (GNUNET_OK != ret)
603 {
604 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to run program. GNUNET_PROGRAM_run returned %d\n", ret);
605 return 1;
606 };
607
608 GNUNET_free ((void *)argv);
609 return 0;
610};
611
612