Use getpass to get user password.
[cascardo/pubsub-bot.git] / status.c
index afb71bd..62572fb 100644 (file)
--- a/status.c
+++ b/status.c
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <limits.h>
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
 static char * server = "vespa.holoscopio.com";
 static char * username = "pubsub";
-static char * password = "pubsub";
-static char * pbservice = "pubsub.vespa.holoscopio.com";
+static char * password = NULL;
+static char * pbservice = "pubsub@vespa.holoscopio.com";
 static char * authed_jid = "vespa";
 
-iks *
+static iks *
 createiq (char *type, char *to, char *qnam, char *xmlns, iks **query)
 {
   static int id = 0;
@@ -48,7 +49,7 @@ createiq (char *type, char *to, char *qnam, char *xmlns, iks **query)
   return iq;
 }
 
-void
+static void
 catnode (iksparser *parser, char *node)
 {
   iks *iq;
@@ -61,7 +62,7 @@ catnode (iksparser *parser, char *node)
   iks_delete (iq);
 }
 
-void
+static void
 listnode (iksparser *parser, char *node)
 {
   iks *iq;
@@ -74,7 +75,7 @@ listnode (iksparser *parser, char *node)
   iks_delete (iq);
 }
 
-void
+static void
 createnode (iksparser *parser, char *node)
 {
   iks *iq;
@@ -86,7 +87,7 @@ createnode (iksparser *parser, char *node)
   iks_delete (iq);
 }
 
-void
+static void
 getnode (iksparser *parser, char *node)
 {
   iks *iq;
@@ -98,7 +99,7 @@ getnode (iksparser *parser, char *node)
   iks_delete (iq);
 }
 
-void
+static void
 vcard (iksparser *parser)
 {
   iks *iq;
@@ -108,7 +109,7 @@ vcard (iksparser *parser)
   iks_delete (iq);
 }
 
-iks *
+static iks *
 createmood (char *line)
 {
   iks *mood;
@@ -118,7 +119,7 @@ createmood (char *line)
   return mood;
 }
 
-void
+static void
 pushmood (iksparser *parser, char *node, char *line)
 {
   iks *iq;
@@ -137,7 +138,7 @@ pushmood (iksparser *parser, char *node, char *line)
   iks_delete (iq);
 }
 
-iks *
+static iks *
 createtune (char *line)
 {
   iks *tune;
@@ -147,7 +148,7 @@ createtune (char *line)
   return tune;
 }
 
-void
+static void
 pushtune (iksparser *parser, char *node, iks *tune)
 {
   iks *iq;
@@ -166,7 +167,7 @@ pushtune (iksparser *parser, char *node, iks *tune)
 }
 
 
-void
+static void
 process_mood (iksparser *parser, char *cmdline)
 {
   char *cmd;
@@ -200,7 +201,7 @@ process_mood (iksparser *parser, char *cmdline)
   free (orig_cmdline);
 }
 
-int
+static int
 xmpp_session_hook (iksparser *parser, iks *node)
 {
   iks *iq;
@@ -214,7 +215,7 @@ xmpp_session_hook (iksparser *parser, iks *node)
   return 0;
 }
 
-int
+static int
 xmpp_initial_presence_hook (iksparser *parser, iks *node)
 {
   iks *pres;
@@ -224,7 +225,7 @@ xmpp_initial_presence_hook (iksparser *parser, iks *node)
   return 0;
 }
 
-int
+static int
 xmpp_id_hook (iksparser *parser, iks *node, char *id)
 {
   if (!iks_strcmp (id, "bind1"))
@@ -244,13 +245,13 @@ xmpp_id_hook (iksparser *parser, iks *node, char *id)
   return 1;
 }
 
-int
+static int
 xmpp_ns_hook (iksparser *parser, iks *node, char *ns)
 {
   return 1;
 }
 
-int
+static int
 xmpp_iq_error (iksparser *parser, iks *node)
 {
   iks *enode;
@@ -277,24 +278,32 @@ xmpp_iq_error (iksparser *parser, iks *node)
   return 0;
 }
 
-int
+static int
 xmpp_tls_hook (iksparser *parser, iks *node)
 {
   iks_start_tls (parser);
   return 0;
 }
 
-int
+static int
 xmpp_sasl_hook (iksparser *parser, iks* node)
 {
+  if (password == NULL)
+    return -1;
   iks_start_sasl (parser, IKS_SASL_DIGEST_MD5, username, password);
   return 0;
 }
 
-int
+static int
 xmpp_bind_hook (iksparser *parser, iks *node)
 {
   iks *iq;
+  if (password)
+    {
+      memset (password, 0, sysconf (_SC_PASS_MAX));
+      free (password);
+      password = NULL;
+    }
   iq = iks_new ("iq");
   iks_insert_attrib (iq, "type", "set");
   iks_insert_attrib (iq, "id", "bind1");
@@ -305,7 +314,7 @@ xmpp_bind_hook (iksparser *parser, iks *node)
   return 0;
 }
 
