-simplifying core API (#2400)
[oweals/gnunet.git] / src / chat / gnunet-chat.c
index 6dba4dda5963708f90a6efc39fa32a0107c7682b..7b11c0d1870cfdd8b297ca1e65a3e8ab10a61299 100644 (file)
@@ -44,13 +44,14 @@ static struct GNUNET_CONTAINER_MetaData *meta;
 
 static struct GNUNET_CHAT_Room *room;
 
-static GNUNET_SCHEDULER_TaskIdentifier handle_cmd_task =
-    GNUNET_SCHEDULER_NO_TASK;
+static GNUNET_SCHEDULER_TaskIdentifier handle_cmd_task;
+
+typedef int (*ActionFunction)(const char *argumetns, const void *xtra);
 
 struct ChatCommand
 {
   const char *command;
-  int (*Action) (const char *arguments, const void *xtra);
+  ActionFunction Action;
   const char *helptext;
 };
 
@@ -76,7 +77,8 @@ free_user_list ()
   }
 }
 
-static int do_help (const char *args, const void *xtra);
+static int
+do_help (const char *args, const void *xtra);
 
 
 /**
@@ -88,7 +90,7 @@ static int do_help (const char *args, const void *xtra);
 static int
 join_cb (void *cls)
 {
-  fprintf (stdout, _("Joined\n"));
+  FPRINTF (stdout, "%s",  _("Joined\n"));
   return GNUNET_OK;
 }
 
@@ -107,22 +109,33 @@ join_cb (void *cls)
  *         accept (but user is away), GNUNET_SYSERR to signal denied delivery
  */
 static int
