aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-11-20 20:27:49 +0900
committerMartin Schanzenbach <schanzen@gnunet.org>2022-11-21 14:05:37 +0900
commit9ee83b68ee601fcfb7026c4b41f8977dba9d372b (patch)
tree6497d1096cef8a28d473908acbe59db41efb2ebb
parent5af36f7f2a3992c1705ec1f8b178fe7d95a48c47 (diff)
downloadgnunet-9ee83b68ee601fcfb7026c4b41f8977dba9d372b.tar.gz
gnunet-9ee83b68ee601fcfb7026c4b41f8977dba9d372b.zip
NAMESTORE: Add recordline format for zone import and display
-rw-r--r--doc/man/gnunet-namestore.132
-rw-r--r--src/namestore/Makefile.am1
-rw-r--r--src/namestore/gnunet-namestore.c421
-rwxr-xr-x[-rw-r--r--]src/namestore/test_namestore_put_multiple.sh49
-rwxr-xr-xsrc/namestore/test_namestore_put_stdin.sh62
5 files changed, 303 insertions, 262 deletions
diff --git a/doc/man/gnunet-namestore.1 b/doc/man/gnunet-namestore.1
index 9391e21bb..c70e4499d 100644
--- a/doc/man/gnunet-namestore.1
+++ b/doc/man/gnunet-namestore.1
@@ -46,6 +46,7 @@
46.Op Fl r Ar PKEY | Fl -reverse= Ns Ar PKEY 46.Op Fl r Ar PKEY | Fl -reverse= Ns Ar PKEY
47.Op Fl R Ar RECORDLINE | Fl -replace= Ns Ar RECORDLINE 47.Op Fl R Ar RECORDLINE | Fl -replace= Ns Ar RECORDLINE
48.Op Fl s | -shadow 48.Op Fl s | -shadow
49.Op Fl S | -from-stdin
49.Op Fl T | -include-maintenance 50.Op Fl T | -include-maintenance
50.Op Fl t Ar TYPE | Fl -type= Ns Ar TYPE 51.Op Fl t Ar TYPE | Fl -type= Ns Ar TYPE
51.Op Fl u Ar URI | Fl -uri= Ns Ar URI 52.Op Fl u Ar URI | Fl -uri= Ns Ar URI
@@ -119,6 +120,12 @@ The VALUE follows the usual human-readable value format(s) of DNS/GNS.
119Create a record that is a shadow record. 120Create a record that is a shadow record.
120Shadow records are only used once all other records of the same type 121Shadow records are only used once all other records of the same type
121under the same label have expired. 122under the same label have expired.
123.It Fl S | -from-stdin
124This reads commands from stdin until EOF is encountered.
125The commands are formatted like the arguments used for gnunet-namestore.
126Arguments that
127.B cannot
128be used for commands in this mode are: -l, -L, -D, -S, -m, -h, -c, -v, -r, -o, -T, -O
122.It Fl T | -include-maintenance 129.It Fl T | -include-maintenance
123Show maintenance records such as TOMBSTONEs. Use in combination with --display. 130Show maintenance records such as TOMBSTONEs. Use in combination with --display.
124.It Fl t Ar TYPE | Fl -type= Ns Ar TYPE 131.It Fl t Ar TYPE | Fl -type= Ns Ar TYPE
@@ -145,7 +152,30 @@ variable. The latter is useful to improve performance of tools like
145Ascension as it allows the command to skip IPC with the identity 152Ascension as it allows the command to skip IPC with the identity
146management subsystem. 153management subsystem.
147.El 154.El
148.\".Sh EXAMPLES 155.Sh EXAMPLES
156.Tp
157.Nm
158-z example -a -n www -t A -V "1.2.3.4" -e 1d -p
159.Tp
160.Pp
161.Dl Add a public record for ego "example" with name "www" containing an IP address.
162.sp
163.Tp
164.Nm
165-z example -D
166.Tp
167.Pp
168.Dl Show all records for ego "example"
169.sp
170.Tp
171.Nm
172--from-stdin <<EOF
173 -z alice -a -n www -t A -V "1.2.3.4" -e 3600s -p
174 -z bob -a -n www -t A -V "4.3.2.1" -e 24h -p
175 EOF
176.Tp
177.Pp
178.Dl Read record multiple import commands from stdin.
149.\".Sh FILES 179.\".Sh FILES
150.Sh SEE ALSO 180.Sh SEE ALSO
151.Xr gnunet-gns 1 , 181.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 cc887c845..ee59e7432 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
@@ -129,11 +130,6 @@ static struct GNUNET_IDENTITY_Handle *idh;
129static char *ego_name; 130static char *ego_name;
130 131
131/** 132/**
132 * Desired action is to add a record.
133 */
134static int add;
135
136/**
137 * Queue entry for the 'add-uri' operation. 133 * Queue entry for the 'add-uri' operation.
138 */ 134 */
139static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri; 135static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri;
@@ -179,11 +175,6 @@ static struct EgoEntry *ego_head;
179static struct EgoEntry *ego_tail; 175static struct EgoEntry *ego_tail;
180 176
181/** 177/**
182 * Desired action is to list records.
183 */
184static int list;
185
186/**
187 * List iterator for the 'list' operation. 178 * List iterator for the 'list' operation.
188 */ 179 */
189static struct GNUNET_NAMESTORE_ZoneIterator *list_it; 180static struct GNUNET_NAMESTORE_ZoneIterator *list_it;
@@ -194,6 +185,16 @@ static struct GNUNET_NAMESTORE_ZoneIterator *list_it;
194static int read_from_stdin; 185static int read_from_stdin;
195 186
196/** 187/**
188 * Desired action is to list records.
189 */
190static int list;
191
192/**
193 * Desired action is to add a record.
194 */
195static int add;
196
197/**
197 * Desired action is to remove a record. 198 * Desired action is to remove a record.
198 */ 199 */
199static int del; 200static int del;
@@ -214,6 +215,12 @@ static int is_shadow;
214static int omit_private; 215static int omit_private;
215 216
216/** 217/**
218 * Output in recordline format
219 */
220static int output_recordline;
221
222
223/**
217 * Purge zone contents 224 * Purge zone contents
218 */ 225 */
219static int purge_zone; 226static int purge_zone;
@@ -386,79 +393,46 @@ parse_expiration (const char *expirationstring,
386} 393}
387 394
388 395
389
390/**
391 * Command-line option parser function that allows the user to specify
392 * a complete record as one argument for adding/removing. A pointer
393 * to the head of the list of record sets must be passed as the "scls"
394 * argument.
395 *
396 * @param ctx command line processor context
397 * @param scls must be of type "struct GNUNET_FS_Uri **"
398 * @param option name of the option (typically 'R')
399 * @param value command line argument given; format is
400 * "TTL TYPE FLAGS VALUE" where TTL is an expiration time (rel or abs),
401 * always given in seconds (without the unit),
402 * TYPE is a DNS/GNS record type, FLAGS is either "n" for no flags or
403 * a combination of 's' (shadow) and 'p' (public) and VALUE is the
404 * value (in human-readable format)
405 * @return #GNUNET_OK on success
406 */
407static int 396static int
408multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 397parse_recordline (const char *line)
409 void *scls,
410 const char *option,
411 const char *value)
412{ 398{
413 struct RecordSetEntry **head = scls; 399 struct RecordSetEntry **head = &recordset;
414 struct RecordSetEntry *r; 400 struct RecordSetEntry *r;
415 struct GNUNET_GNSRECORD_Data record; 401 struct GNUNET_GNSRECORD_Data record;
416 char *cp; 402 char *cp;
417 char *tok; 403 char *tok;
418 char *saveptr; 404 char *saveptr;
419 int etime_is_rel;
420 void *raw_data; 405 void *raw_data;
421 406
422 (void) ctx; 407 cp = GNUNET_strdup (line);
423 (void) option;
424 cp = GNUNET_strdup (value);
425 tok = strtok_r (cp, " ", &saveptr); 408 tok = strtok_r (cp, " ", &saveptr);
426 if (NULL == tok) 409 if (NULL == tok)
427 { 410 {
428 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 411 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
429 _ ("Empty record line argument is not allowed.\n")); 412 _ ("Missing entries in record line `%s'.\n"),
413 line);
430 GNUNET_free (cp); 414 GNUNET_free (cp);
431 return GNUNET_SYSERR; 415 return GNUNET_SYSERR;
432 } 416 }
417 record.record_type = GNUNET_GNSRECORD_typename_to_number (tok);
418 if (UINT32_MAX == record.record_type)
433 { 419 {
434 char *etime_in_s; 420 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Unknown record type `%s'\n"), tok);
435 421 GNUNET_free (cp);
436 GNUNET_asprintf (&etime_in_s, "%s s", tok); 422 return GNUNET_SYSERR;
437 if (GNUNET_OK !=
438 parse_expiration (etime_in_s, &etime_is_rel, &record.expiration_time))
439 {
440 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
441 _ ("Invalid expiration time `%s' (must be without unit)\n"),
442 tok);
443 GNUNET_free (cp);
444 GNUNET_free (etime_in_s);
445 return GNUNET_SYSERR;
446 }
447 GNUNET_free (etime_in_s);
448 } 423 }
449 tok = strtok_r (NULL, " ", &saveptr); 424 tok = strtok_r (NULL, " ", &saveptr);
450 if (NULL == tok) 425 if (NULL == tok)
451 { 426 {
452 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 427 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
453 _ ("Missing entries in record line `%s'.\n"), 428 _ ("Empty record line argument is not allowed.\n"));
454 value);
455 GNUNET_free (cp); 429 GNUNET_free (cp);
456 return GNUNET_SYSERR; 430 return GNUNET_SYSERR;
457 } 431 }
458 record.record_type = GNUNET_GNSRECORD_typename_to_number (tok); 432 if (1 != sscanf (tok, "%" SCNu64, &record.expiration_time))
459 if (UINT32_MAX == record.record_type)
460 { 433 {
461 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Unknown record type `%s'\n"), tok); 434 fprintf (stderr,
435 _ ("Error parsing expiration time %s.\n"), tok);
462 GNUNET_free (cp); 436 GNUNET_free (cp);
463 return GNUNET_SYSERR; 437 return GNUNET_SYSERR;
464 } 438 }
@@ -466,30 +440,29 @@ multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
466 if (NULL == tok) 440 if (NULL == tok)
467 { 441 {
468 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 442 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
469 _ ("Missing entries in record line `%s'.\n"), 443 _ ("Empty record line argument is not allowed.\n"));
470 value);
471 GNUNET_free (cp); 444 GNUNET_free (cp);
472 return GNUNET_SYSERR; 445 return GNUNET_SYSERR;
473 } 446 }
474 record.flags = GNUNET_GNSRECORD_RF_NONE; 447 record.flags = GNUNET_GNSRECORD_RF_NONE;
475 if (etime_is_rel) 448 if (NULL != strchr (tok, (unsigned char) 'r'))
476 record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; 449 record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
477 if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */ 450 if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */
478 record.flags |= GNUNET_GNSRECORD_RF_PRIVATE; 451 record.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
452 if (NULL != strchr (tok, (unsigned char) 'S'))
453 record.flags |= GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
479 if (NULL != strchr (tok, (unsigned char) 's')) 454 if (NULL != strchr (tok, (unsigned char) 's'))
480 record.flags |= GNUNET_GNSRECORD_RF_SHADOW; 455 record.flags |= GNUNET_GNSRECORD_RF_SHADOW;
481 /* find beginning of record value */ 456 if (NULL != strchr (tok, (unsigned char) 'C'))
482 tok = strchr (&value[tok - cp], (unsigned char) ' '); 457 record.flags |= GNUNET_GNSRECORD_RF_CRITICAL;
458 tok = strtok_r (NULL, " ", &saveptr);
483 if (NULL == tok) 459 if (NULL == tok)
484 { 460 {
485 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 461 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
486 _ ("Missing entries in record line `%s'.\n"), 462 _ ("Empty record line argument is not allowed.\n"));
487 value);
488 GNUNET_free (cp); 463 GNUNET_free (cp);
489 return GNUNET_SYSERR; 464 return GNUNET_SYSERR;
490 } 465 }
491 GNUNET_free (cp);
492 tok++; /* skip space */
493 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record.record_type, 466 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record.record_type,
494 tok, 467 tok,
495 &raw_data, 468 &raw_data,
@@ -512,44 +485,45 @@ multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
512 return GNUNET_OK; 485 return GNUNET_OK;
513} 486}
514 487
515/**
516 * Allow user to specify keywords.
517 *
518 * @param shortName short name of the option
519 * @param name long name of the option
520 * @param argumentHelp help text for the option argument
521 * @param description long help text for the option
522 * @param[out] topKeywords set to the desired value
523 */
524struct GNUNET_GETOPT_CommandLineOption
525multirecord_option (char shortName,
526 const char *name,
527 const char *argumentHelp,
528 const char *description,
529 struct RecordSetEntry **rs)
530{
531 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
532 .name = name,
533 .argumentHelp = argumentHelp,
534 .description = description,
535 .require_argument = 1,
536 .processor =
537 &multirecord_process,
538 .scls = (void *) rs };
539
540 return clo;
541}
542
543static void 488static void
544reset_handles (void) 489reset_handles (void)
545{ 490{
546 struct MarkedRecord *mrec; 491 struct MarkedRecord *mrec;
547 struct MarkedRecord *mrec_tmp; 492 struct MarkedRecord *mrec_tmp;
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;
548 if (NULL != ego_name) 502 if (NULL != ego_name)
549 { 503 {
550 GNUNET_free (ego_name); 504 GNUNET_free (ego_name);
551 ego_name = NULL; 505 ego_name = NULL;
552 } 506 }
507 if (NULL != name)
508 {
509 GNUNET_free (name);
510 name = NULL;
511 }
512 if (NULL != value)
513 {
514 GNUNET_free (value);
515 value = NULL;
516 }
517 if (NULL != uri)
518 {
519 GNUNET_free (uri);
520 uri = NULL;
521 }
522 if (NULL != expirationstring)
523 {
524 GNUNET_free (expirationstring);
525 expirationstring = NULL;
526 }
553 if (NULL != purge_task) 527 if (NULL != purge_task)
554 { 528 {
555 GNUNET_SCHEDULER_cancel (purge_task); 529 GNUNET_SCHEDULER_cancel (purge_task);
@@ -598,11 +572,6 @@ reset_handles (void)
598 reverse_qe = NULL; 572 reverse_qe = NULL;
599 } 573 }
600 memset (&zone_pkey, 0, sizeof(zone_pkey)); 574 memset (&zone_pkey, 0, sizeof(zone_pkey));
601 if (NULL != uri)
602 {
603 GNUNET_free (uri);
604 uri = NULL;
605 }
606 if (NULL != zm) 575 if (NULL != zm)
607 { 576 {
608 GNUNET_NAMESTORE_zone_monitor_stop (zm); 577 GNUNET_NAMESTORE_zone_monitor_stop (zm);
@@ -613,6 +582,15 @@ reset_handles (void)
613 GNUNET_free (data); 582 GNUNET_free (data);
614 data = NULL; 583 data = NULL;
615 } 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;
616} 594}
617 595
618 596
@@ -928,18 +906,33 @@ display_record (const struct GNUNET_IDENTITY_PrivateKey *zone_key,
928 at.abs_value_us = rd[i].expiration_time; 906 at.abs_value_us = rd[i].expiration_time;
929 ets = GNUNET_STRINGS_absolute_time_to_string (at); 907 ets = GNUNET_STRINGS_absolute_time_to_string (at);
930 } 908 }
931 fprintf (stdout, 909 char flgstr[16];
932 "\t%s: %s (%s)\t%s\t%s\n", 910 sprintf (flgstr, "[%s%s%s%s%s]",
933 typestr, 911 (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE) ? "" : "p",
934 s, 912 (rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL) ? "S" : "",
935 ets, 913 (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION) ? "r" : "",
936 (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"
937 : "PUBLIC", 930 : "PUBLIC",
938 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW)) ? "SHADOW" 931 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW)) ? "SHADOW"
939 : ""); 932 : "");
940 GNUNET_free (s); 933 GNUNET_free (s);
941 } 934 }
942 fprintf (stdout, "%s", "\n"); 935 // fprintf (stdout, "%s", "\n");
943} 936}
944 937
945static void 938static void
@@ -1377,22 +1370,21 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg)
1377 unsigned int rd_count; 1370 unsigned int rd_count;
1378 struct GNUNET_GNSRECORD_Data *rd; 1371 struct GNUNET_GNSRECORD_Data *rd;
1379 1372
1380 if (NULL == ego_name) 1373 /* FIXME: We could easily support append and delete with this as well */
1374 if (!add)
1381 { 1375 {
1382 fprintf (stderr, 1376 fprintf (stderr, _("Recordlines only work with option `%s'\n"),
1383 _ ("Missing option `%s' for operation `%s'\n"), 1377 "-a");
1384 "-z",
1385 _ ("replace"));
1386 ret = 1; 1378 ret = 1;
1387 finish_command (); 1379 finish_command();
1388 return; 1380 return;
1389 } 1381 }
1390 if (NULL == name) 1382 if (NULL == name)
1391 { 1383 {
1392 fprintf (stderr, 1384 fprintf (stderr,
1393 _ ("Missing option `%s' for operation `%s'\n"), 1385 _ ("Missing option `%s' for operation `%s'\n"),
1394 "-R", 1386 "-n",
1395 _ ("replace")); 1387 _ ("name"));
1396 ret = 1; 1388 ret = 1;
1397 finish_command (); 1389 finish_command ();
1398 return; 1390 return;
@@ -1754,120 +1746,90 @@ process_command_stdin ()
1754{ 1746{
1755 struct EgoEntry *ego_entry; 1747 struct EgoEntry *ego_entry;
1756 char buf[MAX_LINE_LEN]; 1748 char buf[MAX_LINE_LEN];
1757 char *tmp_argv[MAX_ARGS]; 1749 static struct GNUNET_IDENTITY_PrivateKey next_zone_key;
1758 unsigned int tmp_argc = 0; 1750 static char next_name[GNUNET_DNSPARSER_MAX_NAME_LENGTH];
1751 static int finished = GNUNET_NO;
1752 static int have_next_zonekey = GNUNET_NO;
1753 int zonekey_set = GNUNET_NO;
1759 char *tmp; 1754 char *tmp;
1760 struct GNUNET_GETOPT_CommandLineOption options[] =
1761 { GNUNET_GETOPT_option_flag ('a', "add", gettext_noop ("add record"), &add),
1762 GNUNET_GETOPT_option_flag ('d',
1763 "delete",
1764 gettext_noop ("delete record"),
1765 &del),
1766 GNUNET_GETOPT_option_string (
1767 'e',
1768 "expiration",
1769 "TIME",
1770 gettext_noop (
1771 "expiration time for record to use (for adding only), \"never\" is possible"),
1772 &expirationstring),
1773 GNUNET_GETOPT_option_string ('i',
1774 "nick",
1775 "NICKNAME",
1776 gettext_noop (
1777 "set the desired nick name for the zone"),
1778 &nickstring),
1779 GNUNET_GETOPT_option_string ('n',
1780 "name",
1781 "NAME",
1782 gettext_noop (
1783 "name of the record to add/delete/display"),
1784 &name),
1785 multirecord_option (
1786 'R',
1787 "replace",
1788 "RECORDLINE",
1789 gettext_noop (
1790 "set record set to values given by (possibly multiple) RECORDLINES; can be specified multiple times"),
1791 &recordset),
1792 GNUNET_GETOPT_option_string ('t',
1793 "type",
1794 "TYPE",
1795 gettext_noop (
1796 "type of the record to add/delete/display"),
1797 &typestring),
1798 GNUNET_GETOPT_option_string ('u',
1799 "uri",
1800 "URI",
1801 gettext_noop ("URI to import into our zone"),
1802 &uri),
1803 GNUNET_GETOPT_option_string ('V',
1804 "value",
1805 "VALUE",
1806 gettext_noop (
1807 "value of the record to add/delete"),
1808 &value),
1809 GNUNET_GETOPT_option_flag ('p',
1810 "public",
1811 gettext_noop ("create or list public record"),
1812 &is_public),
1813 GNUNET_GETOPT_option_flag ('P',
1814 "purge-orphans",
1815 gettext_noop (
1816 "purge namestore of all orphans"),
1817 &purge_orphaned),
1818 GNUNET_GETOPT_option_flag ('X',
1819 "purge-zone-records",
1820 gettext_noop (
1821 "delete all records in specified zone"),
1822 &purge_zone),
1823 GNUNET_GETOPT_option_flag (
1824 's',
1825 "shadow",
1826 gettext_noop (
1827 "create shadow record (only valid if all other records of the same type have expired"),
1828 &is_shadow),
1829 GNUNET_GETOPT_option_string ('z',
1830 "zone",
1831 "EGO",
1832 gettext_noop (
1833 "name of the ego controlling the zone"),
1834 &ego_name),
1835 GNUNET_GETOPT_OPTION_END };
1836 1755
1837 1756
1838 if (NULL == fgets (buf, sizeof (buf), stdin)) 1757 if (GNUNET_YES == have_next_zonekey)
1839 {
1840 ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL);
1841 return;
1842 }
1843 if (buf[strlen (buf) - 1] == '\n')
1844 buf[strlen (buf) - 1] = '\0';
1845 /* We need to build a char *const *argv here */
1846 /* I guess strtok on space */
1847 tmp = strtok (buf, " ");
1848 if (NULL == tmp)
1849 { 1758 {
1850 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1759 zone_pkey = next_zone_key;
1851 "Error parsing line %s\n", buf); 1760 if (NULL != name)
1852 GNUNET_SCHEDULER_shutdown (); 1761 GNUNET_free (name);
1853 return; 1762 name = GNUNET_strdup (next_name);
1763 zonekey_set = GNUNET_YES;
1854 } 1764 }
1855 tmp_argv[0] = tmp; 1765 while (NULL != fgets (buf, sizeof (buf), stdin))
1856 tmp_argc = 1;
1857 while (NULL != (tmp = strtok (NULL, " ")))
1858 { 1766 {
1859 tmp_argv[tmp_argc] = tmp; 1767 if (1 >= strlen (buf))
1860 tmp_argc++; 1768 continue;
1769 if (buf[strlen (buf) - 1] == '\n')
1770 buf[strlen (buf) - 1] = '\0';
1771 /**
1772 * Check if this is a new name. If yes, and we have records, store them.
1773 */
1774 if (buf[strlen (buf) - 1] == ':')
1775 {
1776 memset (next_name, 0, sizeof (next_name));
1777 strncpy (next_name, buf, strlen (buf) - 1);
1778 tmp = strchr (next_name, '.');
1779 if (NULL == tmp)
1780 {
1781 fprintf (stderr, "Error parsing name `%s'\n", next_name);
1782 ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL);
1783 ret = 1;
1784 return;
1785 }
1786 for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next)
1787 {
1788 /** FIXME: Check for zTLD? **/
1789 if (0 != strcmp (tmp + 1, ego_entry->identifier))
1790 continue;
1791 next_zone_key = *GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1792 break;
1793 }
1794 *tmp = '\0';
1795 printf ("Switching to new name `%s' in zone `%s'\n", next_name, tmp + 1);
1796 have_next_zonekey = GNUNET_YES;
1797 /* Run a command for the previous record set */
1798 if (NULL != recordset)
1799 {
1800 run_with_zone_pkey (cfg);
1801 return;
1802 }
1803 zone_pkey = next_zone_key;
1804 if (NULL != name)
1805 GNUNET_free (name);
1806 name = GNUNET_strdup (next_name);
1807 zonekey_set = GNUNET_YES;
1808 continue;
1809 }
1810 if (GNUNET_NO == zonekey_set)
1811 {
1812 fprintf (stderr, "Warning, encountered recordline without zone\n");
1813 continue;
1814 }
1815 printf ("Parsing `%s'\n", buf);
1816 parse_recordline (buf);
1861 } 1817 }
1862 GNUNET_GETOPT_run ("gnunet-namestore", options, tmp_argc, tmp_argv); 1818 if (GNUNET_NO == finished)
1863 for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next)
1864 { 1819 {
1865 if (0 != strcmp (ego_entry->identifier, ego_name)) 1820 if (GNUNET_NO == zonekey_set)
1866 continue; 1821 {
1867 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 1822 fprintf (stderr, "Warning, encountered recordline without zone\n");
1868 break; 1823 }
1824 else if (NULL != recordset)
1825 {
1826 run_with_zone_pkey (cfg); /** one last time **/
1827 finished = GNUNET_YES;
1828 return;
1829 }
1869 } 1830 }
1870 run_with_zone_pkey (cfg); 1831 ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, &commit_cb, NULL);
1832 return;
1871} 1833}
1872 1834
1873 1835
@@ -2030,19 +1992,16 @@ main (int argc, char *const *argv)
2030 gettext_noop ( 1992 gettext_noop (
2031 "name of the record to add/delete/display"), 1993 "name of the record to add/delete/display"),
2032 &name), 1994 &name),
2033 GNUNET_GETOPT_option_string ('r', 1995 GNUNET_GETOPT_option_flag ('r',
2034 "reverse", 1996 "recordline",
2035 "PKEY", 1997 gettext_noop ("Output in recordline format"),
1998 &output_recordline),
1999 GNUNET_GETOPT_option_string ('Z',
2000 "zone-to-name",
2001 "KEY",
2036 gettext_noop ( 2002 gettext_noop (
2037 "determine our name for the given PKEY"), 2003 "determine our name for the given KEY"),
2038 &reverse_pkey), 2004 &reverse_pkey),
2039 multirecord_option (
2040 'R',
2041 "replace",
2042 "RECORDLINE",
2043 gettext_noop (
2044 "set record set to values given by (possibly multiple) RECORDLINES; can be specified multiple times"),
2045 &recordset),
2046 GNUNET_GETOPT_option_string ('t', 2005 GNUNET_GETOPT_option_string ('t',
2047 "type", 2006 "type",
2048 "TYPE", 2007 "TYPE",
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..8fdcaa23f
--- /dev/null
+++ b/src/namestore/test_namestore_put_stdin.sh
@@ -0,0 +1,62 @@
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}
30
31function stop_peer
32{
33 gnunet-identity -D testego -c $CONFIGURATION
34 gnunet-arm -e -c $CONFIGURATION
35}
36
37
38start_peer
39# Create a public record
40gnunet-namestore -a -c $CONFIGURATION -S <<EOF
41$TEST_RECORD_NAME.testego:
42 A 3600000000 [pr] $TEST_IP
43 TXT 21438201833 [r] $TEST_IP2
44
45 TXT 21438201833 [r] aslkdj asdlkjaslkd 232!
46
47$TEST_RECORD_NAME2.testego:
48 AAAA 324241223 [prS] ::dead:beef
49 A 111324241223000000 [pC] 1.1.1.1
50
51EOF
52NAMESTORE_RES=$?
53gnunet-namestore -z testego -D -r -c $CONFIGURATION
54stop_peer
55
56if [ $NAMESTORE_RES = 0 ]
57then
58 echo "PASS: Creating name in namestore"
59else
60 echo "FAIL: Creating name in namestore failed with $NAMESTORE_RES."
61 exit 1
62fi