+ {
+ dump_pc (pc);
+ return;
+ }
+ pc->address_list_size = pc->off;
+ pc->address_list = GNUNET_malloc (sizeof (struct AddressRecord) * pc->off);
+ GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO,
+ &print_address, pc);
+}
+
+
+/* ************************* GET URI ************************** */
+
+
+/**
+ * Print URI of the peer.
+ *
+ * @param cls the 'struct GetUriContext'
+ * @param peer identity of the peer (unused)
+ * @param hello addresses of the peer
+ * @param err_msg error message
+ */
+static void
+print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_HELLO_Message *hello,
+ const char *err_msg)
+{
+ if (peer == NULL)
+ {
+ pic = NULL;
+ if (err_msg != NULL)
+ FPRINTF (stderr,
+ _("Error in communication with PEERINFO service: %s\n"),
+ err_msg);
+ tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL);
+ return;
+ }
+
+ if (NULL == hello)
+ return;
+
+ char *uri = GNUNET_HELLO_compose_uri(hello, &GPI_plugins_find);
+ if (NULL != uri) {
+ printf ("%s\n", (const char *) uri);
+ GNUNET_free (uri);
+ }
+}
+
+
+/* ************************* import HELLO by URI ********************* */
+
+
+/**
+ * Continuation called from 'GNUNET_PEERINFO_add_peer'
+ *
+ * @param cls closure, NULL
+ * @param emsg error message, NULL on success
+ */
+static void
+add_continuation (void *cls,
+ const char *emsg)
+{
+ ac = NULL;
+ if (NULL != emsg)
+ fprintf (stderr,
+ _("Failure adding HELLO: %s\n"),
+ emsg);
+ tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL);
+}
+
+
+/**
+ * Parse the PUT URI given at the command line and add it to our peerinfo
+ * database.
+ *
+ * @param put_uri URI string to parse
+ * @return GNUNET_OK on success, GNUNET_SYSERR if the URI was invalid, GNUNET_NO on other errors
+ */
+static int
+parse_hello_uri (const char *put_uri)
+{
+ struct GNUNET_HELLO_Message *hello = NULL;
+
+ int ret = GNUNET_HELLO_parse_uri(put_uri, &my_public_key, &hello, &GPI_plugins_find);
+
+ if (NULL != hello) {
+ /* WARNING: this adds the address from URI WITHOUT verification! */
+ if (GNUNET_OK == ret)
+ ac = GNUNET_PEERINFO_add_peer (peerinfo, hello, &add_continuation, NULL);
+ else
+ tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL);
+ GNUNET_free (hello);
+ }
+
+ /* wait 1s to give peerinfo operation a chance to succeed */
+ /* FIXME: current peerinfo API sucks to require this; not to mention
+ that we get no feedback to determine if the operation actually succeeded */
+ return ret;
+}
+
+
+/* ************************ Main state machine ********************* */
+
+
+/**
+ * Main state machine that goes over all options and
+ * runs the next requested function.
+ *
+ * @param cls unused
+ * @param tc scheduler context
+ */
+static void
+shutdown_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct PrintContext *pc;
+ struct AddressRecord *ar;
+ unsigned int i;
+
+ if (NULL != ac)
+ {
+ GNUNET_PEERINFO_add_peer_cancel (ac);
+ ac = NULL;
+ }
+ if (GNUNET_SCHEDULER_NO_TASK != tt)
+ {
+ GNUNET_SCHEDULER_cancel (tt);
+ tt = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL != pic)
+ {
+ GNUNET_PEERINFO_iterate_cancel (pic);
+ pic = NULL;
+ }
+ while (NULL != (pc = pc_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (pc_head,
+ pc_tail,
+ pc);
+ for (i=0;i<pc->address_list_size;i++)