-receive_cb (void *cls,
-            struct GNUNET_CHAT_Room *room,
+receive_cb (void *cls, struct GNUNET_CHAT_Room *room,
             const GNUNET_HashCode * sender,
             const struct GNUNET_CONTAINER_MetaData *member_info,
-            const char *message,
-            struct GNUNET_TIME_Absolute timestamp,
+            const char *message, struct GNUNET_TIME_Absolute timestamp,
             enum GNUNET_CHAT_MsgOptions options)
 {
+  char *non_unique_nick;
   char *nick;
+  int nick_is_a_dup;
   char *time;
   const char *fmt;
 
-  if (NULL != sender)
-    nick = GNUNET_PSEUDONYM_id_to_name (cfg, sender);
-  else
+  if (NULL == sender)
     nick = GNUNET_strdup (_("anonymous"));
+  else
+  {
+    if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
+        sender, NULL, NULL, &non_unique_nick, &nick_is_a_dup)
+        || (nick_is_a_dup == GNUNET_YES))
+    {
+      GNUNET_free (non_unique_nick);
+      non_unique_nick = GNUNET_strdup (_("anonymous"));
+    }
+    nick = GNUNET_PSEUDONYM_name_uniquify (cfg, sender, non_unique_nick, NULL);
+    GNUNET_free (non_unique_nick);
+  }
+
   fmt = NULL;
   switch ((int) options)
   {
@@ -164,7 +177,7 @@ receive_cb (void *cls,
     break;
   }
   time = GNUNET_STRINGS_absolute_time_to_string (timestamp);
-  fprintf (stdout, fmt, time, nick, message);
+  FPRINTF (stdout, fmt, time, nick, message);
   GNUNET_free (nick);
   GNUNET_free (time);
   return GNUNET_OK;
@@ -183,16 +196,26 @@ receive_cb (void *cls,
  *         confirmations from anyone for this message
  */
 static int
-confirmation_cb (void *cls,
-                 struct GNUNET_CHAT_Room *room,
+confirmation_cb (void *cls, struct GNUNET_CHAT_Room *room,
                  uint32_t orig_seq_number,
                  struct GNUNET_TIME_Absolute timestamp,
                  const GNUNET_HashCode * receiver)
 {
   char *nick;
+  char *unique_nick;
+  int nick_is_a_dup;
 
-  nick = GNUNET_PSEUDONYM_id_to_name (cfg, receiver);
-  fprintf (stdout, _("'%s' acknowledged message #%d\n"), nick, orig_seq_number);
+  if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
+      receiver, NULL, NULL, &nick, &nick_is_a_dup)
+      || (nick_is_a_dup == GNUNET_YES))
+  {
+    GNUNET_free (nick);
+    nick = GNUNET_strdup (_("anonymous"));
+  }
+  unique_nick = GNUNET_PSEUDONYM_name_uniquify (cfg, receiver, nick, NULL);
+  GNUNET_free (nick);
+  FPRINTF (stdout, _("'%s' acknowledged message #%d\n"), unique_nick, orig_seq_number);
+  GNUNET_free (unique_nick);
   return GNUNET_OK;
 }
 
@@ -208,12 +231,13 @@ confirmation_cb (void *cls,
  * @return GNUNET_OK
  */
 static int
-member_list_cb (void *cls,
-                const struct GNUNET_CONTAINER_MetaData *member_info,
+member_list_cb (void *cls, const struct GNUNET_CONTAINER_MetaData *member_info,
                 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *member_id,
                 enum GNUNET_CHAT_MsgOptions options)
 {
   char *nick;
+  char *non_unique_nick;
+  int nick_is_a_dup;
   GNUNET_HashCode id;
   struct UserList *pos;
   struct UserList *prev;
@@ -221,9 +245,20 @@ member_list_cb (void *cls,
   GNUNET_CRYPTO_hash (member_id,
                       sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                       &id);
-  nick = GNUNET_PSEUDONYM_id_to_name (cfg, &id);
-  fprintf (stdout, member_info != NULL
-           ? _("`%s' entered the room\n") : _("`%s' left the room\n"), nick);
+  if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
+      &id, NULL, NULL, &non_unique_nick, &nick_is_a_dup)
+      || (nick_is_a_dup == GNUNET_YES))
+  {
+    GNUNET_free (non_unique_nick);
+    non_unique_nick = GNUNET_strdup (_("anonymous"));
+  }
+  nick = GNUNET_PSEUDONYM_name_uniquify (cfg, &id, non_unique_nick, NULL);
+  GNUNET_free (non_unique_nick);
+
+  FPRINTF (stdout,
+           member_info !=
+           NULL ? _("`%s' entered the room\n") : _("`%s' left the room\n"),
+           nick);
   GNUNET_free (nick);
   if (NULL != member_info)
   {
@@ -240,10 +275,9 @@ member_list_cb (void *cls,
     prev = NULL;
     pos = users;
     while ((NULL != pos) &&
-           (0 != memcmp (&pos->pkey,
-                         member_id,
-                         sizeof (struct
-                                 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))))
+           (0 !=
+            memcmp (&pos->pkey, member_id,
+                    sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))))
     {
       prev = pos;
       pos = pos->next;
@@ -269,6 +303,7 @@ static int
 do_join (const char *arg, const void *xtra)
 {
   char *my_name;
+  int my_name_is_a_dup;
   GNUNET_HashCode me;
 
   if (arg[0] == '#')
@@ -277,22 +312,26 @@ do_join (const char *arg, const void *xtra)
   free_user_list ();
   GNUNET_free (room_name);
   room_name = GNUNET_strdup (arg);
-  room = GNUNET_CHAT_join_room (cfg,
-                                nickname,
-                                meta,
-                                room_name,
-                                -1,
-                                &join_cb, NULL,
-                                &receive_cb, NULL,
-                                &member_list_cb, NULL,
-                                &confirmation_cb, NULL, &me);
+  room =
+      GNUNET_CHAT_join_room (cfg, nickname, meta, room_name, -1, &join_cb, NULL,
+                             &receive_cb, NULL, &member_list_cb, NULL,
+                             &confirmation_cb, NULL, &me);
   if (NULL == room)
   {
-    fprintf (stdout, _("Could not change username\n"));
+    FPRINTF (stdout, "%s",  _("Could not change username\n"));
     return GNUNET_SYSERR;
   }
-  my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me);
-  fprintf (stdout, _("Joining room `%s' as user `%s'...\n"), room_name,
+  if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
+      &me, NULL, NULL, &my_name, &my_name_is_a_dup)) ||
+      (my_name_is_a_dup == GNUNET_YES))
+  {
+    GNUNET_free (my_name);
+    my_name = GNUNET_strdup (_("anonymous"));
+  }
+  /* Don't uniquify our own name - other people will have a different
+   * suffix for our own name anyway.
+   */
+  FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name,
            my_name);
   GNUNET_free (my_name);
   return GNUNET_OK;
@@ -303,6 +342,7 @@ static int
 do_nick (const char *msg, const void *xtra)
 {
   char *my_name;
+  int my_name_is_a_dup;
   GNUNET_HashCode me;
 
   GNUNET_CHAT_leave_room (room);
@@ -311,28 +351,26 @@ do_nick (const char *msg, const void *xtra)
   GNUNET_CONTAINER_meta_data_destroy (meta);
   nickname = GNUNET_strdup (msg);
   meta = GNUNET_CONTAINER_meta_data_create ();
-  GNUNET_CONTAINER_meta_data_insert (meta,
-                                     "<gnunet>",
-                                     EXTRACTOR_METATYPE_TITLE,
-                                     EXTRACTOR_METAFORMAT_UTF8,
-                                     "text/plain",
+  GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>", EXTRACTOR_METATYPE_TITLE,
+                                     EXTRACTOR_METAFORMAT_UTF8, "text/plain",
                                      nickname, strlen (nickname) + 1);
-  room = GNUNET_CHAT_join_room (cfg,
-                                nickname,
-                                meta,
-                                room_name,
-                                -1,
-                                &join_cb, NULL,
-                                &receive_cb, NULL,
-                                &member_list_cb, NULL,
-                                &confirmation_cb, NULL, &me);
+  room =
+      GNUNET_CHAT_join_room (cfg, nickname, meta, room_name, -1, &join_cb, NULL,
+                             &receive_cb, NULL, &member_list_cb, NULL,
+                             &confirmation_cb, NULL, &me);
   if (NULL == room)
   {
-    fprintf (stdout, _("Could not change username\n"));
+    FPRINTF (stdout, "%s",  _("Could not change username\n"));
     return GNUNET_SYSERR;
   }
-  my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me);
-  fprintf (stdout, _("Changed username to `%s'\n"), my_name);
+  if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
+      &me, NULL, NULL, &my_name, &my_name_is_a_dup)) ||
+      (my_name_is_a_dup == GNUNET_YES))
+  {
+    GNUNET_free (my_name);
+    my_name = GNUNET_strdup (_("anonymous"));
+  }
+  FPRINTF (stdout, _("Changed username to `%s'\n"), my_name);
   GNUNET_free (my_name);
   return GNUNET_OK;
 }
