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

📄 mod_groups.c

📁 jabber server jabber server jabber server jabber server
💻 C
📖 第 1 页 / 共 3 页
字号:
 */void mod_groups_update_rosters(grouptab gt, jid uid, char *un, char *gn, int add) {    xmlnode packet, item, q;    packet = xmlnode_new_tag("iq");    xmlnode_put_attrib(packet, "type", "set");    q = xmlnode_insert_tag(packet, "query");    xmlnode_put_attrib(q,"xmlns",NS_ROSTER);    item = xmlnode_insert_tag(q,"item");    xmlnode_put_attrib(item,"jid",jid_full(uid));    xmlnode_put_attrib(item,"name",un);    xmlnode_put_attrib(item,"subscription",add ? "to" : "remove");    xmlnode_insert_cdata(xmlnode_insert_tag(item,"group"),gn,-1);    xhash_walk(gt->to,mod_groups_update_walk,(void *) packet);    xmlnode_free(packet);}/** * adds a user to the master group list and to their personal list * * @param mi mod_groups_i struct containing module instance data * @param p memory pool to use * @param uid the user, that should be added * @param un the user's name * @param gid the group id to add the user to * @param gn the group name * @param both subscription type both? * @return 1 on failure, 0 on success */int mod_groups_xdb_add(mod_groups_i mi, pool p, jid uid, char *un, char *gid, char *gn, int both) {    xmlnode groups, user, group;    jid xid;    xid = jid_new(p,uid->server);    jid_set(xid,gid,JID_RESOURCE);    user = xmlnode_new_tag("user");    xmlnode_put_attrib(user,"jid",jid_full(uid));    xmlnode_put_attrib(user,"name",un);    if(both && xdb_act(mi->xc,xid,NS_XGROUPS,"insert",spools(p,"?jid=",jid_full(uid),p),user)) {        log_debug2(ZONE, LOGT_DELIVER, "Failed to insert user");        xmlnode_free(user);        return 1;    }    xmlnode_free(user);    /* get the groups this user is currently part of */    groups = mod_groups_get_current(mi,uid);    if (groups == NULL) {        groups = xmlnode_new_tag("query");        xmlnode_put_attrib(groups,"xmlns",NS_XGROUPS);    }    /* check if the user already as the group listed */    group = xmlnode_get_tag(groups,spools(p,"?id=",gid,p));    if (group == NULL) {        group = xmlnode_insert_tag(groups,"group");        xmlnode_put_attrib(group,"id",gid);    } else if (j_strcmp(xmlnode_get_attrib(group,"type"),"both") == 0 && both) {        /* the group is already there */        xmlnode_free(groups);        return 0;    } else if (both == 0) {        xmlnode_free(groups);        return 0;    }    /* save the new group in the users list groups */    if (both)        xmlnode_put_attrib(group,"type","both");    xdb_set(mi->xc,uid,NS_XGROUPS,groups);    xmlnode_free(groups);    return 0;}/** * removes a user from the master group list and from their personal list * * @param mi the mod_groups_i struct containing module instance data * @param p memory pool to use * @param uid which user to remove * @param host host to use * @param gid group id from which the user should be removed * @return 0 on success, 1 on failure */int mod_groups_xdb_remove(mod_groups_i mi, pool p, jid uid, char *host, char *gid) {    xmlnode groups, group, info;    jid xid;    xid = jid_new(p,uid->server);    jid_set(xid,gid,JID_RESOURCE);    /* insert with a match will overwrite the node with NULL and therefore remove it */    if(xdb_act(mi->xc,xid,NS_XGROUPS,"insert",spools(p,"?jid=",jid_full(uid),p),NULL)) {        log_debug2(ZONE, LOGT_DELIVER, "Failed to remove user");        return 1;    }    info = mod_groups_get_info(mi, p, host, gid);    if (xmlnode_get_tag(info,"require") != NULL)        return 0;    /* get the groups this user is currently part of */    groups = mod_groups_get_current(mi,uid);    if (groups == NULL) {        groups = xmlnode_new_tag("query");        xmlnode_put_attrib(groups,"xmlns",NS_XGROUPS);    }    /* check if the user already as the group listed */    group = xmlnode_get_tag(groups,spools(p,"?id=",gid,p));    if (group == NULL) {        /* the group isn't there */        xmlnode_free(groups);        return 0;    }    /* Delete Node */    xmlnode_hide(group);    xdb_set(mi->xc,uid,NS_XGROUPS,groups);    xmlnode_free(groups);    return 0;}/** * handle register set requests (the actual registration with a group) * * @param mi the mod_groups_i struct containing module instance data * @param m the mapi_struct containing module instance data */void mod_groups_register_set(mod_groups_i mi, mapi m) {    jpacket jp = m->packet;    pool p = jp->p;    grouptab gt;    xmlnode info, roster, users;    jid uid;    char *gid, *host, *key, *un, *gn;    int add, both;    /* make sure it's a valid register query */    key = xmlnode_get_tag_data(jp->iq,"key");    gid = strchr(pstrdup(p,jp->to->resource),'/') + 1;    if (gid == NULL || key == NULL || jutil_regkey(key,jid_full(jp->from)) == NULL) {        js_bounce_xmpp(m->si,jp->x,XTERROR_NOTACCEPTABLE);        return;    }    host = jp->from->server;    /* check if the group exists */    info = mod_groups_get_info(mi,p,host,gid);    if (info == NULL) {        js_bounce_xmpp(m->si,jp->x,XTERROR_NOTFOUND);        return;    }    uid = jid_user(jp->from);    un = xmlnode_get_tag_data(jp->iq,"name");    gn = xmlnode_get_tag_data(info,"name");    /* register or unregister? */    add = (xmlnode_get_tag(jp->iq, "remove") == NULL);    both = (xmlnode_get_tag(info,"static") == NULL);    if (add) {        log_debug2(ZONE, LOGT_DELIVER, "register GID %s",gid);        if (mod_groups_xdb_add(mi,p,uid,un ? un : jid_full(uid),gid,gn,both)) {            js_bounce_xmpp(m->si,jp->x,XTERROR_UNAVAIL);            xmlnode_free(info);            return;        }    } else {        log_debug2(ZONE, LOGT_DELIVER, "unregister GID %s",gid);        if (mod_groups_xdb_remove(mi,p,uid,host,gid)) {            js_bounce_xmpp(m->si,jp->x,XTERROR_UNAVAIL);            xmlnode_free(info);            return;        }    }    gt = GROUP_GET(mi,gid);    /* push the group to the user */    if (add || xmlnode_get_tag(info,"require") == NULL) {        users = mod_groups_get_users(mi,p,host,gid);        if (users != NULL) {            roster = jutil_iqnew(JPACKET__SET,NS_ROSTER);            mod_groups_roster_insert(m->user,roster,users,gn,add);            mod_groups_roster_push(m->s,roster,add);        }    }    /* push/remove the new user to the other members */    if (both)        mod_groups_update_rosters(gt,uid,un,gn,add);    /* send presnce to everyone */    if (add && both) {        mod_groups_presence_from(m->s,gt,m->s->presence);        mod_groups_presence_to(m->s,gt);    }    jutil_iqresult(jp->x);    jpacket_reset(jp);    js_session_to(m->s,jp);    xmlnode_free(info);}/** * handle a register get request * * Return what is required to register a group * * @param mi the mod_groups_i struct containing module instance data * @param m the mapi_struct containing the register get request */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),'/');    /* Check that it is somewhat valid */    if (gid != NULL && *++gid != '\0') {        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) {	    /* if the user is already registered, add the <registered/> element */            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 {	/* there has been no group id in the request */        js_bounce_xmpp(m->si,jp->x,XTERROR_NOTACCEPTABLE);    }}/** * handle browse set requests for groups * * Only users with "edit" rights are allowed to update a group * * @param mi the mod_groups_i struct containing module instance data * @param m the mapi_struct containing the request */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_debug2(ZONE, LOGT_DELIVER, "Setting");    /* get the group ID ... we only handle the request if there is a specified group */    gid = strchr(jp->to->resource,'/');    if (gid == NULL || *++gid == '\0') {        js_bounce_xmpp(m->si,jp->x,XTERROR_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");    /* it's an add action if there is no action attribute or its value is NOT remove */    add = ( ( action == NULL ) || j_strcmp(action, "remove") );    if (uid == NULL || un == NULL) {        js_bounce_xmpp(m->si,jp->x,XTERROR_NOTACCEPTABLE);        return;    }    /* is the user allowed to edit a group? */    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_xmpp(m->si,jp->x,XTERROR_NOTALLOWED);        return;    }    gn = xmlnode_get_tag_data(info,"name");    if (add) {	/* adding a user */        log_debug2(ZONE, LOGT_DELIVER, "Adding");        if (mod_groups_xdb_add(mi,p,uid,un,gid,gn,1)) {            js_bounce_xmpp(m->si,jp->x,XTERROR_UNAVAIL);            xmlnode_free(info);            return;        }    } else {	/* removing a user */        log_debug2(ZONE, LOGT_DELIVER, "Removing");        host = jp->from->server;        if (mod_groups_xdb_remove(mi,p,uid,host,gid)) {            js_bounce_xmpp(m->si,jp->x,XTERROR_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);}/** * build a result jpacket for a browse request containing the browse result for a group * * @param p the memory pool to use * @param jp the jpacket where to place the result * @param group the group for which to generate the result * @param host the hostname of the server * @param gn the group name */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);        }    }}/** * handle browse-get requests by a user * * @param mi the mod_groups_i instance data * @param m the mapi_struct containing the browse-get-request */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_debug2(ZONE, LOGT_DELIVER, "Browse request");    gid = strchr(jp->to->resource,'/');    if (gid != NULL && *++gid != '\0') {	/* there is a group id: get this group's data */        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 {	/* there is no group id: get the toplevel groups */        group = mod_groups_get_top(mi,p,host);        gn = NULL;    }    if (group == NULL && gn == NULL) {        js_bounce_xmpp(m->si,jp->x,XTERROR_NOTFOUND);        return;    }    if (group != NULL) {	/* send (a) group(s) */        mod_groups_browse_result(p,jp,group,host,gn);        xmlnode_free(group);    } else {	/* there is only a name */        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);    }

⌨️ 快捷键说明

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