Use existing conference bookmarks
Add support for XEP-0048 (Bookmark Storage). The bookmarks are retrieved
when we connect and the conference bookmarks are used.
--- a/mcabber/src/commands.c Tue Nov 07 22:43:17 2006 +0100
+++ b/mcabber/src/commands.c Wed Nov 08 22:26:27 2006 +0100
@@ -1568,7 +1568,6 @@
{
char **paramlst;
char *roomname, *nick, *pass, *roomname_tmp;
- char *tmpnick = NULL;
char *pass_utf8;
paramlst = split_arg(arg, 3, 0); // roomid, nickname, password
@@ -1597,25 +1596,15 @@
}
// If no nickname is provided with the /join command,
- // we try the "nickname" option, then the username part of the jid.
- if (!nick || !*nick) {
- nick = (char*)settings_opt_get("nickname");
- if (!nick) {
- nick = (char*)settings_opt_get("username");
- if (nick && (strchr(nick, JID_DOMAIN_SEPARATOR) > nick)) {
- char *p;
- nick = tmpnick = g_strdup(nick);
- p = strchr(nick, JID_DOMAIN_SEPARATOR);
- *p = 0;
- }
- }
- } else {
- nick = tmpnick = to_utf8(nick);
- }
+ // we try to get a default nickname.
+ if (!nick || !*nick)
+ nick = default_muc_nickname();
+ else
+ nick = to_utf8(nick);
// If we still have no nickname, give up
if (!nick || !*nick) {
scr_LogPrint(LPRINT_NORMAL, "Please specify a nickname.");
- g_free(tmpnick);
+ g_free(nick);
free_arg_lst(paramlst);
return;
}
@@ -1632,7 +1621,7 @@
scr_LogPrint(LPRINT_LOGNORM, "Sent a join request to <%s>...", roomname);
g_free(roomname);
- g_free(tmpnick);
+ g_free(nick);
g_free(pass_utf8);
buddylist_build();
update_roster = TRUE;
--- a/mcabber/src/jab_iq.c Tue Nov 07 22:43:17 2006 +0100
+++ b/mcabber/src/jab_iq.c Wed Nov 08 22:26:27 2006 +0100
@@ -481,6 +481,93 @@
g_free(barejid);
}
+static void storage_bookmarks_parse_conference(xmlnode xmldata)
+{
+ const char *jid, *name, *autojoin;
+ char *bjid;
+ GSList *room_elt;
+
+ jid = xmlnode_get_attrib(xmldata, "jid");
+ if (!jid)
+ return;
+ name = xmlnode_get_attrib(xmldata, "name");
+ autojoin = xmlnode_get_attrib(xmldata, "autojoin");
+
+ bjid = jidtodisp(jid); // Bare jid
+
+ // Make sure this is a room (it can be a conversion user->room)
+ room_elt = roster_find(bjid, jidsearch, 0);
+ if (!room_elt) {
+ room_elt = roster_add_user(bjid, name, NULL, ROSTER_TYPE_ROOM, sub_none);
+ } else {
+ buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
+ /*
+ // If the name is available, should we use it?
+ // I don't think so, it would be confusing because this item is already
+ // in the roster.
+ if (name)
+ buddy_setname(room_elt->data, name);
+ */
+ }
+
+ // Is autojoin set?
+ // If it is, we'll look up for more information (nick? password?) and
+ // try to join the room.
+ if (autojoin && !strcmp(autojoin, "1")) {
+ char *nick, *passwd;
+ char *tmpnick = NULL;
+ nick = xmlnode_get_tag_data(xmldata, "nick");
+ passwd = xmlnode_get_tag_data(xmldata, "password");
+ if (!nick || !*nick)
+ nick = tmpnick = default_muc_nickname();
+ // Let's join now
+ scr_LogPrint(LPRINT_LOGNORM, "Auto-join bookmark <%s>", bjid);
+ jb_room_join(bjid, nick, passwd);
+ g_free(tmpnick);
+ }
+ g_free(bjid);
+}
+
+static void iqscallback_storage_bookmarks(eviqs *iqp, xmlnode xml_result,
+ guint iqcontext)
+{
+ xmlnode x, ansqry;
+ char *p;
+
+ // Leave now if we cannot process xml_result
+ if (!xml_result || iqcontext) return;
+
+ ansqry = xmlnode_get_tag(xml_result, "query");
+ ansqry = xmlnode_get_tag(ansqry, "storage");
+ if (!ansqry) {
+ scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! (storage:bookmarks)");
+ return;
+ }
+
+ // Walk through the storage tags
+ x = xmlnode_get_firstchild(ansqry);
+ for ( ; x; x = xmlnode_get_nextsibling(x)) {
+ p = xmlnode_get_name(x);
+ // If the current node is a conference item, parse it and update the roster
+ if (p && !strcmp(p, "conference"))
+ storage_bookmarks_parse_conference(x);
+ }
+}
+
+static void request_storage_bookmarks(void)
+{
+ eviqs *iqn;
+ xmlnode x;
+
+ iqn = iqs_new(JPACKET__GET, NS_PRIVATE, "storage", IQS_DEFAULT_TIMEOUT);
+
+ x = xmlnode_insert_tag(xmlnode_get_tag(iqn->xmldata, "query"), "storage");
+ xmlnode_put_attrib(x, "xmlns", "storage:bookmarks");
+
+ iqn->callback = &iqscallback_storage_bookmarks;
+ jab_send(jc, iqn->xmldata);
+}
+
void iqscallback_auth(eviqs *iqp, xmlnode xml_result)
{
if (jstate == STATE_GETAUTH) {
@@ -499,6 +586,7 @@
jstate = STATE_SENDAUTH;
} else if (jstate == STATE_SENDAUTH) {
request_roster();
+ request_storage_bookmarks();
jstate = STATE_LOGGED;
}
}
--- a/mcabber/src/settings.c Tue Nov 07 22:43:17 2006 +0100
+++ b/mcabber/src/settings.c Wed Nov 08 22:26:27 2006 +0100
@@ -345,4 +345,26 @@
}
}
+
+// default_muc_nickname()
+// Return the user's default nickname
+// The caller should free the string after use
+char *default_muc_nickname(void)
+{
+ char *nick;
+
+ // We try the "nickname" option, then the username part of the jid.
+ nick = (char*)settings_opt_get("nickname");
+ if (nick)
+ return g_strdup(nick);
+
+ nick = g_strdup(settings_opt_get("username"));
+ if (nick) {
+ char *p = strchr(nick, JID_DOMAIN_SEPARATOR);
+ if (p > nick)
+ *p = 0;
+ }
+ return nick;
+}
+
/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
--- a/mcabber/src/settings.h Tue Nov 07 22:43:17 2006 +0100
+++ b/mcabber/src/settings.h Wed Nov 08 22:26:27 2006 +0100
@@ -35,6 +35,8 @@
void (*pfunc)(void *param, char *k, char *v),
void *param);
+char *default_muc_nickname(void);
+
const gchar *isbound(int key);
#endif /* __SETTINGS_H__ */