aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--protocols/jabber/iq.c59
-rw-r--r--protocols/jabber/jabber.c18
-rw-r--r--protocols/jabber/jabber.h1
3 files changed, 78 insertions, 0 deletions
diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c
index 2fa418fe..8518439e 100644
--- a/protocols/jabber/iq.c
+++ b/protocols/jabber/iq.c
@@ -1058,3 +1058,62 @@ static xt_status jabber_iq_carbons_response(struct im_connection *ic,
return XT_HANDLED;
}
+
+xt_status jabber_iq_disco_muc_response(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
+
+int jabber_iq_disco_muc(struct im_connection *ic, const char *muc_server)
+{
+ struct xt_node *node;
+ int st;
+
+ node = xt_new_node("query", NULL, NULL);
+ xt_add_attr(node, "xmlns", XMLNS_DISCO_ITEMS);
+ node = jabber_make_packet("iq", "get", (char *) muc_server, node);
+
+ jabber_cache_add(ic, node, jabber_iq_disco_muc_response);
+ st = jabber_write_packet(ic, node);
+
+ return st;
+}
+
+xt_status jabber_iq_disco_muc_response(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
+{
+ struct xt_node *query, *c;
+ struct jabber_error *err;
+ GSList *rooms = NULL;
+
+ if ((err = jabber_error_parse(xt_find_node(node->children, "error"), XMLNS_STANZA_ERROR))) {
+ imcb_error(ic, "The server replied with an error: %s%s%s",
+ err->code, err->text ? ": " : "", err->text ? err->text : "");
+ jabber_error_free(err);
+ return XT_HANDLED;
+ }
+
+ if (!(query = xt_find_node(node->children, "query"))) {
+ imcb_error(ic, "Received incomplete MUC list reply");
+ return XT_HANDLED;
+ }
+
+ c = query->children;
+ while ((c = xt_find_node(c, "item"))) {
+ char *jid = xt_find_attr(c, "jid");
+
+ if (!jid || !strchr(jid, '@')) {
+ c = c->next;
+ continue;
+ }
+
+ bee_chat_info_t *ci = g_new(bee_chat_info_t, 1);
+ ci->title = g_strdup(xt_find_attr(c, "jid"));
+ ci->topic = g_strdup(xt_find_attr(c, "name"));
+ rooms = g_slist_prepend(rooms, ci);
+
+ c = c->next;
+ }
+
+ imcb_chat_list_free(ic);
+ ic->chatlist = g_slist_reverse(rooms);
+ imcb_chat_list_finish(ic);
+
+ return XT_HANDLED;
+}
diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c
index 36f56fb1..f31abc50 100644
--- a/protocols/jabber/jabber.c
+++ b/protocols/jabber/jabber.c
@@ -320,6 +320,8 @@ static void jabber_logout(struct im_connection *ic)
{
struct jabber_data *jd = ic->proto_data;
+ imcb_chat_list_free(ic);
+
while (jd->filetransfers) {
imcb_file_canceled(ic, (( struct jabber_transfer *) jd->filetransfers->data)->ft, "Logging out");
}
@@ -592,6 +594,21 @@ static struct groupchat *jabber_chat_with_(struct im_connection *ic, char *who)
return jabber_chat_with(ic, who);
}
+static void jabber_chat_list_(struct im_connection *ic, const char *server)
+{
+ struct jabber_data *jd = ic->proto_data;
+
+ if (server && *server) {
+ jabber_iq_disco_muc(ic, server);
+ } else if (jd->muc_host && *jd->muc_host) {
+ jabber_iq_disco_muc(ic, jd->muc_host);
+ } else {
+ /* throw an error here, don't query conference.[server] directly.
+ * for things like jabber.org it gets you 18000 results of garbage */
+ imcb_error(ic, "Please specify a server name such as `conference.%s'", jd->server);
+ }
+}
+
static void jabber_chat_msg_(struct groupchat *c, char *message, int flags)
{
if (c && message) {
@@ -767,6 +784,7 @@ void jabber_initmodule()
ret->chat_leave = jabber_chat_leave_;
ret->chat_join = jabber_chat_join_;
ret->chat_with = jabber_chat_with_;
+ ret->chat_list = jabber_chat_list_;
ret->chat_add_settings = jabber_chat_add_settings;
ret->chat_free_settings = jabber_chat_free_settings;
ret->keepalive = jabber_keepalive;
diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h
index db43f205..7774c855 100644
--- a/protocols/jabber/jabber.h
+++ b/protocols/jabber/jabber.h
@@ -262,6 +262,7 @@ xt_status jabber_iq_query_features(struct im_connection *ic, char *bare_jid);
xt_status jabber_iq_query_server(struct im_connection *ic, char *jid, char *xmlns);
void jabber_iq_version_send(struct im_connection *ic, struct jabber_buddy *bud, void *data);
int jabber_iq_disco_server(struct im_connection *ic);
+int jabber_iq_disco_muc(struct im_connection *ic, const char *muc_server);
/* si.c */
int jabber_si_handle_request(struct im_connection *ic, struct xt_node *node, struct xt_node *sinode);