[JDEV] Patch for classic msn-t to support service discovery

Matthias Wimmer m at tthias.net
Fri Dec 5 06:41:32 CST 2003


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:mawis at charente.de
-------------- next part --------------
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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <https://www.jabber.org/jdev/attachments/20031205/2363d4be/attachment-0002.pgp>


More information about the JDev mailing list