plugin datastore mysql
[oweals/gnunet.git] / src / rps / gnunet-rps.c
index e859ed40bf52b712b2de7013ea2e4015d6cd3f81..3dbb8053e5e4a7494e1d421bddf8429f5a7f467b 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C)
+     Copyright (C)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 /**
  * @file rps/gnunet-rps.c
- * @brief rps tool
+ * @brief random peer sampling
  * @author Julius Bünger
  */
 #include "platform.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_rps_service.h"
+#include <inttypes.h>
 
 static int ret;
 
+/**
+ * RPS handle
+ */
+static struct GNUNET_RPS_Handle *rps_handle;
+
+/**
+ * Request handle
+ */
+static struct GNUNET_RPS_Request_Handle *req_handle;
+
+/**
+ * PeerID (Option --seed)
+ */
+static struct GNUNET_PeerIdentity *peer_id;
+
+
+/**
+ * Set an option of type 'struct GNUNET_PeerIdentity *' from the command line.
+ * A pointer to this function should be passed as part of the
+ * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
+ * of this type.  It should be followed by a pointer to a value of
+ * type 'struct GNUNET_PeerIdentity *', which will be allocated with the requested string.
+ *
+ * @param ctx command line processing context
+ * @param scls additional closure (will point to the 'char *',
+ *             which will be allocated)
+ * @param option name of the option
+ * @param value actual value of the option (a PeerID)
+ * @return #GNUNET_OK
+ */
+static int
+GNUNET_GETOPT_set_peerid (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
+                          void *scls, const char *option, const char *value)
+{
+  struct GNUNET_PeerIdentity **val = (struct GNUNET_PeerIdentity **) scls;
+
+  GNUNET_assert (NULL != value);
+  GNUNET_free_non_null (*val);
+  /* Not quite sure whether that is a sane way */
+  *val = GNUNET_new (struct GNUNET_PeerIdentity);
+  if (GNUNET_OK !=
+      GNUNET_CRYPTO_eddsa_public_key_from_string (value,
+                                                  strlen (value),
+                                                  &((*val)->public_key)))
+  {
+    FPRINTF (stderr, "Invalid peer ID %s\n", value);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Task run when user presses CTRL-C to abort.
+ * Cancels pending request and disconnects.
+ *
+ * @param cls NULL
+ */
+static void
+do_shutdown (void *cls)
+{
+  if (NULL != req_handle)
+    GNUNET_RPS_request_cancel (req_handle);
+  GNUNET_RPS_disconnect (rps_handle);
+}
+
+
+/**
+ * Callback called on receipt of reply.
+ * Prints replied PeerIDs.
+ *
+ * @param cls closure
+ * @param n number of peers
+ * @param recv_peers the received peers
+ */
+static void
+reply_handle (void *cls,
+              uint64_t n,
+              const struct GNUNET_PeerIdentity *recv_peers)
+{
+  uint64_t i;
+
+  req_handle = NULL;
+  for (i = 0; i < n; i++)
+  {
+    FPRINTF (stdout, "%s\n",
+        GNUNET_i2s_full (&recv_peers[i]));
+  }
+  ret = 0;
+
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
 /**
  * Main function that will be run by the scheduler.
  *
@@ -43,7 +138,26 @@ run (void *cls,
      const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  ret = 0;
+  static uint64_t num_peers;
+
+  rps_handle = GNUNET_RPS_connect (cfg);
+
+  if (NULL == peer_id)
+  { /* Request n PeerIDs */
+    /* If number was specified use it, else request single peer. */
+    num_peers = (NULL == args[0]) ? 1 : atoi (args[0]);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+        "Requesting %" PRIu64 " PeerIDs\n", num_peers);
+    req_handle = GNUNET_RPS_request_peers (rps_handle, num_peers, reply_handle, NULL);
+    GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
+  }
+  else
+  { /* Seed PeerID */
+    GNUNET_RPS_seed_ids (rps_handle, 1, peer_id);
+    FPRINTF (stdout, "Seeded PeerID %s\n", GNUNET_i2s_full (peer_id));
+    ret = 0;
+    GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+  }
 }
 
 /**
@@ -56,15 +170,20 @@ run (void *cls,
 int
 main (int argc, char *const *argv)
 {
+  const char helpstr[] =
+    "Get random GNUnet peers. If none is specified a single is requested.";
   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
+    {'s', "seed", "PEER_ID",
+      gettext_noop ("Seed a PeerID"),
+      GNUNET_YES, &GNUNET_GETOPT_set_peerid, &peer_id},
     GNUNET_GETOPT_OPTION_END
   };
   return (GNUNET_OK ==
           GNUNET_PROGRAM_run (argc,
                               argv,
-                              "gnunet-rps [options [value]]",
+                              "gnunet-rps [NUMBER_OF_PEERS]",
                               gettext_noop
-                              ("rps"),
+                              (helpstr),
                               options, &run, NULL)) ? ret : 1;
 }