-add ego creation
[oweals/gnunet.git] / src / identity / gnunet-identity.c
index 15cb17d1b4e5ee12097f1f9c27a9ffd5346ecb78..c167ce95937e9eb3527d6bfd22ee09a1eaefa9ed 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2013 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2013 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -21,6 +21,9 @@
  * @file identity/gnunet-identity.c
  * @brief IDENTITY management command line tool
  * @author Christian Grothoff
+ *
+ * Todo:
+ * - add options to get default egos
  */
 #include "platform.h"
 #include "gnunet_util_lib.h"
@@ -51,6 +54,21 @@ static char *create_ego;
  */
 static char *delete_ego;
 
+/**
+ * -s option.
+ */
+static char *set_ego;
+
+/**
+ * -S option.
+ */
+static char *set_subsystem;
+
+/**
+ * Operation handle for set operation.
+ */
+static struct GNUNET_IDENTITY_Operation *set_op;
+
 /**
  * Handle for create operation.
  */
@@ -72,12 +90,26 @@ static void
 shutdown_task (void *cls,
               const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
+  if (NULL != set_op)
+  {
+    GNUNET_IDENTITY_cancel (set_op);
+    set_op = NULL;
+  }
+  if (NULL != create_op)
+  {
+    GNUNET_IDENTITY_cancel (create_op);
+    create_op = NULL;
+  }
+  if (NULL != delete_op)
+  {
+    GNUNET_IDENTITY_cancel (delete_op);
+    delete_op = NULL;
+  }
   GNUNET_IDENTITY_disconnect (sh);
   sh = NULL;
 }
 
 
-
 /**
  * Test if we are finished yet.
  */
@@ -86,8 +118,10 @@ test_finished ()
 {
   if ( (NULL == create_op) &&
        (NULL == delete_op) &&
+       (NULL == set_op) &&
+       (NULL == set_ego) &&
        (! list) &&
-       (! monitor) )  
+       (! monitor) )
     GNUNET_SCHEDULER_shutdown ();
 }
 
@@ -117,24 +151,38 @@ delete_finished (void *cls,
  * Creation operation finished.
  *
  * @param cls pointer to operation handle
- * @param ego ego handle
- * @param ego_ctx context for application to store data for this ego
- *                 (during the lifetime of this process, initially NULL)
- * @param identifier identifier assigned by the user for this ego
+ * @param emsg error message, NULL on success
  */
 static void
 create_finished (void *cls,
-                struct GNUNET_IDENTITY_Ego *ego,
-                void **ctx,
-                const char *identifier)
+                const char *emsg)
 {
   struct GNUNET_IDENTITY_Operation **op = cls;
 
   *op = NULL;
-  if (NULL == ego)
+  if (NULL != emsg)
     fprintf (stderr,
-            "%s\n",
-            _("Failed to create ego\n"));
+            _("Failed to create ego: %s\n"),
+            emsg);
+  test_finished ();
+}
+
+
+/**
+ * Function called by #GNUNET_IDENTITY_set up on completion.
+ *
+ * @param cls NULL
+ * @param emsg error message (NULL on success)
+ */
+static void
+set_done (void *cls,
+         const char *emsg)
+{
+  set_op = NULL;
+  if (NULL != emsg)
+    fprintf (stderr,
+            _("Failed to set default ego: %s\n"),
+            emsg);
   test_finished ();
 }
 