@@ -342,22 +380,32 @@ static int
 do_names (const char *msg, const void *xtra)
 {
   char *name;
+  char *unique_name;
+  int name_is_a_dup;
   struct UserList *pos;
   GNUNET_HashCode pid;
 
-  fprintf (stdout, _("Users in room `%s': "), room_name);
+  FPRINTF (stdout, _("Users in room `%s': "), room_name);
   pos = users;
   while (NULL != pos)
   {
     GNUNET_CRYPTO_hash (&pos->pkey,
                         sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                         &pid);
-    name = GNUNET_PSEUDONYM_id_to_name (cfg, &pid);
-    fprintf (stdout, "`%s' ", name);
+    if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
+        &pid, NULL, NULL, &name, &name_is_a_dup)
+        || (name_is_a_dup == GNUNET_YES))
+    {
+      GNUNET_free (name);
+      name = GNUNET_strdup (_("anonymous"));
+    }
+    unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &pid, name, NULL);
     GNUNET_free (name);
+    FPRINTF (stdout, "`%s' ", unique_name);
+    GNUNET_free (unique_name);
     pos = pos->next;
   }
-  fprintf (stdout, "\n");
+  FPRINTF (stdout, "%s",  "\n");
   return GNUNET_OK;
 }
 
@@ -383,7 +431,7 @@ do_send_pm (const char *msg, const void *xtra)
 
   if (NULL == strstr (msg, " "))
   {
-    fprintf (stderr, _("Syntax: /msg USERNAME MESSAGE"));
+    FPRINTF (stderr, "%s",  _("Syntax: /msg USERNAME MESSAGE"));
     return GNUNET_OK;
   }
   user = GNUNET_strdup (msg);
