*/
+#include <glib.h>
#include <iksemel.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
-int
+static char * server = "vespa.holoscopio.com";
+static char * username = "pubsub";
+static char * password = "pubsub";
+static char * pbservice = "pubsub.vespa.holoscopio.com";
+static char * authed_jid = "vespa";
+
+static iks *
+createiq (char *type, char *to, char *qnam, char *xmlns, iks **query)
+{
+ static int id = 0;
+ char sid[32];;
+ iks *iq;
+ snprintf (sid, 32, "ps%d", id++);
+ iq = iks_new ("iq");
+ iks_insert_attrib (iq, "type", type);
+ iks_insert_attrib (iq, "to", to);
+ iks_insert_attrib (iq, "id", sid);
+ *query = iks_insert (iq, qnam);
+ iks_insert_attrib (*query, "xmlns", xmlns);
+ return iq;
+}
+
+static void
+catnode (iksparser *parser, char *node)
+{
+ iks *iq;
+ iks *query;
+ iq = createiq ("get", pbservice, "query",
+ "http://jabber.org/protocol/disco#info", &query);
+ if (node != NULL)
+ iks_insert_attrib (query, "node", node);
+ iks_send (parser, iq);
+ iks_delete (iq);
+}
+
+static void
+listnode (iksparser *parser, char *node)
+{
+ iks *iq;
+ iks *query;
+ iq = createiq ("get", pbservice, "query",
+ "http://jabber.org/protocol/disco#items", &query);
+ if (node != NULL)
+ iks_insert_attrib (query, "node", node);
+ iks_send (parser, iq);
+ iks_delete (iq);
+}
+
+static void
+createnode (iksparser *parser, char *node)
+{
+ iks *iq;
+ iks *query;
+ iq = createiq ("set", pbservice, "pubsub",
+ "http://jabber.org/protocol/pubsub", &query);
+ iks_insert_attrib (iks_insert (query, "create"), "node", node);
+ iks_send (parser, iq);
+ iks_delete (iq);
+}
+
+static void
+getnode (iksparser *parser, char *node)
+{
+ iks *iq;
+ iks *query;
+ iq = createiq ("get", pbservice, "pubsub",
+ "http://jabber.org/protocol/pubsub", &query);
+ iks_insert_attrib (iks_insert (query, "items"), "node", node);
+ iks_send (parser, iq);
+ iks_delete (iq);
+}
+
+static void
+vcard (iksparser *parser)
+{
+ iks *iq;
+ iks *query;
+ iq = createiq ("get", pbservice, "vCard", "vcard-temp", &query);
+ iks_send (parser, iq);
+ iks_delete (iq);
+}
+
+static iks *
+createmood (char *line)
+{
+ iks *mood;
+ mood = iks_new ("mood");
+ iks_insert_attrib (mood, "xmlns", "http://jabber.org/protocol/mood");
+ iks_insert (mood, line);
+ return mood;
+}
+
+static void
+pushmood (iksparser *parser, char *node, char *line)
+{
+ iks *iq;
+ iks *query;
+ iks *publish;
+ iks *item;
+ iks *mood;
+ iq = createiq ("set", pbservice, "pubsub",
+ "http://jabber.org/protocol/pubsub", &query);
+ publish = iks_insert (query, "publish");
+ iks_insert_attrib (publish, "node", node);
+ item = iks_insert (publish, "item");
+ mood = createmood (line);
+ iks_insert_node (item, mood);
+ iks_send (parser, iq);
+ iks_delete (iq);
+}
+
+static iks *
+createtune (char *line)
+{
+ iks *tune;
+ tune = iks_new ("tune");
+ iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
+ iks_insert_cdata (iks_insert (tune, "artist"), line, 0);
+ return tune;
+}
+
+static void
+pushtune (iksparser *parser, char *node, iks *tune)
+{
+ iks *iq;
+ iks *query;
+ iks *publish;
+ iks *item;
+ iq = createiq ("set", pbservice, "pubsub",
+ "http://jabber.org/protocol/pubsub", &query);
+ publish = iks_insert (query, "publish");
+ iks_insert_attrib (publish, "node", node);
+ item = iks_insert (publish, "item");
+ iks_insert_node (item, tune);
+ printf ("debug: %s\n", iks_string (iks_stack (iq), iq));
+ iks_send (parser, iq);
+ iks_delete (iq);
+}
+
+
+static void
+process_mood (iksparser *parser, char *cmdline)
+{
+ char *cmd;
+ char *orig_cmdline;
+ orig_cmdline = cmdline = strdup (cmdline);
+ cmd = strsep (&cmdline, " ");
+ if (!strcmp (cmd, "ls"))
+ listnode (parser, cmdline);
+ else if (!strcmp (cmd, "cat"))
+ catnode (parser, cmdline);
+ else if (!strcmp (cmd, "vcard"))
+ vcard (parser);
+ else if (!strcmp (cmd, "create"))
+ createnode (parser, cmdline);
+ else if (!strcmp (cmd, "get"))
+ getnode (parser, cmdline);
+ else if (!strcmp (cmd, "mood"))
+ {
+ char *node;
+ node = "http://jabber.org/protocol/mood";
+ pushmood (parser, node, cmdline);
+ }
+ else if (!strcmp (cmd, "tune"))
+ {
+ char *node;
+ iks *tune;
+ node = "http://jabber.org/protocol/tune";
+ tune = createtune (cmdline);
+ pushtune (parser, node, tune);
+ }
+ free (orig_cmdline);
+}
+
+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!\n");
+ pres = iks_make_pres (IKS_SHOW_AVAILABLE, "Microblogging here!");
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"))
xmpp_initial_presence_hook (parser, node);
return 0;
}
+ else if (!iks_strncmp (id, "ps", 2))
+ {
+ printf ("%s\n", iks_string (iks_stack (node), node));
+ }
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)
{
- iks_start_sasl (parser, IKS_SASL_DIGEST_MD5, "pubsub", "pubsub");
+ iks_start_sasl (parser, IKS_SASL_DIGEST_MD5, username, password);
return 0;
}
-int
+static int
xmpp_bind_hook (iksparser *parser, iks *node)
{
iks *iq;
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"))
{
if (!iks_strcmp (iks_name (node), "success"))
- iks_send_header (parser, "jabber-br.org");
+ iks_send_header (parser, server);
+ else if (!iks_strcmp (iks_name (node), "failure"))
+ printf ("failture to authenticate: %s\n",
+ iks_string (iks_stack (node), node));
return 0;
}
return 1;
}
+
static int
hook (void *data, int type, iks *node)
{
iqns = iks_find_attrib (iks_child (node), "xmlns");
if (!iks_strcmp (name, "message"))
{
- printf ("Got milk?\n");
+ char *from;
+ from = iks_find_attrib (node, "from");
+ if (!iks_strncmp (from, authed_jid, iks_strlen (authed_jid)))
+ {
+ char *body = iks_find_cdata (node, "body");
+ if (body != NULL)
+ process_mood (parser, body);
+ }
+ else
+ {
+ printf ("%s is not authorized\n", from);
+ }
return IKS_OK;
}
else if (!iks_strcmp (name, "presence"))
{
- printf ("I sense a disturbance in the force!\n");
+ char *from;
+ from = iks_find_attrib (node, "from");
+ printf ("I sense a disturbance in the force: %s!\n", from);
}
else if (!iks_strcmp (name, "iq"))
{
if (xmpp_features_hook (parser, node) == 0)
return IKS_OK;
}
+ else if (!iks_strcmp (name, "stream:error"))
+ {
+ printf ("streamerror: %s\n", iks_string (iks_stack (node), node));
+ }
else
{
if (xmpp_other_hook (parser, node, ns) == 0)
return IKS_OK;
}
+static gboolean
+handler (GIOChannel *channel, GIOCondition cond, gpointer data)
+{
+ iksparser *parser = data;
+ iks_recv (parser, 0);
+ return TRUE;
+}
+
+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));
+ 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"))
+ {
+ tune = tune_from_dbus (msg);
+ 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));
+}
+
int
main (int argc, char **argv)
{
iksparser *parser;
+ int c;
+ while ((c = getopt (argc, argv, "s:u:p:i:a:")) != -1)
+ {
+ switch (c)
+ {
+ case 's':
+ server = optarg;
+ break;
+ case 'u':
+ username = optarg;
+ break;
+ case 'p':
+ password = optarg;
+ break;
+ case 'i':
+ pbservice = optarg;
+ break;
+ case 'a':
+ authed_jid = optarg;
+ break;
+ }
+ }
parser = iks_stream_new ("jabber:client", &parser, hook);
- iks_connect_tcp (parser, "jabber-br.org", 5222);
- while (1)
- iks_recv (parser, -1);
+ iks_connect_tcp (parser, server, 5222);
+ loop (parser);
return 0;
}