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

📄 mod_filter.c

📁 AnyQ服务端源代码(2004/10/28)源码
💻 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"/** mod_filter.c: 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>*//* 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 */xmlnode mod_filter__default = NULL;jsmi    mod_filter__jsmi    = NULL;#define MOD_FILTER_MAX_SIZE 100typedef struct action_struct {    pool p;    int is_match, has_action;    int offline, reply, settype, cont, error;    jid forward;    mapi m;} _action, *action;/* get the user's 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;}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_debug("mod_filter","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));    }}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);}void mod_filter_action_error(mapi m,xmlnode rule){    xmlnode err = xmlnode_get_tag(rule, "error");    log_debug(ZONE,"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);}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... */    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( ( j != NULL ) &&                    ( 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),"Forwarding would result in infinite loop");                    return;                }

⌨️ 快捷键说明

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