@@ -391,7 +439,9 @@ do_send_pm (const char *msg, const void *xtra)
   msg += strlen (user) + 1;
   if (GNUNET_OK != GNUNET_PSEUDONYM_name_to_id (cfg, user, &uid))
   {
-    fprintf (stderr, _("Unknown user `%s'\n"), user);
+    FPRINTF (stderr,
+        _("Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n"),
+        user);
     GNUNET_free (user);
     return GNUNET_OK;
   }
@@ -407,12 +457,12 @@ do_send_pm (const char *msg, const void *xtra)
   }
   if (NULL == pos)
   {
-    fprintf (stderr, _("User `%s' is currently not in the room!\n"), user);
+    FPRINTF (stderr, _("User `%s' is currently not in the room!\n"), user);
     GNUNET_free (user);
     return GNUNET_OK;
   }
-  GNUNET_CHAT_send_message (room,
-                            msg, GNUNET_CHAT_MSG_PRIVATE, &pos->pkey, &seq);
+  GNUNET_CHAT_send_message (room, msg, GNUNET_CHAT_MSG_PRIVATE, &pos->pkey,
+                            &seq);
   GNUNET_free (user);
   return GNUNET_OK;
 }
@@ -423,8 +473,8 @@ do_send_sig (const char *msg, const void *xtra)
 {
   uint32_t seq;
 
-  GNUNET_CHAT_send_message (room,
-                            msg, GNUNET_CHAT_MSG_AUTHENTICATED, NULL, &seq);
+  GNUNET_CHAT_send_message (room, msg, GNUNET_CHAT_MSG_AUTHENTICATED, NULL,
+                            &seq);
   return GNUNET_OK;
 }
 
@@ -434,8 +484,8 @@ do_send_ack (const char *msg, const void *xtra)
 {
   uint32_t seq;
 
-  GNUNET_CHAT_send_message (room,
-                            msg, GNUNET_CHAT_MSG_ACKNOWLEDGED, NULL, &seq);
+  GNUNET_CHAT_send_message (room, msg, GNUNET_CHAT_MSG_ACKNOWLEDGED, NULL,
+                            &seq);
   return GNUNET_OK;
 }
 
@@ -460,7 +510,7 @@ do_quit (const char *args, const void *xtra)
 static int
 do_unknown (const char *msg, const void *xtra)
 {
-  fprintf (stderr, _("Unknown command `%s'\n"), msg);
+  FPRINTF (stderr, _("Unknown command `%s'\n"), msg);
   return GNUNET_OK;
 }
 
@@ -520,25 +570,25 @@ do_help (const char *args, const void *xtra)
   int i;
 
   i = 0;
-  while ((NULL != args) &&
-         (0 != strlen (args)) && (commands[i].Action != &do_help))
+  while ((NULL != args) && (0 != strlen (args)) &&
+         (commands[i].Action != &do_help))
   {
     if (0 == strncasecmp (&args[1], &commands[i].command[1], strlen (args) - 1))
     {
-      fprintf (stdout, "%s\n", gettext (commands[i].helptext));
+      FPRINTF (stdout, "%s\n", gettext (commands[i].helptext));
       return GNUNET_OK;
     }
     i++;
   }
   i = 0;
-  fprintf (stdout, "Available commands:");
+  FPRINTF (stdout, "%s",  "Available commands:");
   while (commands[i].Action != &do_help)
   {
-    fprintf (stdout, " %s", gettext (commands[i].command));
+    FPRINTF (stdout, " %s", gettext (commands[i].command));
     i++;
   }
-  fprintf (stdout, "\n");
-  fprintf (stdout, "%s\n", gettext (commands[i].helptext));
+  FPRINTF (stdout, "%s",  "\n");
+  FPRINTF (stdout, "%s\n", gettext (commands[i].helptext));
   return GNUNET_OK;
 }
 
