#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;
return iq;
}
-void
+static void
catnode (iksparser *parser, char *node)
{
iks *iq;
iks_delete (iq);
}
-void
+static void
listnode (iksparser *parser, char *node)
{
iks *iq;
iks_delete (iq);
}
-void
+static void
createnode (iksparser *parser, char *node)
{
iks *iq;
iq = createiq ("set", pbservice, "pubsub",
"http://jabber.org/protocol/pubsub", &query);
iks_insert_attrib (iks_insert (query, "create"), "node", node);
+ iks_insert (query, "configure");
iks_send (parser, iq);
iks_delete (iq);
}
-void
+static void
getnode (iksparser *parser, char *node)
{
iks *iq;
iks_delete (iq);
}
-void
+static void
vcard (iksparser *parser)
{
iks *iq;
iks_delete (iq);
}
-iks *
+static iks *
createmood (char *line)
{
iks *mood;
return mood;
}
-void
+static void
pushmood (iksparser *parser, char *node, char *line)
{
iks *iq;
iks_delete (iq);
}
-iks *
+static iks *
createtune (char *line)
{
iks *tune;
return tune;
}
-void
+static void
pushtune (iksparser *parser, char *node, iks *tune)
{
iks *iq;
}
-void
+static void
process_mood (iksparser *parser, char *cmdline)
{
char *cmd;
free (orig_cmdline);
}
-int
+static int
xmpp_session_hook (iksparser *parser, iks *node)
{
iks *iq;
return 0;
}
-int
+static int
xmpp_initial_presence_hook (iksparser *parser, iks *node)
{
iks *pres;
pres = iks_make_pres (IKS_SHOW_AVAILABLE, "Microblogging here!");
+ iks_insert_cdata (iks_insert (pres, "priority"), "-1", 2);
iks_send (parser, pres);
iks_delete (pres);
return 0;
}
-int
+static int
xmpp_id_hook (iksparser *parser, iks *node, char *id)
{
if (!iks_strcmp (id, "bind1"))
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;
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");
return 0;
}
-int
+static int
xmpp_features_hook (iksparser *parser, iks *node)
{
iks *feat;
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"))
return IKS_OK;
}
-gboolean
+static gboolean
handler (GIOChannel *channel, GIOCondition cond, gpointer data)
{
iksparser *parser = 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;
+ DBusMessageIter var;
+ char *strkey = NULL;
+ char *strval = NULL;
+ dbus_message_iter_recurse (args, &entry);
+ if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_STRING)
+ {
+ dbus_message_iter_get_basic (&entry, &strkey);
+ dbus_message_iter_next (&entry);
+ if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_VARIANT)
+ {
+ dbus_message_iter_recurse (&entry, &var);
+ if (dbus_message_iter_get_arg_type (&var) == DBUS_TYPE_STRING)
+ {
+ dbus_message_iter_get_basic (&var, &strval);
+ }
+ }
+ }
+ 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);
+ }
+}
+
+static iks *
+tune_from_dbus (DBusMessage *msg)
+{
+ DBusMessageIter args;
+ iks *tune;
+ tune = iks_new ("tune");
+ iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
+ dbus_message_iter_init (msg, &args);
+ if (dbus_message_iter_get_arg_type (&args) == DBUS_TYPE_ARRAY)
+ {
+ DBusMessageIter dict;
+ dbus_message_iter_recurse (&args, &dict);
+ while (dbus_message_iter_get_arg_type (&dict) ==
+ DBUS_TYPE_DICT_ENTRY)
+ {
+ tune_add_dbus_arg (tune, &dict);
+ dbus_message_iter_next (&dict);
+ }
+ }
+ return tune;
+}
+
+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;
+}
+
+static void
+prepare_dbus (gpointer parser)
+{
+ DBusConnection *conn;
+ conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+ dbus_bus_register (conn, NULL);
+ dbus_bus_add_match (conn,
+ "type='signal'", NULL);
+ dbus_connection_flush (conn);
+ dbus_connection_setup_with_g_main (conn, g_main_context_default ());
+ dbus_connection_add_filter (conn, gettune, parser, NULL);
+}
+
+static void
loop (iksparser *parser)
{
GIOChannel *channel;
channel = g_io_channel_unix_new (iks_fd (parser));
g_io_add_watch (channel, G_IO_IN, handler, parser);
+ prepare_dbus (parser);
g_main_loop_run (g_main_loop_new (g_main_context_default (), TRUE));
}
{
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)
{
username = optarg;
break;
case 'p':
- password = optarg;
+ free (passwd);
+ passwd = strdup (optarg);
break;
case 'i':
pbservice = optarg;
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);