aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-11-21 15:09:10 +0100
committerChristian Grothoff <christian@grothoff.org>2022-11-21 15:09:10 +0100
commit92c6328195c3bed9abbd56625fcab5952869289c (patch)
treebaecbe996589f4fdc652636e11f078bba94776ae
parentee778d9e8963b4daaae7fbd0eecab7a124c7e1d0 (diff)
parentbdab06894ca42106651e7328657cf87c779b6acf (diff)
downloadgnunet-92c6328195c3bed9abbd56625fcab5952869289c.tar.gz
gnunet-92c6328195c3bed9abbd56625fcab5952869289c.zip
Merge branch 'master' of git+ssh://git.gnunet.org/gnunet
-rw-r--r--doc/man/gnunet-namestore.188
-rw-r--r--src/namestore/Makefile.am1
-rw-r--r--src/namestore/gnunet-namestore.c878
-rwxr-xr-x[-rw-r--r--]src/namestore/test_namestore_put_multiple.sh49
-rwxr-xr-xsrc/namestore/test_namestore_put_stdin.sh68
5 files changed, 669 insertions, 415 deletions
diff --git a/doc/man/gnunet-namestore.1 b/doc/man/gnunet-namestore.1
index 9391e21bb..6915aed6e 100644
--- a/doc/man/gnunet-namestore.1
+++ b/doc/man/gnunet-namestore.1
@@ -43,9 +43,8 @@
43.Op Fl o | -omit-private 43.Op Fl o | -omit-private
44.Op Fl P | -purge-orphans 44.Op Fl P | -purge-orphans
45.Op Fl p | -public 45.Op Fl p | -public
46.Op Fl r Ar PKEY | Fl -reverse= Ns Ar PKEY
47.Op Fl R Ar RECORDLINE | Fl -replace= Ns Ar RECORDLINE
48.Op Fl s | -shadow 46.Op Fl s | -shadow
47.Op Fl S | -from-stdin
49.Op Fl T | -include-maintenance 48.Op Fl T | -include-maintenance
50.Op Fl t Ar TYPE | Fl -type= Ns Ar TYPE 49.Op Fl t Ar TYPE | Fl -type= Ns Ar TYPE
51.Op Fl u Ar URI | Fl -uri= Ns Ar URI 50.Op Fl u Ar URI | Fl -uri= Ns Ar URI
@@ -53,6 +52,7 @@
53.Op Fl V Ar VALUE | Fl -value= Ns Ar VALUE 52.Op Fl V Ar VALUE | Fl -value= Ns Ar VALUE
54.Op Fl X | -purge-zone-records 53.Op Fl X | -purge-zone-records
55.Op Fl z Ar EGO | Fl -zone= Ns Ar EGO 54.Op Fl z Ar EGO | Fl -zone= Ns Ar EGO
55.Op Fl Z Ar KEY | Fl -zone-to-name= Ns Ar KEY
56.Sh DESCRIPTION 56.Sh DESCRIPTION
57.Nm 57.Nm
58can be used to manipulate records in a GNS zone. 58can be used to manipulate records in a GNS zone.
@@ -102,23 +102,42 @@ Delete orphaned records from namestore.
102.It Fl p | -public 102.It Fl p | -public
103Create a record that is public (shared with other users that know the 103Create a record that is public (shared with other users that know the
104label). 104label).
105.It Fl r Ar PKEY | Fl -reverse= Ns Ar PKEY 105.It Fl r | -recordline
106Determine our GNS name for the given public key (reverse lookup of the 106Changes the output format of zones and records to recordline.
107PKEY) in the given zone.
108.It Fl R Ar RECORDLINE | Fl -replace= Ns Ar RECORDLINE
109Sets record set to values given in RECORDLINE.
110This option can be specified multiple times to provide multiple
111records for the record set.
112Existing records under the same label will be deleted.
113The format for the RECORDLINE is "TTL TYPE FLAGS VALUE" where TTL is
114the time to live in seconds (unit must not be given explicitly,
115seconds is always implied), TYPE is the DNS/GNS record type,
116FLAGS is "(N)ORMAL", "(S)HADOW" or "(P)UBLIC".
117The VALUE follows the usual human-readable value format(s) of DNS/GNS.
118.It Fl s | -shadow 107.It Fl s | -shadow
119Create a record that is a shadow record. 108Create a record that is a shadow record.
120Shadow records are only used once all other records of the same type 109Shadow records are only used once all other records of the same type
121under the same label have expired. 110under the same label have expired.
111.It Fl S | -from-stdin
112Read recordlines from stdin until EOF is encountered.
113The format uses
114.B recordlines
115:
116A record in a recordline follows the format
117
118NAME.EGO:
119 TYPE EXPIRATION [FLAGS] VALUE
120 ...
121Multiple records may be provided for a name.
122
123EXPIRATION is given in microseconds without a unit (e.g. 3600000000 for 3600 seconds).
124
125FLAGS is a concatenation of record flags.
126Possible values for flags and their meaning are:
127.Pp
128 p: Public
129 s: Shadow
130 S: Supplemental
131 C: Critical
132 r: Relative expiration
133
134TYPE and VALUE are used in the same way as for the "-t" and "-V" options.
135Example formats for recordlines can be output using the "-D" flag combined
136with "--recordline".
137An example record set in recordline format can be found in the examples.
138It is possible to specify multiple record sets.
139Can only be used in combination with "-a" to add the parsed record sets.
140Existing record sets under names will be replaced.
122.It Fl T | -include-maintenance 141.It Fl T | -include-maintenance
123Show maintenance records such as TOMBSTONEs. Use in combination with --display. 142Show maintenance records such as TOMBSTONEs. Use in combination with --display.
124.It Fl t Ar TYPE | Fl -type= Ns Ar TYPE 143.It Fl t Ar TYPE | Fl -type= Ns Ar TYPE
@@ -144,8 +163,45 @@ Base32-encoding using the GNUNET_NAMESTORE_EGO_PRIVATE_KEY environment
144variable. The latter is useful to improve performance of tools like 163variable. The latter is useful to improve performance of tools like
145Ascension as it allows the command to skip IPC with the identity 164Ascension as it allows the command to skip IPC with the identity
146management subsystem. 165management subsystem.
166.It Fl Z Ar KEY | Fl -zone-to-name= Ns Ar KEY
167Determine our GNS name for the given public key (reverse lookup of the
168KEY) in the given zone.
147.El 169.El
148.\".Sh EXAMPLES 170.Sh EXAMPLES
171.Tp
172.Nm
173-z example -a -n www -t A -V "1.2.3.4" -e 1d -p
174.Tp
175.Pp
176.Dl Add a public record for ego "example" with name "www" containing an IP address.
177.sp
178.Tp
179.Nm
180-z example -D
181.Tp
182.Pp
183.Dl Show all records for ego "example".
184.sp
185.Tp
186.Nm
187-z example -D -r
188.Tp
189.Pp
190.Dl Show all records for ego "example" in recordline format.
191.sp
192.Tp
193.Nm
194--add --from-stdin <<EOF
195 www.alice:
196 A 3600000000 [pr] 1.2.3.4
197 TXT 3600000001 [pr] Hello World
198
199 www.bob:
200 A 12345679000000 [pr] 4.3.2.1
201 EOF
202.Tp
203.Pp
204.Dl Read record sets in recordline format from stdin.
149.\".Sh FILES 205.\".Sh FILES
150.Sh SEE ALSO 206.Sh SEE ALSO
151.Xr gnunet-gns 1 , 207.Xr gnunet-gns 1 ,
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index fb2a670bc..a0ca32fa4 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -514,6 +514,7 @@ test_plugin_namestore_postgres_LDADD = \
514 514
515check_SCRIPTS = \ 515check_SCRIPTS = \
516 test_namestore_put.sh \ 516 test_namestore_put.sh \
517 test_namestore_put_stdin.sh \
517 test_namestore_lookup.sh \ 518 test_namestore_lookup.sh \
518 test_namestore_delete.sh \ 519 test_namestore_delete.sh \
519 test_namestore_zonefile_import.sh 520 test_namestore_zonefile_import.sh
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index 36a0a9ba3..207394dd9 100644
--- a/src/namestore/gnunet-namestore.c
+++ b/src/namestore/gnunet-namestore.c
@@ -32,6 +32,7 @@
32#include <gnunet_gnsrecord_lib.h> 32#include <gnunet_gnsrecord_lib.h>
33#include <gnunet_gns_service.h> 33#include <gnunet_gns_service.h>
34#include <gnunet_namestore_service.h> 34#include <gnunet_namestore_service.h>
35#include <inttypes.h>
35 36
36/** 37/**
37 * The upper bound for the zone iteration interval 38 * The upper bound for the zone iteration interval
@@ -119,11 +120,6 @@ static struct GNUNET_NAMESTORE_Handle *ns;
119static struct GNUNET_IDENTITY_PrivateKey zone_pkey; 120static struct GNUNET_IDENTITY_PrivateKey zone_pkey;
120 121
121/** 122/**
122 * Handle to identity lookup.
123 */
124static struct GNUNET_IDENTITY_EgoLookup *el;
125
126/**
127 * Identity service handle 123 * Identity service handle
128 */ 124 */
129static struct GNUNET_IDENTITY_Handle *idh; 125static struct GNUNET_IDENTITY_Handle *idh;
@@ -134,11 +130,6 @@ static struct GNUNET_IDENTITY_Handle *idh;
134static char *ego_name; 130static char *ego_name;
135 131
136/** 132/**
137 * Desired action is to add a record.
138 */
139static int add;
140
141/**
142 * Queue entry for the 'add-uri' operation. 133 * Queue entry for the 'add-uri' operation.
143 */ 134 */
144static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri; 135static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri;
@@ -168,6 +159,10 @@ static struct MarkedRecord *marked_head;
168 */ 159 */
169static struct MarkedRecord *marked_tail; 160static struct MarkedRecord *marked_tail;
170 161
162/**
163 * Configuration handle
164 */
165const struct GNUNET_CONFIGURATION_Handle *cfg;
171 166
172/** 167/**
173 * Ego list 168 * Ego list
@@ -180,14 +175,24 @@ static struct EgoEntry *ego_head;
180static struct EgoEntry *ego_tail; 175static struct EgoEntry *ego_tail;
181 176
182/** 177/**
178 * List iterator for the 'list' operation.
179 */
180static struct GNUNET_NAMESTORE_ZoneIterator *list_it;
181
182/**
183 * Run in read from stdin mode.
184 */
185static int read_from_stdin;
186
187/**
183 * Desired action is to list records. 188 * Desired action is to list records.
184 */ 189 */
185static int list; 190static int list;
186 191
187/** 192/**
188 * List iterator for the 'list' operation. 193 * Desired action is to add a record.
189 */ 194 */
190static struct GNUNET_NAMESTORE_ZoneIterator *list_it; 195static int add;
191 196
192/** 197/**
193 * Desired action is to remove a record. 198 * Desired action is to remove a record.
@@ -210,6 +215,12 @@ static int is_shadow;
210static int omit_private; 215static int omit_private;
211 216
212/** 217/**
218 * Output in recordline format
219 */
220static int output_recordline;
221
222
223/**
213 * Purge zone contents 224 * Purge zone contents
214 */ 225 */
215static int purge_zone; 226static int purge_zone;
@@ -240,6 +251,11 @@ static struct GNUNET_NAMESTORE_QueueEntry *del_qe;
240static struct GNUNET_NAMESTORE_QueueEntry *set_qe; 251static struct GNUNET_NAMESTORE_QueueEntry *set_qe;
241 252
242/** 253/**
254 * Queue entry for begin/commit
255 */
256static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
257
258/**
243 * Name of the records to add/list/remove. 259 * Name of the records to add/list/remove.
244 */ 260 */
245static char *name; 261static char *name;
@@ -325,37 +341,193 @@ static struct RecordSetEntry *recordset;
325static struct GNUNET_SCHEDULER_Task *purge_task; 341static struct GNUNET_SCHEDULER_Task *purge_task;
326 342
327/** 343/**
328 * Task run on shutdown. Cleans up everything. 344 * Parse expiration time.
329 * 345 *
330 * @param cls unused 346 * @param expirationstring text to parse
347 * @param[out] etime_is_rel set to #GNUNET_YES if time is relative
348 * @param[out] etime set to expiration time (abs or rel)
349 * @return #GNUNET_OK on success
331 */ 350 */
351static int
352parse_expiration (const char *expirationstring,
353 int *etime_is_rel,
354 uint64_t *etime)
355{
356 struct GNUNET_TIME_Relative etime_rel;
357 struct GNUNET_TIME_Absolute etime_abs;
358
359 if (0 == strcmp (expirationstring, "never"))
360 {
361 *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
362 *etime_is_rel = GNUNET_NO;
363 return GNUNET_OK;
364 }
365 if (GNUNET_OK ==
366 GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel))
367 {
368 *etime_is_rel = GNUNET_YES;
369 *etime = etime_rel.rel_value_us;
370 if (GNUNET_TIME_relative_cmp (etime_rel, <, WARN_RELATIVE_EXPIRATION_LIMIT))
371 {
372 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
373 "Relative expiration times of less than %s are not recommended. To improve availability, consider increasing this value.\n",
374 GNUNET_STRINGS_relative_time_to_string (
375 WARN_RELATIVE_EXPIRATION_LIMIT, GNUNET_NO));
376 }
377 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
378 "Storing record with relative expiration time of %s\n",
379 GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO));
380 return GNUNET_OK;
381 }
382 if (GNUNET_OK ==
383 GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs))
384 {
385 *etime_is_rel = GNUNET_NO;
386 *etime = etime_abs.abs_value_us;
387 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
388 "Storing record with absolute expiration time of %s\n",
389 GNUNET_STRINGS_absolute_time_to_string (etime_abs));
390 return GNUNET_OK;
391 }
392 return GNUNET_SYSERR;
393}
394
395
396static int
397parse_recordline (const char *line)
398{
399 struct RecordSetEntry **head = &recordset;
400 struct RecordSetEntry *r;
401 struct GNUNET_GNSRECORD_Data record;
402 char *cp;
403 char *tok;
404 char *saveptr;
405 void *raw_data;
406
407 cp = GNUNET_strdup (line);
408 tok = strtok_r (cp, " ", &saveptr);
409 if (NULL == tok)
410 {
411 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
412 _ ("Missing entries in record line `%s'.\n"),
413 line);
414 GNUNET_free (cp);
415 return GNUNET_SYSERR;
416 }
417 record.record_type = GNUNET_GNSRECORD_typename_to_number (tok);
418 if (UINT32_MAX == record.record_type)
419 {
420 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Unknown record type `%s'\n"), tok);
421 GNUNET_free (cp);
422 return GNUNET_SYSERR;
423 }
424 tok = strtok_r (NULL, " ", &saveptr);
425 if (NULL == tok)
426 {
427 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
428 _ ("Empty record line argument is not allowed.\n"));
429 GNUNET_free (cp);
430 return GNUNET_SYSERR;
431 }
432 if (1 != sscanf (tok, "%" SCNu64, &record.expiration_time))
433 {
434 fprintf (stderr,
435 _ ("Error parsing expiration time %s.\n"), tok);
436 GNUNET_free (cp);
437 return GNUNET_SYSERR;
438 }
439 tok = strtok_r (NULL, " ", &saveptr);
440 if (NULL == tok)
441 {
442 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
443 _ ("Empty record line argument is not allowed.\n"));
444 GNUNET_free (cp);
445 return GNUNET_SYSERR;
446 }
447 record.flags = GNUNET_GNSRECORD_RF_NONE;
448 if (NULL != strchr (tok, (unsigned char) 'r'))
449 record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
450 if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */
451 record.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
452 if (NULL != strchr (tok, (unsigned char) 'S'))
453 record.flags |= GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
454 if (NULL != strchr (tok, (unsigned char) 's'))
455 record.flags |= GNUNET_GNSRECORD_RF_SHADOW;
456 if (NULL != strchr (tok, (unsigned char) 'C'))
457 record.flags |= GNUNET_GNSRECORD_RF_CRITICAL;
458 tok = strtok_r (NULL, " ", &saveptr);
459 if (NULL == tok)
460 {
461 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
462 _ ("Empty record line argument is not allowed.\n"));
463 GNUNET_free (cp);
464 return GNUNET_SYSERR;
465 }
466 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record.record_type,
467 tok,
468 &raw_data,
469 &record.data_size))
470 {
471 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
472 _ ("Invalid record data for type %s: `%s'.\n"),
473 GNUNET_GNSRECORD_number_to_typename (record.record_type),
474 tok);
475 return GNUNET_SYSERR;
476 }
477
478 r = GNUNET_malloc (sizeof(struct RecordSetEntry) + record.data_size);
479 r->next = *head;
480 record.data = &r[1];
481 memcpy (&r[1], raw_data, record.data_size);
482 GNUNET_free (raw_data);
483 r->record = record;
484 *head = r;
485 return GNUNET_OK;
486}
487
332static void 488static void
333do_shutdown (void *cls) 489reset_handles (void)
334{ 490{
335 struct EgoEntry *ego_entry;
336 struct EgoEntry *ego_tmp;
337 struct MarkedRecord *mrec; 491 struct MarkedRecord *mrec;
338 struct MarkedRecord *mrec_tmp; 492 struct MarkedRecord *mrec_tmp;
339 (void) cls; 493 struct RecordSetEntry *rs_entry;
494
495 rs_entry = recordset;
496 while (NULL != (rs_entry = recordset))
497 {
498 recordset = recordset->next;
499 GNUNET_free (rs_entry);
500 }
501 recordset = NULL;
340 if (NULL != ego_name) 502 if (NULL != ego_name)
341 { 503 {
342 GNUNET_free (ego_name); 504 GNUNET_free (ego_name);
343 ego_name = NULL; 505 ego_name = NULL;
344 } 506 }
345 if (NULL != purge_task) 507 if (NULL != name)
346 { 508 {
347 GNUNET_SCHEDULER_cancel (purge_task); 509 GNUNET_free (name);
348 purge_task = NULL; 510 name = NULL;
349 } 511 }
350 if (NULL != idh) 512 if (NULL != value)
351 { 513 {
352 GNUNET_IDENTITY_disconnect (idh); 514 GNUNET_free (value);
353 idh = NULL; 515 value = NULL;
516 }
517 if (NULL != uri)
518 {
519 GNUNET_free (uri);
520 uri = NULL;
354 } 521 }
355 if (NULL != el) 522 if (NULL != expirationstring)
356 { 523 {
357 GNUNET_IDENTITY_ego_lookup_cancel (el); 524 GNUNET_free (expirationstring);
358 el = NULL; 525 expirationstring = NULL;
526 }
527 if (NULL != purge_task)
528 {
529 GNUNET_SCHEDULER_cancel (purge_task);
530 purge_task = NULL;
359 } 531 }
360 for (mrec = marked_head; NULL != mrec;) 532 for (mrec = marked_head; NULL != mrec;)
361 { 533 {
@@ -364,13 +536,6 @@ do_shutdown (void *cls)
364 GNUNET_free (mrec_tmp->name); 536 GNUNET_free (mrec_tmp->name);
365 GNUNET_free (mrec_tmp); 537 GNUNET_free (mrec_tmp);
366 } 538 }
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) 539 if (NULL != list_it)
375 { 540 {
376 GNUNET_NAMESTORE_zone_iteration_stop (list_it); 541 GNUNET_NAMESTORE_zone_iteration_stop (list_it);
@@ -401,17 +566,12 @@ do_shutdown (void *cls)
401 GNUNET_NAMESTORE_cancel (del_qe); 566 GNUNET_NAMESTORE_cancel (del_qe);
402 del_qe = NULL; 567 del_qe = NULL;
403 } 568 }
404 if (NULL != ns) 569 if (NULL != reverse_qe)
405 { 570 {
406 GNUNET_NAMESTORE_disconnect (ns); 571 GNUNET_NAMESTORE_cancel (reverse_qe);
407 ns = NULL; 572 reverse_qe = NULL;
408 } 573 }
409 memset (&zone_pkey, 0, sizeof(zone_pkey)); 574 memset (&zone_pkey, 0, sizeof(zone_pkey));
410 if (NULL != uri)
411 {
412 GNUNET_free (uri);
413 uri = NULL;
414 }
415 if (NULL != zm) 575 if (NULL != zm)
416 { 576 {
417 GNUNET_NAMESTORE_zone_monitor_stop (zm); 577 GNUNET_NAMESTORE_zone_monitor_stop (zm);
@@ -422,18 +582,83 @@ do_shutdown (void *cls)
422 GNUNET_free (data); 582 GNUNET_free (data);
423 data = NULL; 583 data = NULL;
424 } 584 }
585 if (NULL != typestring)
586 {
587 GNUNET_free (typestring);
588 typestring = NULL;
589 }
590 list = 0;
591 is_public = 0;
592 is_shadow = 0;
593 purge_zone = 0;
425} 594}
426 595
427 596
597
428/** 598/**
429 * Check if we are finished, and if so, perform shutdown. 599 * Task run on shutdown. Cleans up everything.
600 *
601 * @param cls unused
430 */ 602 */
431static void 603static void
432test_finished () 604do_shutdown (void *cls)
433{ 605{
434 if ((NULL == add_qe) && (NULL == add_qe_uri) && (NULL == get_qe) && 606 struct EgoEntry *ego_entry;
435 (NULL == del_qe) && (NULL == reverse_qe) && (NULL == list_it)) 607 struct EgoEntry *ego_tmp;
436 GNUNET_SCHEDULER_shutdown (); 608 (void) cls;
609
610 reset_handles ();
611 if (NULL != ns_qe)
612 {
613 GNUNET_NAMESTORE_cancel (ns_qe);
614 ns_qe = NULL;
615 }
616 if (NULL != ns)
617 {
618 GNUNET_NAMESTORE_disconnect (ns);
619 ns = NULL;
620 }
621 if (NULL != idh)
622 {
623 GNUNET_IDENTITY_disconnect (idh);
624 idh = NULL;
625 }
626 for (ego_entry = ego_head; NULL != ego_entry;)
627 {
628 ego_tmp = ego_entry;
629 ego_entry = ego_entry->next;
630 GNUNET_free (ego_tmp->identifier);
631 GNUNET_free (ego_tmp);
632 }
633}
634
635static void
636commit_cb (void *cls, enum GNUNET_ErrorCode ec)
637{
638 ns_qe = NULL;
639 if (GNUNET_EC_NONE != ec)
640 {
641 fprintf (stderr, "Failed to commit to namestore: `%s'\n",
642 GNUNET_ErrorCode_get_hint (ec));
643 ret = 1;
644 }
645 GNUNET_SCHEDULER_shutdown ();
646}
647
648static void
649process_command_stdin ();
650
651
652static void
653finish_command (void)
654{
655 reset_handles ();
656 if (read_from_stdin)
657 {
658 process_command_stdin ();
659 return;
660 }
661 ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL);
437} 662}
438 663
439 664
@@ -452,7 +677,7 @@ add_continuation (void *cls, enum GNUNET_ErrorCode ec)
452 ret = 1; 677 ret = 1;
453 } 678 }
454 ret = 0; 679 ret = 0;
455 test_finished (); 680 finish_command ();
456} 681}
457 682
458 683
@@ -467,7 +692,7 @@ del_continuation (void *cls, enum GNUNET_ErrorCode ec)
467 _ ("Deleting record failed: %s\n"), GNUNET_ErrorCode_get_hint ( 692 _ ("Deleting record failed: %s\n"), GNUNET_ErrorCode_get_hint (
468 ec)); 693 ec));
469 } 694 }
470 test_finished (); 695 finish_command ();
471} 696}
472 697
473static void 698static void
@@ -496,7 +721,7 @@ purge_next_record (void *cls)
496 if (NULL == marked_head) 721 if (NULL == marked_head)
497 { 722 {
498 ret = 0; 723 ret = 0;
499 test_finished (); 724 finish_command ();
500 return; 725 return;
501 } 726 }
502 mrec = marked_head; 727 mrec = marked_head;
@@ -527,7 +752,7 @@ zone_iteration_finished (void *cls)
527 return; 752 return;
528 } 753 }
529 ret = 0; 754 ret = 0;
530 test_finished (); 755 finish_command ();
531} 756}
532 757
533 758
@@ -541,7 +766,7 @@ zone_iteration_error_cb (void *cls)
541 list_it = NULL; 766 list_it = NULL;
542 fprintf (stderr, "Error iterating over zone\n"); 767 fprintf (stderr, "Error iterating over zone\n");
543 ret = 1; 768 ret = 1;
544 test_finished (); 769 finish_command ();
545} 770}
546 771
547static void 772static void
@@ -681,18 +906,33 @@ display_record (const struct GNUNET_IDENTITY_PrivateKey *zone_key,
681 at.abs_value_us = rd[i].expiration_time; 906 at.abs_value_us = rd[i].expiration_time;
682 ets = GNUNET_STRINGS_absolute_time_to_string (at); 907 ets = GNUNET_STRINGS_absolute_time_to_string (at);
683 } 908 }
684 fprintf (stdout, 909 char flgstr[16];
685 "\t%s: %s (%s)\t%s\t%s\n", 910 sprintf (flgstr, "[%s%s%s%s%s]",
686 typestr, 911 (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE) ? "" : "p",
687 s, 912 (rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL) ? "S" : "",
688 ets, 913 (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION) ? "r" : "",
689 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE" 914 (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW) ? "S" : "",
915 (rd[i].flags & GNUNET_GNSRECORD_RF_CRITICAL) ? "C" : "");
916 if (output_recordline)
917 fprintf (stdout,
918 " %s %" PRIu64 " %s %s\n",
919 typestr,
920 rd[i].expiration_time,
921 flgstr,
922 s);
923 else
924 fprintf (stdout,
925 "\t%s: %s (%s)\t%s\t%s\n",
926 typestr,
927 s,
928 ets,
929 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE"
690 : "PUBLIC", 930 : "PUBLIC",
691 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW)) ? "SHADOW" 931 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW)) ? "SHADOW"
692 : ""); 932 : "");
693 GNUNET_free (s); 933 GNUNET_free (s);
694 } 934 }
695 fprintf (stdout, "%s", "\n"); 935 // fprintf (stdout, "%s", "\n");
696} 936}
697 937
698static void 938static void
@@ -797,7 +1037,7 @@ display_record_lookup (void *cls,
797 (void) zone_key; 1037 (void) zone_key;
798 get_qe = NULL; 1038 get_qe = NULL;
799 display_record (zone_key, rname, rd_len, rd); 1039 display_record (zone_key, rname, rd_len, rd);
800 test_finished (); 1040 finish_command ();
801} 1041}
802 1042
803 1043
@@ -838,7 +1078,7 @@ lookup_error_cb (void *cls)
838 (void) cls; 1078 (void) cls;
839 get_qe = NULL; 1079 get_qe = NULL;
840 fprintf (stderr, "%s", "Failed to lookup record.\n"); 1080 fprintf (stderr, "%s", "Failed to lookup record.\n");
841 test_finished (); 1081 finish_command ();
842} 1082}
843 1083
844 1084
@@ -852,7 +1092,7 @@ add_error_cb (void *cls)
852 add_qe = NULL; 1092 add_qe = NULL;
853 GNUNET_break (0); 1093 GNUNET_break (0);
854 ret = 1; 1094 ret = 1;
855 test_finished (); 1095 finish_command ();
856} 1096}
857 1097
858 1098
@@ -883,7 +1123,7 @@ get_existing_record (void *cls,
883 { 1123 {
884 GNUNET_break (0); 1124 GNUNET_break (0);
885 ret = 1; 1125 ret = 1;
886 test_finished (); 1126 finish_command ();
887 return; 1127 return;
888 } 1128 }
889 1129
@@ -904,7 +1144,7 @@ get_existing_record (void *cls,
904 "A SOA record exists already under `%s', cannot add a second SOA to the same zone.\n"), 1144 "A SOA record exists already under `%s', cannot add a second SOA to the same zone.\n"),
905 rec_name); 1145 rec_name);
906 ret = 1; 1146 ret = 1;
907 test_finished (); 1147 finish_command ();
908 return; 1148 return;
909 } 1149 }
910 break; 1150 break;
@@ -974,7 +1214,7 @@ handle_reverse_lookup (void *cls,
974 fprintf (stdout, "%s\n", reverse_pkey); 1214 fprintf (stdout, "%s\n", reverse_pkey);
975 else 1215 else
976 fprintf (stdout, "%s.%s\n", label, ego_name); 1216 fprintf (stdout, "%s.%s\n", label, ego_name);
977 test_finished (); 1217 finish_command ();
978} 1218}
979 1219
980 1220
@@ -988,7 +1228,7 @@ del_lookup_error_cb (void *cls)
988 del_qe = NULL; 1228 del_qe = NULL;
989 GNUNET_break (0); 1229 GNUNET_break (0);
990 ret = 1; 1230 ret = 1;
991 test_finished (); 1231 finish_command ();
992} 1232}
993 1233
994 1234
@@ -1025,7 +1265,7 @@ del_monitor (void *cls,
1025 "There are no records under label `%s' that could be deleted.\n"), 1265 "There are no records under label `%s' that could be deleted.\n"),
1026 label); 1266 label);
1027 ret = 1; 1267 ret = 1;
1028 test_finished (); 1268 finish_command ();
1029 return; 1269 return;
1030 } 1270 }
1031 if ((NULL == value) && (NULL == typestring)) 1271 if ((NULL == value) && (NULL == typestring))
@@ -1067,7 +1307,7 @@ del_monitor (void *cls,
1067 _ ( 1307 _ (
1068 "There are no records under label `%s' that match the request for deletion.\n"), 1308 "There are no records under label `%s' that match the request for deletion.\n"),
1069 label); 1309 label);
1070 test_finished (); 1310 finish_command ();
1071 return; 1311 return;
1072 } 1312 }
1073 /* delete everything but what we copied to 'rdx' */ 1313 /* delete everything but what we copied to 'rdx' */
@@ -1081,59 +1321,6 @@ del_monitor (void *cls,
1081} 1321}
1082 1322
1083 1323
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 */
1092static int
1093parse_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
1137static void 1324static void
1138replace_cont (void *cls, enum GNUNET_ErrorCode ec) 1325replace_cont (void *cls, enum GNUNET_ErrorCode ec)
1139{ 1326{
@@ -1147,7 +1334,7 @@ replace_cont (void *cls, enum GNUNET_ErrorCode ec)
1147 GNUNET_ErrorCode_get_hint (ec)); 1334 GNUNET_ErrorCode_get_hint (ec));
1148 ret = 1; /* fail from 'main' */ 1335 ret = 1; /* fail from 'main' */
1149 } 1336 }
1150 GNUNET_SCHEDULER_shutdown (); 1337 finish_command ();
1151} 1338}
1152 1339
1153 1340
@@ -1173,14 +1360,7 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1173 { 1360 {
1174 /* nothing more to be done */ 1361 /* nothing more to be done */
1175 fprintf (stderr, _ ("No options given\n")); 1362 fprintf (stderr, _ ("No options given\n"));
1176 GNUNET_SCHEDULER_shutdown (); 1363 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; 1364 return;
1185 } 1365 }
1186 1366
@@ -1190,24 +1370,23 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1190 unsigned int rd_count; 1370 unsigned int rd_count;
1191 struct GNUNET_GNSRECORD_Data *rd; 1371 struct GNUNET_GNSRECORD_Data *rd;
1192 1372
1193 if (NULL == ego_name) 1373 /* FIXME: We could easily support append and delete with this as well */
1374 if (! add)
1194 { 1375 {
1195 fprintf (stderr, 1376 fprintf (stderr, _ ("Recordlines only work with option `%s'\n"),
1196 _ ("Missing option `%s' for operation `%s'\n"), 1377 "-a");
1197 "-z",
1198 _ ("replace"));
1199 GNUNET_SCHEDULER_shutdown ();
1200 ret = 1; 1378 ret = 1;
1379 finish_command ();
1201 return; 1380 return;
1202 } 1381 }
1203 if (NULL == name) 1382 if (NULL == name)
1204 { 1383 {
1205 fprintf (stderr, 1384 fprintf (stderr,
1206 _ ("Missing option `%s' for operation `%s'\n"), 1385 _ ("Missing option `%s' for operation `%s'\n"),
1207 "-R", 1386 "-n",
1208 _ ("replace")); 1387 _ ("name"));
1209 GNUNET_SCHEDULER_shutdown ();
1210 ret = 1; 1388 ret = 1;
1389 finish_command ();
1211 return; 1390 return;
1212 } 1391 }
1213 rd_count = 0; 1392 rd_count = 0;
@@ -1235,8 +1414,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1235 if (0 == strlen (nickstring)) 1414 if (0 == strlen (nickstring))
1236 { 1415 {
1237 fprintf (stderr, _ ("Invalid nick `%s'\n"), nickstring); 1416 fprintf (stderr, _ ("Invalid nick `%s'\n"), nickstring);
1238 GNUNET_SCHEDULER_shutdown ();
1239 ret = 1; 1417 ret = 1;
1418 finish_command ();
1240 return; 1419 return;
1241 } 1420 }
1242 add = 1; 1421 add = 1;
@@ -1258,8 +1437,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1258 _ ("Missing option `%s' for operation `%s'\n"), 1437 _ ("Missing option `%s' for operation `%s'\n"),
1259 "-z", 1438 "-z",
1260 _ ("add")); 1439 _ ("add"));
1261 GNUNET_SCHEDULER_shutdown ();
1262 ret = 1; 1440 ret = 1;
1441 finish_command ();
1263 return; 1442 return;
1264 } 1443 }
1265 if (NULL == name) 1444 if (NULL == name)
@@ -1268,8 +1447,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1268 _ ("Missing option `%s' for operation `%s'\n"), 1447 _ ("Missing option `%s' for operation `%s'\n"),
1269 "-n", 1448 "-n",
1270 _ ("add")); 1449 _ ("add"));
1271 GNUNET_SCHEDULER_shutdown ();
1272 ret = 1; 1450 ret = 1;
1451 finish_command ();
1273 return; 1452 return;
1274 } 1453 }
1275 if (NULL == typestring) 1454 if (NULL == typestring)
@@ -1278,16 +1457,16 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1278 _ ("Missing option `%s' for operation `%s'\n"), 1457 _ ("Missing option `%s' for operation `%s'\n"),
1279 "-t", 1458 "-t",
1280 _ ("add")); 1459 _ ("add"));
1281 GNUNET_SCHEDULER_shutdown ();
1282 ret = 1; 1460 ret = 1;
1461 finish_command ();
1283 return; 1462 return;
1284 } 1463 }
1285 type = GNUNET_GNSRECORD_typename_to_number (typestring); 1464 type = GNUNET_GNSRECORD_typename_to_number (typestring);
1286 if (UINT32_MAX == type) 1465 if (UINT32_MAX == type)
1287 { 1466 {
1288 fprintf (stderr, _ ("Unsupported type `%s'\n"), typestring); 1467 fprintf (stderr, _ ("Unsupported type `%s'\n"), typestring);
1289 GNUNET_SCHEDULER_shutdown ();
1290 ret = 1; 1468 ret = 1;
1469 finish_command ();
1291 return; 1470 return;
1292 } 1471 }
1293 if ((GNUNET_DNSPARSER_TYPE_SRV == type) || 1472 if ((GNUNET_DNSPARSER_TYPE_SRV == type) ||
@@ -1297,8 +1476,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1297 fprintf (stderr, 1476 fprintf (stderr,
1298 _ ("For DNS record types `SRV', `TLSA' and `OPENPGPKEY'")); 1477 _ ("For DNS record types `SRV', `TLSA' and `OPENPGPKEY'"));
1299 fprintf (stderr, ", please use a `BOX' record instead\n"); 1478 fprintf (stderr, ", please use a `BOX' record instead\n");
1300 GNUNET_SCHEDULER_shutdown ();
1301 ret = 1; 1479 ret = 1;
1480 finish_command ();
1302 return; 1481 return;
1303 } 1482 }
1304 if (NULL == value) 1483 if (NULL == value)
@@ -1308,7 +1487,7 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1308 "-V", 1487 "-V",
1309 _ ("add")); 1488 _ ("add"));
1310 ret = 1; 1489 ret = 1;
1311 GNUNET_SCHEDULER_shutdown (); 1490 finish_command ();
1312 return; 1491 return;
1313 } 1492 }
1314 if (GNUNET_OK != 1493 if (GNUNET_OK !=
@@ -1318,8 +1497,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1318 _ ("Value `%s' invalid for record type `%s'\n"), 1497 _ ("Value `%s' invalid for record type `%s'\n"),
1319 value, 1498 value,
1320 typestring); 1499 typestring);
1321 GNUNET_SCHEDULER_shutdown ();
1322 ret = 1; 1500 ret = 1;
1501 finish_command ();
1323 return; 1502 return;
1324 } 1503 }
1325 if (NULL == expirationstring) 1504 if (NULL == expirationstring)
@@ -1328,15 +1507,15 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1328 _ ("Missing option `%s' for operation `%s'\n"), 1507 _ ("Missing option `%s' for operation `%s'\n"),
1329 "-e", 1508 "-e",
1330 _ ("add")); 1509 _ ("add"));
1331 GNUNET_SCHEDULER_shutdown ();
1332 ret = 1; 1510 ret = 1;
1511 finish_command ();
1333 return; 1512 return;
1334 } 1513 }
1335 if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) 1514 if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime))
1336 { 1515 {
1337 fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); 1516 fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring);
1338 GNUNET_SCHEDULER_shutdown ();
1339 ret = 1; 1517 ret = 1;
1518 finish_command ();
1340 return; 1519 return;
1341 } 1520 }
1342 add_qe = GNUNET_NAMESTORE_records_lookup (ns, 1521 add_qe = GNUNET_NAMESTORE_records_lookup (ns,
@@ -1355,8 +1534,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1355 _ ("Missing option `%s' for operation `%s'\n"), 1534 _ ("Missing option `%s' for operation `%s'\n"),
1356 "-z", 1535 "-z",
1357 _ ("del")); 1536 _ ("del"));
1358 GNUNET_SCHEDULER_shutdown ();
1359 ret = 1; 1537 ret = 1;
1538 finish_command ();
1360 return; 1539 return;
1361 } 1540 }
1362 if (NULL == name) 1541 if (NULL == name)
@@ -1365,8 +1544,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1365 _ ("Missing option `%s' for operation `%s'\n"), 1544 _ ("Missing option `%s' for operation `%s'\n"),
1366 "-n", 1545 "-n",
1367 _ ("del")); 1546 _ ("del"));
1368 GNUNET_SCHEDULER_shutdown ();
1369 ret = 1; 1547 ret = 1;
1548 finish_command ();
1370 return; 1549 return;
1371 } 1550 }
1372 del_qe = GNUNET_NAMESTORE_records_lookup (ns, 1551 del_qe = GNUNET_NAMESTORE_records_lookup (ns,
@@ -1398,8 +1577,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1398 _ ("Missing option `%s' for operation `%s'\n"), 1577 _ ("Missing option `%s' for operation `%s'\n"),
1399 "-z", 1578 "-z",
1400 _ ("purge-zone")); 1579 _ ("purge-zone"));
1401 GNUNET_SCHEDULER_shutdown ();
1402 ret = 1; 1580 ret = 1;
1581 finish_command ();
1403 return; 1582 return;
1404 } 1583 }
1405 list_it = GNUNET_NAMESTORE_zone_iteration_start2 (ns, 1584 list_it = GNUNET_NAMESTORE_zone_iteration_start2 (ns,
@@ -1423,8 +1602,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1423 _ ("Missing option `%s' for operation `%s'\n"), 1602 _ ("Missing option `%s' for operation `%s'\n"),
1424 "-z", 1603 "-z",
1425 _ ("list")); 1604 _ ("list"));
1426 GNUNET_SCHEDULER_shutdown ();
1427 ret = 1; 1605 ret = 1;
1606 finish_command ();
1428 return; 1607 return;
1429 } 1608 }
1430 get_qe = GNUNET_NAMESTORE_records_lookup (ns, 1609 get_qe = GNUNET_NAMESTORE_records_lookup (ns,
@@ -1457,8 +1636,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1457 _ ("Missing option `%s' for operation `%s'\n"), 1636 _ ("Missing option `%s' for operation `%s'\n"),
1458 "-z", 1637 "-z",
1459 _ ("reverse-pkey")); 1638 _ ("reverse-pkey"));
1460 GNUNET_SCHEDULER_shutdown ();
1461 ret = 1; 1639 ret = 1;
1640 finish_command ();
1462 return; 1641 return;
1463 } 1642 }
1464 if (GNUNET_OK != 1643 if (GNUNET_OK !=
@@ -1468,7 +1647,9 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1468 fprintf (stderr, 1647 fprintf (stderr,
1469 _ ("Invalid public key for reverse lookup `%s'\n"), 1648 _ ("Invalid public key for reverse lookup `%s'\n"),
1470 reverse_pkey); 1649 reverse_pkey);
1471 GNUNET_SCHEDULER_shutdown (); 1650 ret = 1;
1651 finish_command ();
1652 return;
1472 } 1653 }
1473 reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns, 1654 reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns,
1474 &zone_pkey, 1655 &zone_pkey,
@@ -1489,8 +1670,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1489 _ ("Missing option `%s' for operation `%s'\n"), 1670 _ ("Missing option `%s' for operation `%s'\n"),
1490 "-z", 1671 "-z",
1491 _ ("uri")); 1672 _ ("uri"));
1492 GNUNET_SCHEDULER_shutdown ();
1493 ret = 1; 1673 ret = 1;
1674 finish_command ();
1494 return; 1675 return;
1495 } 1676 }
1496 1677
@@ -1502,8 +1683,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1502 GNUNET_IDENTITY_public_key_from_string (sh, &pkey))) 1683 GNUNET_IDENTITY_public_key_from_string (sh, &pkey)))
1503 { 1684 {
1504 fprintf (stderr, _ ("Invalid URI `%s'\n"), uri); 1685 fprintf (stderr, _ ("Invalid URI `%s'\n"), uri);
1505 GNUNET_SCHEDULER_shutdown ();
1506 ret = 1; 1686 ret = 1;
1687 finish_command ();
1507 return; 1688 return;
1508 } 1689 }
1509 if (NULL == expirationstring) 1690 if (NULL == expirationstring)
@@ -1512,15 +1693,15 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1512 _ ("Missing option `%s' for operation `%s'\n"), 1693 _ ("Missing option `%s' for operation `%s'\n"),
1513 "-e", 1694 "-e",
1514 _ ("add")); 1695 _ ("add"));
1515 GNUNET_SCHEDULER_shutdown ();
1516 ret = 1; 1696 ret = 1;
1697 finish_command ();
1517 return; 1698 return;
1518 } 1699 }
1519 if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime)) 1700 if (GNUNET_OK != parse_expiration (expirationstring, &etime_is_rel, &etime))
1520 { 1701 {
1521 fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring); 1702 fprintf (stderr, _ ("Invalid time format `%s'\n"), expirationstring);
1522 GNUNET_SCHEDULER_shutdown ();
1523 ret = 1; 1703 ret = 1;
1704 finish_command ();
1524 return; 1705 return;
1525 } 1706 }
1526 memset (&rd, 0, sizeof(rd)); 1707 memset (&rd, 0, sizeof(rd));
@@ -1556,34 +1737,155 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1556 } 1737 }
1557} 1738}
1558 1739
1740#define MAX_LINE_LEN 4086
1741
1742#define MAX_ARGS 20
1743
1744static int
1745get_identity_for_string (const char *str,
1746 struct GNUNET_IDENTITY_PrivateKey *zk)
1747{
1748 const struct GNUNET_IDENTITY_PrivateKey *privkey;
1749 struct GNUNET_IDENTITY_PublicKey pubkey;
1750 struct GNUNET_IDENTITY_PublicKey ego_pubkey;
1751 struct EgoEntry *ego_entry;
1752
1753 if (GNUNET_OK == GNUNET_IDENTITY_public_key_from_string (str,
1754 &pubkey))
1755 {
1756 for (ego_entry = ego_head;
1757 NULL != ego_entry; ego_entry = ego_entry->next)
1758 {
1759 privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1760 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &ego_pubkey);
1761 if (0 == memcmp (&ego_pubkey, &pubkey, sizeof (pubkey)))
1762 {
1763 *zk = *privkey;
1764 return GNUNET_OK;
1765 }
1766 }
1767 }
1768 else
1769 {
1770 for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next)
1771 {
1772 /** FIXME: Check for zTLD? **/
1773 if (0 != strcmp (str, ego_entry->identifier))
1774 continue;
1775 *zk = *GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1776 return GNUNET_OK;
1777 }
1778 }
1779 return GNUNET_NO;
1780}
1559 1781
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 */
1567static void 1782static void
1568identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) 1783process_command_stdin ()
1569{ 1784{
1570 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 1785 char buf[MAX_LINE_LEN];
1786 static struct GNUNET_IDENTITY_PrivateKey next_zone_key;
1787 static char next_name[GNUNET_DNSPARSER_MAX_NAME_LENGTH];
1788 static int finished = GNUNET_NO;
1789 static int have_next_zonekey = GNUNET_NO;
1790 int zonekey_set = GNUNET_NO;
1791 char *tmp;
1571 1792
1572 el = NULL;
1573 1793
1574 if (NULL == ego) 1794 if (GNUNET_YES == have_next_zonekey)
1795 {
1796 zone_pkey = next_zone_key;
1797 if (NULL != name)
1798 GNUNET_free (name);
1799 name = GNUNET_strdup (next_name);
1800 zonekey_set = GNUNET_YES;
1801 }
1802 while (NULL != fgets (buf, sizeof (buf), stdin))
1575 { 1803 {
1576 if (NULL != ego_name) 1804 if (1 >= strlen (buf))
1805 continue;
1806 if (buf[strlen (buf) - 1] == '\n')
1807 buf[strlen (buf) - 1] = '\0';
1808 /**
1809 * Check if this is a new name. If yes, and we have records, store them.
1810 */
1811 if (buf[strlen (buf) - 1] == ':')
1577 { 1812 {
1578 fprintf (stderr, 1813 memset (next_name, 0, sizeof (next_name));
1579 _ ("Ego `%s' not known to identity service\n"), 1814 strncpy (next_name, buf, strlen (buf) - 1);
1580 ego_name); 1815 tmp = strchr (next_name, '.');
1816 if (NULL == tmp)
1817 {
1818 fprintf (stderr, "Error parsing name `%s'\n", next_name);
1819 ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL);
1820 ret = 1;
1821 return;
1822 }
1823 if (GNUNET_OK != get_identity_for_string (tmp + 1, &next_zone_key))
1824 {
1825 fprintf (stderr, "Error parsing zone name `%s'\n", tmp + 1);
1826 ret = 1;
1827 GNUNET_SCHEDULER_shutdown ();
1828 return;
1829 }
1830 *tmp = '\0';
1831 printf ("Switching to new name `%s' in zone `%s'\n", next_name, tmp + 1);
1832 have_next_zonekey = GNUNET_YES;
1833 /* Run a command for the previous record set */
1834 if (NULL != recordset)
1835 {
1836 run_with_zone_pkey (cfg);
1837 return;
1838 }
1839 zone_pkey = next_zone_key;
1840 if (NULL != name)
1841 GNUNET_free (name);
1842 name = GNUNET_strdup (next_name);
1843 zonekey_set = GNUNET_YES;
1844 continue;
1581 } 1845 }
1846 if (GNUNET_NO == zonekey_set)
1847 {
1848 fprintf (stderr, "Warning, encountered recordline without zone\n");
1849 continue;
1850 }
1851 printf ("Parsing `%s'\n", buf);
1852 parse_recordline (buf);
1853 }
1854 if (GNUNET_NO == finished)
1855 {
1856 if (GNUNET_NO == zonekey_set)
1857 {
1858 fprintf (stderr, "Warning, encountered recordline without zone\n");
1859 }
1860 else if (NULL != recordset)
1861 {
1862 run_with_zone_pkey (cfg); /** one last time **/
1863 finished = GNUNET_YES;
1864 return;
1865 }
1866 }
1867 ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL);
1868 return;
1869}
1870
1871
1872static void
1873begin_cb (void *cls, enum GNUNET_ErrorCode ec)
1874{
1875 ns_qe = NULL;
1876 if (GNUNET_EC_NONE != ec)
1877 {
1878 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1879 "Failed to start transaction: %s\n",
1880 GNUNET_ErrorCode_get_hint (ec));
1582 GNUNET_SCHEDULER_shutdown (); 1881 GNUNET_SCHEDULER_shutdown ();
1583 ret = -1;
1584 return; 1882 return;
1585 } 1883 }
1586 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); 1884 if (read_from_stdin)
1885 {
1886 process_command_stdin ();
1887 return;
1888 }
1587 run_with_zone_pkey (cfg); 1889 run_with_zone_pkey (cfg);
1588} 1890}
1589 1891
@@ -1606,7 +1908,6 @@ id_connect_cb (void *cls,
1606 void **ctx, 1908 void **ctx,
1607 const char *name) 1909 const char *name)
1608{ 1910{
1609 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
1610 struct GNUNET_IDENTITY_PublicKey pk; 1911 struct GNUNET_IDENTITY_PublicKey pk;
1611 struct EgoEntry *ego_entry; 1912 struct EgoEntry *ego_entry;
1612 1913
@@ -1621,17 +1922,20 @@ id_connect_cb (void *cls,
1621 GNUNET_CONTAINER_DLL_insert_tail (ego_head, 1922 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
1622 ego_tail, 1923 ego_tail,
1623 ego_entry); 1924 ego_entry);
1925 if ((NULL != ego_name) &&
1926 (0 == strcmp (name, ego_name)))
1927 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
1624 return; 1928 return;
1625 } 1929 }
1626 if (NULL != ego) 1930 if (NULL != ego)
1627 return; 1931 return;
1628 if (NULL == ego_name) 1932 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} 1933}
1633 1934
1634 1935
1936
1937
1938
1635/** 1939/**
1636 * Main function that will be run. 1940 * Main function that will be run.
1637 * 1941 *
@@ -1644,202 +1948,36 @@ static void
1644run (void *cls, 1948run (void *cls,
1645 char *const *args, 1949 char *const *args,
1646 const char *cfgfile, 1950 const char *cfgfile,
1647 const struct GNUNET_CONFIGURATION_Handle *cfg) 1951 const struct GNUNET_CONFIGURATION_Handle *_cfg)
1648{ 1952{
1649 const char *pkey_str;
1650
1651 (void) cls; 1953 (void) cls;
1652 (void) args; 1954 (void) args;
1653 (void) cfgfile; 1955 (void) cfgfile;
1956 cfg = _cfg;
1654 if (NULL != args[0]) 1957 if (NULL != args[0])
1655 GNUNET_log ( 1958 GNUNET_log (
1656 GNUNET_ERROR_TYPE_WARNING, 1959 GNUNET_ERROR_TYPE_WARNING,
1657 _ ("Superfluous command line arguments (starting with `%s') ignored\n"), 1960 _ ("Superfluous command line arguments (starting with `%s') ignored\n"),
1658 args[0]); 1961 args[0]);
1659 if ((NULL != args[0]) && (NULL == uri))
1660 uri = GNUNET_strdup (args[0]);
1661 1962
1662 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, (void *) cfg); 1963 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, (void *) cfg);
1663 pkey_str = getenv ("GNUNET_NAMESTORE_EGO_PRIVATE_KEY"); 1964 ns = GNUNET_NAMESTORE_connect (cfg);
1664 if (NULL != pkey_str) 1965 if (NULL == ns)
1665 { 1966 {
1666 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (pkey_str, 1967 fprintf (stderr, _ ("Failed to connect to namestore\n"));
1667 strlen (pkey_str), 1968 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; 1969 return;
1681 } 1970 }
1682 idh = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, (void *) cfg); 1971 idh = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, (void *) cfg);
1683 if (NULL == idh) 1972 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 */
1706static int
1707multirecord_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 {
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 { 1973 {
1797 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1974 ret = -1;
1798 _ ("Invalid record data for type %s: `%s'.\n"), 1975 fprintf (stderr, _ ("Cannot connect to identity service\n"));
1799 GNUNET_GNSRECORD_number_to_typename (record.record_type), 1976 GNUNET_SCHEDULER_shutdown ();
1800 tok);
1801 return GNUNET_SYSERR;
1802 } 1977 }
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} 1978}
1813 1979
1814 1980
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 */
1824struct GNUNET_GETOPT_CommandLineOption
1825multirecord_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 1981
1844/** 1982/**
1845 * The main function for gnunet-namestore. 1983 * The main function for gnunet-namestore.
@@ -1851,6 +1989,7 @@ multirecord_option (char shortName,
1851int 1989int
1852main (int argc, char *const *argv) 1990main (int argc, char *const *argv)
1853{ 1991{
1992 int lret;
1854 struct GNUNET_GETOPT_CommandLineOption options[] = 1993 struct GNUNET_GETOPT_CommandLineOption options[] =
1855 { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add), 1994 { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add),
1856 GNUNET_GETOPT_option_flag ('d', 1995 GNUNET_GETOPT_option_flag ('d',
@@ -1861,6 +2000,10 @@ main (int argc, char *const *argv)
1861 "display", 2000 "display",
1862 gettext_noop ("display records"), 2001 gettext_noop ("display records"),
1863 &list), 2002 &list),
2003 GNUNET_GETOPT_option_flag ('S',
2004 "from-stdin",
2005 gettext_noop ("read commands from stdin"),
2006 &read_from_stdin),
1864 GNUNET_GETOPT_option_string ( 2007 GNUNET_GETOPT_option_string (
1865 'e', 2008 'e',
1866 "expiration", 2009 "expiration",
@@ -1885,19 +2028,16 @@ main (int argc, char *const *argv)
1885 gettext_noop ( 2028 gettext_noop (
1886 "name of the record to add/delete/display"), 2029 "name of the record to add/delete/display"),
1887 &name), 2030 &name),
1888 GNUNET_GETOPT_option_string ('r', 2031 GNUNET_GETOPT_option_flag ('r',
1889 "reverse", 2032 "recordline",
1890 "PKEY", 2033 gettext_noop ("Output in recordline format"),
2034 &output_recordline),
2035 GNUNET_GETOPT_option_string ('Z',
2036 "zone-to-name",
2037 "KEY",
1891 gettext_noop ( 2038 gettext_noop (
1892 "determine our name for the given PKEY"), 2039 "determine our name for the given KEY"),
1893 &reverse_pkey), 2040 &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', 2041 GNUNET_GETOPT_option_string ('t',
1902 "type", 2042 "type",
1903 "TYPE", 2043 "TYPE",
@@ -1956,7 +2096,7 @@ main (int argc, char *const *argv)
1956 "name of the ego controlling the zone"), 2096 "name of the ego controlling the zone"),
1957 &ego_name), 2097 &ego_name),
1958 GNUNET_GETOPT_OPTION_END }; 2098 GNUNET_GETOPT_OPTION_END };
1959 int lret; 2099
1960 2100
1961 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 2101 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1962 return 2; 2102 return 2;
diff --git a/src/namestore/test_namestore_put_multiple.sh b/src/namestore/test_namestore_put_multiple.sh
index f33fb1c3a..4c7340440 100644..100755
--- a/src/namestore/test_namestore_put_multiple.sh
+++ b/src/namestore/test_namestore_put_multiple.sh
@@ -24,25 +24,9 @@ if [ 0 -ne $ret ]; then
24 gnunet-identity -C randomtestingid 24 gnunet-identity -C randomtestingid
25fi 25fi
26 26
27function minimize_ttl {
28 ttl=10000000
29 arr=$1
30 # parse each element and update ttl to smallest one
31 for i in "${arr[@]}"
32 do
33 currttl=$(echo -n "$i" | cut -d' ' -f1)
34 if [ "$currttl" -lt "$ttl" ]
35 then
36 ttl=$currttl
37 fi
38
39 done
40 echo "$ttl"
41}
42
43function get_record_type { 27function get_record_type {
44 arr=$1 28 arr=$1
45 typ=$(echo -n "${arr[0]}" | cut -d' ' -f2) 29 typ=$(echo -n "${arr[0]}" | cut -d' ' -f1)
46 echo "$typ" 30 echo "$typ"
47} 31}
48 32
@@ -59,10 +43,14 @@ function testing {
59 typ=$(get_record_type "${records[@]}") 43 typ=$(get_record_type "${records[@]}")
60 for i in "${records[@]}" 44 for i in "${records[@]}"
61 do 45 do
62 recordstring+="-R $i" 46 recordstring+="$i"$'\n'
63 done 47 done
64 #echo "$recordstring" 48 echo "$recordstring"
65 gnunet-namestore -z randomtestingid -n "$label" "$recordstring" 2>&1 /dev/null 49 gnunet-namestore -a -S <<EOF
50$label.randomtestingid:
51 $recordstring
52EOF
53 ret=$?
66 if [ 0 -ne $ret ]; then 54 if [ 0 -ne $ret ]; then
67 echo "failed to add record $label: $recordstring" 55 echo "failed to add record $label: $recordstring"
68 fi 56 fi
@@ -75,26 +63,27 @@ function testing {
75# TEST CASES 63# TEST CASES
76# 1 64# 1
77echo "Testing adding of single A record with -R" 65echo "Testing adding of single A record with -R"
66declare -a arr=('A 1200 [r] 127.0.0.1')
78testing test1 "${arr[@]}" 67testing test1 "${arr[@]}"
79# 2 68# 2
80echo "Testing adding of multiple A records with -R" 69echo "Testing adding of multiple A records with -R"
81declare -a arr=('1200 A n 127.0.0.1' '2400 A n 127.0.0.2') 70declare -a arr=('A 1200 [r] 127.0.0.1' 'A 2400 [r] 127.0.0.2')
82testing test2 "${arr[@]}" 71testing test2 "${arr[@]}"
83# 3 72# 3
84echo "Testing adding of multiple different records with -R" 73echo "Testing adding of multiple different records with -R"
85declare -a arr=('1200 A n 127.0.0.1' '2400 AAAA n 2002::') 74declare -a arr=('A 1200 [r] 127.0.0.1' 'AAAA 2400 [r] 2002::')
86testing test3 "${arr[@]}" 75testing test3 "${arr[@]}"
87# 4 76# 4
88echo "Testing adding of single GNS2DNS record with -R" 77echo "Testing adding of single GNS2DNS record with -R"
89declare -a arr=('86400 GNS2DNS n gnu.org@127.0.0.1') 78declare -a arr=('GNS2DNS 86400 [r] gnu.org@127.0.0.1')
90testing test4 "${arr[@]}" 79testing test4 "${arr[@]}"
91# 5 80# 5
92echo "Testing adding of single GNS2DNS shadow record with -R" 81echo "Testing adding of single GNS2DNS shadow record with -R"
93declare -a arr=('86409 GNS2DNS s gnu.org@127.0.0.250') 82declare -a arr=('GNS2DNS 86409 [rs] gnu.org@127.0.0.250')
94testing test5 "${arr[@]}" 83testing test5 "${arr[@]}"
95# 6 84# 6
96echo "Testing adding of multiple GNS2DNS record with -R" 85echo "Testing adding of multiple GNS2DNS record with -R"
97declare -a arr=('1 GNS2DNS n gnunet.org@127.0.0.1' '3600 GNS2DNS s gnunet.org@127.0.0.2') 86declare -a arr=('GNS2DNS 1 [r] gnunet.org@127.0.0.1' 'GNS2DNS 3600 [s] gnunet.org@127.0.0.2')
98testing test6 "${arr[@]}" 87testing test6 "${arr[@]}"
99val=$(gnunet-gns -t GNS2DNS -u test6.randomtestingid) 88val=$(gnunet-gns -t GNS2DNS -u test6.randomtestingid)
100if [[ $val == *"127.0.0.1"* ]]; then 89if [[ $val == *"127.0.0.1"* ]]; then
@@ -108,16 +97,16 @@ if [[ $val == *"127.0.0.2"* ]]; then
108fi 97fi
109# 7 98# 7
110echo "Testing adding MX record with -R" 99echo "Testing adding MX record with -R"
111declare -a arr=('3600 MX n 10,mail') 100declare -a arr=('MX 3600 [r] 10,mail')
112testing test7 "${arr[@]}" 101testing test7 "${arr[@]}"
113# 8 102# 8
114echo "Testing adding TXT record with -R" 103echo "Testing adding TXT record with -R"
115declare -a arr=('3600 TXT n Pretty_Unicorns') 104declare -a arr=('TXT 3600 [r] Pretty_Unicorns')
116testing test8 "${arr[@]}" 105testing test8 "${arr[@]}"
117# 8 106# 8
118echo "Testing adding TXT record with -R" 107#echo "Testing adding TXT record with -R"
119declare -a arr=('3600 SRV n _autodiscover_old._tcp.bfh.ch.') 108#declare -a arr=('SRV 3600 [r] _autodiscover_old._tcp.bfh.ch.')
120testing test8 "${arr[@]}" 109#testing test8 "${arr[@]}"
121 110
122# CLEANUP 111# CLEANUP
123gnunet-identity -D randomtestingid 112gnunet-identity -D randomtestingid
diff --git a/src/namestore/test_namestore_put_stdin.sh b/src/namestore/test_namestore_put_stdin.sh
new file mode 100755
index 000000000..deb7bc4cb
--- /dev/null
+++ b/src/namestore/test_namestore_put_stdin.sh
@@ -0,0 +1,68 @@
1#!/bin/bash
2CONFIGURATION="test_namestore_api.conf"
3trap "gnunet-arm -e -c $CONFIGURATION" SIGINT
4
5LOCATION=$(which gnunet-config)
6if [ -z $LOCATION ]
7then
8 LOCATION="gnunet-config"
9fi
10$LOCATION --version 1> /dev/null
11if test $? != 0
12then
13 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
14 exit 77
15fi
16
17rm -rf `$LOCATION -c $CONFIGURATION -s PATHS -o GNUNET_HOME`
18TEST_RECORD_NAME="www3"
19TEST_RECORD_NAME2="www"
20TEST_IP="8.7.6.5"
21TEST_IP2="1.2.3.4"
22
23which timeout &> /dev/null && DO_TIMEOUT="timeout 5"
24
25function start_peer
26{
27 gnunet-arm -s -c $CONFIGURATION
28 gnunet-identity -C testego -c $CONFIGURATION
29 gnunet-identity -C testego2 -c $CONFIGURATION
30}
31
32function stop_peer
33{
34 gnunet-identity -D testego -c $CONFIGURATION
35 gnunet-identity -D testego2 -c $CONFIGURATION
36 gnunet-arm -e -c $CONFIGURATION
37}
38
39
40start_peer
41# Create a public record
42EGOKEY=`gnunet-identity -d | grep testego2 | cut -d' ' -f3`
43gnunet-namestore -a -c $CONFIGURATION -S <<EOF
44$TEST_RECORD_NAME.testego:
45 A 3600000000 [pr] $TEST_IP
46 TXT 21438201833 [r] $TEST_IP2
47
48 TXT 21438201833 [r] aslkdj asdlkjaslkd 232!
49
50$TEST_RECORD_NAME2.testego:
51 AAAA 324241223 [prS] ::dead:beef
52 A 111324241223000000 [pC] 1.1.1.1
53
54www7.$EGOKEY:
55 A 3600000000 [pr] $TEST_IP
56
57EOF
58NAMESTORE_RES=$?
59gnunet-namestore -D -r -c $CONFIGURATION
60stop_peer
61
62if [ $NAMESTORE_RES = 0 ]
63then
64 echo "PASS: Creating name in namestore"
65else
66 echo "FAIL: Creating name in namestore failed with $NAMESTORE_RES."
67 exit 1
68fi