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

📄 mod_groups.c

📁 AnyQ服务端源代码(2004/10/28)源码
💻 C
📖 第 1 页 / 共 2 页
字号:
        mod_groups_presence_to(m->s,gt);    }    jutil_iqresult(jp->x);    jpacket_reset(jp);    js_session_to(m->s,jp);    xmlnode_free(info);}void mod_groups_register_get(mod_groups_i mi, mapi m){    jpacket jp = m->packet;    xmlnode q;    char *gid, *name = "";    xmlnode members, user;    jid uid = m->user->id;    gid = strchr(pstrdup(jp->p, jp->to->resource),'/');    if (gid != NULL && ++gid != NULL) /* Check that it is somewhat valid */    {        jutil_iqresult(jp->x);        q = xmlnode_insert_tag(jp->x,"query");        xmlnode_put_attrib(q,"xmlns",NS_REGISTER);        /* Search to see if this users is already registered */        members = mod_groups_get_users(mi,jp->p,jp->from->server,gid);        user =  xmlnode_get_tag(members,spools(jp->p,"?jid=",uid->full,jp->p));        if (user)        {            name = xmlnode_get_attrib(user, "name");            xmlnode_insert_tag(q,"registered");        }        xmlnode_free(members);        xmlnode_insert_cdata(xmlnode_insert_tag(q,"name"),name,-1);        xmlnode_insert_cdata(xmlnode_insert_tag(q,"key"),jutil_regkey(NULL,jid_full(jp->from)),-1);        xmlnode_insert_cdata(xmlnode_insert_tag(q,"instructions"),mi->inst,-1);        jpacket_reset(jp);        js_session_to(m->s,jp);    }    else        js_bounce(m->si,jp->x,TERROR_NOTACCEPTABLE);}void mod_groups_browse_set(mod_groups_i mi, mapi m){    jpacket jp = m->packet;    pool p = jp->p;    grouptab gt;    xmlnode info, user;    jid uid;    char *gid, *gn, *un, *host, *action;    int add;    log_debug(ZONE,"Setting");    gid = strchr(jp->to->resource,'/');    if (gid == NULL || ++gid == NULL)    {        js_bounce(m->si,jp->x,TERROR_NOTACCEPTABLE);        return;    }    user = xmlnode_get_tag(jp->iq,"user");    uid = jid_new(p,xmlnode_get_attrib(user,"jid"));    un = xmlnode_get_attrib(user,"name");    action = xmlnode_get_attrib(user, "action");    add = ( ( action == NULL ) || j_strcmp(action, "remove") );    if (uid == NULL || un == NULL)    {        js_bounce(m->si,jp->x,TERROR_NOTACCEPTABLE);        return;    }    info = mod_groups_get_info(mi,p,jp->to->server,gid);    if (info == NULL ||  xmlnode_get_tag(info,spools(p,"edit/user=",jid_full(jp->from),p)) == NULL)    {        js_bounce(m->si,jp->x,TERROR_NOTALLOWED);        return;    }    gn = xmlnode_get_tag_data(info,"name");    if ( add )    {        log_debug("mod_groups", "Adding");        if (mod_groups_xdb_add(mi,p,uid,un,gid,gn,1))        {            js_bounce(m->si,jp->x,TERROR_UNAVAIL);            xmlnode_free(info);            return;        }    }    else    {        log_debug("mod_groups", "Removing");        host = jp->from->server;        if (mod_groups_xdb_remove(mi,p,uid,host,gid))        {            js_bounce(m->si,jp->x,TERROR_UNAVAIL);            xmlnode_free(info);            return;        }    }    gt = GROUP_GET(mi,gid);    /* push the new user to the other members */    mod_groups_update_rosters(gt,uid,un,gn,add);    /* XXX how can we push the roster to the new user and send their presence?  lookup their session? */    xmlnode_free(info);    jutil_iqresult(jp->x);    jpacket_reset(jp);    js_session_to(m->s,jp);}void mod_groups_browse_result(pool p, jpacket jp, xmlnode group, char *host, char *gn){    xmlnode q, cur, tag;    char *id, *name;    q = xmlnode_insert_tag(jutil_iqresult(jp->x),"item");    xmlnode_put_attrib(q,"xmlns",NS_BROWSE);    xmlnode_put_attrib(q,"jid",jid_full(jp->to));    xmlnode_put_attrib(q,"name",gn ? gn : "Toplevel groups");    for (cur = xmlnode_get_firstchild(group); cur != NULL; cur = xmlnode_get_nextsibling(cur))    {        if (xmlnode_get_type(cur) != NTYPE_TAG) continue;        name = xmlnode_get_name(cur);        if (j_strcmp(name,"group") == 0)        {            tag = xmlnode_insert_tag(q,"item");            xmlnode_put_attrib(tag,"name",xmlnode_get_attrib(cur,"name"));            id = spools(p,host,"/groups/",xmlnode_get_attrib(cur,"id"),p);            xmlnode_put_attrib(tag,"jid",id);        }        else if (j_strcmp(name,"user") == 0)        {            xmlnode_insert_node(q,cur);        }    }}void mod_groups_browse_get(mod_groups_i mi, mapi m){    jpacket jp = m->packet;    xmlnode group;    pool p = jp->p;    xmlnode info = NULL;    char *gid, *gn, *host = jp->to->server;    log_debug("mod_groups","Browse request");    gid = strchr(jp->to->resource,'/');    if (gid != NULL && ++gid != NULL)    {        group = mod_groups_get_users(mi,p,host,gid);        info = mod_groups_get_info(mi,p,host,gid);        gn = xmlnode_get_tag_data(info,"name");    }    else    {        group = mod_groups_get_top(mi,p,host);        gn = NULL;    }    if (group == NULL && gn == NULL)    {        js_bounce(m->si,jp->x,TERROR_NOTFOUND);        return;    }    if (group)    {        mod_groups_browse_result(p,jp,group,host,gn);        xmlnode_free(group);    }    else    {        xmlnode q;        q = xmlnode_insert_tag(jutil_iqresult(jp->x),"item");        xmlnode_put_attrib(q,"xmlns",NS_BROWSE);        xmlnode_put_attrib(q,"jid",jid_full(jp->to));        xmlnode_put_attrib(q,"name",gn);    }    jpacket_reset(jp);    if (gid)    {        xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq,"ns"),NS_REGISTER,-1);        xmlnode_free(info);    }    js_session_to(m->s,jp);}void mod_groups_roster(mod_groups_i mi, mapi m){    xmlnode groups, users, cur, roster;    pool p;    udata u = m->user;    char *gid, *host = m->user->id->server;    /* get group the user is a member of */    if ((groups = mod_groups_get_current(mi,u->id)) == NULL)        return;    p = xmlnode_pool(groups);    roster = jutil_iqnew(JPACKET__SET,NS_ROSTER);    /* push each group */    for (cur = xmlnode_get_firstchild(groups); cur != NULL; cur = xmlnode_get_nextsibling(cur))    {        if (xmlnode_get_type(cur) != NTYPE_TAG) continue;        gid = xmlnode_get_attrib(cur,"id");        users = mod_groups_get_users(mi,p,host,gid);        if (users != NULL)        {            xmlnode info;            char *gn;            info = mod_groups_get_info(mi,p,host,gid);            gn = xmlnode_get_tag_data(info,"name");            mod_groups_roster_insert(u,roster,users,gn ? gn : gid,1);            xmlnode_free(info);        }        else            log_debug("mod_groups","Failed to get users for group");    }    mod_groups_roster_push(m->s,roster,0);    xmlnode_free(groups);}mreturn mod_groups_iq(mod_groups_i mi, mapi m){    char *ns, *res;    int type;    ns = xmlnode_get_attrib(m->packet->iq,"xmlns");    /* handle roster gets */    type = jpacket_subtype(m->packet);    if (j_strcmp(ns,NS_ROSTER) == 0)    {        if (jpacket_subtype(m->packet) == JPACKET__GET)        {            log_debug("mod_groups","Roster request");            mod_groups_roster(mi,m);        }        return M_PASS;    }    /* handle iq's to groups */    res = m->packet->to ? m->packet->to->resource : NULL;    if (res && strncmp(res,"groups",6) == 0 && (strlen(res) == 6 || res[6] == '/'))    {        if (j_strcmp(ns,NS_BROWSE) == 0)        {            log_debug("mod_groups","Browse request");            if (type == JPACKET__GET)                mod_groups_browse_get(mi,m);            else if (type == JPACKET__SET)                mod_groups_browse_set(mi,m);            else                xmlnode_free(m->packet->x);        }        else if (j_strcmp(ns,NS_REGISTER) == 0)        {            log_debug("mod_groups","Register request");            if (type == JPACKET__GET)                mod_groups_register_get(mi,m);            else if (type == JPACKET__SET)                mod_groups_register_set(mi,m);            else                xmlnode_free(m->packet->x);        }        else            js_bounce(m->si,m->packet->x,TERROR_NOTALLOWED);        return M_HANDLED;    }    return M_PASS;}void mod_groups_presence(mod_groups_i mi, mapi m){    grouptab gt;    session s = m->s;    udata u = m->user;    xmlnode groups, cur;    if ((groups = mod_groups_get_current(mi,u->id)) == NULL)        return;    log_debug("mod_groups","Getting groups for %s",jid_full(u->id));    /* get each group */    for (cur = xmlnode_get_firstchild(groups); cur != NULL; cur = xmlnode_get_nextsibling(cur))    {        char *gid;        if ((gid = xmlnode_get_attrib(cur,"id")) == NULL) continue;        gt = GROUP_GET(mi,gid);        if(j_strcmp(xmlnode_get_attrib(cur,"type"),"both") == 0)            mod_groups_presence_from(s,gt,m->packet->x);        /* if we are new or our old priority was less then zero then "probe" the group members */        if (js_session_primary(m->user) || m->s->priority < 0)            mod_groups_presence_to(s,gt);    }    xmlnode_free(groups);}mreturn mod_groups_out(mapi m, void *arg){    mod_groups_i mi = (mod_groups_i) arg;    if (m->packet->type == JPACKET_PRESENCE)    {        if (m->packet->to == NULL) mod_groups_presence(mi,m);        return M_PASS;    }    else if (m->packet->type == JPACKET_IQ)        return mod_groups_iq(mi,m);    return M_IGNORE;}mreturn mod_groups_end(mapi m, void *arg){    mod_groups_i mi = (mod_groups_i) arg;    xmlnode groups, cur;    udata u = m->user;    jid id = u->id;    grouptab gt;    if (js_session_primary(u) != NULL || (groups = mod_groups_get_current(mi,id)) == NULL)        return M_PASS;    log_debug("mod_groups","removing user from table");    for (cur = xmlnode_get_firstchild(groups); cur != NULL; cur = xmlnode_get_nextsibling(cur))    {        gt = (grouptab) xhash_get(mi->groups,xmlnode_get_attrib(cur,"id"));        if (gt == NULL) continue;        if(j_strcmp(xmlnode_get_attrib(cur,"type"),"both") == 0)            xhash_zap(gt->from,jid_full(id));        xhash_zap(gt->to,jid_full(id));    }    xmlnode_free(groups);    return M_PASS;}mreturn mod_groups_session(mapi m, void *arg){    js_mapi_session(es_OUT,m->s,mod_groups_out,arg);    js_mapi_session(es_END,m->s,mod_groups_end,arg);    return M_PASS;}/* messages to groups */void mod_groups_message_walk(xht h, const char *key, void *val, void *arg){    xmlnode m = (xmlnode) arg;    udata u = (udata) val;    m = xmlnode_dup(m);    xmlnode_put_attrib(m,"to",jid_full(u->id));    js_deliver(u->si,jpacket_new(m));}void mod_groups_message_online(mod_groups_i mi, xmlnode msg, char *gid){    grouptab gt;    log_debug("mod_groups","broadcast message to '%s'",gid);    gt = (grouptab) xhash_get(mi->groups,gid);    if (gt != NULL)    {        xmlnode_put_attrib(msg,"from",xmlnode_get_attrib(msg,"to"));        xmlnode_hide_attrib(msg,"to");        xhash_walk(gt->from,mod_groups_message_walk,(void *) msg);    }    xmlnode_free(msg);}mreturn mod_groups_message(mapi m, void *arg){    mod_groups_i mi = (mod_groups_i) arg;    xmlnode info;    jpacket jp = m->packet;    char *gid;    if(jp->type != JPACKET_MESSAGE) return M_IGNORE;    if(jp->to == NULL || j_strncmp(jp->to->resource,"groups/",7) != 0) return M_PASS;    /* circular safety */    if(xmlnode_get_tag(jp->x,"x?xmlns=" NS_DELAY) != NULL)    {        xmlnode_free(jp->x);        return M_HANDLED;    }    gid = strchr(jp->to->resource,'/');    if (gid == NULL || ++gid == NULL)    {        js_bounce(m->si,jp->x,TERROR_NOTACCEPTABLE);        return M_HANDLED;    }    info = mod_groups_get_info(mi,jp->p,jp->to->server,gid);    if (info == NULL)    {        js_bounce(m->si,jp->x,TERROR_NOTFOUND);        return M_HANDLED;    }    if (xmlnode_get_tag(info,spools(jp->p,"write/user=",jid_full(jp->from),jp->p)) != NULL)        mod_groups_message_online(mi,jp->x,gid);    else        js_bounce(m->si,jp->x,TERROR_NOTALLOWED);    xmlnode_free(info);    return M_HANDLED;}void mod_groups_destroy(xht h, const char *key, void *val, void *arg){    grouptab gt = (grouptab) val;    xhash_free(gt->to);    xhash_free(gt->from);}mreturn mod_groups_shutdown(mapi m, void *arg){    mod_groups_i mi = (mod_groups_i) arg;    xhash_walk(mi->groups,mod_groups_destroy,NULL);    xhash_free(mi->groups);    xhash_free(mi->config);    pool_free(mi->p);    return M_PASS;}void mod_groups(jsmi si){    pool p;    mod_groups_i mi;    xmlnode cur, config;    char *gid, *id = si->i->id;    log_debug("mod_groups","initing");    p = pool_new();    mi = pmalloco(p,sizeof(_mod_groups_i));    mi->p = p;    mi->groups = xhash_new(67);    mi->xc = si->xc;    config = js_config(si,"groups");    mi->inst = xmlnode_get_tag_data(config,"instructions");    if (mi->inst == NULL)        mi->inst = pstrdup(p,"This will add the group to your roster");    if (config != NULL)    {        mi->config = xhash_new(67);        for (cur = xmlnode_get_firstchild(config); cur != NULL; cur = xmlnode_get_nextsibling(cur))        {            if (j_strcmp(xmlnode_get_name(cur),"group") != 0) continue;            gid = xmlnode_get_attrib(cur,"id");            if (gid == NULL)            {                log_error(id,"mod_groups: Error loading, no id attribute on group");                pool_free(p);                return;            }            else if (xhash_get(mi->config,gid) != NULL)            {                log_error(si->i->id,"mod_groups: Error loading, group '%s' configured twice",gid);                pool_free(p);                return;            }            if (xmlnode_get_tag(cur,"info") || xmlnode_get_tag(cur,"users"))                xhash_put(mi->config,pstrdup(p,gid),cur);        }    }    js_mapi_register(si,e_SERVER,mod_groups_message,(void *) mi);    js_mapi_register(si,e_SESSION,mod_groups_session,(void *) mi);    js_mapi_register(si,e_SHUTDOWN,mod_groups_shutdown,(void *) mi);}

⌨️ 快捷键说明

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