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

📄 mod_filter.c

📁 jabber server jabber server jabber server jabber server
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -------------------------------------------------------------------------- * * 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_filter.c * @brief This module handles the undocumented namespace jabber:iq:filter. The module is DEPRECATED, it may generate endless looping message bounces. * It also handles what mod_offline.c does as it needs to filter offline storage. * * it's alive! it now handles all functions that used to be handled by mod_offline.c  * * mod_filter supports the following conditions: * - unavailable - matches when you aren't online * - from        - matches if the sender is the same as the cdata in the <from/> tag * - resource    - matches YOUR resource * - subject     - matches the subject of the message * - body        - matches the body of the message * - show        - matches your <show/> in presence * - type        - matches the type='' attrib * * and the following Actions: * - offline     - stores the message offline * - forward     - forwards the message to another jid * - reply       - sends back an auto-reply message to the sender * - continue    - continues processing of other rules * - settype     - change the incoming message type * * you may specify any number of conditions/actions, if there are more than one condition, * ALL conditions must match for the rule to match, and ALL the listed actions will be taken. * * rules are checked in order, stopping when a match is found, unless a <continue/> flag is in place * * example rule: * <rule> *    <unavailable/> *    <offline/> *    <reply>I'm not available right now</reply> *    <forward>tsbandit@jabber.org</forward> * </rule> * * @note mod_filter must go first in module ordering * * * basic principle of mod_filter: * - each user has their own filter * - each filter contains zero or more rules * - each rule contains one or more conditions and one or more actions * - some conditions/actions may contain text to limit it further * - first matching condition is applied and processing quits (unless an action is continue) * - processed in order from client * - NO ACTION IMPLIES DROP * - FUTURE CONDITIONS: type, time, size * - FUTURE ACTIONS: edit,error,settype *//** default maximum ruleset size, can be overwritten by configuration */#define MOD_FILTER_MAX_SIZE 100/** * structure that contains a parsed action */typedef struct action_struct {    pool p;		/**< memory pool */    int is_match;	/**< if the action is matched */    int has_action;	/**< if there is an action at all */    int offline;	/**< store offline */    int reply;		/**< send an automated reply */    int settype;	/**< set the type for a stanza */    int cont;		/**< continue processing */    int error;		/**< send an error reply */    jid forward;	/**< forwarding destination *//*    mapi m; */} _action, *action;/** * get the user's filter rules * * @param u the user * @return the filter rules */xmlnode mod_filter_get(udata u) {    xmlnode ret;    /* get the existing rules */    ret = xdb_get(u->si->xc, u->id, NS_FILTER);    if(ret == NULL)    {        ret = xmlnode_new_tag("query");        xmlnode_put_attrib(ret, "xmlns", NS_FILTER);    }    return ret;}/** * store a message offline * * @param m the mapi_struct containing the message * @param rule the rule that configures if the message should be stored offline */void mod_filter_action_offline(mapi m, xmlnode rule) {    xmlnode cur;   /* look for event messages */    for(cur = xmlnode_get_firstchild(m->packet->x); cur != NULL; cur = xmlnode_get_nextsibling(cur)) {        if(NSCHECK(cur, NS_EVENT)) {            if(xmlnode_get_tag(cur, "id") != NULL)                return; /* bah, we don't want to store events offline (XXX: do we?) */            if(xmlnode_get_tag(cur, "offline") != NULL)                break; /* cur remaining set is the flag */        }    }    log_debug2(ZONE, LOGT_DELIVER|LOGT_STORAGE, "storing message for %s offline.",m->user->user);    jutil_delay(m->packet->x,"Offline Storage");    if(xdb_act(m->si->xc, m->user->id, NS_OFFLINE, "insert", NULL, m->packet->x))        return;    if(cur != NULL) {	/* if there was an offline event to be sent, send it for gosh sakes! */        xmlnode cur2;        jutil_tofrom(m->packet->x);        /* erease everything else in the message */        for(cur2 = xmlnode_get_firstchild(m->packet->x); cur2 != NULL; cur2 = xmlnode_get_nextsibling(cur2))            if(cur2 != cur)                xmlnode_hide(cur2);        /* erase any other events */        for(cur2 = xmlnode_get_firstchild(cur); cur2 != NULL; cur2 = xmlnode_get_nextsibling(cur2))            xmlnode_hide(cur2);        /* fill it in and send it on */        xmlnode_insert_tag(cur,"offline");        xmlnode_insert_cdata(xmlnode_insert_tag(cur,"id"),xmlnode_get_attrib(m->packet->x,"id"), -1);        js_deliver(m->si, jpacket_reset(m->packet));    }}/** * send a reply message * * @param m the mapi_struct containing the stanza * @param rule the rule containing the instruction */void mod_filter_action_reply(mapi m,xmlnode rule) {    char *reply=xmlnode_get_tag_data(rule,"reply");    xmlnode x = xmlnode_get_tag(m->packet->x, "x?xmlns=jabber:x:envelope");    int has_envelope = 0;    /* check for infinite loops */    if(x != NULL) {        xmlnode cur = xmlnode_get_tag(x, "forwardedby");        has_envelope = 1;        for(; cur != NULL; cur = xmlnode_get_nextsibling(cur))        {            if(xmlnode_get_type(cur) != NTYPE_TAG)                continue;            if(j_strcmp(xmlnode_get_name(cur), "forwardedby") == 0)            {                char *fb = xmlnode_get_attrib(cur, "jid");                jid j    = jid_new(m->packet->p, fb);                if(jid_cmpx(j, m->packet->to, JID_USER | JID_SERVER) == 0)                {                    x = xmlnode_dup(m->packet->x);                    xmlnode_put_attrib(x, "to", jid_full(j));                    xmlnode_put_attrib(x, "from", jid_full(m->packet->to));                    deliver_fail(dpacket_new(x), "Replying would result in infinite loop");                    return;                }            }        }    }    if(!has_envelope)        xmlnode_put_attrib(x = xmlnode_insert_tag(m->packet->x, "x"), "xmlns", "jabber:x:envelope");    xmlnode_put_attrib(xmlnode_insert_tag(x, "forwardedby"), "jid", jid_full(m->packet->to));    xmlnode_put_attrib(xmlnode_insert_tag(x, "from"), "jid", jid_full(m->packet->to));    xmlnode_put_attrib(xmlnode_insert_tag(x, "to"), "jid", jid_full(m->packet->from));    if(jid_cmpx(m->packet->to, m->packet->from, JID_USER | JID_SERVER) == 0) {	/* special case, we sent a msg to ourselves */        /* try to find a session to deliver to... */        session s = js_session_get(m->user, m->packet->to->resource);        s = s ? s : js_session_primary(m->user);        s = s ? s : m->s;        if(s == NULL) {	    /* can't find a deliverable session, store offline */            mod_filter_action_offline(m, rule);            return;        }                /* just deliver to the session */        x = xmlnode_dup(m->packet->x);        jutil_tofrom(x);        if(xmlnode_get_tag(x, "body") != NULL)             xmlnode_hide(xmlnode_get_tag(x, "body"));        if(reply != NULL)            xmlnode_insert_cdata(xmlnode_insert_tag(x, "body"), reply, -1);        js_session_to(s, jpacket_new(x));        return;    }    x = xmlnode_dup(m->packet->x);    jutil_tofrom(x);    if(xmlnode_get_tag(x, "body") != NULL)         xmlnode_hide(xmlnode_get_tag(x, "body"));    if(reply != NULL)        xmlnode_insert_cdata(xmlnode_insert_tag(x, "body"), reply, -1);    deliver(dpacket_new(x),m->si->i);}/** * send an error reply to a stanza * * @param m the mapi_struct containing the incoming stanza * @param rule the rule containing the error command */void mod_filter_action_error(mapi m,xmlnode rule) {    xmlnode err = xmlnode_get_tag(rule, "error");    log_debug2(ZONE, LOGT_DELIVER, "sending an error reply");        if(err != NULL) {        xmlnode_insert_tag_node(m->packet->x, err);        xmlnode_put_attrib(m->packet->x, "type", "error");        jpacket_reset(m->packet);    }    mod_filter_action_reply(m, rule);}/** * handle forwarding of a stanza * * @param m the mapi_struct containing the incoming stanza * @param rule the rule that configures the forwarding * @param j destination of the forwarded packet */void mod_filter_action_forward(mapi m,xmlnode rule,jid j) {    int has_envelope=0;    jid cur;    xmlnode x=xmlnode_get_tag(m->packet->x,"x?xmlns=jabber:x:envelope");    /* check for infinite loops... */

⌨️ 快捷键说明

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