diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-03-05 19:56:16 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-03-05 19:56:16 +0000 |
commit | b1780f05127f1c84c442f12fe84ae8e712032164 (patch) | |
tree | 58ecfc3fc8b92b3b5705b885260fcf456d6fe7d5 /src/peerinfo-tool | |
parent | dffa6f386418b19956f23f13f3f2a32cd803bca4 (diff) | |
download | gnunet-b1780f05127f1c84c442f12fe84ae8e712032164.tar.gz gnunet-b1780f05127f1c84c442f12fe84ae8e712032164.zip |
-LRN: experimental HELLO URIs
Diffstat (limited to 'src/peerinfo-tool')
-rw-r--r-- | src/peerinfo-tool/Makefile.am | 5 | ||||
-rw-r--r-- | src/peerinfo-tool/gnunet-peerinfo.c | 386 |
2 files changed, 389 insertions, 2 deletions
diff --git a/src/peerinfo-tool/Makefile.am b/src/peerinfo-tool/Makefile.am index 8c5fd8fbb..7270bfb51 100644 --- a/src/peerinfo-tool/Makefile.am +++ b/src/peerinfo-tool/Makefile.am | |||
@@ -13,11 +13,14 @@ bin_PROGRAMS = \ | |||
13 | gnunet-peerinfo | 13 | gnunet-peerinfo |
14 | 14 | ||
15 | gnunet_peerinfo_SOURCES = \ | 15 | gnunet_peerinfo_SOURCES = \ |
16 | gnunet-peerinfo.c | 16 | gnunet-peerinfo.c \ |
17 | ../transport/gnunet-service-transport_plugins.c | ||
18 | |||
17 | gnunet_peerinfo_LDADD = \ | 19 | gnunet_peerinfo_LDADD = \ |
18 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | 20 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ |
19 | $(top_builddir)/src/transport/libgnunettransport.la \ | 21 | $(top_builddir)/src/transport/libgnunettransport.la \ |
20 | $(top_builddir)/src/hello/libgnunethello.la \ | 22 | $(top_builddir)/src/hello/libgnunethello.la \ |
23 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
21 | $(top_builddir)/src/util/libgnunetutil.la | 24 | $(top_builddir)/src/util/libgnunetutil.la |
22 | 25 | ||
23 | if HAVE_PYTHON_PEXPECT | 26 | if HAVE_PYTHON_PEXPECT |
diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c index 21c996661..1e93a5ee8 100644 --- a/src/peerinfo-tool/gnunet-peerinfo.c +++ b/src/peerinfo-tool/gnunet-peerinfo.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include "gnunet_peerinfo_service.h" | 30 | #include "gnunet_peerinfo_service.h" |
31 | #include "gnunet_transport_service.h" | 31 | #include "gnunet_transport_service.h" |
32 | #include "gnunet_program_lib.h" | 32 | #include "gnunet_program_lib.h" |
33 | #include "gnunet_transport_plugin.h" | ||
34 | #include "../transport/gnunet-service-transport_plugins.h" | ||
33 | 35 | ||
34 | static int no_resolve; | 36 | static int no_resolve; |
35 | 37 | ||
@@ -37,8 +39,29 @@ static int be_quiet; | |||
37 | 39 | ||
38 | static int get_self; | 40 | static int get_self; |
39 | 41 | ||
42 | static int get_uri; | ||
43 | |||
44 | static char *put_uri; | ||
45 | |||
40 | static struct GNUNET_PEERINFO_Handle *peerinfo; | 46 | static struct GNUNET_PEERINFO_Handle *peerinfo; |
41 | 47 | ||
48 | /** | ||
49 | * Configuration handle. | ||
50 | */ | ||
51 | const struct GNUNET_CONFIGURATION_Handle *GST_cfg; | ||
52 | |||
53 | /** | ||
54 | * Statistics handle. | ||
55 | */ | ||
56 | struct GNUNET_STATISTICS_Handle *GST_stats; | ||
57 | |||
58 | /** | ||
59 | * Configuration handle. | ||
60 | */ | ||
61 | struct GNUNET_PeerIdentity GST_my_identity; | ||
62 | |||
63 | struct GNUNET_MessageHeader *our_hello = NULL; | ||
64 | |||
42 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 65 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
43 | 66 | ||
44 | struct PrintContext | 67 | struct PrintContext |
@@ -47,8 +70,20 @@ struct PrintContext | |||
47 | char **address_list; | 70 | char **address_list; |
48 | unsigned int num_addresses; | 71 | unsigned int num_addresses; |
49 | uint32_t off; | 72 | uint32_t off; |
73 | char *uri; | ||
74 | size_t uri_len; | ||
50 | }; | 75 | }; |
51 | 76 | ||
77 | /** | ||
78 | * Obtain this peers HELLO message. | ||
79 | * | ||
80 | * @return our HELLO message | ||
81 | */ | ||
82 | const struct GNUNET_MessageHeader * | ||
83 | GST_hello_get () | ||
84 | { | ||
85 | return (struct GNUNET_MessageHeader *) our_hello; | ||
86 | } | ||
52 | 87 | ||
53 | static void | 88 | static void |
54 | dump_pc (struct PrintContext *pc) | 89 | dump_pc (struct PrintContext *pc) |
@@ -150,6 +185,8 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
150 | if (err_msg != NULL) | 185 | if (err_msg != NULL) |
151 | FPRINTF (stderr, "%s", _("Error in communication with PEERINFO service\n")); | 186 | FPRINTF (stderr, "%s", _("Error in communication with PEERINFO service\n")); |
152 | GNUNET_PEERINFO_disconnect (peerinfo); | 187 | GNUNET_PEERINFO_disconnect (peerinfo); |
188 | GST_plugins_unload (); | ||
189 | GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO); | ||
153 | return; | 190 | return; |
154 | } | 191 | } |
155 | if ((be_quiet) || (NULL == hello)) | 192 | if ((be_quiet) || (NULL == hello)) |
@@ -169,6 +206,310 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
169 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &print_address, pc); | 206 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &print_address, pc); |
170 | } | 207 | } |
171 | 208 | ||
209 | static int | ||
210 | compose_uri (void *cls, const struct GNUNET_HELLO_Address *address, | ||
211 | struct GNUNET_TIME_Absolute expiration) | ||
212 | { | ||
213 | struct PrintContext *pc = cls; | ||
214 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | ||
215 | static const char *addr; | ||
216 | |||
217 | papi = GST_plugins_find (address->transport_name); | ||
218 | if (papi == NULL) | ||
219 | { | ||
220 | /* Not an error - we might just not have the right plugin. */ | ||
221 | return GNUNET_OK; | ||
222 | } | ||
223 | |||
224 | addr = papi->address_to_string (papi->cls, address->address, address->address_length); | ||
225 | if (addr != NULL) | ||
226 | { | ||
227 | ssize_t l = strlen (addr); | ||
228 | if (l > 0) | ||
229 | { | ||
230 | struct tm *t; | ||
231 | time_t seconds; | ||
232 | int s; | ||
233 | seconds = expiration.abs_value / 1000; | ||
234 | t = gmtime(&seconds); | ||
235 | pc->uri = GNUNET_realloc (pc->uri, pc->uri_len + 1 + 14 + 1 + strlen (address->transport_name) + 1 + l + 1 /* 0 */); | ||
236 | s = sprintf (&pc->uri[pc->uri_len], "!%04u%02u%02u%02u%02u%02u!%s!%s", | ||
237 | t->tm_year, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, | ||
238 | address->transport_name, addr); | ||
239 | if (s > 0) | ||
240 | pc->uri_len += s; | ||
241 | } | ||
242 | } | ||
243 | return GNUNET_OK; | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * Print information about the peer. | ||
248 | */ | ||
249 | static void | ||
250 | print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
251 | const struct GNUNET_HELLO_Message *hello, const char *err_msg) | ||
252 | { | ||
253 | struct GNUNET_CRYPTO_HashAsciiEncoded enc; | ||
254 | struct PrintContext *pc = cls; | ||
255 | char *pkey; | ||
256 | |||
257 | if (peer == NULL) | ||
258 | { | ||
259 | if (err_msg != NULL) | ||
260 | FPRINTF (stderr, "%s", _("Error in communication with PEERINFO service\n")); | ||
261 | GNUNET_PEERINFO_disconnect (peerinfo); | ||
262 | GST_plugins_unload (); | ||
263 | GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO); | ||
264 | return; | ||
265 | } | ||
266 | if ((be_quiet) || (NULL == hello)) | ||
267 | { | ||
268 | GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc); | ||
269 | printf ("%s\n", (const char *) &enc); | ||
270 | if (be_quiet && get_uri != GNUNET_YES) | ||
271 | return; | ||
272 | } | ||
273 | pc->peer = *peer; | ||
274 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_address, pc); | ||
275 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &compose_uri, pc); | ||
276 | printf ("%s\n", pc->uri); | ||
277 | GNUNET_free (pc->uri); | ||
278 | GNUNET_free (pc); | ||
279 | } | ||
280 | |||
281 | struct GNUNET_PEERINFO_HelloAddressParsingContext | ||
282 | { | ||
283 | char *tmp; | ||
284 | char *pos; | ||
285 | size_t tmp_len; | ||
286 | }; | ||
287 | |||
288 | static size_t | ||
289 | add_addr_to_hello (void *cls, size_t max, void *buffer) | ||
290 | { | ||
291 | struct tm expiration_time; | ||
292 | char buf[5]; | ||
293 | long l; | ||
294 | time_t expiration_seconds; | ||
295 | struct GNUNET_TIME_Absolute expire; | ||
296 | |||
297 | struct GNUNET_PEERINFO_HelloAddressParsingContext *ctx = cls; | ||
298 | char *exp1, *exp2; | ||
299 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | ||
300 | void *addr; | ||
301 | size_t addr_len; | ||
302 | |||
303 | /* End of string */ | ||
304 | if (ctx->pos - ctx->tmp == ctx->tmp_len) | ||
305 | return 0; | ||
306 | |||
307 | /* Parsed past the end of string, OR wrong format */ | ||
308 | if ((ctx->pos - ctx->tmp > ctx->tmp_len) || ctx->pos[0] != '!') | ||
309 | { | ||
310 | GNUNET_break (0); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | /* Not enough bytes (3 for three '!', 14 for expiration date, and | ||
315 | * at least 1 for type and 1 for address (1-byte long address is a joke, | ||
316 | * but it is not completely unrealistic. Zero-length address is. | ||
317 | */ | ||
318 | if (ctx->tmp_len - (ctx->pos - ctx->tmp) < 1 /*!*/ * 3 + 14 + /* at least */ 2) | ||
319 | { | ||
320 | GNUNET_break (0); | ||
321 | return 0; | ||
322 | } | ||
323 | /* Go past the first '!', now we're on expiration date */ | ||
324 | ctx->pos += 1; | ||
325 | /* Its length is known, so check for the next '!' right away */ | ||
326 | if (ctx->pos[14] != '!') | ||
327 | { | ||
328 | GNUNET_break (0); | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | memset (&expiration_time, 0, sizeof (struct tm)); | ||
333 | |||
334 | /* This is FAR more strict than strptime(ctx->pos, "%Y%m%d%H%M%S", ...); */ | ||
335 | /* FIXME: make it a separate function, since expiration is specified to every address */ | ||
336 | #define GETNDIGITS(n,cond) \ | ||
337 | strncpy (buf, &ctx->pos[0], n); \ | ||
338 | buf[n] = '\0'; \ | ||
339 | errno = 0; \ | ||
340 | l = strtol (buf, NULL, 10); \ | ||
341 | if (errno != 0 || cond) \ | ||
342 | { \ | ||
343 | GNUNET_break (0); \ | ||
344 | return 0; \ | ||
345 | } \ | ||
346 | ctx->pos += n; | ||
347 | |||
348 | GETNDIGITS (4, l < 1900) | ||
349 | expiration_time.tm_year = l - 1900; | ||
350 | |||
351 | GETNDIGITS (2, l < 1 || l > 12) | ||
352 | expiration_time.tm_mon = l; | ||
353 | |||
354 | GETNDIGITS (2, l < 1 || l > 31) | ||
355 | expiration_time.tm_mday = l; | ||
356 | |||
357 | GETNDIGITS (2, l < 0 || l > 23) | ||
358 | expiration_time.tm_hour = l; | ||
359 | |||
360 | GETNDIGITS (2, l < 0 || l > 59) | ||
361 | expiration_time.tm_min = l; | ||
362 | |||
363 | /* 60 - with a leap second */ | ||
364 | GETNDIGITS (2, l < 0 || l > 60) | ||
365 | expiration_time.tm_sec = l; | ||
366 | |||
367 | expiration_time.tm_isdst = -1; | ||
368 | |||
369 | #undef GETNDIGITS | ||
370 | |||
371 | expiration_seconds = mktime (&expiration_time); | ||
372 | if (expiration_seconds == (time_t) -1) | ||
373 | { | ||
374 | GNUNET_break (0); | ||
375 | return 0; | ||
376 | } | ||
377 | expire.abs_value = expiration_seconds * 1000; | ||
378 | |||
379 | /* Now we're at '!', advance to the transport type */ | ||
380 | ctx->pos += 1; | ||
381 | |||
382 | /* Find the next '!' that separates transport type from | ||
383 | * the address | ||
384 | */ | ||
385 | exp1 = strstr (ctx->pos, "!"); | ||
386 | if (exp1 == NULL) | ||
387 | { | ||
388 | GNUNET_break (0); | ||
389 | return 0; | ||
390 | } | ||
391 | /* We need it 0-terminated */ | ||
392 | exp1[0] = '\0'; | ||
393 | /* Find the '!' that separates address from the next record. | ||
394 | * It might not be there, if this is the last record. | ||
395 | */ | ||
396 | exp2 = strstr (&exp1[1], "!"); | ||
397 | if (exp2 == NULL) | ||
398 | exp2 = &ctx->tmp[ctx->tmp_len]; | ||
399 | |||
400 | papi = GST_plugins_find (ctx->pos); | ||
401 | if (papi == NULL) | ||
402 | { | ||
403 | /* Not an error - we might just not have the right plugin. | ||
404 | * Skip this part, advance to the next one and recurse. | ||
405 | * But only if this is not the end of string. | ||
406 | */ | ||
407 | ctx->pos = exp2 + 1; | ||
408 | if (ctx->pos - ctx->tmp >= ctx->tmp_len) | ||
409 | return 0; | ||
410 | return add_addr_to_hello (cls, max, buffer); | ||
411 | } | ||
412 | |||
413 | if (GNUNET_OK == papi->string_to_address (papi->cls, &exp1[1], exp2 - &exp1[1], &addr, &addr_len)) | ||
414 | { | ||
415 | struct GNUNET_HELLO_Address address; | ||
416 | int ret; | ||
417 | |||
418 | /* address.peer is unset - not used by add_address() */ | ||
419 | address.address_length = addr_len; | ||
420 | address.address = addr; | ||
421 | address.transport_name = ctx->pos; | ||
422 | ret = GNUNET_HELLO_add_address (&address, expire, buffer, max); | ||
423 | GNUNET_free (addr); | ||
424 | ctx->pos = exp2; | ||
425 | return ret; | ||
426 | } | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | void | ||
431 | parse_hello (const struct GNUNET_CONFIGURATION_Handle *c, | ||
432 | const char *put_uri) | ||
433 | { | ||
434 | int r; | ||
435 | char *scheme_part = NULL; | ||
436 | char *path_part = NULL; | ||
437 | char *exc; | ||
438 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; | ||
439 | int std_result; | ||
440 | struct GNUNET_HELLO_Message *hello; | ||
441 | struct GNUNET_PEERINFO_HelloAddressParsingContext ctx; | ||
442 | |||
443 | r = GNUNET_STRINGS_parse_uri (put_uri, &scheme_part, (const char **) &path_part); | ||
444 | if (r == GNUNET_NO) | ||
445 | return; | ||
446 | if (scheme_part == NULL || strcmp (scheme_part, "gnunet://") != 0) | ||
447 | { | ||
448 | GNUNET_free_non_null (scheme_part); | ||
449 | return; | ||
450 | } | ||
451 | GNUNET_free (scheme_part); | ||
452 | |||
453 | if (strncmp (path_part, "hello/", 6) != 0) | ||
454 | return; | ||
455 | |||
456 | path_part = &path_part[6]; | ||
457 | ctx.tmp = GNUNET_strdup (path_part); | ||
458 | ctx.tmp_len = strlen (path_part); | ||
459 | exc = strstr (ctx.tmp, "!"); | ||
460 | if (exc == NULL) | ||
461 | exc = ctx.pos + ctx.tmp_len; | ||
462 | ctx.pos = exc; | ||
463 | |||
464 | std_result = GNUNET_STRINGS_string_to_data (ctx.tmp, exc - ctx.tmp, | ||
465 | (unsigned char *) &pub, sizeof (pub)); | ||
466 | if (std_result != GNUNET_OK) | ||
467 | { | ||
468 | GNUNET_free (ctx.tmp); | ||
469 | return; | ||
470 | } | ||
471 | |||
472 | hello = GNUNET_HELLO_create (&pub, add_addr_to_hello, &ctx); | ||
473 | GNUNET_free (ctx.tmp); | ||
474 | |||
475 | /* WARNING: this adds the address from URI WITHOUT verification! */ | ||
476 | GNUNET_PEERINFO_add_peer (peerinfo, hello); | ||
477 | } | ||
478 | |||
479 | static struct GNUNET_TIME_Relative | ||
480 | receive_stub (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
481 | const struct GNUNET_MessageHeader *message, | ||
482 | const struct GNUNET_ATS_Information *ats, uint32_t ats_count, | ||
483 | struct Session *session, const char *sender_address, | ||
484 | uint16_t sender_address_len) | ||
485 | { | ||
486 | struct GNUNET_TIME_Relative t; | ||
487 | t.rel_value = 0; | ||
488 | return t; | ||
489 | } | ||
490 | |||
491 | static void | ||
492 | address_notification_stub (void *cls, int add_remove, | ||
493 | const void *addr, size_t addrlen) | ||
494 | { | ||
495 | } | ||
496 | |||
497 | static void | ||
498 | session_end_stub (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
499 | struct Session * session) | ||
500 | { | ||
501 | } | ||
502 | |||
503 | static const struct GNUNET_ATS_Information | ||
504 | address_to_type_stub (void *cls, const struct sockaddr *addr, | ||
505 | size_t addrlen) | ||
506 | { | ||
507 | struct GNUNET_ATS_Information t; | ||
508 | t.type = 0; | ||
509 | t.value = 0; | ||
510 | return t; | ||
511 | } | ||
512 | |||
172 | 513 | ||
173 | /** | 514 | /** |
174 | * Main function that will be run by the scheduler. | 515 | * Main function that will be run by the scheduler. |
@@ -194,7 +535,12 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
194 | FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]); | 535 | FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]); |
195 | return; | 536 | return; |
196 | } | 537 | } |
197 | if (get_self != GNUNET_YES) | 538 | if (put_uri != NULL && get_uri == GNUNET_YES) |
539 | { | ||
540 | FPRINTF (stderr, "%s", _("--put-uri and --get-uri are mutually exclusive\n")); | ||
541 | return; | ||
542 | } | ||
543 | if (put_uri != NULL || get_uri == GNUNET_YES) | ||
198 | { | 544 | { |
199 | peerinfo = GNUNET_PEERINFO_connect (cfg); | 545 | peerinfo = GNUNET_PEERINFO_connect (cfg); |
200 | if (peerinfo == NULL) | 546 | if (peerinfo == NULL) |
@@ -202,6 +548,21 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
202 | FPRINTF (stderr, "%s", _("Could not access PEERINFO service. Exiting.\n")); | 548 | FPRINTF (stderr, "%s", _("Could not access PEERINFO service. Exiting.\n")); |
203 | return; | 549 | return; |
204 | } | 550 | } |
551 | GST_cfg = c; | ||
552 | GST_stats = GNUNET_STATISTICS_create ("transport", c); | ||
553 | /* FIXME: shouldn't we free GST_stats somewhere? */ | ||
554 | GST_plugins_load (receive_stub, address_notification_stub, | ||
555 | session_end_stub, address_to_type_stub); | ||
556 | } | ||
557 | if (put_uri != NULL) | ||
558 | { | ||
559 | parse_hello (c, put_uri); | ||
560 | GST_plugins_unload (); | ||
561 | GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO); | ||
562 | return; | ||
563 | } | ||
564 | if (get_self != GNUNET_YES) | ||
565 | { | ||
205 | GNUNET_PEERINFO_iterate (peerinfo, NULL, | 566 | GNUNET_PEERINFO_iterate (peerinfo, NULL, |
206 | GNUNET_TIME_relative_multiply | 567 | GNUNET_TIME_relative_multiply |
207 | (GNUNET_TIME_UNIT_SECONDS, 5), &print_peer_info, | 568 | (GNUNET_TIME_UNIT_SECONDS, 5), &print_peer_info, |
@@ -233,6 +594,23 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
233 | printf ("%s\n", (char *) &enc); | 594 | printf ("%s\n", (char *) &enc); |
234 | else | 595 | else |
235 | printf (_("I am peer `%s'.\n"), (const char *) &enc); | 596 | printf (_("I am peer `%s'.\n"), (const char *) &enc); |
597 | if (get_uri == GNUNET_YES) | ||
598 | { | ||
599 | struct PrintContext *pc; | ||
600 | char *pkey; | ||
601 | ssize_t l, pl; | ||
602 | pc = GNUNET_malloc (sizeof (struct PrintContext)); | ||
603 | pkey = GNUNET_CRYPTO_rsa_public_key_to_string (&pub); | ||
604 | pl = strlen ("gnunet://hello/"); | ||
605 | l = strlen (pkey) + pl; | ||
606 | pc->uri = GNUNET_malloc (l + 1); | ||
607 | strcpy (pc->uri, "gnunet://hello/"); | ||
608 | strcpy (&pc->uri[pl], pkey); | ||
609 | pc->uri_len = l; | ||
610 | GNUNET_PEERINFO_iterate (peerinfo, &pid, | ||
611 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), | ||
612 | print_my_uri, pc); | ||
613 | } | ||
236 | } | 614 | } |
237 | } | 615 | } |
238 | 616 | ||
@@ -257,6 +635,12 @@ main (int argc, char *const *argv) | |||
257 | {'s', "self", NULL, | 635 | {'s', "self", NULL, |
258 | gettext_noop ("output our own identity only"), | 636 | gettext_noop ("output our own identity only"), |
259 | 0, &GNUNET_GETOPT_set_one, &get_self}, | 637 | 0, &GNUNET_GETOPT_set_one, &get_self}, |
638 | {'g', "get-hello", NULL, | ||
639 | gettext_noop ("also output HELLO uri(s)"), | ||
640 | 0, &GNUNET_GETOPT_set_one, &get_uri}, | ||
641 | {'p', "put-hello", "HELLO", | ||
642 | gettext_noop ("add given HELLO uri to the database"), | ||
643 | 1, &GNUNET_GETOPT_set_string, &put_uri}, | ||
260 | GNUNET_GETOPT_OPTION_END | 644 | GNUNET_GETOPT_OPTION_END |
261 | }; | 645 | }; |
262 | return (GNUNET_OK == | 646 | return (GNUNET_OK == |