# HG changeset patch # User Mikael Berthe # Date 1163021187 -3600 # Node ID b57a01ffeed631a2c6df0af0f9b2b98482012a21 # Parent c8b1a52b2fd6b960a46af4b28818218a117af3d5 Use existing conference bookmarks Add support for XEP-0048 (Bookmark Storage). The bookmarks are retrieved when we connect and the conference bookmarks are used. diff -r c8b1a52b2fd6 -r b57a01ffeed6 mcabber/src/commands.c --- 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; diff -r c8b1a52b2fd6 -r b57a01ffeed6 mcabber/src/jab_iq.c --- 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; } } diff -r c8b1a52b2fd6 -r b57a01ffeed6 mcabber/src/settings.c --- 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... */ diff -r c8b1a52b2fd6 -r b57a01ffeed6 mcabber/src/settings.h --- 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__ */