-int
+static int
 xmpp_features_hook (iksparser *parser, iks *node)
 {
   iks *feat;
@@ -332,7 +341,7 @@ xmpp_features_hook (iksparser *parser, iks *node)
   return 1;
 }
 
-int
+static int
 xmpp_other_hook (iksparser *parser, iks *node, char *ns)
 {
   if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
@@ -409,7 +418,7 @@ hook (void *data, int type, iks *node)
   return IKS_OK;
 }
 
-gboolean
+static gboolean
 handler (GIOChannel *channel, GIOCondition cond, gpointer data)
 {
   iksparser *parser = data;
@@ -417,7 +426,29 @@ handler (GIOChannel *channel, GIOCondition cond, gpointer data)
   return TRUE;
 }
 
-void
+struct
+  { char * key; char * val; } keymaps[] =
+{
+  { "artist", "artist" },
+  { "duration", "length" },
+  { "album", "source" },
+  { "title", "title" },
+  { "track-number", "track" },
+  { "location", "uri" },
+  { NULL, NULL }
+};
+
+static char *
+map_key (char *orig)
+{
+  int i;
+  for (i = 0; keymaps[i].key != NULL; i++)
+    if (strcmp (orig, keymaps[i].key) == 0)
+      return keymaps[i].val;
+  return NULL;
+}
+
+static void
 tune_add_dbus_arg (iks *tune, DBusMessageIter *args)
 {
   DBusMessageIter entry;
@@ -440,13 +471,14 @@ tune_add_dbus_arg (iks *tune, DBusMessageIter *args)
     }
   else
     printf ("%c\n", dbus_message_iter_get_arg_type (&entry));
+  strkey = map_key (strkey);
   if (strkey && strval)
     {
       iks_insert_cdata (iks_insert (tune, strkey), strval, 0);
     }
 }
 
-iks *
+static iks *
 tune_from_dbus (DBusMessage *msg)
 {
   DBusMessageIter args;
@@ -468,16 +500,25 @@ tune_from_dbus (DBusMessage *msg)
   return tune;
 }
 
-DBusHandlerResult
+static DBusHandlerResult
 gettune (DBusConnection *conn, DBusMessage *msg, void *data)
 {
   iks *tune;
   if (dbus_message_is_signal (msg, "org.MetaPlayer.tag", "playing"))
     {
+      printf("publishing tune\n");
       tune = tune_from_dbus (msg);
       pushtune (data, "http://jabber.org/protocol/tune", tune);
       return DBUS_HANDLER_RESULT_HANDLED;
     }
+  else if (dbus_message_is_signal (msg, "org.MetaPlayer.player", "stop"))
+    {
+      printf("tune stopped\n");
+      tune = iks_new ("tune");
+      iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
+      pushtune (data, "http://jabber.org/protocol/tune", tune);
+      return DBUS_HANDLER_RESULT_HANDLED;
+    }
   else
     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
@@ -495,7 +536,7 @@ prepare_dbus (gpointer parser)
   dbus_connection_add_filter (conn, gettune, parser, NULL);
 }
 
-void
+static void
 loop (iksparser *parser)
 {
   GIOChannel *channel;
@@ -510,7 +551,9 @@ main (int argc, char **argv)
 {
   iksparser *parser;
   int c;
-  while ((c = getopt (argc, argv, "s:u:p:i:a:")) != -1)
+  int askpasswd = 0;
+  char *passwd = strdup ("pubsub");
+  while ((c = getopt (argc, argv, "s:u:p:i:a:w")) != -1)
     {
       switch (c)
         {
@@ -521,7 +564,8 @@ main (int argc, char **argv)
           username = optarg;
           break;
         case 'p':
-          password = optarg;
+          free (passwd);
+          passwd = strdup (optarg);
           break;
         case 'i':
           pbservice = optarg;
@@ -529,8 +573,21 @@ main (int argc, char **argv)
         case 'a':
           authed_jid = optarg;
           break;
+        case 'w':
+          askpasswd = 1;
+          break;
         }
     }
+  if (askpasswd)
+    passwd = getpass ("Type password: ");
+  password = malloc (sysconf (_SC_PASS_MAX));
+  strcpy (password, passwd);
+  memset (passwd, 0, strlen (passwd));
+  if (!askpasswd)
+    {
+      free (passwd);
+      passwd = NULL;
+    }
   parser = iks_stream_new ("jabber:client", &parser, hook);
   iks_connect_tcp (parser, server, 5222);
   loop (parser);