⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_browse.c

📁 jabber server jabber server jabber server jabber server
💻 C
字号:
/* -------------------------------------------------------------------------- * * License * * The contents of this file are subject to the Jabber Open Source License * Version 1.0 (the "JOSL").  You may not copy or use this file, in either * source code or executable form, except in compliance with the JOSL. You * may obtain a copy of the JOSL at http://www.jabber.org/ or at * http://www.opensource.org/.   * * Software distributed under the JOSL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL * for the specific language governing rights and limitations under the * JOSL. * * Copyrights *  * Portions created by or assigned to Jabber.com, Inc. are  * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact * information for Jabber.com, Inc. is available at http://www.jabber.com/. * * Portions Copyright (c) 1998-1999 Jeremie Miller. *  * Acknowledgements *  * Special thanks to the Jabber Open Source Contributors for their * suggestions and support of Jabber. *  * Alternatively, the contents of this file may be used under the terms of the * GNU General Public License Version 2 or later (the "GPL"), in which case * the provisions of the GPL are applicable instead of those above.  If you * wish to allow use of your version of this file only under the terms of the * GPL and not to allow others to use your version of this file under the JOSL, * indicate your decision by deleting the provisions above and replace them * with the notice and other provisions required by the GPL.  If you do not * delete the provisions above, a recipient may use your version of this file * under either the JOSL or the GPL.  *  *  * --------------------------------------------------------------------------*/#include "jsm.h"/** * @file mod_browse.c * @brief implement handling of the jabber:iq:browse namespace (JEP-0011) in the session manager - DEPRICATED * * This module implements the handling of jabber:iq:browse to query client information * in the session manager. jabber:iq:browse is documented in JEP-0011. Browsing * is DEPRICATED, clients should use service discovery instead. * * Part of the jabber:iq:browse functionallity is also implemented in mod_admin.c. *//** * Generate the browse result for a user by loading the information from xdb or creating it if there is nothing stored yet. * * @param m the mapi structure * @param id the JID of the user for which the browse info should be build * @return the xml fragment containing the browse result */xmlnode mod_browse_get(mapi m, jid id){    xmlnode browse, x;    if(id == NULL) /* use the user id as a backup */        id = m->user->id;    /* get main account browse */    if((browse = xdb_get(m->si->xc, id, NS_BROWSE)) == NULL)    { /* no browse is set up yet, we must create one for this user! */        if(id->resource == NULL)        { /* a user is only the user@host */            browse = xmlnode_new_tag("user");            /* get the friendly name for this user from somewhere */            if((x = xdb_get(m->si->xc, m->user->id, NS_VCARD)) != NULL)                xmlnode_put_attrib(browse,"name",xmlnode_get_tag_data(x,"FN"));            else if((x = xdb_get(m->si->xc, m->user->id, NS_REGISTER)) != NULL)                xmlnode_put_attrib(browse,"name",xmlnode_get_tag_data(x,"name"));            xmlnode_free(x);        }else{ /* everything else is generic unless set by the user */            browse = xmlnode_new_tag("item");        }        xmlnode_put_attrib(browse,"xmlns",NS_BROWSE);        xmlnode_put_attrib(browse,"jid",jid_full(id));        xdb_set(m->si->xc, id, NS_BROWSE, browse);    }    return browse;}/** * Handle iq stanzas of type 'set' containing a jabber:iq:browse request. * * This callback is only inserted in the es_OUT handler list, therefore it is only called for stanzas the user * sents itself. It is NOT called for stanzas arriving at the user's address. It only handles stanzas with NO * to attribute. * * Handling iq stanzas of type 'set' is not documented in JEP-0011. I guess, it is an undocumented extension in jabberd14. * * @param m the mapi structure containing the request * @param arg unused/ignored * @return M_IGNORE if it is no iq stanza, M_PASS if the packet has not been processed, M_HANDLED if the packet has been processed */mreturn mod_browse_set(mapi m, void *arg){    xmlnode browse, cur;    jid id, to;    if(m->packet->type != JPACKET_IQ) return M_IGNORE;    if(!NSCHECK(m->packet->iq,NS_BROWSE) || jpacket_subtype(m->packet) != JPACKET__SET) return M_PASS;    if(m->packet->to != NULL) return M_PASS; /* if its to someone other than ourselves */    log_debug2(ZONE, LOGT_DELIVER, "handling set request %s",xmlnode2str(m->packet->iq));    /* no to implies to ourselves */    if(m->packet->to != NULL)        to = m->packet->to;    else        to = m->user->id;    /* if we set to a resource, we need to make sure that resource's browse is in the users browse */    if(to->resource != NULL)    {        browse = mod_browse_get(m, to); /* get our browse info */        xmlnode_hide_attrib(browse,"xmlns"); /* don't need a ns as a child */        for(cur = xmlnode_get_firstchild(browse); cur != NULL; cur = xmlnode_get_nextsibling(cur))            xmlnode_hide(cur); /* erase all children */        xdb_act(m->si->xc, m->user->id, NS_BROWSE, "insert", spools(m->packet->p,"?jid=",jid_full(to),m->packet->p), browse); /* insert and match replace */        xmlnode_free(browse);    }    /* get the id of the new browse item */    if((cur = xmlnode_get_firstchild(m->packet->iq)) == NULL || (id = jid_new(m->packet->p, xmlnode_get_attrib(cur,"jid"))) == NULL)    {        js_bounce_xmpp(m->si,m->packet->x,XTERROR_NOTACCEPTABLE);        return M_HANDLED;    }    /* insert the new item into the resource it was sent to */    xmlnode_hide_attrib(cur,"xmlns"); /* just in case, to make sure it inserts */    if(xdb_act(m->si->xc, to, NS_BROWSE, "insert", spools(m->packet->p,"?jid=",jid_full(id),m->packet->p), cur))    {        js_bounce_xmpp(m->si,m->packet->x,XTERROR_UNAVAIL);        return M_HANDLED;    }            /* if the new data we're inserting is to one of our resources, update that resource's browse */    if(jid_cmpx(m->user->id, id, JID_USER|JID_SERVER) == 0 && id->resource != NULL)    {        /* get the old */        browse = mod_browse_get(m, id);        /* transform the new one into the old one */        xmlnode_put_attrib(cur, "xmlns", NS_BROWSE);        xmlnode_insert_node(cur, xmlnode_get_firstchild(browse));        xdb_set(m->si->xc, id, NS_BROWSE, cur); /* replace the resource's browse w/ this one */        xmlnode_free(browse);    }    /* send response to the user */    jutil_iqresult(m->packet->x);    jpacket_reset(m->packet);    js_session_to(m->s,m->packet);    return M_HANDLED;}/** * register a callback for stanzas the user sends (to be able to handle queries without a to attribute) * * @param m the mapi structure * @param arg unused/ignored * @return always M_PASS */mreturn mod_browse_session(mapi m, void *arg){    js_mapi_session(es_OUT,m->s,mod_browse_set,NULL);    return M_PASS;}/** * This callback handles iq stanzas sent to an offline user. * Everything but iq stanzas are ignored, iq queries not in the jabber:iq:browse namespace are not handled. * Only iq stanzas of type 'get' are really processed, stanzas of type 'set' are denied, other types are ignored. * * The result is build using the user's stored browse info. If the user that sent the query is subscribed * to the target's presence, a list of active sessions of the users is added to the result as well. * * @param m the mapi instance containing the query * @param arg not used/ignored * @return M_IGNORE if the packet is no iq stanza, M_PASS if the stanza has not been processed, M_HANDLED if the request has been handled */mreturn mod_browse_reply(mapi m, void *arg){    xmlnode browse, ns, cur;    session s;    if(m->packet->type != JPACKET_IQ) return M_IGNORE;    if(!NSCHECK(m->packet->iq,NS_BROWSE)) return M_PASS;    /* first, is this a valid request? */    switch(jpacket_subtype(m->packet))    {    case JPACKET__RESULT:    case JPACKET__ERROR:        return M_PASS;    case JPACKET__SET:        js_bounce_xmpp(m->si,m->packet->x,XTERROR_NOTALLOWED);        return M_HANDLED;    }    log_debug2(ZONE, LOGT_DELIVER, "handling query for user %s",m->user->user);    /* get this dudes browse info */    browse = mod_browse_get(m, m->packet->to);    /* insert the namespaces */    ns = xdb_get(m->si->xc, m->packet->to, NS_XDBNSLIST);    for(cur = xmlnode_get_firstchild(ns); cur != NULL; cur = xmlnode_get_nextsibling(cur))        if(xmlnode_get_attrib(cur,"type") == NULL)            xmlnode_insert_tag_node(browse,cur); /* only include the generic <ns>foo</ns> */    xmlnode_free(ns);    /* include any connected resources if there's a s10n from them */    if(js_trust(m->user, m->packet->from))        for(s = m->user->sessions; s != NULL; s = s->next)        {            /* if(s->priority < 0) continue; *** include all resources I guess */            if(xmlnode_get_tag(browse,spools(m->packet->p,"?jid=",jid_full(s->id),m->packet->p)) != NULL) continue; /* already in the browse result */            cur = xmlnode_insert_tag(browse,"user");            xmlnode_put_attrib(cur,"type", "client");            xmlnode_put_attrib(cur,"jid", jid_full(s->id));        }    /* XXX include iq:filter forwards */    jutil_iqresult(m->packet->x);    jpacket_reset(m->packet);    xmlnode_insert_tag_node(m->packet->x,browse);    js_deliver(m->si,m->packet);    xmlnode_free(browse);    return M_HANDLED;}/** * Handle stanzas that are sent to the server's address. * Everything but iq stanzas are ignored. The iq stanzas have to be of type 'get', the content must be in the jabber:iq:browse namespace * and there must be no resource, else the stanza won't be handled either. * * The result will be build using the content of the <browse/> element in the session manager configuration. The the user that sent * the query as read admin privileges, and advertizement for serverdomain/admin will be sent as well. (Queries to this address * are handled by mod_admin.c.) * * @param m the mapi structure containing the request * @param arg not used/ignored * @return M_IGNORE if the stanza is no iq, M_PASS if this module is not responsible, M_HANDLED if the stanza has been processed */mreturn mod_browse_server(mapi m, void *arg){    xmlnode browse, query, x;    if(m->packet->type != JPACKET_IQ) return M_IGNORE;    if(jpacket_subtype(m->packet) != JPACKET__GET || !NSCHECK(m->packet->iq,NS_BROWSE) || m->packet->to->resource != NULL) return M_PASS;    /* get data from the config file */    if((browse = js_config(m->si,"browse")) == NULL)        return M_PASS;    log_debug2(ZONE, LOGT_DELIVER, "handling browse query");    /* build the result IQ */    query = xmlnode_insert_tag(jutil_iqresult(m->packet->x),"service");    xmlnode_put_attrib(query,"xmlns",NS_BROWSE);    xmlnode_put_attrib(query,"type","jabber");    xmlnode_put_attrib(query,"jid",m->packet->to->server);    xmlnode_put_attrib(query,"name",xmlnode_get_data(js_config(m->si,"vCard/FN"))); /* pull name from the server vCard */    /* copy in the configured services */    xmlnode_insert_node(query,xmlnode_get_firstchild(browse));    /* list the admin stuff */    if(js_admin(m->user, ADMIN_READ))    {        x = xmlnode_insert_tag(query,"item");        xmlnode_put_attrib(x,"jid",spools(xmlnode_pool(x),m->packet->to->server,"/admin",xmlnode_pool(x)));        xmlnode_put_attrib(x,"name","Online Users");        xmlnode_insert_cdata(xmlnode_insert_tag(query,"ns"),NS_ADMIN,-1);    }    jpacket_reset(m->packet);    js_deliver(m->si,m->packet);    return M_HANDLED;}/** * init the mod_browse module in the session manager * registers three callbacks: if a session is started, mod_browse_session should be called, * if an offline user gets a stanza, mod_browse_reply should be called, * if a stanza is sent to the server, mod_browse_server should be called. * * @param si the session manager instance */void mod_browse(jsmi si){    js_mapi_register(si,e_SESSION,mod_browse_session,NULL);    js_mapi_register(si,e_OFFLINE,mod_browse_reply,NULL);    js_mapi_register(si,e_SERVER,mod_browse_server,NULL);}/*<mass> wow<mass> they had this four gallon thing of detergent at costco<mass> I'm set for about two years * mass goes to read the directions on how to get soap out of it<mass> the thing is really complicated. I'm reminded of the lament cube from Hellraiser<mass> although I'm hoping I get soap instead of pinhead*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -