diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-11-20 19:51:03 +0900 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-11-20 19:51:03 +0900 |
commit | 56a3e354dba3b348e508359af6b43160f99d7df3 (patch) | |
tree | 5fc0371a14e53e7432e6e7a1a4f754cd0283a69c /src/namestore | |
parent | f2b264a16c3c9a4199876740a210496e63b0bea4 (diff) | |
download | gnunet-56a3e354dba3b348e508359af6b43160f99d7df3.tar.gz gnunet-56a3e354dba3b348e508359af6b43160f99d7df3.zip |
NAMESTORE: CLI utility can now parse multiple records from stdin
Diffstat (limited to 'src/namestore')
-rw-r--r-- | src/namestore/gnunet-namestore.c | 846 |
1 files changed, 512 insertions, 334 deletions
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c index 36a0a9ba3..46012cf21 100644 --- a/src/namestore/gnunet-namestore.c +++ b/src/namestore/gnunet-namestore.c | |||
@@ -119,11 +119,6 @@ static struct GNUNET_NAMESTORE_Handle *ns; | |||
119 | static struct GNUNET_IDENTITY_PrivateKey zone_pkey; | 119 | static struct GNUNET_IDENTITY_PrivateKey zone_pkey; |
120 | 120 | ||
121 | /** | 121 | /** |
122 | * Handle to identity lookup. | ||
123 | */ | ||
124 | static struct GNUNET_IDENTITY_EgoLookup *el; | ||
125 | |||
126 | /** | ||
127 | * Identity service handle | 122 | * Identity service handle |
128 | */ | 123 | */ |
129 | static struct GNUNET_IDENTITY_Handle *idh; | 124 | static struct GNUNET_IDENTITY_Handle *idh; |
@@ -168,6 +163,10 @@ static struct MarkedRecord *marked_head; | |||
168 | */ | 163 | */ |
169 | static struct MarkedRecord *marked_tail; | 164 | static struct MarkedRecord *marked_tail; |
170 | 165 | ||
166 | /** | ||
167 | * Configuration handle | ||
168 | */ | ||
169 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
171 | 170 | ||
172 | /** | 171 | /** |
173 | * Ego list | 172 | * Ego list |
@@ -190,6 +189,11 @@ static int list; | |||
190 | static struct GNUNET_NAMESTORE_ZoneIterator *list_it; | 189 | static struct GNUNET_NAMESTORE_ZoneIterator *list_it; |
191 | 190 | ||
192 | /** | 191 | /** |
192 | * Run in read from stdin mode. | ||
193 | */ | ||
194 | static int read_from_stdin; | ||
195 | |||
196 | /** | ||
193 | * Desired action is to remove a record. | 197 | * Desired action is to remove a record. |
194 | */ | 198 | */ |
195 | static int del; | 199 | static int del; |
@@ -240,6 +244,11 @@ static struct GNUNET_NAMESTORE_QueueEntry *del_qe; | |||
240 | static struct GNUNET_NAMESTORE_QueueEntry *set_qe; | 244 | static struct GNUNET_NAMESTORE_QueueEntry *set_qe; |
241 | 245 | ||
242 | /** | 246 | /** |
247 | * Queue entry for begin/commit | ||
248 | */ | ||
249 | static struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
250 | |||
251 | /** | ||
243 | * Name of the records to add/list/remove. | 252 | * Name of the records to add/list/remove. |
244 | */ | 253 | */ |
245 | static char *name; | 254 | static char *name; |
@@ -325,18 +334,217 @@ static struct RecordSetEntry *recordset; | |||
325 | static struct GNUNET_SCHEDULER_Task *purge_task; | 334 | static struct GNUNET_SCHEDULER_Task *purge_task; |
326 | 335 | ||
327 | /** | 336 | /** |
328 | * Task run on shutdown. Cleans up everything. | 337 | * Parse expiration time. |
329 | * | 338 | * |
330 | * @param cls unused | 339 | * @param expirationstring text to parse |
340 | * @param[out] etime_is_rel set to #GNUNET_YES if time is relative | ||
341 | * @param[out] etime set to expiration time (abs or rel) | ||
342 | * @return #GNUNET_OK on success | ||
331 | */ | 343 | */ |
344 | static int | ||
345 | parse_expiration (const char *expirationstring, | ||
346 | int *etime_is_rel, | ||
347 | uint64_t *etime) | ||
348 | { | ||
349 | struct GNUNET_TIME_Relative etime_rel; | ||
350 | struct GNUNET_TIME_Absolute etime_abs; | ||
351 | |||
352 | if (0 == strcmp (expirationstring, "never")) | ||
353 | { | ||
354 | *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | ||
355 | *etime_is_rel = GNUNET_NO; | ||
356 | return GNUNET_OK; | ||
357 | } | ||
358 | if (GNUNET_OK == | ||
359 | GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel)) | ||
360 | { | ||
361 | *etime_is_rel = GNUNET_YES; | ||
362 | *etime = etime_rel.rel_value_us; | ||
363 | if (GNUNET_TIME_relative_cmp (etime_rel, <, WARN_RELATIVE_EXPIRATION_LIMIT)) | ||
364 | { | ||
365 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
366 | "Relative expiration times of less than %s are not recommended. To improve availability, consider increasing this value.\n", | ||
367 | GNUNET_STRINGS_relative_time_to_string ( | ||
368 | WARN_RELATIVE_EXPIRATION_LIMIT, GNUNET_NO)); | ||
369 | } | ||
370 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
371 | "Storing record with relative expiration time of %s\n", | ||
372 | GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO)); | ||
373 | return GNUNET_OK; | ||
374 | } | ||
375 | if (GNUNET_OK == | ||
376 | GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs)) | ||
377 | { | ||
378 | *etime_is_rel = GNUNET_NO; | ||
379 | *etime = etime_abs.abs_value_us; | ||
380 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
381 | "Storing record with absolute expiration time of %s\n", | ||
382 | GNUNET_STRINGS_absolute_time_to_string (etime_abs)); | ||
383 | return GNUNET_OK; | ||
384 | } | ||
385 | return GNUNET_SYSERR; | ||
386 | } | ||
387 | |||
388 | |||
389 | |||
390 | /** | ||
391 | * Command-line option parser function that allows the user to specify | ||
392 | * a complete record as one argument for adding/removing. A pointer | ||
393 | * to the head of the list of record sets must be passed as the "scls" | ||
394 | * argument. | ||
395 | * | ||
396 | * @param ctx command line processor context | ||
397 | * @param scls must be of type "struct GNUNET_FS_Uri **" | ||
398 | * @param option name of the option (typically 'R') | ||
399 | * @param value command line argument given; format is | ||
400 | * "TTL TYPE FLAGS VALUE" where TTL is an expiration time (rel or abs), | ||
401 | * always given in seconds (without the unit), | ||
402 | * TYPE is a DNS/GNS record type, FLAGS is either "n" for no flags or | ||
403 | * a combination of 's' (shadow) and 'p' (public) and VALUE is the | ||
404 | * value (in human-readable format) | ||
405 | * @return #GNUNET_OK on success | ||
406 | */ | ||
407 | static int | ||
408 | multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | ||
409 | void *scls, | ||
410 | const char *option, | ||
411 | const char *value) | ||
412 | { | ||
413 | struct RecordSetEntry **head = scls; | ||
414 | struct RecordSetEntry *r; | ||
415 | struct GNUNET_GNSRECORD_Data record; | ||
416 | char *cp; | ||
417 | char *tok; | ||
418 | char *saveptr; | ||
419 | int etime_is_rel; | ||
420 | void *raw_data; | ||
421 | |||
422 | (void) ctx; | ||
423 | (void) option; | ||
424 | cp = GNUNET_strdup (value); | ||
425 | tok = strtok_r (cp, " ", &saveptr); | ||
426 | if (NULL == tok) | ||
427 | { | ||
428 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
429 | _ ("Empty record line argument is not allowed.\n")); | ||
430 | GNUNET_free (cp); | ||
431 | return GNUNET_SYSERR; | ||
432 | } | ||
433 | { | ||
434 | char *etime_in_s; | ||
435 | |||
436 | GNUNET_asprintf (&etime_in_s, "%s s", tok); | ||
437 | if (GNUNET_OK != | ||
438 | parse_expiration (etime_in_s, &etime_is_rel, &record.expiration_time)) | ||
439 | { | ||
440 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
441 | _ ("Invalid expiration time `%s' (must be without unit)\n"), | ||
442 | tok); | ||
443 | GNUNET_free (cp); | ||
444 | GNUNET_free (etime_in_s); | ||
445 | return GNUNET_SYSERR; | ||
446 | } | ||
447 | GNUNET_free (etime_in_s); | ||
448 | } | ||
449 | tok = strtok_r (NULL, " ", &saveptr); | ||
450 | if (NULL == tok) | ||
451 | { | ||
452 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
453 | _ ("Missing entries in record line `%s'.\n"), | ||
454 | value); | ||
455 | GNUNET_free (cp); | ||
456 | return GNUNET_SYSERR; | ||
457 | } | ||
458 | record.record_type = GNUNET_GNSRECORD_typename_to_number (tok); | ||
459 | if (UINT32_MAX == record.record_type) | ||
460 | { | ||
461 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Unknown record type `%s'\n"), tok); | ||
462 | GNUNET_free (cp); | ||
463 | return GNUNET_SYSERR; | ||
464 | } | ||
465 | tok = strtok_r (NULL, " ", &saveptr); | ||
466 | if (NULL == tok) | ||
467 | { | ||
468 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
469 | _ ("Missing entries in record line `%s'.\n"), | ||
470 | value); | ||
471 | GNUNET_free (cp); | ||
472 | return GNUNET_SYSERR; | ||
473 | } | ||
474 | record.flags = GNUNET_GNSRECORD_RF_NONE; | ||
475 | if (etime_is_rel) | ||
476 | record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
477 | if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */ | ||
478 | record.flags |= GNUNET_GNSRECORD_RF_PRIVATE; | ||
479 | if (NULL != strchr (tok, (unsigned char) 's')) | ||
480 | record.flags |= GNUNET_GNSRECORD_RF_SHADOW; | ||
481 | /* find beginning of record value */ | ||
482 | tok = strchr (&value[tok - cp], (unsigned char) ' '); | ||
483 | if (NULL == tok) | ||
484 | { | ||
485 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
486 | _ ("Missing entries in record line `%s'.\n"), | ||
487 | value); | ||
488 | GNUNET_free (cp); | ||
489 | return GNUNET_SYSERR; | ||
490 | } | ||
491 | GNUNET_free (cp); | ||
492 | tok++; /* skip space */ | ||
493 | if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record.record_type, | ||
494 | tok, | ||
495 | &raw_data, | ||
496 | &record.data_size)) | ||
497 | { | ||
498 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
499 | _ ("Invalid record data for type %s: `%s'.\n"), | ||
500 | GNUNET_GNSRECORD_number_to_typename (record.record_type), | ||
501 | tok); | ||
502 | return GNUNET_SYSERR; | ||
503 | } | ||
504 | |||
505 | r = GNUNET_malloc (sizeof(struct RecordSetEntry) + record.data_size); | ||
506 | r->next = *head; | ||
507 | record.data = &r[1]; | ||
508 | memcpy (&r[1], raw_data, record.data_size); | ||
509 | GNUNET_free (raw_data); | ||
510 | r->record = record; | ||
511 | *head = r; | ||
512 | return GNUNET_OK; | ||
513 | } | ||
514 | |||
515 | /** | ||
516 | * Allow user to specify keywords. | ||
517 | * | ||
518 | * @param shortName short name of the option | ||
519 | * @param name long name of the option | ||
520 | * @param argumentHelp help text for the option argument | ||
521 | * @param description long help text for the option | ||
522 | * @param[out] topKeywords set to the desired value | ||
523 | */ | ||
524 | struct GNUNET_GETOPT_CommandLineOption | ||
525 | multirecord_option (char shortName, | ||
526 | const char *name, | ||
527 | const char *argumentHelp, | ||
528 | const char *description, | ||
529 | struct RecordSetEntry **rs) | ||
530 | { | ||
531 | struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName, | ||
532 | .name = name, | ||
533 | .argumentHelp = argumentHelp, | ||
534 | .description = description, | ||
535 | .require_argument = 1, | ||
536 | .processor = | ||
537 | &multirecord_process, | ||
538 | .scls = (void *) rs }; | ||
539 | |||
540 | return clo; | ||
541 | } | ||
542 | |||
332 | static void | 543 | static void |
333 | do_shutdown (void *cls) | 544 | reset_handles (void) |
334 | { | 545 | { |
335 | struct EgoEntry *ego_entry; | ||
336 | struct EgoEntry *ego_tmp; | ||
337 | struct MarkedRecord *mrec; | 546 | struct MarkedRecord *mrec; |
338 | struct MarkedRecord *mrec_tmp; | 547 | struct MarkedRecord *mrec_tmp; |
339 | (void) cls; | ||
340 | if (NULL != ego_name) | 548 | if (NULL != ego_name) |
341 | { | 549 | { |
342 | GNUNET_free (ego_name); | 550 | GNUNET_free (ego_name); |
@@ -347,16 +555,6 @@ do_shutdown (void *cls) | |||
347 | GNUNET_SCHEDULER_cancel (purge_task); | 555 | GNUNET_SCHEDULER_cancel (purge_task); |
348 | purge_task = NULL; | 556 | purge_task = NULL; |
349 | } | 557 | } |
350 | if (NULL != idh) | ||
351 | { | ||
352 | GNUNET_IDENTITY_disconnect (idh); | ||
353 | idh = NULL; | ||
354 | } | ||
355 | if (NULL != el) | ||
356 | { | ||
357 | GNUNET_IDENTITY_ego_lookup_cancel (el); | ||
358 | el = NULL; | ||
359 | } | ||
360 | for (mrec = marked_head; NULL != mrec;) | 558 | for (mrec = marked_head; NULL != mrec;) |
361 | { | 559 | { |
362 | mrec_tmp = mrec; | 560 | mrec_tmp = mrec; |
@@ -364,13 +562,6 @@ do_shutdown (void *cls) | |||
364 | GNUNET_free (mrec_tmp->name); | 562 | GNUNET_free (mrec_tmp->name); |
365 | GNUNET_free (mrec_tmp); | 563 | GNUNET_free (mrec_tmp); |
366 | } | 564 | } |
367 | for (ego_entry = ego_head; NULL != ego_entry;) | ||
368 | { | ||
369 | ego_tmp = ego_entry; | ||
370 | ego_entry = ego_entry->next; | ||
371 | GNUNET_free (ego_tmp->identifier); | ||
372 | GNUNET_free (ego_tmp); | ||
373 | } | ||
374 | if (NULL != list_it) | 565 | if (NULL != list_it) |
375 | { | 566 | { |
376 | GNUNET_NAMESTORE_zone_iteration_stop (list_it); | 567 | GNUNET_NAMESTORE_zone_iteration_stop (list_it); |
@@ -401,10 +592,10 @@ do_shutdown (void *cls) | |||
401 | GNUNET_NAMESTORE_cancel (del_qe); | 592 | GNUNET_NAMESTORE_cancel (del_qe); |
402 | del_qe = NULL; | 593 | del_qe = NULL; |
403 | } | 594 | } |
404 | if (NULL != ns) | 595 | if (NULL != reverse_qe) |
405 | { | 596 | { |
406 | GNUNET_NAMESTORE_disconnect (ns); | 597 | GNUNET_NAMESTORE_cancel (reverse_qe); |
407 | ns = NULL; | 598 | reverse_qe = NULL; |
408 | } | 599 | } |
409 | memset (&zone_pkey, 0, sizeof(zone_pkey)); | 600 | memset (&zone_pkey, 0, sizeof(zone_pkey)); |
410 | if (NULL != uri) | 601 | if (NULL != uri) |
@@ -425,15 +616,71 @@ do_shutdown (void *cls) | |||
425 | } | 616 | } |
426 | 617 | ||
427 | 618 | ||
619 | |||
428 | /** | 620 | /** |
429 | * Check if we are finished, and if so, perform shutdown. | 621 | * Task run on shutdown. Cleans up everything. |
622 | * | ||
623 | * @param cls unused | ||
430 | */ | 624 | */ |
431 | static void | 625 | static void |
432 | test_finished () | 626 | do_shutdown (void *cls) |
433 | { | 627 | { |
434 | if ((NULL == add_qe) && (NULL == add_qe_uri) && (NULL == get_qe) && | 628 | struct EgoEntry *ego_entry; |
435 | (NULL == del_qe) && (NULL == reverse_qe) && (NULL == list_it)) | 629 | struct EgoEntry *ego_tmp; |
436 | GNUNET_SCHEDULER_shutdown (); | 630 | (void) cls; |
631 | |||
632 | reset_handles (); | ||
633 | if (NULL != ns_qe) | ||
634 | { | ||
635 | GNUNET_NAMESTORE_cancel (ns_qe); | ||
636 | ns_qe = NULL; | ||
637 | } | ||
638 | if (NULL != ns) | ||
639 | { | ||
640 | GNUNET_NAMESTORE_disconnect (ns); | ||
641 | ns = NULL; | ||
642 | } | ||
643 | if (NULL != idh) | ||
644 | { | ||
645 | GNUNET_IDENTITY_disconnect (idh); | ||
646 | idh = NULL; | ||
647 | } | ||
648 | for (ego_entry = ego_head; NULL != ego_entry;) | ||
649 | { | ||
650 | ego_tmp = ego_entry; | ||
651 | ego_entry = ego_entry->next; | ||
652 | GNUNET_free (ego_tmp->identifier); | ||
653 | GNUNET_free (ego_tmp); | ||
654 | } | ||
655 | } | ||
656 | |||
657 | static void | ||
658 | commit_cb (void *cls, enum GNUNET_ErrorCode ec) | ||
659 | { | ||
660 | ns_qe = NULL; | ||
661 | if (GNUNET_EC_NONE != ec) | ||
662 | { | ||
663 | fprintf (stderr, "Failed to commit to namestore: `%s'\n", | ||
664 | GNUNET_ErrorCode_get_hint (ec)); | ||
665 | ret = 1; | ||
666 | } | ||
667 | GNUNET_SCHEDULER_shutdown (); | ||
668 | } | ||
669 | |||
670 | static void | ||
671 | process_command_stdin (); | ||
672 | |||
673 | |||
674 | static void | ||
675 | finish_command (void) | ||
676 | { | ||
677 | reset_handles (); | ||
678 | if (read_from_stdin) | ||
679 | { | ||
680 | process_command_stdin (); | ||
681 | return; | ||
682 | } | ||
683 | ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL); | ||
437 | } | 684 | } |
438 | 685 | ||
439 | 686 | ||
@@ -452,7 +699,7 @@ add_continuation (void *cls, enum GNUNET_ErrorCode ec) | |||
452 | ret = 1; | 699 | ret = 1; |
453 | } | 700 | } |
454 | ret = 0; | 701 | ret = 0; |
455 | test_finished (); | 702 | finish_command (); |
456 | } | 703 | } |
457 | 704 | ||
458 | 705 | ||
@@ -467,7 +714,7 @@ del_continuation (void *cls, enum GNUNET_ErrorCode ec) | |||
467 | _ ("Deleting record failed: %s\n"), GNUNET_ErrorCode_get_hint ( | 714 | _ ("Deleting record failed: %s\n"), GNUNET_ErrorCode_get_hint ( |
468 | ec)); | 715 | ec)); |
469 | } | 716 | } |
470 | test_finished (); | 717 | finish_command (); |
471 | } | 718 | } |
472 | 719 | ||
473 | static void | 720 | static void |
@@ -496,7 +743,7 @@ purge_next_record (void *cls) | |||
496 | if (NULL == marked_head) | 743 | if (NULL == marked_head) |
497 | { | 744 | { |
498 | ret = 0; | 745 | ret = 0; |
499 | test_finished (); | 746 | finish_command (); |
500 | return; | 747 | return; |
501 | } | 748 | } |
502 | mrec = marked_head; | 749 | mrec = marked_head; |
@@ -527,7 +774,7 @@ zone_iteration_finished (void *cls) | |||
527 | return; | 774 | return; |
528 | } | 775 | } |
529 | ret = 0; | 776 | ret = 0; |
530 | test_finished (); | 777 | finish_command (); |
531 | } | 778 | } |
532 | 779 | ||
533 | 780 | ||
@@ -541,7 +788,7 @@ zone_iteration_error_cb (void *cls) | |||
541 | list_it = NULL; | 788 | list_it = NULL; |
542 | fprintf (stderr, "Error iterating over zone\n"); | 789 | fprintf (stderr, "Error iterating over zone\n"); |
543 | ret = 1; | 790 | ret = 1; |
544 | test_finished (); | 791 | finish_command (); |
545 | } | 792 | } |
546 | 793 | ||
547 | static void | 794 | static void |
@@ -797,7 +1044,7 @@ display_record_lookup (void *cls, | |||
797 | (void) zone_key; | 1044 | (void) zone_key; |
798 | get_qe = NULL; | 1045 | get_qe = NULL; |
799 | display_record (zone_key, rname, rd_len, rd); | 1046 | display_record (zone_key, rname, rd_len, rd); |
800 | test_finished (); | 1047 | finish_command (); |
801 | } | 1048 | } |
802 | 1049 | ||
803 | 1050 | ||
@@ -838,7 +1085,7 @@ lookup_error_cb (void *cls) | |||
838 | (void) cls; | 1085 | (void) cls; |
839 | get_qe = NULL; | 1086 | get_qe = NULL; |
840 | fprintf (stderr, "%s", "Failed to lookup record.\n"); | 1087 | fprintf (stderr, "%s", "Failed to lookup record.\n"); |
841 | test_finished (); | 1088 | finish_command (); |
842 | } | 1089 | } |
843 | 1090 | ||
844 | 1091 | ||
@@ -852,7 +1099,7 @@ add_error_cb (void *cls) | |||
852 | add_qe = NULL; | 1099 | add_qe = NULL; |
853 | GNUNET_break (0); | 1100 | GNUNET_break (0); |
854 | ret = 1; | 1101 | ret = 1; |
855 | test_finished (); | 1102 | finish_command (); |
856 | } | 1103 | } |
857 | 1104 | ||
858 | 1105 | ||
@@ -883,7 +1130,7 @@ get_existing_record (void *cls, | |||
883 | { | 1130 | { |
884 | GNUNET_break (0); | 1131 | GNUNET_break (0); |
885 | ret = 1; | 1132 | ret = 1; |
886 | test_finished (); | 1133 | finish_command (); |
887 | return; | 1134 | return; |
888 | } | 1135 | } |
889 | 1136 | ||
@@ -904,7 +1151,7 @@ get_existing_record (void *cls, | |||
904 | "A SOA record exists already under `%s', cannot add a second SOA to the same zone.\n"), | 1151 | "A SOA record exists already under `%s', cannot add a second SOA to the same zone.\n"), |
905 | rec_name); | 1152 | rec_name); |
906 | ret = 1; | 1153 | ret = 1; |
907 | test_finished (); | 1154 | finish_command (); |
908 | return; | 1155 | return; |
909 | } | 1156 | } |
910 | break; | 1157 | break; |
@@ -974,7 +1221,7 @@ handle_reverse_lookup (void *cls, | |||
974 | fprintf (stdout, "%s\n", reverse_pkey); | 1221 | fprintf (stdout, "%s\n", reverse_pkey); |
975 | else | 1222 | else |
976 | fprintf (stdout, "%s.%s\n", label, ego_name); | 1223 | fprintf (stdout, "%s.%s\n", label, ego_name); |
977 | test_finished (); | 1224 | finish_command (); |
978 | } | 1225 | } |
979 | 1226 | ||
980 | 1227 | ||
@@ -988,7 +1235,7 @@ del_lookup_error_cb (void *cls) | |||
988 | del_qe = NULL; | 1235 | del_qe = NULL; |
989 | GNUNET_break (0); | 1236 | GNUNET_break (0); |
990 | ret = 1; | 1237 | ret = 1; |
991 | test_finished (); | 1238 | finish_command (); |
992 | } | 1239 | } |
993 | 1240 | ||
994 | 1241 | ||
@@ -1025,7 +1272,7 @@ del_monitor (void *cls, | |||
1025 | "There are no records under label `%s' that could be deleted.\n"), | 1272 | "There are no records under label `%s' that could be deleted.\n"), |
1026 | label); | 1273 | label); |
1027 | ret = 1; | 1274 | ret = 1; |
1028 | test_finished (); | 1275 | finish_command (); |
1029 | return; | 1276 | return; |
1030 | } | 1277 | } |
1031 | if ((NULL == value) && (NULL == typestring)) | 1278 | if ((NULL == value) && (NULL == typestring)) |
@@ -1067,7 +1314,7 @@ del_monitor (void *cls, | |||
1067 | _ ( | 1314 | _ ( |
1068 | "There are no records under label `%s' that match the request for deletion.\n"), | 1315 | "There are no records under label `%s' that match the request for deletion.\n"), |
1069 | label); | 1316 | label); |
1070 | test_finished (); | 1317 | finish_command (); |
1071 | return; | 1318 | return; |
1072 | } | 1319 | } |
1073 | /* delete everything but what we copied to 'rdx' */ | 1320 | /* delete everything but what we copied to 'rdx' */ |
@@ -1081,59 +1328,6 @@ del_monitor (void *cls, | |||
1081 | } | 1328 | } |
1082 | 1329 | ||
1083 | 1330 | ||
1084 | /** | ||
1085 | * Parse expiration time. | ||
1086 | * | ||
1087 | * @param expirationstring text to parse | ||
1088 | * @param[out] etime_is_rel set to #GNUNET_YES if time is relative | ||
1089 | * @param[out] etime set to expiration time (abs or rel) | ||
1090 | * @return #GNUNET_OK on success | ||
1091 | */ | ||
1092 | static int | ||
1093 | parse_expiration (const char *expirationstring, | ||
1094 | int *etime_is_rel, | ||
1095 | uint64_t *etime) | ||
1096 | { | ||
1097 | struct GNUNET_TIME_Relative etime_rel; | ||
1098 | struct GNUNET_TIME_Absolute etime_abs; | ||
1099 | |||
1100 | if (0 == strcmp (expirationstring, "never")) | ||
1101 | { | ||
1102 | *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | ||
1103 | *etime_is_rel = GNUNET_NO; | ||
1104 | return GNUNET_OK; | ||
1105 | } | ||
1106 | if (GNUNET_OK == | ||
1107 | GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel)) | ||
1108 | { | ||
1109 | *etime_is_rel = GNUNET_YES; | ||
1110 | *etime = etime_rel.rel_value_us; | ||
1111 | if (GNUNET_TIME_relative_cmp (etime_rel, <, WARN_RELATIVE_EXPIRATION_LIMIT)) | ||
1112 | { | ||
1113 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1114 | "Relative expiration times of less than %s are not recommended. To improve availability, consider increasing this value.\n", | ||
1115 | GNUNET_STRINGS_relative_time_to_string ( | ||
1116 | WARN_RELATIVE_EXPIRATION_LIMIT, GNUNET_NO)); | ||
1117 | } | ||
1118 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1119 | "Storing record with relative expiration time of %s\n", | ||
1120 | GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO)); | ||
1121 | return GNUNET_OK; | ||
1122 | } | ||
1123 | if (GNUNET_OK == | ||
1124 | GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs)) | ||
1125 | { | ||
1126 | *etime_is_rel = GNUNET_NO; | ||
1127 | *etime = etime_abs.abs_value_us; | ||
1128 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1129 | "Storing record with absolute expiration time of %s\n", | ||
1130 | GNUNET_STRINGS_absolute_time_to_string (etime_abs)); | ||
1131 | return GNUNET_OK; | ||
1132 | } | ||
1133 | return GNUNET_SYSERR; | ||
1134 | } | ||
1135 | |||
1136 | |||
1137 | static void | 1331 | static void |
1138 | replace_cont (void *cls, enum GNUNET_ErrorCode ec) | 1332 | replace_cont (void *cls, enum GNUNET_ErrorCode ec) |
1139 | { | 1333 | { |
@@ -1147,7 +1341,7 @@ replace_cont (void *cls, enum GNUNET_ErrorCode ec) | |||
1147 | GNUNET_ErrorCode_get_hint (ec)); | 1341 | GNUNET_ErrorCode_get_hint (ec)); |
1148 | ret = 1; /* fail from 'main' */ | 1342 | ret = 1; /* fail from 'main' */ |
1149 | } | 1343 | } |
1150 | GNUNET_SCHEDULER_shutdown (); | 1344 | finish_command (); |
1151 | } | 1345 | } |
1152 | 1346 | ||
1153 | 1347 | ||
@@ -1173,14 +1367,7 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1173 | { | 1367 | { |
1174 | /* nothing more to be done */ | 1368 | /* nothing more to be done */ |
1175 | fprintf (stderr, _ ("No options given\n")); | 1369 | fprintf (stderr, _ ("No options given\n")); |
1176 | GNUNET_SCHEDULER_shutdown (); | 1370 | finish_command (); |
1177 | return; | ||
1178 | } | ||
1179 | ns = GNUNET_NAMESTORE_connect (cfg); | ||
1180 | if (NULL == ns) | ||
1181 | { | ||
1182 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1183 | _ ("Failed to connect to namestore\n")); | ||
1184 | return; | 1371 | return; |
1185 | } | 1372 | } |
1186 | 1373 | ||
@@ -1196,8 +1383,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1196 | _ ("Missing option `%s' for operation `%s'\n"), | 1383 | _ ("Missing option `%s' for operation `%s'\n"), |
1197 | "-z", | 1384 | "-z", |
1198 | _ ("replace")); | 1385 | _ ("replace")); |
1199 | GNUNET_SCHEDULER_shutdown (); | ||
1200 | ret = 1; | 1386 | ret = 1; |
1387 | finish_command (); | ||
1201 | return; | 1388 | return; |
1202 | } | 1389 | } |
1203 | if (NULL == name) | 1390 | if (NULL == name) |
@@ -1206,8 +1393,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1206 | _ ("Missing option `%s' for operation `%s'\n"), | 1393 | _ ("Missing option `%s' for operation `%s'\n"), |
1207 | "-R", | 1394 | "-R", |
1208 | _ ("replace")); | 1395 | _ ("replace")); |
1209 | GNUNET_SCHEDULER_shutdown (); | ||
1210 | ret = 1; | 1396 | ret = 1; |
1397 | finish_command (); | ||
1211 | return; | 1398 | return; |
1212 | } | 1399 | } |
1213 | rd_count = 0; | 1400 | rd_count = 0; |
@@ -1235,8 +1422,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1235 | if (0 == strlen (nickstring)) | 1422 | if (0 == strlen (nickstring)) |
1236 | { | 1423 | { |
1237 | fprintf (stderr, _ ("Invalid nick `%s'\n"), nickstring); | 1424 | fprintf (stderr, _ ("Invalid nick `%s'\n"), nickstring); |
1238 | GNUNET_SCHEDULER_shutdown (); | ||
1239 | ret = 1; | 1425 | ret = 1; |
1426 | finish_command (); | ||
1240 | return; | 1427 | return; |
1241 | } | 1428 | } |
1242 | add = 1; | 1429 | add = 1; |
@@ -1258,8 +1445,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1258 | _ ("Missing option `%s' for operation `%s'\n"), | 1445 | _ ("Missing option `%s' for operation `%s'\n"), |
1259 | "-z", | 1446 | "-z", |
1260 | _ ("add")); | 1447 | _ ("add")); |
1261 | GNUNET_SCHEDULER_shutdown (); | ||
1262 | ret = 1; | 1448 | ret = 1; |
1449 | finish_command (); | ||
1263 | return; | 1450 | return; |
1264 | } | 1451 | } |
1265 | if (NULL == name) | 1452 | if (NULL == name) |
@@ -1268,8 +1455,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1268 | _ ("Missing option `%s' for operation `%s'\n"), | 1455 | _ ("Missing option `%s' for operation `%s'\n"), |
1269 | "-n", | 1456 | "-n", |
1270 | _ ("add")); | 1457 | _ ("add")); |
1271 | GNUNET_SCHEDULER_shutdown (); | ||
1272 | ret = 1; | 1458 | ret = 1; |
1459 | finish_command (); | ||
1273 | return; | 1460 | return; |
1274 | } | 1461 | } |
1275 | if (NULL == typestring) | 1462 | if (NULL == typestring) |
@@ -1278,16 +1465,16 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1278 | _ ("Missing option `%s' for operation `%s'\n"), | 1465 | _ ("Missing option `%s' for operation `%s'\n"), |
1279 | "-t", | 1466 | "-t", |
1280 | _ ("add")); | 1467 | _ ("add")); |
1281 | GNUNET_SCHEDULER_shutdown (); | ||
1282 | ret = 1; | 1468 | ret = 1; |
1469 | finish_command (); | ||
1283 | return; | 1470 | return; |
1284 | } | 1471 | } |
1285 | type = GNUNET_GNSRECORD_typename_to_number (typestring); | 1472 | type = GNUNET_GNSRECORD_typename_to_number (typestring); |
1286 | if (UINT32_MAX == type) | 1473 | if (UINT32_MAX == type) |
1287 | { | 1474 | { |
1288 | fprintf (stderr, _ ("Unsupported type `%s'\n"), typestring); | 1475 | fprintf (stderr, _ ("Unsupported type `%s'\n"), typestring); |
1289 | GNUNET_SCHEDULER_shutdown (); | ||
1290 | ret = 1; | 1476 | ret = 1; |
1477 | finish_command (); | ||
1291 | return; | 1478 | return; |
1292 | } | 1479 | } |
1293 | if ((GNUNET_DNSPARSER_TYPE_SRV == type) || | 1480 | if ((GNUNET_DNSPARSER_TYPE_SRV == type) || |
@@ -1297,8 +1484,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1297 | fprintf (stderr, | 1484 | fprintf (stderr, |
1298 | _ ("For DNS record types `SRV', `TLSA' and `OPENPGPKEY'")); | 1485 | _ ("For DNS record types `SRV', `TLSA' and `OPENPGPKEY'")); |
1299 | fprintf (stderr, ", please use a `BOX' record instead\n"); | 1486 | fprintf (stderr, ", please use a `BOX' record instead\n"); |
1300 | GNUNET_SCHEDULER_shutdown (); | ||
1301 | ret = 1; | 1487 | ret = 1; |
1488 | finish_command (); | ||
1302 | return; | 1489 | return; |
1303 | } | 1490 | } |
1304 | if (NULL == value) | 1491 | if (NULL == value) |
@@ -1308,7 +1495,7 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1308 | "-V", | 1495 | "-V", |
1309 | _ ("add")); | 1496 | _ ("add")); |
1310 | ret = 1; | 1497 | ret = 1; |
1311 | GNUNET_SCHEDULER_shutdown (); | 1498 | finish_command (); |
1312 | return; | 1499 | return; |
1313 | } | 1500 | } |
1314 | if (GNUNET_OK != | 1501 | if (GNUNET_OK != |
@@ -1318,8 +1505,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1318 | _ ("Value `%s' invalid for record type `%s'\n"), | 1505 | _ ("Value `%s' invalid for record type `%s'\n"), |
1319 | value, | 1506 | value, |
1320 | typestring); | 1507 | typestring); |
1321 | GNUNET_SCHEDULER_shutdown (); | ||
1322 | ret = 1; | 1508 | ret = 1; |
1509 | finish_command (); | ||
1323 | return; | 1510 | return; |
1324 | } | 1511 | } |
1325 | if (NULL == expirationstring) | 1512 | if (NULL == expirationstring) |
@@ -1328,15 +1515,15 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1328 | _ ("Missing option `%s' for operation `%s'\n"), | 1515 | _ ("Missing option `%s' for operation `%s'\n"), |
1329 | "-e", | 1516 | "-e", |
1330 | _ ("add")); | 1517 | _ ("add")); |
1331 | GNUNET_SCHEDULER_shutdown (); | ||
1332 | ret = 1; | 1518 | ret = 1; |
1519 | finish_command (); | ||
1333 | return; | 1520 | return; |
1334 | } | 1521 | } |
1335 | if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) | 1522 | if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) |
1336 | { | 1523 | { |
1337 | fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); | 1524 | fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); |
1338 | GNUNET_SCHEDULER_shutdown (); | ||
1339 | ret = 1; | 1525 | ret = 1; |
1526 | finish_command (); | ||
1340 | return; | 1527 | return; |
1341 | } | 1528 | } |
1342 | add_qe = GNUNET_NAMESTORE_records_lookup (ns, | 1529 | add_qe = GNUNET_NAMESTORE_records_lookup (ns, |
@@ -1355,8 +1542,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1355 | _ ("Missing option `%s' for operation `%s'\n"), | 1542 | _ ("Missing option `%s' for operation `%s'\n"), |
1356 | "-z", | 1543 | "-z", |
1357 | _ ("del")); | 1544 | _ ("del")); |
1358 | GNUNET_SCHEDULER_shutdown (); | ||
1359 | ret = 1; | 1545 | ret = 1; |
1546 | finish_command (); | ||
1360 | return; | 1547 | return; |
1361 | } | 1548 | } |
1362 | if (NULL == name) | 1549 | if (NULL == name) |
@@ -1365,8 +1552,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1365 | _ ("Missing option `%s' for operation `%s'\n"), | 1552 | _ ("Missing option `%s' for operation `%s'\n"), |
1366 | "-n", | 1553 | "-n", |
1367 | _ ("del")); | 1554 | _ ("del")); |
1368 | GNUNET_SCHEDULER_shutdown (); | ||
1369 | ret = 1; | 1555 | ret = 1; |
1556 | finish_command (); | ||
1370 | return; | 1557 | return; |
1371 | } | 1558 | } |
1372 | del_qe = GNUNET_NAMESTORE_records_lookup (ns, | 1559 | del_qe = GNUNET_NAMESTORE_records_lookup (ns, |
@@ -1398,8 +1585,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1398 | _ ("Missing option `%s' for operation `%s'\n"), | 1585 | _ ("Missing option `%s' for operation `%s'\n"), |
1399 | "-z", | 1586 | "-z", |
1400 | _ ("purge-zone")); | 1587 | _ ("purge-zone")); |
1401 | GNUNET_SCHEDULER_shutdown (); | ||
1402 | ret = 1; | 1588 | ret = 1; |
1589 | finish_command (); | ||
1403 | return; | 1590 | return; |
1404 | } | 1591 | } |
1405 | list_it = GNUNET_NAMESTORE_zone_iteration_start2 (ns, | 1592 | list_it = GNUNET_NAMESTORE_zone_iteration_start2 (ns, |
@@ -1423,8 +1610,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1423 | _ ("Missing option `%s' for operation `%s'\n"), | 1610 | _ ("Missing option `%s' for operation `%s'\n"), |
1424 | "-z", | 1611 | "-z", |
1425 | _ ("list")); | 1612 | _ ("list")); |
1426 | GNUNET_SCHEDULER_shutdown (); | ||
1427 | ret = 1; | 1613 | ret = 1; |
1614 | finish_command (); | ||
1428 | return; | 1615 | return; |
1429 | } | 1616 | } |
1430 | get_qe = GNUNET_NAMESTORE_records_lookup (ns, | 1617 | get_qe = GNUNET_NAMESTORE_records_lookup (ns, |
@@ -1457,8 +1644,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1457 | _ ("Missing option `%s' for operation `%s'\n"), | 1644 | _ ("Missing option `%s' for operation `%s'\n"), |
1458 | "-z", | 1645 | "-z", |
1459 | _ ("reverse-pkey")); | 1646 | _ ("reverse-pkey")); |
1460 | GNUNET_SCHEDULER_shutdown (); | ||
1461 | ret = 1; | 1647 | ret = 1; |
1648 | finish_command (); | ||
1462 | return; | 1649 | return; |
1463 | } | 1650 | } |
1464 | if (GNUNET_OK != | 1651 | if (GNUNET_OK != |
@@ -1468,7 +1655,9 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1468 | fprintf (stderr, | 1655 | fprintf (stderr, |
1469 | _ ("Invalid public key for reverse lookup `%s'\n"), | 1656 | _ ("Invalid public key for reverse lookup `%s'\n"), |
1470 | reverse_pkey); | 1657 | reverse_pkey); |
1471 | GNUNET_SCHEDULER_shutdown (); | 1658 | ret = 1; |
1659 | finish_command (); | ||
1660 | return; | ||
1472 | } | 1661 | } |
1473 | reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns, | 1662 | reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns, |
1474 | &zone_pkey, | 1663 | &zone_pkey, |
@@ -1489,8 +1678,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1489 | _ ("Missing option `%s' for operation `%s'\n"), | 1678 | _ ("Missing option `%s' for operation `%s'\n"), |
1490 | "-z", | 1679 | "-z", |
1491 | _ ("uri")); | 1680 | _ ("uri")); |
1492 | GNUNET_SCHEDULER_shutdown (); | ||
1493 | ret = 1; | 1681 | ret = 1; |
1682 | finish_command (); | ||
1494 | return; | 1683 | return; |
1495 | } | 1684 | } |
1496 | 1685 | ||
@@ -1502,8 +1691,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1502 | GNUNET_IDENTITY_public_key_from_string (sh, &pkey))) | 1691 | GNUNET_IDENTITY_public_key_from_string (sh, &pkey))) |
1503 | { | 1692 | { |
1504 | fprintf (stderr, _ ("Invalid URI `%s'\n"), uri); | 1693 | fprintf (stderr, _ ("Invalid URI `%s'\n"), uri); |
1505 | GNUNET_SCHEDULER_shutdown (); | ||
1506 | ret = 1; | 1694 | ret = 1; |
1695 | finish_command (); | ||
1507 | return; | 1696 | return; |
1508 | } | 1697 | } |
1509 | if (NULL == expirationstring) | 1698 | if (NULL == expirationstring) |
@@ -1512,15 +1701,15 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1512 | _ ("Missing option `%s' for operation `%s'\n"), | 1701 | _ ("Missing option `%s' for operation `%s'\n"), |
1513 | "-e", | 1702 | "-e", |
1514 | _ ("add")); | 1703 | _ ("add")); |
1515 | GNUNET_SCHEDULER_shutdown (); | ||
1516 | ret = 1; | 1704 | ret = 1; |
1705 | finish_command (); | ||
1517 | return; | 1706 | return; |
1518 | } | 1707 | } |
1519 | if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) | 1708 | if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) |
1520 | { | 1709 | { |
1521 | fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); | 1710 | fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); |
1522 | GNUNET_SCHEDULER_shutdown (); | ||
1523 | ret = 1; | 1711 | ret = 1; |
1712 | finish_command (); | ||
1524 | return; | 1713 | return; |
1525 | } | 1714 | } |
1526 | memset (&rd, 0, sizeof(rd)); | 1715 | memset (&rd, 0, sizeof(rd)); |
@@ -1556,34 +1745,182 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1556 | } | 1745 | } |
1557 | } | 1746 | } |
1558 | 1747 | ||
1748 | #define MAX_LINE_LEN 4086 | ||
1749 | |||
1750 | #define MAX_ARGS 20 | ||
1559 | 1751 | ||
1560 | /** | ||
1561 | * Callback invoked from identity service with ego information. | ||
1562 | * An @a ego of NULL means the ego was not found. | ||
1563 | * | ||
1564 | * @param cls closure with the configuration | ||
1565 | * @param ego an ego known to identity service, or NULL | ||
1566 | */ | ||
1567 | static void | 1752 | static void |
1568 | identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | 1753 | process_command_stdin () |
1569 | { | 1754 | { |
1570 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 1755 | struct EgoEntry *ego_entry; |
1756 | char buf[MAX_LINE_LEN]; | ||
1757 | char *tmp_argv[MAX_ARGS]; | ||
1758 | unsigned int tmp_argc = 0; | ||
1759 | char *tmp; | ||
1760 | struct GNUNET_GETOPT_CommandLineOption options[] = | ||
1761 | { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add), | ||
1762 | GNUNET_GETOPT_option_flag ('d', | ||
1763 | "delete", | ||
1764 | gettext_noop ("delete record"), | ||
1765 | &del), | ||
1766 | GNUNET_GETOPT_option_flag ('D', | ||
1767 | "display", | ||
1768 | gettext_noop ("display records"), | ||
1769 | &list), | ||
1770 | GNUNET_GETOPT_option_flag ('S', | ||
1771 | "from-stdin", | ||
1772 | gettext_noop ("read commands from stdin"), | ||
1773 | &read_from_stdin), | ||
1774 | GNUNET_GETOPT_option_string ( | ||
1775 | 'e', | ||
1776 | "expiration", | ||
1777 | "TIME", | ||
1778 | gettext_noop ( | ||
1779 | "expiration time for record to use (for adding only), \"never\" is possible"), | ||
1780 | &expirationstring), | ||
1781 | GNUNET_GETOPT_option_string ('i', | ||
1782 | "nick", | ||
1783 | "NICKNAME", | ||
1784 | gettext_noop ( | ||
1785 | "set the desired nick name for the zone"), | ||
1786 | &nickstring), | ||
1787 | GNUNET_GETOPT_option_flag ('m', | ||
1788 | "monitor", | ||
1789 | gettext_noop ( | ||
1790 | "monitor changes in the namestore"), | ||
1791 | &monitor), | ||
1792 | GNUNET_GETOPT_option_string ('n', | ||
1793 | "name", | ||
1794 | "NAME", | ||
1795 | gettext_noop ( | ||
1796 | "name of the record to add/delete/display"), | ||
1797 | &name), | ||
1798 | GNUNET_GETOPT_option_string ('r', | ||
1799 | "reverse", | ||
1800 | "PKEY", | ||
1801 | gettext_noop ( | ||
1802 | "determine our name for the given PKEY"), | ||
1803 | &reverse_pkey), | ||
1804 | multirecord_option ( | ||
1805 | 'R', | ||
1806 | "replace", | ||
1807 | "RECORDLINE", | ||
1808 | gettext_noop ( | ||
1809 | "set record set to values given by (possibly multiple) RECORDLINES; can be specified multiple times"), | ||
1810 | &recordset), | ||
1811 | GNUNET_GETOPT_option_string ('t', | ||
1812 | "type", | ||
1813 | "TYPE", | ||
1814 | gettext_noop ( | ||
1815 | "type of the record to add/delete/display"), | ||
1816 | &typestring), | ||
1817 | GNUNET_GETOPT_option_string ('u', | ||
1818 | "uri", | ||
1819 | "URI", | ||
1820 | gettext_noop ("URI to import into our zone"), | ||
1821 | &uri), | ||
1822 | GNUNET_GETOPT_option_string ('V', | ||
1823 | "value", | ||
1824 | "VALUE", | ||
1825 | gettext_noop ( | ||
1826 | "value of the record to add/delete"), | ||
1827 | &value), | ||
1828 | GNUNET_GETOPT_option_flag ('p', | ||
1829 | "public", | ||
1830 | gettext_noop ("create or list public record"), | ||
1831 | &is_public), | ||
1832 | GNUNET_GETOPT_option_flag ('o', | ||
1833 | "omit-private", | ||
1834 | gettext_noop ("omit private records"), | ||
1835 | &omit_private), | ||
1836 | GNUNET_GETOPT_option_flag ('T', | ||
1837 | "include-maintenance", | ||
1838 | gettext_noop ( | ||
1839 | "do not filter maintenance records"), | ||
1840 | &include_maintenance), | ||
1841 | GNUNET_GETOPT_option_flag ('P', | ||
1842 | "purge-orphans", | ||
1843 | gettext_noop ( | ||
1844 | "purge namestore of all orphans"), | ||
1845 | &purge_orphaned), | ||
1846 | GNUNET_GETOPT_option_flag ('O', | ||
1847 | "list-orphans", | ||
1848 | gettext_noop ( | ||
1849 | "show private key for orphaned records for recovery using `gnunet-identity -C -P <key>'. Use in combination with --display"), | ||
1850 | &list_orphaned), | ||
1851 | GNUNET_GETOPT_option_flag ('X', | ||
1852 | "purge-zone-records", | ||
1853 | gettext_noop ( | ||
1854 | "delete all records in specified zone"), | ||
1855 | &purge_zone), | ||
1856 | GNUNET_GETOPT_option_flag ( | ||
1857 | 's', | ||
1858 | "shadow", | ||
1859 | gettext_noop ( | ||
1860 | "create shadow record (only valid if all other records of the same type have expired"), | ||
1861 | &is_shadow), | ||
1862 | GNUNET_GETOPT_option_string ('z', | ||
1863 | "zone", | ||
1864 | "EGO", | ||
1865 | gettext_noop ( | ||
1866 | "name of the ego controlling the zone"), | ||
1867 | &ego_name), | ||
1868 | GNUNET_GETOPT_OPTION_END }; | ||
1571 | 1869 | ||
1572 | el = NULL; | ||
1573 | 1870 | ||
1574 | if (NULL == ego) | 1871 | if (NULL == fgets (buf, sizeof (buf), stdin)) |
1575 | { | 1872 | { |
1576 | if (NULL != ego_name) | 1873 | ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL); |
1577 | { | 1874 | return; |
1578 | fprintf (stderr, | 1875 | } |
1579 | _ ("Ego `%s' not known to identity service\n"), | 1876 | if (buf[strlen (buf) - 1] == '\n') |
1580 | ego_name); | 1877 | buf[strlen (buf) - 1] = '\0'; |
1581 | } | 1878 | /* We need to build a char *const *argv here */ |
1879 | /* I guess strtok on space */ | ||
1880 | tmp = strtok (buf, " "); | ||
1881 | if (NULL == tmp) | ||
1882 | { | ||
1883 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1884 | "Error parsing line %s\n", buf); | ||
1582 | GNUNET_SCHEDULER_shutdown (); | 1885 | GNUNET_SCHEDULER_shutdown (); |
1583 | ret = -1; | ||
1584 | return; | 1886 | return; |
1585 | } | 1887 | } |
1586 | zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); | 1888 | tmp_argv[0] = tmp; |
1889 | tmp_argc = 1; | ||
1890 | while (NULL != (tmp = strtok (NULL, " "))) | ||
1891 | { | ||
1892 | tmp_argv[tmp_argc] = tmp; | ||
1893 | tmp_argc++; | ||
1894 | } | ||
1895 | GNUNET_GETOPT_run ("gnunet-namestore", options, tmp_argc, tmp_argv); | ||
1896 | for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) | ||
1897 | { | ||
1898 | if (0 != strcmp (ego_entry->identifier, ego_name)) | ||
1899 | continue; | ||
1900 | zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | ||
1901 | break; | ||
1902 | } | ||
1903 | run_with_zone_pkey (cfg); | ||
1904 | } | ||
1905 | |||
1906 | |||
1907 | static void | ||
1908 | begin_cb (void *cls, enum GNUNET_ErrorCode ec) | ||
1909 | { | ||
1910 | ns_qe = NULL; | ||
1911 | if (GNUNET_EC_NONE != ec) | ||
1912 | { | ||
1913 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1914 | "Failed to start transaction: %s\n", | ||
1915 | GNUNET_ErrorCode_get_hint (ec)); | ||
1916 | GNUNET_SCHEDULER_shutdown (); | ||
1917 | return; | ||
1918 | } | ||
1919 | if (read_from_stdin) | ||
1920 | { | ||
1921 | process_command_stdin (); | ||
1922 | return; | ||
1923 | } | ||
1587 | run_with_zone_pkey (cfg); | 1924 | run_with_zone_pkey (cfg); |
1588 | } | 1925 | } |
1589 | 1926 | ||
@@ -1606,7 +1943,6 @@ id_connect_cb (void *cls, | |||
1606 | void **ctx, | 1943 | void **ctx, |
1607 | const char *name) | 1944 | const char *name) |
1608 | { | 1945 | { |
1609 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | ||
1610 | struct GNUNET_IDENTITY_PublicKey pk; | 1946 | struct GNUNET_IDENTITY_PublicKey pk; |
1611 | struct EgoEntry *ego_entry; | 1947 | struct EgoEntry *ego_entry; |
1612 | 1948 | ||
@@ -1621,17 +1957,20 @@ id_connect_cb (void *cls, | |||
1621 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, | 1957 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, |
1622 | ego_tail, | 1958 | ego_tail, |
1623 | ego_entry); | 1959 | ego_entry); |
1960 | if ((NULL != ego_name) && | ||
1961 | (0 == strcmp (name, ego_name))) | ||
1962 | zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
1624 | return; | 1963 | return; |
1625 | } | 1964 | } |
1626 | if (NULL != ego) | 1965 | if (NULL != ego) |
1627 | return; | 1966 | return; |
1628 | if (NULL == ego_name) | 1967 | ns_qe = GNUNET_NAMESTORE_transaction_begin (ns, &begin_cb, (void *) cfg); |
1629 | run_with_zone_pkey (cfg); | ||
1630 | else | ||
1631 | el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &identity_cb, (void *) cfg); | ||
1632 | } | 1968 | } |
1633 | 1969 | ||
1634 | 1970 | ||
1971 | |||
1972 | |||
1973 | |||
1635 | /** | 1974 | /** |
1636 | * Main function that will be run. | 1975 | * Main function that will be run. |
1637 | * | 1976 | * |
@@ -1644,202 +1983,36 @@ static void | |||
1644 | run (void *cls, | 1983 | run (void *cls, |
1645 | char *const *args, | 1984 | char *const *args, |
1646 | const char *cfgfile, | 1985 | const char *cfgfile, |
1647 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 1986 | const struct GNUNET_CONFIGURATION_Handle *_cfg) |
1648 | { | 1987 | { |
1649 | const char *pkey_str; | ||
1650 | |||
1651 | (void) cls; | 1988 | (void) cls; |
1652 | (void) args; | 1989 | (void) args; |
1653 | (void) cfgfile; | 1990 | (void) cfgfile; |
1991 | cfg = _cfg; | ||
1654 | if (NULL != args[0]) | 1992 | if (NULL != args[0]) |
1655 | GNUNET_log ( | 1993 | GNUNET_log ( |
1656 | GNUNET_ERROR_TYPE_WARNING, | 1994 | GNUNET_ERROR_TYPE_WARNING, |
1657 | _ ("Superfluous command line arguments (starting with `%s') ignored\n"), | 1995 | _ ("Superfluous command line arguments (starting with `%s') ignored\n"), |
1658 | args[0]); | 1996 | args[0]); |
1659 | if ((NULL != args[0]) && (NULL == uri)) | ||
1660 | uri = GNUNET_strdup (args[0]); | ||
1661 | 1997 | ||
1662 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, (void *) cfg); | 1998 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, (void *) cfg); |
1663 | pkey_str = getenv ("GNUNET_NAMESTORE_EGO_PRIVATE_KEY"); | 1999 | ns = GNUNET_NAMESTORE_connect (cfg); |
1664 | if (NULL != pkey_str) | 2000 | if (NULL == ns) |
1665 | { | 2001 | { |
1666 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (pkey_str, | 2002 | fprintf (stderr, _ ("Failed to connect to namestore\n")); |
1667 | strlen (pkey_str), | 2003 | GNUNET_SCHEDULER_shutdown (); |
1668 | &zone_pkey, | ||
1669 | sizeof(zone_pkey))) | ||
1670 | { | ||
1671 | fprintf (stderr, | ||
1672 | "Malformed private key `%s' in $%s\n", | ||
1673 | pkey_str, | ||
1674 | "GNUNET_NAMESTORE_EGO_PRIVATE_KEY"); | ||
1675 | ret = 1; | ||
1676 | GNUNET_SCHEDULER_shutdown (); | ||
1677 | return; | ||
1678 | } | ||
1679 | run_with_zone_pkey (cfg); | ||
1680 | return; | 2004 | return; |
1681 | } | 2005 | } |
1682 | idh = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, (void *) cfg); | 2006 | idh = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, (void *) cfg); |
1683 | if (NULL == idh) | 2007 | if (NULL == idh) |
1684 | fprintf (stderr, _ ("Cannot connect to identity service\n")); | ||
1685 | ret = -1; | ||
1686 | } | ||
1687 | |||
1688 | |||
1689 | /** | ||
1690 | * Command-line option parser function that allows the user to specify | ||
1691 | * a complete record as one argument for adding/removing. A pointer | ||
1692 | * to the head of the list of record sets must be passed as the "scls" | ||
1693 | * argument. | ||
1694 | * | ||
1695 | * @param ctx command line processor context | ||
1696 | * @param scls must be of type "struct GNUNET_FS_Uri **" | ||
1697 | * @param option name of the option (typically 'R') | ||
1698 | * @param value command line argument given; format is | ||
1699 | * "TTL TYPE FLAGS VALUE" where TTL is an expiration time (rel or abs), | ||
1700 | * always given in seconds (without the unit), | ||
1701 | * TYPE is a DNS/GNS record type, FLAGS is either "n" for no flags or | ||
1702 | * a combination of 's' (shadow) and 'p' (public) and VALUE is the | ||
1703 | * value (in human-readable format) | ||
1704 | * @return #GNUNET_OK on success | ||
1705 | */ | ||
1706 | static int | ||
1707 | multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | ||
1708 | void *scls, | ||
1709 | const char *option, | ||
1710 | const char *value) | ||
1711 | { | ||
1712 | struct RecordSetEntry **head = scls; | ||
1713 | struct RecordSetEntry *r; | ||
1714 | struct GNUNET_GNSRECORD_Data record; | ||
1715 | char *cp; | ||
1716 | char *tok; | ||
1717 | char *saveptr; | ||
1718 | int etime_is_rel; | ||
1719 | void *raw_data; | ||
1720 | |||
1721 | (void) ctx; | ||
1722 | (void) option; | ||
1723 | cp = GNUNET_strdup (value); | ||
1724 | tok = strtok_r (cp, " ", &saveptr); | ||
1725 | if (NULL == tok) | ||
1726 | { | ||
1727 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1728 | _ ("Empty record line argument is not allowed.\n")); | ||
1729 | GNUNET_free (cp); | ||
1730 | return GNUNET_SYSERR; | ||
1731 | } | ||
1732 | { | 2008 | { |
1733 | char *etime_in_s; | 2009 | ret = -1; |
1734 | 2010 | fprintf (stderr, _ ("Cannot connect to identity service\n")); | |
1735 | GNUNET_asprintf (&etime_in_s, "%s s", tok); | 2011 | GNUNET_SCHEDULER_shutdown (); |
1736 | if (GNUNET_OK != | ||
1737 | parse_expiration (etime_in_s, &etime_is_rel, &record.expiration_time)) | ||
1738 | { | ||
1739 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1740 | _ ("Invalid expiration time `%s' (must be without unit)\n"), | ||
1741 | tok); | ||
1742 | GNUNET_free (cp); | ||
1743 | GNUNET_free (etime_in_s); | ||
1744 | return GNUNET_SYSERR; | ||
1745 | } | ||
1746 | GNUNET_free (etime_in_s); | ||
1747 | } | ||
1748 | tok = strtok_r (NULL, " ", &saveptr); | ||
1749 | if (NULL == tok) | ||
1750 | { | ||
1751 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1752 | _ ("Missing entries in record line `%s'.\n"), | ||
1753 | value); | ||
1754 | GNUNET_free (cp); | ||
1755 | return GNUNET_SYSERR; | ||
1756 | } | ||
1757 | record.record_type = GNUNET_GNSRECORD_typename_to_number (tok); | ||
1758 | if (UINT32_MAX == record.record_type) | ||
1759 | { | ||
1760 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Unknown record type `%s'\n"), tok); | ||
1761 | GNUNET_free (cp); | ||
1762 | return GNUNET_SYSERR; | ||
1763 | } | ||
1764 | tok = strtok_r (NULL, " ", &saveptr); | ||
1765 | if (NULL == tok) | ||
1766 | { | ||
1767 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1768 | _ ("Missing entries in record line `%s'.\n"), | ||
1769 | value); | ||
1770 | GNUNET_free (cp); | ||
1771 | return GNUNET_SYSERR; | ||
1772 | } | ||
1773 | record.flags = GNUNET_GNSRECORD_RF_NONE; | ||
1774 | if (etime_is_rel) | ||
1775 | record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1776 | if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */ | ||
1777 | record.flags |= GNUNET_GNSRECORD_RF_PRIVATE; | ||
1778 | if (NULL != strchr (tok, (unsigned char) 's')) | ||
1779 | record.flags |= GNUNET_GNSRECORD_RF_SHADOW; | ||
1780 | /* find beginning of record value */ | ||
1781 | tok = strchr (&value[tok - cp], (unsigned char) ' '); | ||
1782 | if (NULL == tok) | ||
1783 | { | ||
1784 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1785 | _ ("Missing entries in record line `%s'.\n"), | ||
1786 | value); | ||
1787 | GNUNET_free (cp); | ||
1788 | return GNUNET_SYSERR; | ||
1789 | } | ||
1790 | GNUNET_free (cp); | ||
1791 | tok++; /* skip space */ | ||
1792 | if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record.record_type, | ||
1793 | tok, | ||
1794 | &raw_data, | ||
1795 | &record.data_size)) | ||
1796 | { | ||
1797 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1798 | _ ("Invalid record data for type %s: `%s'.\n"), | ||
1799 | GNUNET_GNSRECORD_number_to_typename (record.record_type), | ||
1800 | tok); | ||
1801 | return GNUNET_SYSERR; | ||
1802 | } | 2012 | } |
1803 | |||
1804 | r = GNUNET_malloc (sizeof(struct RecordSetEntry) + record.data_size); | ||
1805 | r->next = *head; | ||
1806 | record.data = &r[1]; | ||
1807 | memcpy (&r[1], raw_data, record.data_size); | ||
1808 | GNUNET_free (raw_data); | ||
1809 | r->record = record; | ||
1810 | *head = r; | ||
1811 | return GNUNET_OK; | ||
1812 | } | 2013 | } |
1813 | 2014 | ||
1814 | 2015 | ||
1815 | /** | ||
1816 | * Allow user to specify keywords. | ||
1817 | * | ||
1818 | * @param shortName short name of the option | ||
1819 | * @param name long name of the option | ||
1820 | * @param argumentHelp help text for the option argument | ||
1821 | * @param description long help text for the option | ||
1822 | * @param[out] topKeywords set to the desired value | ||
1823 | */ | ||
1824 | struct GNUNET_GETOPT_CommandLineOption | ||
1825 | multirecord_option (char shortName, | ||
1826 | const char *name, | ||
1827 | const char *argumentHelp, | ||
1828 | const char *description, | ||
1829 | struct RecordSetEntry **rs) | ||
1830 | { | ||
1831 | struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName, | ||
1832 | .name = name, | ||
1833 | .argumentHelp = argumentHelp, | ||
1834 | .description = description, | ||
1835 | .require_argument = 1, | ||
1836 | .processor = | ||
1837 | &multirecord_process, | ||
1838 | .scls = (void *) rs }; | ||
1839 | |||
1840 | return clo; | ||
1841 | } | ||
1842 | |||
1843 | 2016 | ||
1844 | /** | 2017 | /** |
1845 | * The main function for gnunet-namestore. | 2018 | * The main function for gnunet-namestore. |
@@ -1851,6 +2024,7 @@ multirecord_option (char shortName, | |||
1851 | int | 2024 | int |
1852 | main (int argc, char *const *argv) | 2025 | main (int argc, char *const *argv) |
1853 | { | 2026 | { |
2027 | int lret; | ||
1854 | struct GNUNET_GETOPT_CommandLineOption options[] = | 2028 | struct GNUNET_GETOPT_CommandLineOption options[] = |
1855 | { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add), | 2029 | { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add), |
1856 | GNUNET_GETOPT_option_flag ('d', | 2030 | GNUNET_GETOPT_option_flag ('d', |
@@ -1861,6 +2035,10 @@ main (int argc, char *const *argv) | |||
1861 | "display", | 2035 | "display", |
1862 | gettext_noop ("display records"), | 2036 | gettext_noop ("display records"), |
1863 | &list), | 2037 | &list), |
2038 | GNUNET_GETOPT_option_flag ('S', | ||
2039 | "from-stdin", | ||
2040 | gettext_noop ("read commands from stdin"), | ||
2041 | &read_from_stdin), | ||
1864 | GNUNET_GETOPT_option_string ( | 2042 | GNUNET_GETOPT_option_string ( |
1865 | 'e', | 2043 | 'e', |
1866 | "expiration", | 2044 | "expiration", |
@@ -1956,7 +2134,7 @@ main (int argc, char *const *argv) | |||
1956 | "name of the ego controlling the zone"), | 2134 | "name of the ego controlling the zone"), |
1957 | &ego_name), | 2135 | &ego_name), |
1958 | GNUNET_GETOPT_OPTION_END }; | 2136 | GNUNET_GETOPT_OPTION_END }; |
1959 | int lret; | 2137 | |
1960 | 2138 | ||
1961 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 2139 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) |
1962 | return 2; | 2140 | return 2; |