@@ -153,11 +201,11 @@ create_finished (void *cls,
  * 'ego' does indicate an error (i.e. name is taken or no default
  * value is known).  If 'ego' is non-NULL and if '*ctx'
  * is set in those callbacks, the value WILL be passed to a subsequent
- * call to the identity callback of 'GNUNET_IDENTITY_connect' (if 
+ * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
  * that one was not NULL).
  *
  * When an identity is renamed, this function is called with the
- * (known) ego but the NEW identifier.  
+ * (known) ego but the NEW identifier.
  *
  * When an identity is deleted, this function is called with the
  * (known) ego and "NULL" for the 'identifier'.  In this case,
@@ -166,7 +214,7 @@ create_finished (void *cls,
  *
  * @param cls closure
  * @param ego ego handle
- * @param ego_ctx context for application to store data for this ego
+ * @param ctx context for application to store data for this ego
  *                 (during the lifetime of this process, initially NULL)
  * @param identifier identifier assigned by the user for this ego,
  *                   NULL if the user just deleted the ego and it
@@ -177,16 +225,52 @@ print_ego (void *cls,
           struct GNUNET_IDENTITY_Ego *ego,
           void **ctx,
           const char *identifier)
-{  
-
-  if (! (list | monitor))
-    return;
+{
+  struct GNUNET_CRYPTO_EcdsaPublicKey pk;
+  char *s;
+
+  if ( (NULL != set_ego) &&
+       (NULL != ego) &&
+       (NULL != identifier) &&
+       (0 == strcmp (identifier,
+                    set_ego)) )
+    {
+      set_op = GNUNET_IDENTITY_set (sh,
+                                   set_subsystem,
+                                   ego,
+                                   &set_done,
+                                   NULL);
+      GNUNET_free (set_subsystem);
+      set_subsystem = NULL;
+      GNUNET_free (set_ego);
+      set_ego = NULL;
+    }
+  if ( (NULL == ego) &&
+       (NULL != set_ego) )
+  {
+    fprintf (stderr,
+            "Could not set ego to `%s' for subsystem `%s', ego not known\n",
+            set_ego,
+            set_subsystem);
+    GNUNET_free (set_subsystem);
+    set_subsystem = NULL;
+    GNUNET_free (set_ego);
+    set_ego = NULL;
+  }
   if ( (NULL == ego) && (! monitor) )
   {
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  fprintf (stderr, "%s\n", identifier);
+  if (! (list | monitor))
+    return;
+  if (NULL == ego)
+    return;
+  GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
+  s = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
+  if ( (monitor) || (NULL != identifier) )
+    fprintf (stdout, "%s - %s\n", identifier, s);
+  GNUNET_free (s);
 }
 
 
@@ -202,6 +286,13 @@ static void
 run (void *cls, char *const *args, const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
+  if ( (NULL == set_subsystem) ^
+       (NULL == set_ego) )
+  {
+    fprintf (stderr,
+            "Options -e and -s must always be specified together\n");
+    return;
+  }
   sh = GNUNET_IDENTITY_connect (cfg, &print_ego, NULL);
   if (NULL != delete_ego)
     delete_op = GNUNET_IDENTITY_delete (sh,
@@ -238,12 +329,18 @@ main (int argc, char *const *argv)
     {'D', "delete", "NAME",
      gettext_noop ("delete ego NAME "),
      1, &GNUNET_GETOPT_set_string, &delete_ego},
-    {'L', "list", NULL,
-     gettext_noop ("list all egos"),
+    {'d', "display", NULL,
+     gettext_noop ("display all egos"),
      0, &GNUNET_GETOPT_set_one, &list},
+    {'e', "ego", "NAME",
+     gettext_noop ("set default identity to EGO for a subsystem SUBSYSTEM (use together with -s)"),
+     1, &GNUNET_GETOPT_set_string, &set_ego},
     {'m', "monitor", NULL,
      gettext_noop ("run in monitor mode egos"),
      0, &GNUNET_GETOPT_set_one, &monitor},
+    {'s', "set", "SUBSYSYSTEM",
+     gettext_noop ("set default identity to EGO for a subsystem SUBSYSTEM (use together with -e)"),
+     1, &GNUNET_GETOPT_set_string, &set_subsystem},
     GNUNET_GETOPT_OPTION_END
   };
 
@@ -251,7 +348,7 @@ main (int argc, char *const *argv)
     return 2;
 
   res = GNUNET_PROGRAM_run (argc, argv, "gnunet-identity",
-                           gettext_noop ("Maintain egos"), 
+                           gettext_noop ("Maintain egos"),
                            options, &run,
                            NULL);
   GNUNET_free ((void *) argv);