diff options
Diffstat (limited to 'src/namestore/gnunet-namestore.c')
-rw-r--r-- | src/namestore/gnunet-namestore.c | 876 |
1 files changed, 503 insertions, 373 deletions
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c index 6444d446d..7288db902 100644 --- a/src/namestore/gnunet-namestore.c +++ b/src/namestore/gnunet-namestore.c | |||
@@ -27,11 +27,11 @@ | |||
27 | */ | 27 | */ |
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include <gnunet_util_lib.h> | 29 | #include <gnunet_util_lib.h> |
30 | #include <gnunet_dnsparser_lib.h> | ||
31 | #include <gnunet_identity_service.h> | 30 | #include <gnunet_identity_service.h> |
32 | #include <gnunet_gnsrecord_lib.h> | 31 | #include <gnunet_gnsrecord_lib.h> |
33 | #include <gnunet_gns_service.h> | 32 | #include <gnunet_gns_service.h> |
34 | #include <gnunet_namestore_service.h> | 33 | #include <gnunet_namestore_service.h> |
34 | #include <inttypes.h> | ||
35 | 35 | ||
36 | /** | 36 | /** |
37 | * The upper bound for the zone iteration interval | 37 | * The upper bound for the zone iteration interval |
@@ -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; |
@@ -134,11 +129,6 @@ static struct GNUNET_IDENTITY_Handle *idh; | |||
134 | static char *ego_name; | 129 | static char *ego_name; |
135 | 130 | ||
136 | /** | 131 | /** |
137 | * Desired action is to add a record. | ||
138 | */ | ||
139 | static int add; | ||
140 | |||
141 | /** | ||
142 | * Queue entry for the 'add-uri' operation. | 132 | * Queue entry for the 'add-uri' operation. |
143 | */ | 133 | */ |
144 | static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri; | 134 | static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri; |
@@ -168,6 +158,10 @@ static struct MarkedRecord *marked_head; | |||
168 | */ | 158 | */ |
169 | static struct MarkedRecord *marked_tail; | 159 | static struct MarkedRecord *marked_tail; |
170 | 160 | ||
161 | /** | ||
162 | * Configuration handle | ||
163 | */ | ||
164 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
171 | 165 | ||
172 | /** | 166 | /** |
173 | * Ego list | 167 | * Ego list |
@@ -180,14 +174,24 @@ static struct EgoEntry *ego_head; | |||
180 | static struct EgoEntry *ego_tail; | 174 | static struct EgoEntry *ego_tail; |
181 | 175 | ||
182 | /** | 176 | /** |
177 | * List iterator for the 'list' operation. | ||
178 | */ | ||
179 | static struct GNUNET_NAMESTORE_ZoneIterator *list_it; | ||
180 | |||
181 | /** | ||
182 | * Run in read from stdin mode. | ||
183 | */ | ||
184 | static int read_from_stdin; | ||
185 | |||
186 | /** | ||
183 | * Desired action is to list records. | 187 | * Desired action is to list records. |
184 | */ | 188 | */ |
185 | static int list; | 189 | static int list; |
186 | 190 | ||
187 | /** | 191 | /** |
188 | * List iterator for the 'list' operation. | 192 | * Desired action is to add a record. |
189 | */ | 193 | */ |
190 | static struct GNUNET_NAMESTORE_ZoneIterator *list_it; | 194 | static int add; |
191 | 195 | ||
192 | /** | 196 | /** |
193 | * Desired action is to remove a record. | 197 | * Desired action is to remove a record. |
@@ -200,7 +204,7 @@ static int del; | |||
200 | static int is_public; | 204 | static int is_public; |
201 | 205 | ||
202 | /** | 206 | /** |
203 | * Is record a shadow record (#GNUNET_GNSRECORD_RF_SHADOW_RECORD) | 207 | * Is record a shadow record (#GNUNET_GNSRECORD_RF_SHADOW) |
204 | */ | 208 | */ |
205 | static int is_shadow; | 209 | static int is_shadow; |
206 | 210 | ||
@@ -210,6 +214,12 @@ static int is_shadow; | |||
210 | static int omit_private; | 214 | static int omit_private; |
211 | 215 | ||
212 | /** | 216 | /** |
217 | * Output in recordline format | ||
218 | */ | ||
219 | static int output_recordline; | ||
220 | |||
221 | |||
222 | /** | ||
213 | * Purge zone contents | 223 | * Purge zone contents |
214 | */ | 224 | */ |
215 | static int purge_zone; | 225 | static int purge_zone; |
@@ -240,6 +250,11 @@ static struct GNUNET_NAMESTORE_QueueEntry *del_qe; | |||
240 | static struct GNUNET_NAMESTORE_QueueEntry *set_qe; | 250 | static struct GNUNET_NAMESTORE_QueueEntry *set_qe; |
241 | 251 | ||
242 | /** | 252 | /** |
253 | * Queue entry for begin/commit | ||
254 | */ | ||
255 | static struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
256 | |||
257 | /** | ||
243 | * Name of the records to add/list/remove. | 258 | * Name of the records to add/list/remove. |
244 | */ | 259 | */ |
245 | static char *name; | 260 | static char *name; |
@@ -325,37 +340,186 @@ static struct RecordSetEntry *recordset; | |||
325 | static struct GNUNET_SCHEDULER_Task *purge_task; | 340 | static struct GNUNET_SCHEDULER_Task *purge_task; |
326 | 341 | ||
327 | /** | 342 | /** |
328 | * Task run on shutdown. Cleans up everything. | 343 | * Parse expiration time. |
329 | * | 344 | * |
330 | * @param cls unused | 345 | * @param expirationstring text to parse |
346 | * @param[out] etime_is_rel set to #GNUNET_YES if time is relative | ||
347 | * @param[out] etime set to expiration time (abs or rel) | ||
348 | * @return #GNUNET_OK on success | ||
331 | */ | 349 | */ |
350 | static int | ||
351 | parse_expiration (const char *expirationstring, | ||
352 | int *etime_is_rel, | ||
353 | uint64_t *etime) | ||
354 | { | ||
355 | struct GNUNET_TIME_Relative etime_rel; | ||
356 | struct GNUNET_TIME_Absolute etime_abs; | ||
357 | |||
358 | if (0 == strcmp (expirationstring, "never")) | ||
359 | { | ||
360 | *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | ||
361 | *etime_is_rel = GNUNET_NO; | ||
362 | return GNUNET_OK; | ||
363 | } | ||
364 | if (GNUNET_OK == | ||
365 | GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel)) | ||
366 | { | ||
367 | *etime_is_rel = GNUNET_YES; | ||
368 | *etime = etime_rel.rel_value_us; | ||
369 | if (GNUNET_TIME_relative_cmp (etime_rel, <, WARN_RELATIVE_EXPIRATION_LIMIT)) | ||
370 | { | ||
371 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
372 | "Relative expiration times of less than %s are not recommended. To improve availability, consider increasing this value.\n", | ||
373 | GNUNET_STRINGS_relative_time_to_string ( | ||
374 | WARN_RELATIVE_EXPIRATION_LIMIT, GNUNET_NO)); | ||
375 | } | ||
376 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
377 | "Storing record with relative expiration time of %s\n", | ||
378 | GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO)); | ||
379 | return GNUNET_OK; | ||
380 | } | ||
381 | if (GNUNET_OK == | ||
382 | GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs)) | ||
383 | { | ||
384 | *etime_is_rel = GNUNET_NO; | ||
385 | *etime = etime_abs.abs_value_us; | ||
386 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
387 | "Storing record with absolute expiration time of %s\n", | ||
388 | GNUNET_STRINGS_absolute_time_to_string (etime_abs)); | ||
389 | return GNUNET_OK; | ||
390 | } | ||
391 | return GNUNET_SYSERR; | ||
392 | } | ||
393 | |||
394 | |||
395 | static int | ||
396 | parse_recordline (const char *line) | ||
397 | { | ||
398 | struct RecordSetEntry **head = &recordset; | ||
399 | struct RecordSetEntry *r; | ||
400 | struct GNUNET_GNSRECORD_Data record; | ||
401 | char *cp; | ||
402 | char *tok; | ||
403 | char *saveptr; | ||
404 | void *raw_data; | ||
405 | |||
406 | cp = GNUNET_strdup (line); | ||
407 | tok = strtok_r (cp, " ", &saveptr); | ||
408 | if (NULL == tok) | ||
409 | { | ||
410 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
411 | _ ("Missing entries in record line `%s'.\n"), | ||
412 | line); | ||
413 | GNUNET_free (cp); | ||
414 | return GNUNET_SYSERR; | ||
415 | } | ||
416 | record.record_type = GNUNET_GNSRECORD_typename_to_number (tok); | ||
417 | if (UINT32_MAX == record.record_type) | ||
418 | { | ||
419 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Unknown record type `%s'\n"), tok); | ||
420 | GNUNET_free (cp); | ||
421 | return GNUNET_SYSERR; | ||
422 | } | ||
423 | tok = strtok_r (NULL, " ", &saveptr); | ||
424 | if (NULL == tok) | ||
425 | { | ||
426 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
427 | _ ("Empty record line argument is not allowed.\n")); | ||
428 | GNUNET_free (cp); | ||
429 | return GNUNET_SYSERR; | ||
430 | } | ||
431 | if (1 != sscanf (tok, "%" SCNu64, &record.expiration_time)) | ||
432 | { | ||
433 | fprintf (stderr, | ||
434 | _ ("Error parsing expiration time %s.\n"), tok); | ||
435 | GNUNET_free (cp); | ||
436 | return GNUNET_SYSERR; | ||
437 | } | ||
438 | tok = strtok_r (NULL, " ", &saveptr); | ||
439 | if (NULL == tok) | ||
440 | { | ||
441 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
442 | _ ("Empty record line argument is not allowed.\n")); | ||
443 | GNUNET_free (cp); | ||
444 | return GNUNET_SYSERR; | ||
445 | } | ||
446 | record.flags = GNUNET_GNSRECORD_RF_NONE; | ||
447 | if (NULL != strchr (tok, (unsigned char) 'r')) | ||
448 | record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
449 | if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */ | ||
450 | record.flags |= GNUNET_GNSRECORD_RF_PRIVATE; | ||
451 | if (NULL != strchr (tok, (unsigned char) 'S')) | ||
452 | record.flags |= GNUNET_GNSRECORD_RF_SUPPLEMENTAL; | ||
453 | if (NULL != strchr (tok, (unsigned char) 's')) | ||
454 | record.flags |= GNUNET_GNSRECORD_RF_SHADOW; | ||
455 | if (NULL != strchr (tok, (unsigned char) 'C')) | ||
456 | record.flags |= GNUNET_GNSRECORD_RF_CRITICAL; | ||
457 | tok += strlen (tok) + 1; | ||
458 | if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record.record_type, | ||
459 | tok, | ||
460 | &raw_data, | ||
461 | &record.data_size)) | ||
462 | { | ||
463 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
464 | _ ("Invalid record data for type %s: `%s'.\n"), | ||
465 | GNUNET_GNSRECORD_number_to_typename (record.record_type), | ||
466 | tok); | ||
467 | return GNUNET_SYSERR; | ||
468 | } | ||
469 | |||
470 | r = GNUNET_malloc (sizeof(struct RecordSetEntry) + record.data_size); | ||
471 | r->next = *head; | ||
472 | record.data = &r[1]; | ||
473 | memcpy (&r[1], raw_data, record.data_size); | ||
474 | GNUNET_free (raw_data); | ||
475 | r->record = record; | ||
476 | *head = r; | ||
477 | return GNUNET_OK; | ||
478 | } | ||
479 | |||
332 | static void | 480 | static void |
333 | do_shutdown (void *cls) | 481 | reset_handles (void) |
334 | { | 482 | { |
335 | struct EgoEntry *ego_entry; | ||
336 | struct EgoEntry *ego_tmp; | ||
337 | struct MarkedRecord *mrec; | 483 | struct MarkedRecord *mrec; |
338 | struct MarkedRecord *mrec_tmp; | 484 | struct MarkedRecord *mrec_tmp; |
339 | (void) cls; | 485 | struct RecordSetEntry *rs_entry; |
486 | |||
487 | rs_entry = recordset; | ||
488 | while (NULL != (rs_entry = recordset)) | ||
489 | { | ||
490 | recordset = recordset->next; | ||
491 | GNUNET_free (rs_entry); | ||
492 | } | ||
493 | recordset = NULL; | ||
340 | if (NULL != ego_name) | 494 | if (NULL != ego_name) |
341 | { | 495 | { |
342 | GNUNET_free (ego_name); | 496 | GNUNET_free (ego_name); |
343 | ego_name = NULL; | 497 | ego_name = NULL; |
344 | } | 498 | } |
345 | if (NULL != purge_task) | 499 | if (NULL != name) |
346 | { | 500 | { |
347 | GNUNET_SCHEDULER_cancel (purge_task); | 501 | GNUNET_free (name); |
348 | purge_task = NULL; | 502 | name = NULL; |
349 | } | 503 | } |
350 | if (NULL != idh) | 504 | if (NULL != value) |
351 | { | 505 | { |
352 | GNUNET_IDENTITY_disconnect (idh); | 506 | GNUNET_free (value); |
353 | idh = NULL; | 507 | value = NULL; |
508 | } | ||
509 | if (NULL != uri) | ||
510 | { | ||
511 | GNUNET_free (uri); | ||
512 | uri = NULL; | ||
513 | } | ||
514 | if (NULL != expirationstring) | ||
515 | { | ||
516 | GNUNET_free (expirationstring); | ||
517 | expirationstring = NULL; | ||
354 | } | 518 | } |
355 | if (NULL != el) | 519 | if (NULL != purge_task) |
356 | { | 520 | { |
357 | GNUNET_IDENTITY_ego_lookup_cancel (el); | 521 | GNUNET_SCHEDULER_cancel (purge_task); |
358 | el = NULL; | 522 | purge_task = NULL; |
359 | } | 523 | } |
360 | for (mrec = marked_head; NULL != mrec;) | 524 | for (mrec = marked_head; NULL != mrec;) |
361 | { | 525 | { |
@@ -364,13 +528,6 @@ do_shutdown (void *cls) | |||
364 | GNUNET_free (mrec_tmp->name); | 528 | GNUNET_free (mrec_tmp->name); |
365 | GNUNET_free (mrec_tmp); | 529 | GNUNET_free (mrec_tmp); |
366 | } | 530 | } |
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) | 531 | if (NULL != list_it) |
375 | { | 532 | { |
376 | GNUNET_NAMESTORE_zone_iteration_stop (list_it); | 533 | GNUNET_NAMESTORE_zone_iteration_stop (list_it); |
@@ -401,17 +558,12 @@ do_shutdown (void *cls) | |||
401 | GNUNET_NAMESTORE_cancel (del_qe); | 558 | GNUNET_NAMESTORE_cancel (del_qe); |
402 | del_qe = NULL; | 559 | del_qe = NULL; |
403 | } | 560 | } |
404 | if (NULL != ns) | 561 | if (NULL != reverse_qe) |
405 | { | 562 | { |
406 | GNUNET_NAMESTORE_disconnect (ns); | 563 | GNUNET_NAMESTORE_cancel (reverse_qe); |
407 | ns = NULL; | 564 | reverse_qe = NULL; |
408 | } | 565 | } |
409 | memset (&zone_pkey, 0, sizeof(zone_pkey)); | 566 | memset (&zone_pkey, 0, sizeof(zone_pkey)); |
410 | if (NULL != uri) | ||
411 | { | ||
412 | GNUNET_free (uri); | ||
413 | uri = NULL; | ||
414 | } | ||
415 | if (NULL != zm) | 567 | if (NULL != zm) |
416 | { | 568 | { |
417 | GNUNET_NAMESTORE_zone_monitor_stop (zm); | 569 | GNUNET_NAMESTORE_zone_monitor_stop (zm); |
@@ -422,18 +574,83 @@ do_shutdown (void *cls) | |||
422 | GNUNET_free (data); | 574 | GNUNET_free (data); |
423 | data = NULL; | 575 | data = NULL; |
424 | } | 576 | } |
577 | if (NULL != typestring) | ||
578 | { | ||
579 | GNUNET_free (typestring); | ||
580 | typestring = NULL; | ||
581 | } | ||
582 | list = 0; | ||
583 | is_public = 0; | ||
584 | is_shadow = 0; | ||
585 | purge_zone = 0; | ||
425 | } | 586 | } |
426 | 587 | ||
427 | 588 | ||
589 | |||
428 | /** | 590 | /** |
429 | * Check if we are finished, and if so, perform shutdown. | 591 | * Task run on shutdown. Cleans up everything. |
592 | * | ||
593 | * @param cls unused | ||
430 | */ | 594 | */ |
431 | static void | 595 | static void |
432 | test_finished () | 596 | do_shutdown (void *cls) |
433 | { | 597 | { |
434 | if ((NULL == add_qe) && (NULL == add_qe_uri) && (NULL == get_qe) && | 598 | struct EgoEntry *ego_entry; |
435 | (NULL == del_qe) && (NULL == reverse_qe) && (NULL == list_it)) | 599 | struct EgoEntry *ego_tmp; |
436 | GNUNET_SCHEDULER_shutdown (); | 600 | (void) cls; |
601 | |||
602 | reset_handles (); | ||
603 | if (NULL != ns_qe) | ||
604 | { | ||
605 | GNUNET_NAMESTORE_cancel (ns_qe); | ||
606 | ns_qe = NULL; | ||
607 | } | ||
608 | if (NULL != ns) | ||
609 | { | ||
610 | GNUNET_NAMESTORE_disconnect (ns); | ||
611 | ns = NULL; | ||
612 | } | ||
613 | if (NULL != idh) | ||
614 | { | ||
615 | GNUNET_IDENTITY_disconnect (idh); | ||
616 | idh = NULL; | ||
617 | } | ||
618 | for (ego_entry = ego_head; NULL != ego_entry;) | ||
619 | { | ||
620 | ego_tmp = ego_entry; | ||
621 | ego_entry = ego_entry->next; | ||
622 | GNUNET_free (ego_tmp->identifier); | ||
623 | GNUNET_free (ego_tmp); | ||
624 | } | ||
625 | } | ||
626 | |||
627 | static void | ||
628 | commit_cb (void *cls, enum GNUNET_ErrorCode ec) | ||
629 | { | ||
630 | ns_qe = NULL; | ||
631 | if (GNUNET_EC_NONE != ec) | ||
632 | { | ||
633 | fprintf (stderr, "Failed to commit to namestore: `%s'\n", | ||
634 | GNUNET_ErrorCode_get_hint (ec)); | ||
635 | ret = 1; | ||
636 | } | ||
637 | GNUNET_SCHEDULER_shutdown (); | ||
638 | } | ||
639 | |||
640 | static void | ||
641 | process_command_stdin (); | ||
642 | |||
643 | |||
644 | static void | ||
645 | finish_command (void) | ||
646 | { | ||
647 | reset_handles (); | ||
648 | if (read_from_stdin) | ||
649 | { | ||
650 | process_command_stdin (); | ||
651 | return; | ||
652 | } | ||
653 | ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL); | ||
437 | } | 654 | } |
438 | 655 | ||
439 | 656 | ||
@@ -452,7 +669,7 @@ add_continuation (void *cls, enum GNUNET_ErrorCode ec) | |||
452 | ret = 1; | 669 | ret = 1; |
453 | } | 670 | } |
454 | ret = 0; | 671 | ret = 0; |
455 | test_finished (); | 672 | finish_command (); |
456 | } | 673 | } |
457 | 674 | ||
458 | 675 | ||
@@ -467,7 +684,7 @@ del_continuation (void *cls, enum GNUNET_ErrorCode ec) | |||
467 | _ ("Deleting record failed: %s\n"), GNUNET_ErrorCode_get_hint ( | 684 | _ ("Deleting record failed: %s\n"), GNUNET_ErrorCode_get_hint ( |
468 | ec)); | 685 | ec)); |
469 | } | 686 | } |
470 | test_finished (); | 687 | finish_command (); |
471 | } | 688 | } |
472 | 689 | ||
473 | static void | 690 | static void |
@@ -496,7 +713,7 @@ purge_next_record (void *cls) | |||
496 | if (NULL == marked_head) | 713 | if (NULL == marked_head) |
497 | { | 714 | { |
498 | ret = 0; | 715 | ret = 0; |
499 | test_finished (); | 716 | finish_command (); |
500 | return; | 717 | return; |
501 | } | 718 | } |
502 | mrec = marked_head; | 719 | mrec = marked_head; |
@@ -527,7 +744,7 @@ zone_iteration_finished (void *cls) | |||
527 | return; | 744 | return; |
528 | } | 745 | } |
529 | ret = 0; | 746 | ret = 0; |
530 | test_finished (); | 747 | finish_command (); |
531 | } | 748 | } |
532 | 749 | ||
533 | 750 | ||
@@ -541,7 +758,7 @@ zone_iteration_error_cb (void *cls) | |||
541 | list_it = NULL; | 758 | list_it = NULL; |
542 | fprintf (stderr, "Error iterating over zone\n"); | 759 | fprintf (stderr, "Error iterating over zone\n"); |
543 | ret = 1; | 760 | ret = 1; |
544 | test_finished (); | 761 | finish_command (); |
545 | } | 762 | } |
546 | 763 | ||
547 | static void | 764 | static void |
@@ -681,18 +898,33 @@ display_record (const struct GNUNET_IDENTITY_PrivateKey *zone_key, | |||
681 | at.abs_value_us = rd[i].expiration_time; | 898 | at.abs_value_us = rd[i].expiration_time; |
682 | ets = GNUNET_STRINGS_absolute_time_to_string (at); | 899 | ets = GNUNET_STRINGS_absolute_time_to_string (at); |
683 | } | 900 | } |
684 | fprintf (stdout, | 901 | char flgstr[16]; |
685 | "\t%s: %s (%s)\t%s\t%s\n", | 902 | sprintf (flgstr, "[%s%s%s%s%s]", |
686 | typestr, | 903 | (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE) ? "" : "p", |
687 | s, | 904 | (rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL) ? "S" : "", |
688 | ets, | 905 | (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION) ? "r" : "", |
689 | (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE" | 906 | (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW) ? "S" : "", |
907 | (rd[i].flags & GNUNET_GNSRECORD_RF_CRITICAL) ? "C" : ""); | ||
908 | if (output_recordline) | ||
909 | fprintf (stdout, | ||
910 | " %s %" PRIu64 " %s %s\n", | ||
911 | typestr, | ||
912 | rd[i].expiration_time, | ||
913 | flgstr, | ||
914 | s); | ||
915 | else | ||
916 | fprintf (stdout, | ||
917 | "\t%s: %s (%s)\t%s\t%s\n", | ||
918 | typestr, | ||
919 | s, | ||
920 | ets, | ||
921 | (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE" | ||
690 | : "PUBLIC", | 922 | : "PUBLIC", |
691 | (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) ? "SHADOW" | 923 | (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW)) ? "SHADOW" |
692 | : ""); | 924 | : ""); |
693 | GNUNET_free (s); | 925 | GNUNET_free (s); |
694 | } | 926 | } |
695 | fprintf (stdout, "%s", "\n"); | 927 | // fprintf (stdout, "%s", "\n"); |
696 | } | 928 | } |
697 | 929 | ||
698 | static void | 930 | static void |
@@ -797,7 +1029,7 @@ display_record_lookup (void *cls, | |||
797 | (void) zone_key; | 1029 | (void) zone_key; |
798 | get_qe = NULL; | 1030 | get_qe = NULL; |
799 | display_record (zone_key, rname, rd_len, rd); | 1031 | display_record (zone_key, rname, rd_len, rd); |
800 | test_finished (); | 1032 | finish_command (); |
801 | } | 1033 | } |
802 | 1034 | ||
803 | 1035 | ||
@@ -838,7 +1070,7 @@ lookup_error_cb (void *cls) | |||
838 | (void) cls; | 1070 | (void) cls; |
839 | get_qe = NULL; | 1071 | get_qe = NULL; |
840 | fprintf (stderr, "%s", "Failed to lookup record.\n"); | 1072 | fprintf (stderr, "%s", "Failed to lookup record.\n"); |
841 | test_finished (); | 1073 | finish_command (); |
842 | } | 1074 | } |
843 | 1075 | ||
844 | 1076 | ||
@@ -852,7 +1084,7 @@ add_error_cb (void *cls) | |||
852 | add_qe = NULL; | 1084 | add_qe = NULL; |
853 | GNUNET_break (0); | 1085 | GNUNET_break (0); |
854 | ret = 1; | 1086 | ret = 1; |
855 | test_finished (); | 1087 | finish_command (); |
856 | } | 1088 | } |
857 | 1089 | ||
858 | 1090 | ||
@@ -883,7 +1115,7 @@ get_existing_record (void *cls, | |||
883 | { | 1115 | { |
884 | GNUNET_break (0); | 1116 | GNUNET_break (0); |
885 | ret = 1; | 1117 | ret = 1; |
886 | test_finished (); | 1118 | finish_command (); |
887 | return; | 1119 | return; |
888 | } | 1120 | } |
889 | 1121 | ||
@@ -904,7 +1136,7 @@ get_existing_record (void *cls, | |||
904 | "A SOA record exists already under `%s', cannot add a second SOA to the same zone.\n"), | 1136 | "A SOA record exists already under `%s', cannot add a second SOA to the same zone.\n"), |
905 | rec_name); | 1137 | rec_name); |
906 | ret = 1; | 1138 | ret = 1; |
907 | test_finished (); | 1139 | finish_command (); |
908 | return; | 1140 | return; |
909 | } | 1141 | } |
910 | break; | 1142 | break; |
@@ -917,7 +1149,7 @@ get_existing_record (void *cls, | |||
917 | rde->data_size = data_size; | 1149 | rde->data_size = data_size; |
918 | rde->record_type = type; | 1150 | rde->record_type = type; |
919 | if (1 == is_shadow) | 1151 | if (1 == is_shadow) |
920 | rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; | 1152 | rde->flags |= GNUNET_GNSRECORD_RF_SHADOW; |
921 | if (1 != is_public) | 1153 | if (1 != is_public) |
922 | rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE; | 1154 | rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE; |
923 | rde->expiration_time = etime; | 1155 | rde->expiration_time = etime; |
@@ -974,7 +1206,7 @@ handle_reverse_lookup (void *cls, | |||
974 | fprintf (stdout, "%s\n", reverse_pkey); | 1206 | fprintf (stdout, "%s\n", reverse_pkey); |
975 | else | 1207 | else |
976 | fprintf (stdout, "%s.%s\n", label, ego_name); | 1208 | fprintf (stdout, "%s.%s\n", label, ego_name); |
977 | test_finished (); | 1209 | finish_command (); |
978 | } | 1210 | } |
979 | 1211 | ||
980 | 1212 | ||
@@ -988,7 +1220,7 @@ del_lookup_error_cb (void *cls) | |||
988 | del_qe = NULL; | 1220 | del_qe = NULL; |
989 | GNUNET_break (0); | 1221 | GNUNET_break (0); |
990 | ret = 1; | 1222 | ret = 1; |
991 | test_finished (); | 1223 | finish_command (); |
992 | } | 1224 | } |
993 | 1225 | ||
994 | 1226 | ||
@@ -1025,7 +1257,7 @@ del_monitor (void *cls, | |||
1025 | "There are no records under label `%s' that could be deleted.\n"), | 1257 | "There are no records under label `%s' that could be deleted.\n"), |
1026 | label); | 1258 | label); |
1027 | ret = 1; | 1259 | ret = 1; |
1028 | test_finished (); | 1260 | finish_command (); |
1029 | return; | 1261 | return; |
1030 | } | 1262 | } |
1031 | if ((NULL == value) && (NULL == typestring)) | 1263 | if ((NULL == value) && (NULL == typestring)) |
@@ -1067,7 +1299,7 @@ del_monitor (void *cls, | |||
1067 | _ ( | 1299 | _ ( |
1068 | "There are no records under label `%s' that match the request for deletion.\n"), | 1300 | "There are no records under label `%s' that match the request for deletion.\n"), |
1069 | label); | 1301 | label); |
1070 | test_finished (); | 1302 | finish_command (); |
1071 | return; | 1303 | return; |
1072 | } | 1304 | } |
1073 | /* delete everything but what we copied to 'rdx' */ | 1305 | /* delete everything but what we copied to 'rdx' */ |
@@ -1081,59 +1313,6 @@ del_monitor (void *cls, | |||
1081 | } | 1313 | } |
1082 | 1314 | ||
1083 | 1315 | ||
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 | 1316 | static void |
1138 | replace_cont (void *cls, enum GNUNET_ErrorCode ec) | 1317 | replace_cont (void *cls, enum GNUNET_ErrorCode ec) |
1139 | { | 1318 | { |
@@ -1147,7 +1326,7 @@ replace_cont (void *cls, enum GNUNET_ErrorCode ec) | |||
1147 | GNUNET_ErrorCode_get_hint (ec)); | 1326 | GNUNET_ErrorCode_get_hint (ec)); |
1148 | ret = 1; /* fail from 'main' */ | 1327 | ret = 1; /* fail from 'main' */ |
1149 | } | 1328 | } |
1150 | GNUNET_SCHEDULER_shutdown (); | 1329 | finish_command (); |
1151 | } | 1330 | } |
1152 | 1331 | ||
1153 | 1332 | ||
@@ -1173,14 +1352,7 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1173 | { | 1352 | { |
1174 | /* nothing more to be done */ | 1353 | /* nothing more to be done */ |
1175 | fprintf (stderr, _ ("No options given\n")); | 1354 | fprintf (stderr, _ ("No options given\n")); |
1176 | GNUNET_SCHEDULER_shutdown (); | 1355 | 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; | 1356 | return; |
1185 | } | 1357 | } |
1186 | 1358 | ||
@@ -1190,24 +1362,23 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1190 | unsigned int rd_count; | 1362 | unsigned int rd_count; |
1191 | struct GNUNET_GNSRECORD_Data *rd; | 1363 | struct GNUNET_GNSRECORD_Data *rd; |
1192 | 1364 | ||
1193 | if (NULL == ego_name) | 1365 | /* FIXME: We could easily support append and delete with this as well */ |
1366 | if (! add) | ||
1194 | { | 1367 | { |
1195 | fprintf (stderr, | 1368 | fprintf (stderr, _ ("Recordlines only work with option `%s'\n"), |
1196 | _ ("Missing option `%s' for operation `%s'\n"), | 1369 | "-a"); |
1197 | "-z", | ||
1198 | _ ("replace")); | ||
1199 | GNUNET_SCHEDULER_shutdown (); | ||
1200 | ret = 1; | 1370 | ret = 1; |
1371 | finish_command (); | ||
1201 | return; | 1372 | return; |
1202 | } | 1373 | } |
1203 | if (NULL == name) | 1374 | if (NULL == name) |
1204 | { | 1375 | { |
1205 | fprintf (stderr, | 1376 | fprintf (stderr, |
1206 | _ ("Missing option `%s' for operation `%s'\n"), | 1377 | _ ("Missing option `%s' for operation `%s'\n"), |
1207 | "-R", | 1378 | "-n", |
1208 | _ ("replace")); | 1379 | _ ("name")); |
1209 | GNUNET_SCHEDULER_shutdown (); | ||
1210 | ret = 1; | 1380 | ret = 1; |
1381 | finish_command (); | ||
1211 | return; | 1382 | return; |
1212 | } | 1383 | } |
1213 | rd_count = 0; | 1384 | rd_count = 0; |
@@ -1235,8 +1406,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1235 | if (0 == strlen (nickstring)) | 1406 | if (0 == strlen (nickstring)) |
1236 | { | 1407 | { |
1237 | fprintf (stderr, _ ("Invalid nick `%s'\n"), nickstring); | 1408 | fprintf (stderr, _ ("Invalid nick `%s'\n"), nickstring); |
1238 | GNUNET_SCHEDULER_shutdown (); | ||
1239 | ret = 1; | 1409 | ret = 1; |
1410 | finish_command (); | ||
1240 | return; | 1411 | return; |
1241 | } | 1412 | } |
1242 | add = 1; | 1413 | add = 1; |
@@ -1258,8 +1429,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1258 | _ ("Missing option `%s' for operation `%s'\n"), | 1429 | _ ("Missing option `%s' for operation `%s'\n"), |
1259 | "-z", | 1430 | "-z", |
1260 | _ ("add")); | 1431 | _ ("add")); |
1261 | GNUNET_SCHEDULER_shutdown (); | ||
1262 | ret = 1; | 1432 | ret = 1; |
1433 | finish_command (); | ||
1263 | return; | 1434 | return; |
1264 | } | 1435 | } |
1265 | if (NULL == name) | 1436 | if (NULL == name) |
@@ -1268,8 +1439,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1268 | _ ("Missing option `%s' for operation `%s'\n"), | 1439 | _ ("Missing option `%s' for operation `%s'\n"), |
1269 | "-n", | 1440 | "-n", |
1270 | _ ("add")); | 1441 | _ ("add")); |
1271 | GNUNET_SCHEDULER_shutdown (); | ||
1272 | ret = 1; | 1442 | ret = 1; |
1443 | finish_command (); | ||
1273 | return; | 1444 | return; |
1274 | } | 1445 | } |
1275 | if (NULL == typestring) | 1446 | if (NULL == typestring) |
@@ -1278,16 +1449,16 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1278 | _ ("Missing option `%s' for operation `%s'\n"), | 1449 | _ ("Missing option `%s' for operation `%s'\n"), |
1279 | "-t", | 1450 | "-t", |
1280 | _ ("add")); | 1451 | _ ("add")); |
1281 | GNUNET_SCHEDULER_shutdown (); | ||
1282 | ret = 1; | 1452 | ret = 1; |
1453 | finish_command (); | ||
1283 | return; | 1454 | return; |
1284 | } | 1455 | } |
1285 | type = GNUNET_GNSRECORD_typename_to_number (typestring); | 1456 | type = GNUNET_GNSRECORD_typename_to_number (typestring); |
1286 | if (UINT32_MAX == type) | 1457 | if (UINT32_MAX == type) |
1287 | { | 1458 | { |
1288 | fprintf (stderr, _ ("Unsupported type `%s'\n"), typestring); | 1459 | fprintf (stderr, _ ("Unsupported type `%s'\n"), typestring); |
1289 | GNUNET_SCHEDULER_shutdown (); | ||
1290 | ret = 1; | 1460 | ret = 1; |
1461 | finish_command (); | ||
1291 | return; | 1462 | return; |
1292 | } | 1463 | } |
1293 | if ((GNUNET_DNSPARSER_TYPE_SRV == type) || | 1464 | if ((GNUNET_DNSPARSER_TYPE_SRV == type) || |
@@ -1297,8 +1468,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1297 | fprintf (stderr, | 1468 | fprintf (stderr, |
1298 | _ ("For DNS record types `SRV', `TLSA' and `OPENPGPKEY'")); | 1469 | _ ("For DNS record types `SRV', `TLSA' and `OPENPGPKEY'")); |
1299 | fprintf (stderr, ", please use a `BOX' record instead\n"); | 1470 | fprintf (stderr, ", please use a `BOX' record instead\n"); |
1300 | GNUNET_SCHEDULER_shutdown (); | ||
1301 | ret = 1; | 1471 | ret = 1; |
1472 | finish_command (); | ||
1302 | return; | 1473 | return; |
1303 | } | 1474 | } |
1304 | if (NULL == value) | 1475 | if (NULL == value) |
@@ -1308,7 +1479,7 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1308 | "-V", | 1479 | "-V", |
1309 | _ ("add")); | 1480 | _ ("add")); |
1310 | ret = 1; | 1481 | ret = 1; |
1311 | GNUNET_SCHEDULER_shutdown (); | 1482 | finish_command (); |
1312 | return; | 1483 | return; |
1313 | } | 1484 | } |
1314 | if (GNUNET_OK != | 1485 | if (GNUNET_OK != |
@@ -1318,8 +1489,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1318 | _ ("Value `%s' invalid for record type `%s'\n"), | 1489 | _ ("Value `%s' invalid for record type `%s'\n"), |
1319 | value, | 1490 | value, |
1320 | typestring); | 1491 | typestring); |
1321 | GNUNET_SCHEDULER_shutdown (); | ||
1322 | ret = 1; | 1492 | ret = 1; |
1493 | finish_command (); | ||
1323 | return; | 1494 | return; |
1324 | } | 1495 | } |
1325 | if (NULL == expirationstring) | 1496 | if (NULL == expirationstring) |
@@ -1328,15 +1499,15 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1328 | _ ("Missing option `%s' for operation `%s'\n"), | 1499 | _ ("Missing option `%s' for operation `%s'\n"), |
1329 | "-e", | 1500 | "-e", |
1330 | _ ("add")); | 1501 | _ ("add")); |
1331 | GNUNET_SCHEDULER_shutdown (); | ||
1332 | ret = 1; | 1502 | ret = 1; |
1503 | finish_command (); | ||
1333 | return; | 1504 | return; |
1334 | } | 1505 | } |
1335 | if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) | 1506 | if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) |
1336 | { | 1507 | { |
1337 | fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); | 1508 | fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); |
1338 | GNUNET_SCHEDULER_shutdown (); | ||
1339 | ret = 1; | 1509 | ret = 1; |
1510 | finish_command (); | ||
1340 | return; | 1511 | return; |
1341 | } | 1512 | } |
1342 | add_qe = GNUNET_NAMESTORE_records_lookup (ns, | 1513 | add_qe = GNUNET_NAMESTORE_records_lookup (ns, |
@@ -1355,8 +1526,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1355 | _ ("Missing option `%s' for operation `%s'\n"), | 1526 | _ ("Missing option `%s' for operation `%s'\n"), |
1356 | "-z", | 1527 | "-z", |
1357 | _ ("del")); | 1528 | _ ("del")); |
1358 | GNUNET_SCHEDULER_shutdown (); | ||
1359 | ret = 1; | 1529 | ret = 1; |
1530 | finish_command (); | ||
1360 | return; | 1531 | return; |
1361 | } | 1532 | } |
1362 | if (NULL == name) | 1533 | if (NULL == name) |
@@ -1365,8 +1536,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1365 | _ ("Missing option `%s' for operation `%s'\n"), | 1536 | _ ("Missing option `%s' for operation `%s'\n"), |
1366 | "-n", | 1537 | "-n", |
1367 | _ ("del")); | 1538 | _ ("del")); |
1368 | GNUNET_SCHEDULER_shutdown (); | ||
1369 | ret = 1; | 1539 | ret = 1; |
1540 | finish_command (); | ||
1370 | return; | 1541 | return; |
1371 | } | 1542 | } |
1372 | del_qe = GNUNET_NAMESTORE_records_lookup (ns, | 1543 | del_qe = GNUNET_NAMESTORE_records_lookup (ns, |
@@ -1398,8 +1569,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1398 | _ ("Missing option `%s' for operation `%s'\n"), | 1569 | _ ("Missing option `%s' for operation `%s'\n"), |
1399 | "-z", | 1570 | "-z", |
1400 | _ ("purge-zone")); | 1571 | _ ("purge-zone")); |
1401 | GNUNET_SCHEDULER_shutdown (); | ||
1402 | ret = 1; | 1572 | ret = 1; |
1573 | finish_command (); | ||
1403 | return; | 1574 | return; |
1404 | } | 1575 | } |
1405 | list_it = GNUNET_NAMESTORE_zone_iteration_start2 (ns, | 1576 | list_it = GNUNET_NAMESTORE_zone_iteration_start2 (ns, |
@@ -1423,8 +1594,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1423 | _ ("Missing option `%s' for operation `%s'\n"), | 1594 | _ ("Missing option `%s' for operation `%s'\n"), |
1424 | "-z", | 1595 | "-z", |
1425 | _ ("list")); | 1596 | _ ("list")); |
1426 | GNUNET_SCHEDULER_shutdown (); | ||
1427 | ret = 1; | 1597 | ret = 1; |
1598 | finish_command (); | ||
1428 | return; | 1599 | return; |
1429 | } | 1600 | } |
1430 | get_qe = GNUNET_NAMESTORE_records_lookup (ns, | 1601 | get_qe = GNUNET_NAMESTORE_records_lookup (ns, |
@@ -1457,8 +1628,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1457 | _ ("Missing option `%s' for operation `%s'\n"), | 1628 | _ ("Missing option `%s' for operation `%s'\n"), |
1458 | "-z", | 1629 | "-z", |
1459 | _ ("reverse-pkey")); | 1630 | _ ("reverse-pkey")); |
1460 | GNUNET_SCHEDULER_shutdown (); | ||
1461 | ret = 1; | 1631 | ret = 1; |
1632 | finish_command (); | ||
1462 | return; | 1633 | return; |
1463 | } | 1634 | } |
1464 | if (GNUNET_OK != | 1635 | if (GNUNET_OK != |
@@ -1468,7 +1639,9 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1468 | fprintf (stderr, | 1639 | fprintf (stderr, |
1469 | _ ("Invalid public key for reverse lookup `%s'\n"), | 1640 | _ ("Invalid public key for reverse lookup `%s'\n"), |
1470 | reverse_pkey); | 1641 | reverse_pkey); |
1471 | GNUNET_SCHEDULER_shutdown (); | 1642 | ret = 1; |
1643 | finish_command (); | ||
1644 | return; | ||
1472 | } | 1645 | } |
1473 | reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns, | 1646 | reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns, |
1474 | &zone_pkey, | 1647 | &zone_pkey, |
@@ -1489,8 +1662,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1489 | _ ("Missing option `%s' for operation `%s'\n"), | 1662 | _ ("Missing option `%s' for operation `%s'\n"), |
1490 | "-z", | 1663 | "-z", |
1491 | _ ("uri")); | 1664 | _ ("uri")); |
1492 | GNUNET_SCHEDULER_shutdown (); | ||
1493 | ret = 1; | 1665 | ret = 1; |
1666 | finish_command (); | ||
1494 | return; | 1667 | return; |
1495 | } | 1668 | } |
1496 | 1669 | ||
@@ -1502,8 +1675,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1502 | GNUNET_IDENTITY_public_key_from_string (sh, &pkey))) | 1675 | GNUNET_IDENTITY_public_key_from_string (sh, &pkey))) |
1503 | { | 1676 | { |
1504 | fprintf (stderr, _ ("Invalid URI `%s'\n"), uri); | 1677 | fprintf (stderr, _ ("Invalid URI `%s'\n"), uri); |
1505 | GNUNET_SCHEDULER_shutdown (); | ||
1506 | ret = 1; | 1678 | ret = 1; |
1679 | finish_command (); | ||
1507 | return; | 1680 | return; |
1508 | } | 1681 | } |
1509 | if (NULL == expirationstring) | 1682 | if (NULL == expirationstring) |
@@ -1512,15 +1685,15 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1512 | _ ("Missing option `%s' for operation `%s'\n"), | 1685 | _ ("Missing option `%s' for operation `%s'\n"), |
1513 | "-e", | 1686 | "-e", |
1514 | _ ("add")); | 1687 | _ ("add")); |
1515 | GNUNET_SCHEDULER_shutdown (); | ||
1516 | ret = 1; | 1688 | ret = 1; |
1689 | finish_command (); | ||
1517 | return; | 1690 | return; |
1518 | } | 1691 | } |
1519 | if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) | 1692 | if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) |
1520 | { | 1693 | { |
1521 | fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); | 1694 | fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); |
1522 | GNUNET_SCHEDULER_shutdown (); | ||
1523 | ret = 1; | 1695 | ret = 1; |
1696 | finish_command (); | ||
1524 | return; | 1697 | return; |
1525 | } | 1698 | } |
1526 | memset (&rd, 0, sizeof(rd)); | 1699 | memset (&rd, 0, sizeof(rd)); |
@@ -1531,7 +1704,7 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1531 | if (GNUNET_YES == etime_is_rel) | 1704 | if (GNUNET_YES == etime_is_rel) |
1532 | rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | 1705 | rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; |
1533 | if (1 == is_shadow) | 1706 | if (1 == is_shadow) |
1534 | rd.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; | 1707 | rd.flags |= GNUNET_GNSRECORD_RF_SHADOW; |
1535 | add_qe_uri = GNUNET_NAMESTORE_records_store (ns, | 1708 | add_qe_uri = GNUNET_NAMESTORE_records_store (ns, |
1536 | &zone_pkey, | 1709 | &zone_pkey, |
1537 | sname, | 1710 | sname, |
@@ -1556,34 +1729,153 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1556 | } | 1729 | } |
1557 | } | 1730 | } |
1558 | 1731 | ||
1732 | #define MAX_LINE_LEN 4086 | ||
1733 | |||
1734 | #define MAX_ARGS 20 | ||
1735 | |||
1736 | static int | ||
1737 | get_identity_for_string (const char *str, | ||
1738 | struct GNUNET_IDENTITY_PrivateKey *zk) | ||
1739 | { | ||
1740 | const struct GNUNET_IDENTITY_PrivateKey *privkey; | ||
1741 | struct GNUNET_IDENTITY_PublicKey pubkey; | ||
1742 | struct GNUNET_IDENTITY_PublicKey ego_pubkey; | ||
1743 | struct EgoEntry *ego_entry; | ||
1744 | |||
1745 | if (GNUNET_OK == GNUNET_IDENTITY_public_key_from_string (str, | ||
1746 | &pubkey)) | ||
1747 | { | ||
1748 | for (ego_entry = ego_head; | ||
1749 | NULL != ego_entry; ego_entry = ego_entry->next) | ||
1750 | { | ||
1751 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | ||
1752 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &ego_pubkey); | ||
1753 | if (0 == memcmp (&ego_pubkey, &pubkey, sizeof (pubkey))) | ||
1754 | { | ||
1755 | *zk = *privkey; | ||
1756 | return GNUNET_OK; | ||
1757 | } | ||
1758 | } | ||
1759 | } | ||
1760 | else | ||
1761 | { | ||
1762 | for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) | ||
1763 | { | ||
1764 | /** FIXME: Check for zTLD? **/ | ||
1765 | if (0 != strcmp (str, ego_entry->identifier)) | ||
1766 | continue; | ||
1767 | *zk = *GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | ||
1768 | return GNUNET_OK; | ||
1769 | } | ||
1770 | } | ||
1771 | return GNUNET_NO; | ||
1772 | } | ||
1559 | 1773 | ||
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 | 1774 | static void |
1568 | identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | 1775 | process_command_stdin () |
1569 | { | 1776 | { |
1570 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 1777 | char buf[MAX_LINE_LEN]; |
1778 | static struct GNUNET_IDENTITY_PrivateKey next_zone_key; | ||
1779 | static char next_name[GNUNET_DNSPARSER_MAX_NAME_LENGTH]; | ||
1780 | static int finished = GNUNET_NO; | ||
1781 | static int have_next_zonekey = GNUNET_NO; | ||
1782 | int zonekey_set = GNUNET_NO; | ||
1783 | char *tmp; | ||
1571 | 1784 | ||
1572 | el = NULL; | ||
1573 | 1785 | ||
1574 | if (NULL == ego) | 1786 | if (GNUNET_YES == have_next_zonekey) |
1575 | { | 1787 | { |
1576 | if (NULL != ego_name) | 1788 | zone_pkey = next_zone_key; |
1789 | if (NULL != name) | ||
1790 | GNUNET_free (name); | ||
1791 | name = GNUNET_strdup (next_name); | ||
1792 | zonekey_set = GNUNET_YES; | ||
1793 | } | ||
1794 | while (NULL != fgets (buf, sizeof (buf), stdin)) | ||
1795 | { | ||
1796 | if (1 >= strlen (buf)) | ||
1797 | continue; | ||
1798 | if (buf[strlen (buf) - 1] == '\n') | ||
1799 | buf[strlen (buf) - 1] = '\0'; | ||
1800 | /** | ||
1801 | * Check if this is a new name. If yes, and we have records, store them. | ||
1802 | */ | ||
1803 | if (buf[strlen (buf) - 1] == ':') | ||
1577 | { | 1804 | { |
1578 | fprintf (stderr, | 1805 | memset (next_name, 0, sizeof (next_name)); |
1579 | _ ("Ego `%s' not known to identity service\n"), | 1806 | strncpy (next_name, buf, strlen (buf) - 1); |
1580 | ego_name); | 1807 | tmp = strchr (next_name, '.'); |
1808 | if (NULL == tmp) | ||
1809 | { | ||
1810 | fprintf (stderr, "Error parsing name `%s'\n", next_name); | ||
1811 | ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL); | ||
1812 | ret = 1; | ||
1813 | return; | ||
1814 | } | ||
1815 | if (GNUNET_OK != get_identity_for_string (tmp + 1, &next_zone_key)) | ||
1816 | { | ||
1817 | fprintf (stderr, "Error parsing zone name `%s'\n", tmp + 1); | ||
1818 | ret = 1; | ||
1819 | GNUNET_SCHEDULER_shutdown (); | ||
1820 | return; | ||
1821 | } | ||
1822 | *tmp = '\0'; | ||
1823 | have_next_zonekey = GNUNET_YES; | ||
1824 | /* Run a command for the previous record set */ | ||
1825 | if (NULL != recordset) | ||
1826 | { | ||
1827 | run_with_zone_pkey (cfg); | ||
1828 | return; | ||
1829 | } | ||
1830 | zone_pkey = next_zone_key; | ||
1831 | if (NULL != name) | ||
1832 | GNUNET_free (name); | ||
1833 | name = GNUNET_strdup (next_name); | ||
1834 | zonekey_set = GNUNET_YES; | ||
1835 | continue; | ||
1836 | } | ||
1837 | if (GNUNET_NO == zonekey_set) | ||
1838 | { | ||
1839 | fprintf (stderr, "Warning, encountered recordline without zone\n"); | ||
1840 | continue; | ||
1581 | } | 1841 | } |
1842 | parse_recordline (buf); | ||
1843 | } | ||
1844 | if (GNUNET_NO == finished) | ||
1845 | { | ||
1846 | if (NULL != recordset) | ||
1847 | { | ||
1848 | if (GNUNET_YES == zonekey_set) | ||
1849 | { | ||
1850 | run_with_zone_pkey (cfg); /** one last time **/ | ||
1851 | finished = GNUNET_YES; | ||
1852 | return; | ||
1853 | } | ||
1854 | fprintf (stderr, "Warning, encountered recordline without zone\n"); | ||
1855 | } | ||
1856 | } | ||
1857 | ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL); | ||
1858 | return; | ||
1859 | } | ||
1860 | |||
1861 | |||
1862 | static void | ||
1863 | begin_cb (void *cls, enum GNUNET_ErrorCode ec) | ||
1864 | { | ||
1865 | ns_qe = NULL; | ||
1866 | if (GNUNET_EC_NONE != ec) | ||
1867 | { | ||
1868 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1869 | "Failed to start transaction: %s\n", | ||
1870 | GNUNET_ErrorCode_get_hint (ec)); | ||
1582 | GNUNET_SCHEDULER_shutdown (); | 1871 | GNUNET_SCHEDULER_shutdown (); |
1583 | ret = -1; | ||
1584 | return; | 1872 | return; |
1585 | } | 1873 | } |
1586 | zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); | 1874 | if (read_from_stdin) |
1875 | { | ||
1876 | process_command_stdin (); | ||
1877 | return; | ||
1878 | } | ||
1587 | run_with_zone_pkey (cfg); | 1879 | run_with_zone_pkey (cfg); |
1588 | } | 1880 | } |
1589 | 1881 | ||
@@ -1606,7 +1898,6 @@ id_connect_cb (void *cls, | |||
1606 | void **ctx, | 1898 | void **ctx, |
1607 | const char *name) | 1899 | const char *name) |
1608 | { | 1900 | { |
1609 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | ||
1610 | struct GNUNET_IDENTITY_PublicKey pk; | 1901 | struct GNUNET_IDENTITY_PublicKey pk; |
1611 | struct EgoEntry *ego_entry; | 1902 | struct EgoEntry *ego_entry; |
1612 | 1903 | ||
@@ -1621,17 +1912,20 @@ id_connect_cb (void *cls, | |||
1621 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, | 1912 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, |
1622 | ego_tail, | 1913 | ego_tail, |
1623 | ego_entry); | 1914 | ego_entry); |
1915 | if ((NULL != ego_name) && | ||
1916 | (0 == strcmp (name, ego_name))) | ||
1917 | zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
1624 | return; | 1918 | return; |
1625 | } | 1919 | } |
1626 | if (NULL != ego) | 1920 | if (NULL != ego) |
1627 | return; | 1921 | return; |
1628 | if (NULL == ego_name) | 1922 | 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 | } | 1923 | } |
1633 | 1924 | ||
1634 | 1925 | ||
1926 | |||
1927 | |||
1928 | |||
1635 | /** | 1929 | /** |
1636 | * Main function that will be run. | 1930 | * Main function that will be run. |
1637 | * | 1931 | * |
@@ -1644,202 +1938,36 @@ static void | |||
1644 | run (void *cls, | 1938 | run (void *cls, |
1645 | char *const *args, | 1939 | char *const *args, |
1646 | const char *cfgfile, | 1940 | const char *cfgfile, |
1647 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 1941 | const struct GNUNET_CONFIGURATION_Handle *_cfg) |
1648 | { | 1942 | { |
1649 | const char *pkey_str; | ||
1650 | |||
1651 | (void) cls; | 1943 | (void) cls; |
1652 | (void) args; | 1944 | (void) args; |
1653 | (void) cfgfile; | 1945 | (void) cfgfile; |
1946 | cfg = _cfg; | ||
1654 | if (NULL != args[0]) | 1947 | if (NULL != args[0]) |
1655 | GNUNET_log ( | 1948 | GNUNET_log ( |
1656 | GNUNET_ERROR_TYPE_WARNING, | 1949 | GNUNET_ERROR_TYPE_WARNING, |
1657 | _ ("Superfluous command line arguments (starting with `%s') ignored\n"), | 1950 | _ ("Superfluous command line arguments (starting with `%s') ignored\n"), |
1658 | args[0]); | 1951 | args[0]); |
1659 | if ((NULL != args[0]) && (NULL == uri)) | ||
1660 | uri = GNUNET_strdup (args[0]); | ||
1661 | 1952 | ||
1662 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, (void *) cfg); | 1953 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, (void *) cfg); |
1663 | pkey_str = getenv ("GNUNET_NAMESTORE_EGO_PRIVATE_KEY"); | 1954 | ns = GNUNET_NAMESTORE_connect (cfg); |
1664 | if (NULL != pkey_str) | 1955 | if (NULL == ns) |
1665 | { | 1956 | { |
1666 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (pkey_str, | 1957 | fprintf (stderr, _ ("Failed to connect to namestore\n")); |
1667 | strlen (pkey_str), | 1958 | 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; | 1959 | return; |
1681 | } | 1960 | } |
1682 | idh = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, (void *) cfg); | 1961 | idh = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, (void *) cfg); |
1683 | if (NULL == idh) | 1962 | 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 | { | ||
1733 | char *etime_in_s; | ||
1734 | |||
1735 | GNUNET_asprintf (&etime_in_s, "%s s", tok); | ||
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 | { | 1963 | { |
1767 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1964 | ret = -1; |
1768 | _ ("Missing entries in record line `%s'.\n"), | 1965 | fprintf (stderr, _ ("Cannot connect to identity service\n")); |
1769 | value); | 1966 | GNUNET_SCHEDULER_shutdown (); |
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_RECORD; | ||
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 | } | 1967 | } |
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 | } | 1968 | } |
1813 | 1969 | ||
1814 | 1970 | ||
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 | 1971 | ||
1844 | /** | 1972 | /** |
1845 | * The main function for gnunet-namestore. | 1973 | * The main function for gnunet-namestore. |
@@ -1851,6 +1979,7 @@ multirecord_option (char shortName, | |||
1851 | int | 1979 | int |
1852 | main (int argc, char *const *argv) | 1980 | main (int argc, char *const *argv) |
1853 | { | 1981 | { |
1982 | int lret; | ||
1854 | struct GNUNET_GETOPT_CommandLineOption options[] = | 1983 | struct GNUNET_GETOPT_CommandLineOption options[] = |
1855 | { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add), | 1984 | { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add), |
1856 | GNUNET_GETOPT_option_flag ('d', | 1985 | GNUNET_GETOPT_option_flag ('d', |
@@ -1861,6 +1990,10 @@ main (int argc, char *const *argv) | |||
1861 | "display", | 1990 | "display", |
1862 | gettext_noop ("display records"), | 1991 | gettext_noop ("display records"), |
1863 | &list), | 1992 | &list), |
1993 | GNUNET_GETOPT_option_flag ('S', | ||
1994 | "from-stdin", | ||
1995 | gettext_noop ("read commands from stdin"), | ||
1996 | &read_from_stdin), | ||
1864 | GNUNET_GETOPT_option_string ( | 1997 | GNUNET_GETOPT_option_string ( |
1865 | 'e', | 1998 | 'e', |
1866 | "expiration", | 1999 | "expiration", |
@@ -1885,19 +2018,16 @@ main (int argc, char *const *argv) | |||
1885 | gettext_noop ( | 2018 | gettext_noop ( |
1886 | "name of the record to add/delete/display"), | 2019 | "name of the record to add/delete/display"), |
1887 | &name), | 2020 | &name), |
1888 | GNUNET_GETOPT_option_string ('r', | 2021 | GNUNET_GETOPT_option_flag ('r', |
1889 | "reverse", | 2022 | "recordline", |
1890 | "PKEY", | 2023 | gettext_noop ("Output in recordline format"), |
2024 | &output_recordline), | ||
2025 | GNUNET_GETOPT_option_string ('Z', | ||
2026 | "zone-to-name", | ||
2027 | "KEY", | ||
1891 | gettext_noop ( | 2028 | gettext_noop ( |
1892 | "determine our name for the given PKEY"), | 2029 | "determine our name for the given KEY"), |
1893 | &reverse_pkey), | 2030 | &reverse_pkey), |
1894 | multirecord_option ( | ||
1895 | 'R', | ||
1896 | "replace", | ||
1897 | "RECORDLINE", | ||
1898 | gettext_noop ( | ||
1899 | "set record set to values given by (possibly multiple) RECORDLINES; can be specified multiple times"), | ||
1900 | &recordset), | ||
1901 | GNUNET_GETOPT_option_string ('t', | 2031 | GNUNET_GETOPT_option_string ('t', |
1902 | "type", | 2032 | "type", |
1903 | "TYPE", | 2033 | "TYPE", |
@@ -1956,7 +2086,7 @@ main (int argc, char *const *argv) | |||
1956 | "name of the ego controlling the zone"), | 2086 | "name of the ego controlling the zone"), |
1957 | &ego_name), | 2087 | &ego_name), |
1958 | GNUNET_GETOPT_OPTION_END }; | 2088 | GNUNET_GETOPT_OPTION_END }; |
1959 | int lret; | 2089 | |
1960 | 2090 | ||
1961 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 2091 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) |
1962 | return 2; | 2092 | return 2; |