Hi! I wrote the attached patch for msn-transport to enable the transport to reply on disco requests.
Tot kijk
Matthias
--
Fon: +49-(0)70 0770 07770 http://matthias.wimmer.name/
HAM: DB1MW xmpp:[EMAIL PROTECTED]
diff -Naur msn-transport/include/msntrans.h msn-transport-disco/include/msntrans.h --- msn-transport/include/msntrans.h 2003-11-24 13:02:24.000000000 +0100 +++ msn-transport-disco/include/msntrans.h 2003-12-05 13:35:22.000000000 +0100 @@ -37,6 +37,10 @@ #define PACKET_DEBUG */ +/* namespaces for service discovery */ +#define NS_DISCO_ITEMS "http://jabber.org/protocol/disco#items" +#define NS_DISCO_INFO "http://jabber.org/protocol/disco#info" + /* MSN Transport instance */ typedef struct mti_struct { diff -Naur msn-transport/src/conf_room.c msn-transport-disco/src/conf_room.c --- msn-transport/src/conf_room.c 2003-10-22 09:24:53.000000000 +0200 +++ msn-transport-disco/src/conf_room.c 2003-12-05 13:35:25.000000000 +0100 @@ -147,6 +147,21 @@ xmlnode_put_attrib(x,"name",spools(xmlnode_pool(q),r->name," (",buf,")",xmlnode_pool(q))); } +void mt_con_disco_server_walk(xht h, const char *key, void *val, void *arg) +{ + sbroom r = (sbroom) val; + xmlnode q = (xmlnode) arg; + xmlnode item; + char buf[3]; + + item = xmlnode_insert_tag(q, "item"); + xmlnode_put_attrib(item, "jid", jid_full(r->rid)); + + /* the number of users in this room */ + snprintf(buf, 3, "%d", r->count+1); + xmlnode_put_attrib(item, "name", spools(xmlnode_pool(q), r->name, " (",buf, ")", xmlnode_pool(q))); +} + void mt_con_browse_server(session s, jpacket jp) { if (jpacket_subtype(jp) == JPACKET__GET) @@ -167,6 +182,49 @@ mt_deliver(s->ti,jp->x); } +void mt_con_disco_items_server(session s, jpacket jp) +{ + xmlnode q; + + if (jpacket_subtype(jp) != JPACKET__GET) + { + jutil_error(jp->x,TERROR_BAD); + mt_deliver(s->ti, jp->x); + return; + } + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_ITEMS); + + xhash_walk(s->rooms,&mt_con_disco_server_walk,(void *) q); + + mt_deliver(s->ti, jp->x); +} + +void mt_con_disco_info_server(session s, jpacket jp) +{ + xmlnode q, info; + + if (jpacket_subtype(jp) != JPACKET__GET) + { + jutil_error(jp->x, TERROR_BAD); + mt_deliver(s->ti, jp->x); + return; + } + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_INFO); + + info = xmlnode_insert_tag(q, "identity"); + xmlnode_put_attrib(info, "category", "conference"); + xmlnode_put_attrib(info, "type", "text"); + xmlnode_put_attrib(info, "name","MSN Conference"); + + mt_deliver(s->ti, jp->x); +} + void mt_con_browse_user(sbroom r, jpacket jp) { sbr_user user; @@ -189,6 +247,45 @@ jutil_error(jp->x,TERROR_NOTFOUND); } +void mt_con_disco_items_user(sbroom r, jpacket jp) +{ + sbr_user user; + xmlnode q; + + user = (sbr_user) xhash_get(r->users_lid, jp->to->resource); + if (user == NULL) + { + jutil_error(jp->x,TERROR_BAD); + return; + } + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_ITEMS); +} + +void mt_con_disco_info_user(sbroom r, jpacket jp) +{ + sbr_user user; + xmlnode q, info; + + user = (sbr_user) xhash_get(r->users_lid, jp->to->resource); + if (user == NULL) + { + jutil_error(jp->x,TERROR_BAD); + return; + } + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_INFO); + + info = xmlnode_insert_tag(q, "identity"); + xmlnode_put_attrib(info, "category", "client"); + xmlnode_put_attrib(info, "type", "pc"); + xmlnode_put_attrib(info, "name", user->nick); +} + void mt_con_browse_room_walk(xht h, const char *key, void *val, void *arg) { sbr_user user = (sbr_user) val; @@ -199,6 +296,16 @@ xmlnode_put_attrib(x,"name",user->nick); } +void mt_con_disco_room_walk(xht h, const char *key, void *val, void *arg) +{ + sbr_user user = (sbr_user) val; + xmlnode q = (xmlnode) arg; + xmlnode x = xmlnode_insert_tag(q, "item"); + + xmlnode_put_attrib(x, "jid", jid_full(user->lid)); + xmlnode_put_attrib(x, "name", user->nick); +} + void mt_con_browse_room(sbroom r, jpacket jp) { xmlnode q, x; @@ -216,6 +323,34 @@ xmlnode_put_attrib(x,"name",r->nick); } +void mt_con_disco_items_room(sbroom r, jpacket jp) +{ + xmlnode q; + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_ITEMS); + + xhash_walk(r->users_mid, &mt_con_disco_room_walk, (void *)q); +} + +void mt_con_disco_info_room(sbroom r, jpacket jp) +{ + xmlnode q, info; + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_INFO); + + info = xmlnode_insert_tag(q, "identity"); + xmlnode_put_attrib(info, "category", "conference"); + xmlnode_put_attrib(info, "type", "text"); + xmlnode_put_attrib(info, "name", jp->to->user); + + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_CONFERENCE); +} + void mt_con_browse(session s, jpacket jp) { if (jpacket_subtype(jp) == JPACKET__GET) @@ -237,6 +372,44 @@ mt_deliver(s->ti,jp->x); } +void mt_con_disco_items(session s, jpacket jp) +{ + if (jpacket_subtype(jp) != JPACKET__GET) + jutil_error(jp->x, TERROR_NOTALLOWED); + else + { + sbroom r = (sbroom) xhash_get(s->rooms, jp->to->user); + if (r != NULL) + if (jp->to->resource == NULL) + mt_con_disco_items_room(r, jp); + else + mt_con_disco_items_user(r, jp); + else + jutil_error(jp->x, TERROR_NOTFOUND); + } + + mt_deliver(s->ti, jp->x); +} + +void mt_con_disco_info(session s, jpacket jp) +{ + if (jpacket_subtype(jp) != JPACKET__GET) + jutil_error(jp->x, TERROR_NOTALLOWED); + else + { + sbroom r = (sbroom) xhash_get(s->rooms, jp->to->user); + if (r != NULL) + if (jp->to->resource == NULL) + mt_con_disco_info_room(r, jp); + else + mt_con_disco_info_user(r, jp); + else + jutil_error(jp->x, TERROR_NOTFOUND); + } + + mt_deliver(s->ti, jp->x); +} + void mt_con_get(session s, jpacket jp) { sbroom r; @@ -351,6 +524,10 @@ mt_con_iq_conference(s,jp); else if (j_strcmp(xmlns,NS_BROWSE) == 0) mt_con_browse(s,jp); + else if (j_strcmp(xmlns,NS_DISCO_ITEMS) == 0) + mt_con_disco_items(s,jp); + else if (j_strcmp(xmlns,NS_DISCO_INFO) == 0) + mt_con_disco_info(s,jp); else xmlnode_free(jp->x); } @@ -358,6 +535,10 @@ { if (j_strcmp(xmlns,NS_BROWSE) == 0) mt_con_browse_server(s,jp); + else if (j_strcmp(xmlns, NS_DISCO_ITEMS) == 0) + mt_con_disco_items_server(s, jp); + else if (j_strcmp(xmlns, NS_DISCO_INFO) == 0) + mt_con_disco_info_server(s, jp); else mt_iq_server(s->ti,jp); } diff -Naur msn-transport/src/iq.c msn-transport-disco/src/iq.c --- msn-transport/src/iq.c 2002-04-24 01:56:58.000000000 +0200 +++ msn-transport-disco/src/iq.c 2003-12-05 13:35:25.000000000 +0100 @@ -198,6 +198,77 @@ mt_deliver(ti,jp->x); } +void mt_iq_disco_items_server(mti ti, jpacket jp) +{ + xmlnode q; + + if (jpacket_subtype(jp) != JPACKET__GET) + { + jutil_error(jp->x,TERROR_NOTALLOWED); + mt_deliver(ti, jp->x); + return; + } + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_ITEMS); + + if (ti->con) + { + xmlnode item = xmlnode_insert_tag(q,"item"); + xmlnode_put_attrib(item, "name", "MSN Conference"); + xmlnode_put_attrib(item, "jid", ti->con_id); + } + + mt_deliver(ti,jp->x); +} + +void mt_iq_disco_info_server(mti ti, jpacket jp) +{ + xmlnode q, info; + + if (jpacket_subtype(jp) != JPACKET__GET) + { + jutil_error(jp->x,TERROR_NOTALLOWED); + mt_deliver(ti, jp->x); + return; + } + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_INFO); + info = xmlnode_insert_tag(q, "identity"); + xmlnode_put_attrib(info, "category", "gateway"); + xmlnode_put_attrib(info, "type", "msn"); + xmlnode_put_attrib(info, "name",xmlnode_get_tag_data(ti->vcard,"FN")); + + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_REGISTER); + + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_VERSION); + + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_TIME); + + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_LAST); + + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_GATEWAY); + + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_VCARD); + + if (ti->admin != NULL && xmlnode_get_tag(ti->admin,spools(jp->p,"read=",jid_full(jid_user(jp->from)),jp->p)) != NULL) + { + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_ADMIN); + } + + mt_deliver(ti,jp->x); +} + void mt_iq_vcard_user(session s, jpacket jp) { xmlnode q; @@ -242,6 +313,49 @@ mt_deliver(s->ti,jp->x); } +void mt_iq_disco_items_user(session s, jpacket jp) +{ + xmlnode q; + char *m; + + if (jpacket_subtype(jp) != JPACKET__GET || (m = mt_jid2mid(jp->p, jp->to)) == NULL) + jutil_error(jp->x, TERROR_BAD); + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_ITEMS); + + mt_deliver(s->ti, jp->x); +} + +void mt_iq_disco_info_user(session s, jpacket jp) +{ + xmlnode q, info; + muser u; + char *m = NULL; + + if (jpacket_subtype(jp) != JPACKET__GET || (m = mt_jid2mid(jp->p, jp->to)) == NULL) + jutil_error(jp->x, TERROR_BAD); + + jutil_iqresult(jp->x); + q = xmlnode_insert_tag(jp->x, "query"); + xmlnode_put_attrib(q, "xmlns", NS_DISCO_INFO); + + info = xmlnode_insert_tag(q, "identity"); + xmlnode_put_attrib(info, "category", "client"); + xmlnode_put_attrib(info, "type", "pc"); + u = (muser) xhash_get(s->users,m); + xmlnode_put_attrib(info,"name",u != NULL ? mt_decode(jp->p,u->handle) : m); + + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_VERSION); + + info = xmlnode_insert_tag(q, "feature"); + xmlnode_put_attrib(info, "var", NS_VCARD); + + mt_deliver(s->ti, jp->x); +} + typedef void (*iq_server_cb)(mti ti, jpacket jp); void mt_iq_server(mti ti, jpacket jp) @@ -272,6 +386,8 @@ xhash_put(h,NS_ADMIN,&mt_iq_admin); xhash_put(h,NS_VCARD,&mt_iq_vcard_server); xhash_put(h,NS_BROWSE,&mt_iq_browse_server); + xhash_put(h,NS_DISCO_ITEMS,&mt_iq_disco_items_server); + xhash_put(h,NS_DISCO_INFO,&mt_iq_disco_info_server); } void mt_iq(session s, jpacket jp) @@ -294,6 +410,10 @@ mt_iq_browse_user(s,jp); else if (j_strcmp(xmlns,NS_VERSION) == 0) mt_iq_version(s->ti,jp); + else if (j_strcmp(xmlns,NS_DISCO_ITEMS) == 0) + mt_iq_disco_items_user(s,jp); + else if (j_strcmp(xmlns,NS_DISCO_INFO) == 0) + mt_iq_disco_info_user(s,jp); else { jutil_error(jp->x,TERROR_NOTALLOWED);
signature.asc
Description: Digital signature
