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_insert (query, "configure");
87 iks_send (parser, iq);
92 getnode (iksparser *parser, char *node)
96 iq = createiq ("get", pbservice, "pubsub",
97 "http://jabber.org/protocol/pubsub", &query);
98 iks_insert_attrib (iks_insert (query, "items"), "node", node);
99 iks_send (parser, iq);
104 vcard (iksparser *parser)
108 iq = createiq ("get", pbservice, "vCard", "vcard-temp", &query);
109 iks_send (parser, iq);
114 createmood (char *line)
117 mood = iks_new ("mood");
118 iks_insert_attrib (mood, "xmlns", "http://jabber.org/protocol/mood");
119 iks_insert (mood, line);
124 pushmood (iksparser *parser, char *node, char *line)
131 iq = createiq ("set", pbservice, "pubsub",
132 "http://jabber.org/protocol/pubsub", &query);
133 publish = iks_insert (query, "publish");
134 iks_insert_attrib (publish, "node", node);
135 item = iks_insert (publish, "item");
136 mood = createmood (line);
137 iks_insert_node (item, mood);
138 iks_send (parser, iq);
143 createtune (char *line)
146 tune = iks_new ("tune");
147 iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
148 iks_insert_cdata (iks_insert (tune, "artist"), line, 0);
153 pushtune (iksparser *parser, char *node, iks *tune)
159 iq = createiq ("set", pbservice, "pubsub",
160 "http://jabber.org/protocol/pubsub", &query);
161 publish = iks_insert (query, "publish");
162 iks_insert_attrib (publish, "node", node);
163 item = iks_insert (publish, "item");
164 iks_insert_node (item, tune);
165 printf ("debug: %s\n", iks_string (iks_stack (iq), iq));
166 iks_send (parser, iq);
172 process_mood (iksparser *parser, char *cmdline)
176 orig_cmdline = cmdline = strdup (cmdline);
177 cmd = strsep (&cmdline, " ");
178 if (!strcmp (cmd, "ls"))
179 listnode (parser, cmdline);
180 else if (!strcmp (cmd, "cat"))
181 catnode (parser, cmdline);
182 else if (!strcmp (cmd, "vcard"))
184 else if (!strcmp (cmd, "create"))
185 createnode (parser, cmdline);
186 else if (!strcmp (cmd, "get"))
187 getnode (parser, cmdline);
188 else if (!strcmp (cmd, "mood"))
191 node = "http://jabber.org/protocol/mood";
192 pushmood (parser, node, cmdline);
194 else if (!strcmp (cmd, "tune"))
198 node = "http://jabber.org/protocol/tune";
199 tune = createtune (cmdline);
200 pushtune (parser, node, tune);
206 xmpp_session_hook (iksparser *parser, iks *node)
210 iks_insert_attrib (iq, "type", "set");
211 iks_insert_attrib (iq, "id", "session1");
212 iks_insert_attrib (iks_insert (iq, "session"),
213 "xmlns", "urn:ietf:params:xml:ns:xmpp-session");
214 iks_send (parser, iq);
220 xmpp_initial_presence_hook (iksparser *parser, iks *node)
223 pres = iks_make_pres (IKS_SHOW_AVAILABLE, "Microblogging here!");
224 iks_insert_cdata (iks_insert (pres, "priority"), "-1", 2);
225 iks_send (parser, pres);
231 xmpp_id_hook (iksparser *parser, iks *node, char *id)
233 if (!iks_strcmp (id, "bind1"))
235 xmpp_session_hook (parser, node);
238 else if (!iks_strcmp (id, "session1"))
240 xmpp_initial_presence_hook (parser, node);
243 else if (!iks_strncmp (id, "ps", 2))
245 printf ("%s\n", iks_string (iks_stack (node), node));
251 xmpp_ns_hook (iksparser *parser, iks *node, char *ns)
257 xmpp_iq_error (iksparser *parser, iks *node)
262 if (!iks_strcmp (iks_find_attrib (node, "type"), "error"))
264 to = iks_find_attrib (node, "to");
265 from = iks_find_attrib (node, "from");
267 iks_insert_attrib (node, "from", to);
269 iks_insert_attrib (node, "from", NULL);
271 iks_insert_attrib (node, "to", from);
273 iks_insert_attrib (node, "to", NULL);
274 iks_insert_attrib (node, "type", "error");
275 enode = iks_insert (node, "error");
276 iks_insert_attrib (enode, "type", "cancel");
277 iks_insert_attrib (iks_insert (enode, "feature-not-implemented"),
278 "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
279 iks_send (parser, node);
284 xmpp_tls_hook (iksparser *parser, iks *node)
286 iks_start_tls (parser);
291 xmpp_sasl_hook (iksparser *parser, iks* node)
293 if (password == NULL)
295 iks_start_sasl (parser, IKS_SASL_DIGEST_MD5, username, password);
300 xmpp_bind_hook (iksparser *parser, iks *node)
305 memset (password, 0, sysconf (_SC_PASS_MAX));
310 iks_insert_attrib (iq, "type", "set");
311 iks_insert_attrib (iq, "id", "bind1");
312 iks_insert_attrib (iks_insert (iq, "bind"),
313 "xmlns", "urn:ietf:params:xml:ns:xmpp-bind");
314 iks_send (parser, iq);
320 xmpp_features_hook (iksparser *parser, iks *node)
324 for (feat = iks_child (node); feat != NULL; feat = iks_next (feat))
326 ns = iks_find_attrib (feat, "xmlns");
327 if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-tls"))
329 xmpp_tls_hook (parser, node);
332 else if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
334 xmpp_sasl_hook (parser, node);
337 else if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-bind"))
339 xmpp_bind_hook (parser, node);
347 xmpp_other_hook (iksparser *parser, iks *node, char *ns)
349 if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
351 if (!iks_strcmp (iks_name (node), "success"))
352 iks_send_header (parser, server);
353 else if (!iks_strcmp (iks_name (node), "failure"))
354 printf ("failture to authenticate: %s\n",
355 iks_string (iks_stack (node), node));
363 hook (void *data, int type, iks *node)
370 parser = *(iksparser **) data;
371 name = iks_name (node);
372 id = iks_find_attrib (node, "id");
373 ns = iks_find_attrib (node, "xmlns");
374 iqns = iks_find_attrib (iks_child (node), "xmlns");
375 if (!iks_strcmp (name, "message"))
378 from = iks_find_attrib (node, "from");
379 if (!iks_strncmp (from, authed_jid, iks_strlen (authed_jid)))
381 char *body = iks_find_cdata (node, "body");
383 process_mood (parser, body);
387 printf ("%s is not authorized\n", from);
391 else if (!iks_strcmp (name, "presence"))
394 from = iks_find_attrib (node, "from");
395 printf ("I sense a disturbance in the force: %s!\n", from);
397 else if (!iks_strcmp (name, "iq"))
399 if (xmpp_id_hook (parser, node, id) == 0)
401 if (xmpp_ns_hook (parser, node, iqns) == 0)
403 xmpp_iq_error (parser, node);
405 else if (!iks_strcmp (name, "stream:features"))
407 if (xmpp_features_hook (parser, node) == 0)
410 else if (!iks_strcmp (name, "stream:error"))
412 printf ("streamerror: %s\n", iks_string (iks_stack (node), node));
416 if (xmpp_other_hook (parser, node, ns) == 0)
418 printf ("No no: %s\n", name);
424 handler (GIOChannel *channel, GIOCondition cond, gpointer data)
426 iksparser *parser = data;
427 iks_recv (parser, 0);
432 { char * key; char * val; } keymaps[] =
434 { "artist", "artist" },
435 { "duration", "length" },
436 { "album", "source" },
437 { "title", "title" },
438 { "track-number", "track" },
439 { "location", "uri" },
447 for (i = 0; keymaps[i].key != NULL; i++)
448 if (strcmp (orig, keymaps[i].key) == 0)
449 return keymaps[i].val;
454 tune_add_dbus_arg (iks *tune, DBusMessageIter *args)
456 DBusMessageIter entry;
460 dbus_message_iter_recurse (args, &entry);
461 if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_STRING)
463 dbus_message_iter_get_basic (&entry, &strkey);
464 dbus_message_iter_next (&entry);
465 if (dbus_message_iter_get_arg_type (&entry) == DBUS_TYPE_VARIANT)
467 dbus_message_iter_recurse (&entry, &var);
468 if (dbus_message_iter_get_arg_type (&var) == DBUS_TYPE_STRING)
470 dbus_message_iter_get_basic (&var, &strval);
475 printf ("%c\n", dbus_message_iter_get_arg_type (&entry));
476 strkey = map_key (strkey);
477 if (strkey && strval)
479 iks_insert_cdata (iks_insert (tune, strkey), strval, 0);
484 tune_from_dbus (DBusMessage *msg)
486 DBusMessageIter args;
488 tune = iks_new ("tune");
489 iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
490 dbus_message_iter_init (msg, &args);
491 if (dbus_message_iter_get_arg_type (&args) == DBUS_TYPE_ARRAY)
493 DBusMessageIter dict;
494 dbus_message_iter_recurse (&args, &dict);
495 while (dbus_message_iter_get_arg_type (&dict) ==
496 DBUS_TYPE_DICT_ENTRY)
498 tune_add_dbus_arg (tune, &dict);
499 dbus_message_iter_next (&dict);
505 static DBusHandlerResult
506 gettune (DBusConnection *conn, DBusMessage *msg, void *data)
509 if (dbus_message_is_signal (msg, "org.MetaPlayer.tag", "playing"))
511 printf("publishing tune\n");
512 tune = tune_from_dbus (msg);
513 pushtune (data, "http://jabber.org/protocol/tune", tune);
514 return DBUS_HANDLER_RESULT_HANDLED;
516 else if (dbus_message_is_signal (msg, "org.MetaPlayer.player", "stop"))
518 printf("tune stopped\n");
519 tune = iks_new ("tune");
520 iks_insert_attrib (tune, "xmlns", "http://jabber.org/protocol/tune");
521 pushtune (data, "http://jabber.org/protocol/tune", tune);
522 return DBUS_HANDLER_RESULT_HANDLED;
525 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
529 prepare_dbus (gpointer parser)
531 DBusConnection *conn;
532 conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
533 dbus_bus_register (conn, NULL);
534 dbus_bus_add_match (conn,
535 "type='signal'", NULL);
536 dbus_connection_flush (conn);
537 dbus_connection_setup_with_g_main (conn, g_main_context_default ());
538 dbus_connection_add_filter (conn, gettune, parser, NULL);
542 loop (iksparser *parser)
545 channel = g_io_channel_unix_new (iks_fd (parser));
546 g_io_add_watch (channel, G_IO_IN, handler, parser);
547 prepare_dbus (parser);
548 g_main_loop_run (g_main_loop_new (g_main_context_default (), TRUE));
552 main (int argc, char **argv)
557 char *passwd = strdup ("pubsub");
558 while ((c = getopt (argc, argv, "s:u:p:i:a:w")) != -1)
570 passwd = strdup (optarg);
584 passwd = getpass ("Type password: ");
585 password = malloc (sysconf (_SC_PASS_MAX));
586 strcpy (password, passwd);
587 memset (passwd, 0, strlen (passwd));
593 parser = iks_stream_new ("jabber:client", &parser, hook);
594 iks_connect_tcp (parser, server, 5222);