@@ -577,8 +627,9 @@ handle_command (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     goto next;
   i = 0;
   while ((NULL != commands[i].command) &&
-         (0 != strncasecmp (commands[i].command,
-                            message, strlen (commands[i].command))))
+         (0 !=
+          strncasecmp (commands[i].command, message,
+                       strlen (commands[i].command))))
     i++;
   if (GNUNET_OK !=
       commands[i].Action (&message[strlen (commands[i].command)], NULL))
@@ -586,9 +637,10 @@ handle_command (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
 next:
   handle_cmd_task =
-      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
-                                    (GNUNET_TIME_UNIT_MILLISECONDS, 100),
-                                    &handle_command, NULL);
+    GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_multiply
+                                               (GNUNET_TIME_UNIT_MILLISECONDS, 100),
+                                               GNUNET_SCHEDULER_PRIORITY_UI,
+                                               &handle_command, NULL);
   return;
 
 out:
@@ -606,57 +658,55 @@ out:
  * @param c configuration
  */
 static void
-run (void *cls,
-     char *const *args,
-     const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
+run (void *cls, char *const *args, const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *c)
 {
   GNUNET_HashCode me;
   char *my_name;
+  int my_name_is_a_dup;
 
   cfg = c;
   /* check arguments */
   if (NULL == nickname)
   {
-    fprintf (stderr, _("You must specify a nickname\n"));
+    FPRINTF (stderr, "%s",  _("You must specify a nickname\n"));
     ret = -1;
     return;
   }
   if (NULL == room_name)
     room_name = GNUNET_strdup ("gnunet");
   meta = GNUNET_CONTAINER_meta_data_create ();
-  GNUNET_CONTAINER_meta_data_insert (meta,
-                                     "<gnunet>",
-                                     EXTRACTOR_METATYPE_TITLE,
-                                     EXTRACTOR_METAFORMAT_UTF8,
-                                     "text/plain",
+  GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>", EXTRACTOR_METATYPE_TITLE,
+                                     EXTRACTOR_METAFORMAT_UTF8, "text/plain",
                                      nickname, strlen (nickname) + 1);
-  room = GNUNET_CHAT_join_room (cfg,
-                                nickname,
-                                meta,
-                                room_name,
-                                -1,
-                                &join_cb, NULL,
-                                &receive_cb, NULL,
-                                &member_list_cb, NULL,
-                                &confirmation_cb, NULL, &me);
+  room =
+      GNUNET_CHAT_join_room (cfg, nickname, meta, room_name, -1, &join_cb, NULL,
+                             &receive_cb, NULL, &member_list_cb, NULL,
+                             &confirmation_cb, NULL, &me);
   if (NULL == room)
   {
-    fprintf (stderr, _("Failed to join room `%s'\n"), room_name);
+    FPRINTF (stderr, _("Failed to join room `%s'\n"), room_name);
     GNUNET_free (room_name);
     GNUNET_free (nickname);
     GNUNET_CONTAINER_meta_data_destroy (meta);
     ret = -1;
     return;
   }
-  my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me);
-  fprintf (stdout, _("Joining room `%s' as user `%s'...\n"), room_name,
+  if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg,
+      &me, NULL, NULL, &my_name, &my_name_is_a_dup)) ||
+      (my_name_is_a_dup == GNUNET_YES))
+  {
+    GNUNET_free (my_name);
+    my_name = GNUNET_strdup (_("anonymous"));
+  }
+  FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name,
            my_name);
   GNUNET_free (my_name);
   handle_cmd_task =
       GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI,
                                           &handle_command, NULL);
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
-                                &do_stop_task, NULL);
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_stop_task,
+                                NULL);
 }
 
 
@@ -688,11 +738,9 @@ main (int argc, char *const *argv)
   fcntl (0, F_SETFL, flags);
 #endif
   return (GNUNET_OK ==
-          GNUNET_PROGRAM_run (argc,
-                              argv,
-                              "gnunet-chat",
-                              gettext_noop ("Join a chat on GNUnet."),
-                              options, &run, NULL)) ? ret : 1;
+          GNUNET_PROGRAM_run (argc, argv, "gnunet-chat",
+                              gettext_noop ("Join a chat on GNUnet."), options,
+                              &run, NULL)) ? ret : 1;
 }
 
 /* end of gnunet-chat.c */