2 * Copyright (C) 2009 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <dbus/dbus.h>
28 #include <dbus/dbus-glib-lowlevel.h>
30 static char * server = "vespa.holoscopio.com";
31 static char * username = "pubsub";
32 static char * password = NULL;
33 static char * pbservice = "pubsub@vespa.holoscopio.com";
34 static char * authed_jid = "vespa";
37 createiq (char *type, char *to, char *qnam, char *xmlns, iks **query)
42 snprintf (sid, 32, "ps%d", id++);
44 iks_insert_attrib (iq, "type", type);
45 iks_insert_attrib (iq, "to", to);
46 iks_insert_attrib (iq, "id", sid);
47 *query = iks_insert (iq, qnam);
48 iks_insert_attrib (*query, "xmlns", xmlns);
53 catnode (iksparser *parser, char *node)
57 iq = createiq ("get", pbservice, "query",
58 "http://jabber.org/protocol/disco#info", &query);
60 iks_insert_attrib (query, "node", node);
61 iks_send (parser, iq);
66 listnode (iksparser *parser, char *node)
70 iq = createiq ("get", pbservice, "query",
71 "http://jabber.org/protocol/disco#items", &query);
73 iks_insert_attrib (query, "node", node);
74 iks_send (parser, iq);
79 createnode (iksparser *parser, char *node)
83 iq = createiq ("set", pbservice, "pubsub",
84 "http://jabber.org/protocol/pubsub", &query);
85 iks_insert_attrib (iks_insert (query, "create"), "node", node);
86 iks_send (parser, iq);
91 getnode (iksparser *parser, char *node)
95 iq = createiq ("get", pbservice, "pubsub",
96 "http://jabber.org/protocol/pubsub", &query);
97 iks_insert_attrib (iks_insert (query, "items"), "node", node);
98 iks_send (parser, iq);
103 vcard (iksparser *parser)
107 iq = createiq ("get", pbservice, "vCard", "vcard-temp", &query);
108 iks_send (parser, iq);
113 createmood (char *line)
116 mood = iks_new ("mood");
117 iks_insert_attrib (mood, "xmlns", "http://jabber.org/protocol/mood");
118 iks_insert (mood, line);
123 pushmood (iksparser *parser, char *node, char *line)
130 iq = createiq ("set", pbservice, "pubsub",
131 "http://jabber.org/protocol/pubsub", &query);
132 publish = iks_insert (query, "publish");
133 iks_insert_attrib (publish, "node", node);
134 item = iks_insert (publish, "item");
135 mood = createmood (line);
136 iks_insert_node (item, mood);
137 iks_send (parser, iq);
142 createtune (char *line)
145 tune = iks_new ("tune");
146 iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
147 iks_insert_cdata (iks_insert (tune, "artist"), line, 0);
152 pushtune (iksparser *parser, char *node, iks *tune)
158 iq = createiq ("set", pbservice, "pubsub",
159 "http://jabber.org/protocol/pubsub", &query);
160 publish = iks_insert (query, "publish");
161 iks_insert_attrib (publish, "node", node);
162 item = iks_insert (publish, "item");
163 iks_insert_node (item, tune);
164 printf ("debug: %s\n", iks_string (iks_stack (iq), iq));
165 iks_send (parser, iq);
171 process_mood (iksparser *parser, char *cmdline)
175 orig_cmdline = cmdline = strdup (cmdline);
176 cmd = strsep (&cmdline, " ");
177 if (!strcmp (cmd, "ls"))
178 listnode (parser, cmdline);
179 else if (!strcmp (cmd, "cat"))
180 catnode (parser, cmdline);
181 else if (!strcmp (cmd, "vcard"))
183 else if (!strcmp (cmd, "create"))
184 createnode (parser, cmdline);
185 else if (!strcmp (cmd, "get"))
186 getnode (parser, cmdline);
187 else if (!strcmp (cmd, "mood"))
190 node = "http://jabber.org/protocol/mood";
191 pushmood (parser, node, cmdline);
193 else if (!strcmp (cmd, "tune"))
197 node = "http://jabber.org/protocol/tune";
198 tune = createtune (cmdline);
199 pushtune (parser, node, tune);
205 xmpp_session_hook (iksparser *parser, iks *node)
209 iks_insert_attrib (iq, "type", "set");
210 iks_insert_attrib (iq, "id", "session1");
211 iks_insert_attrib (iks_insert (iq, "session"),
212 "xmlns", "urn:ietf:params:xml:ns:xmpp-session");
213 iks_send (parser, iq);
219 xmpp_initial_presence_hook (iksparser *parser, iks *node)
222 pres = iks_make_pres (IKS_SHOW_AVAILABLE, "Microblogging here!");
223 iks_send (parser, pres);
229 xmpp_id_hook (iksparser *parser, iks *node, char *id)
231 if (!iks_strcmp (id, "bind1"))
233 xmpp_session_hook (parser, node);
236 else if (!iks_strcmp (id, "session1"))
238 xmpp_initial_presence_hook (parser, node);
241 else if (!iks_strncmp (id, "ps", 2))
243 printf ("%s\n", iks_string (iks_stack (node), node));
249 xmpp_ns_hook (iksparser *parser, iks *node, char *ns)
255 xmpp_iq_error (iksparser *parser, iks *node)
260 if (!iks_strcmp (iks_find_attrib (node, "type"), "error"))
262 to = iks_find_attrib (node, "to");
263 from = iks_find_attrib (node, "from");
265 iks_insert_attrib (node, "from", to);
267 iks_insert_attrib (node, "from", NULL);
269 iks_insert_attrib (node, "to", from);
271 iks_insert_attrib (node, "to", NULL);
272 iks_insert_attrib (node, "type", "error");
273 enode = iks_insert (node, "error");
274 iks_insert_attrib (enode, "type", "cancel");
275 iks_insert_attrib (iks_insert (enode, "feature-not-implemented"),
276 "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
277 iks_send (parser, node);
282 xmpp_tls_hook (iksparser *parser, iks *node)
284 iks_start_tls (parser);
289 xmpp_sasl_hook (iksparser *parser, iks* node)
291 if (password == NULL)
293 iks_start_sasl (parser, IKS_SASL_DIGEST_MD5, username, password);
298 xmpp_bind_hook (iksparser *parser, iks *node)
303 memset (password, 0, sysconf (_SC_PASS_MAX));
308 iks_insert_attrib (iq, "type", "set");
309 iks_insert_attrib (iq, "id", "bind1");
310 iks_insert_attrib (iks_insert (iq, "bind"),
311 "xmlns", "urn:ietf:params:xml:ns:xmpp-bind");
312 iks_send (parser, iq);
318 xmpp_features_hook (iksparser *parser, iks *node)
322 for (feat = iks_child (node); feat != NULL; feat = iks_next (feat))
324 ns = iks_find_attrib (feat, "xmlns");
325 if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-tls"))
327 xmpp_tls_hook (parser, node);
330 else if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
332 xmpp_sasl_hook (parser, node);
335 else if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-bind"))
337 xmpp_bind_hook (parser, node);
345 xmpp_other_hook (iksparser *parser, iks *node, char *ns)
347 if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
349 if (!iks_strcmp (iks_name (node), "success"))
350 iks_send_header (parser, server);
351 else if (!iks_strcmp (iks_name (node), "failure"))
352 printf ("failture to authenticate: %s\n",
353 iks_string (iks_stack (node), node));
361 hook (void *data, int type, iks *node)
368 parser = *(iksparser **) data;
369 name = iks_name (node);
370 id = iks_find_attrib (node, "id");
371 ns = iks_find_attrib (node, "xmlns");
372 iqns = iks_find_attrib (iks_child (node), "xmlns");
373 if (!iks_strcmp (name, "message"))
376 from = iks_find_attrib (node, "from");
377 if (!iks_strncmp (from, authed_jid, iks_strlen (authed_jid)))
379 char *body = iks_find_cdata (node, "body");
381 process_mood (parser, body);
385 printf ("%s is not authorized\n", from);
389 else if (!iks_strcmp (name, "presence"))
392 from = iks_find_attrib (node, "from");
393 printf ("I sense a disturbance in the force: %s!\n", from);
395 else if (!iks_strcmp (name, "iq"))
397 if (xmpp_id_hook (parser, node, id) == 0)
399 if (xmpp_ns_hook (parser, node, iqns) == 0)
401 xmpp_iq_error (parser, node);
403 else if (!iks_strcmp (name, "stream:features"))
405 if (xmpp_features_hook (parser, node) == 0)
408 else if (!iks_strcmp (name, "stream:error"))
410 printf ("streamerror: %s\n", iks_string (iks_stack (node), node));
414 if (xmpp_other_hook (parser, node, ns) == 0)
416 printf ("No no: %s\n", name);
422 handler (GIOChannel *channel, GIOCondition cond, gpointer data)
424 iksparser *parser = data;
425 iks_recv (parser, 0);
430 { char * key; char * val; } keymaps[] =
432 { "artist", "artist" },
433 { "duration", "length" },
434 { "album", "source" },
435 { "title", "title" },
436 { "track-number", "track" },
437 { "location", "uri" },
445 for (i = 0; keymaps[i].key != NULL; i++)
446 if (strcmp (orig, keymaps[i].key) == 0)
447 return keymaps[i].val;
452 tune_add_dbus_arg (iks *tune, DBusMessageIter *args)
454 DBusMessageIter entry;
458 dbus_message_iter_recurse (args, &entry);
459 if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_STRING)
461 dbus_message_iter_get_basic (&entry, &strkey);
462 dbus_message_iter_next (&entry);
463 if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_VARIANT)
465 dbus_message_iter_recurse (&entry, &var);
466 if (dbus_message_iter_get_arg_type (&var) == DBUS_TYPE_STRING)
468 dbus_message_iter_get_basic (&var, &strval);
473 printf ("%c\n", dbus_message_iter_get_arg_type (&entry));
474 strkey = map_key (strkey);
475 if (strkey && strval)
477 iks_insert_cdata (iks_insert (tune, strkey), strval, 0);
482 tune_from_dbus (DBusMessage *msg)
484 DBusMessageIter args;
486 tune = iks_new ("tune");
487 iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
488 dbus_message_iter_init (msg, &args);
489 if (dbus_message_iter_get_arg_type (&args) == DBUS_TYPE_ARRAY)
491 DBusMessageIter dict;
492 dbus_message_iter_recurse (&args, &dict);
493 while (dbus_message_iter_get_arg_type (&dict) ==
494 DBUS_TYPE_DICT_ENTRY)
496 tune_add_dbus_arg (tune, &dict);
497 dbus_message_iter_next (&dict);
503 static DBusHandlerResult
504 gettune (DBusConnection *conn, DBusMessage *msg, void *data)
507 if (dbus_message_is_signal (msg, "org.MetaPlayer.tag", "playing"))
509 printf("publishing tune\n");
510 tune = tune_from_dbus (msg);
511 pushtune (data, "http://jabber.org/protocol/tune", tune);
512 return DBUS_HANDLER_RESULT_HANDLED;
514 else if (dbus_message_is_signal (msg, "org.MetaPlayer.player", "stop"))
516 printf("tune stopped\n");
517 tune = iks_new ("tune");
518 iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
519 pushtune (data, "http://jabber.org/protocol/tune", tune);
520 return DBUS_HANDLER_RESULT_HANDLED;
523 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
527 prepare_dbus (gpointer parser)
529 DBusConnection *conn;
530 conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
531 dbus_bus_register (conn, NULL);
532 dbus_bus_add_match (conn,
533 "type='signal'", NULL);
534 dbus_connection_flush (conn);
535 dbus_connection_setup_with_g_main (conn, g_main_context_default ());
536 dbus_connection_add_filter (conn, gettune, parser, NULL);
540 loop (iksparser *parser)
543 channel = g_io_channel_unix_new (iks_fd (parser));
544 g_io_add_watch (channel, G_IO_IN, handler, parser);
545 prepare_dbus (parser);
546 g_main_loop_run (g_main_loop_new (g_main_context_default (), TRUE));
550 main (int argc, char **argv)
555 char *passwd = strdup ("pubsub");
556 while ((c = getopt (argc, argv, "s:u:p:i:a:w")) != -1)
568 passwd = strdup (optarg);
582 passwd = getpass ("Type password: ");
583 password = malloc (sysconf (_SC_PASS_MAX));
584 strcpy (password, passwd);
585 memset (passwd, 0, strlen (passwd));
591 parser = iks_stream_new ("jabber:client", &parser, hook);
592 iks_connect_tcp (parser, server, 5222);