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

📄 conference_room.c

📁 AnyQ服务端源代码(2004/10/28)源码
💻 C
📖 第 1 页 / 共 3 页
字号:
}

/* Browse for members of a room */
void con_room_browsewalk(const char *key, void *data, void *arg)
{
    jid userjid;
    cnu user = (cnu)data;

    xmlnode q = (xmlnode)arg;
    xmlnode xml = xmlnode_insert_tag(q, "item");

    userjid = jid_new(xmlnode_pool(xml), jid_full(jid_fix(user->room->id)));
    jid_set(userjid, xmlnode_get_data(user->nick), JID_RESOURCE);

    xmlnode_put_attrib(xml, "category", "user");
    xmlnode_put_attrib(xml, "type", "client");
    xmlnode_put_attrib(xml, "name", xmlnode_get_data(user->nick));
    xmlnode_put_attrib(xml, "jid", jid_full(jid_fix(userjid)));
}

void _con_room_discoinfo(cnr room, jpacket jp)
{
    xmlnode result;

    jutil_iqresult(jp->x);
    xmlnode_put_attrib(xmlnode_insert_tag(jp->x,"query"), "xmlns", NS_DISCO_INFO);
    jpacket_reset(jp);

    result = xmlnode_insert_tag(jp->iq,"identity");
    xmlnode_put_attrib(result, "category", "conference");
    xmlnode_put_attrib(result, "type", "text");
    xmlnode_put_attrib(result, "name", room->name);

    xmlnode_put_attrib(xmlnode_insert_tag(jp->iq, "feature"), "var", NS_GROUPCHAT);
    xmlnode_put_attrib(xmlnode_insert_tag(jp->iq, "feature"), "var", NS_MUC);

    if(j_strlen(room->secret) > 0)
        xmlnode_put_attrib(xmlnode_insert_tag(jp->iq,"feature"), "var", "muc-password");

    if(room->public == 0)
        xmlnode_put_attrib(xmlnode_insert_tag(jp->iq,"feature"), "var", "muc-hidden");

    if(room->persistant == 0)
        xmlnode_put_attrib(xmlnode_insert_tag(jp->iq,"feature"), "var", "muc-temporary");

    if(room->invitation == 0)
        xmlnode_put_attrib(xmlnode_insert_tag(jp->iq,"feature"), "var", "muc-open");

    if(room->moderated == 0)
        xmlnode_put_attrib(xmlnode_insert_tag(jp->iq,"feature"), "var", "muc-unmoderated");

    if(room->visible == 1)
        xmlnode_put_attrib(xmlnode_insert_tag(jp->iq,"feature"), "var", "muc-nonanonymous");

    if(room->legacy == 1)
        xmlnode_put_attrib(xmlnode_insert_tag(jp->iq,"feature"), "var", "muc-legacy");

    deliver(dpacket_new(jp->x), NULL);
    return;
}

void _con_room_discoitem(const char *key, void *data, void *arg)
{
    jid userjid;
    cnu user = (cnu)data;

    xmlnode query = (xmlnode)arg;
    xmlnode xml = xmlnode_insert_tag(query, "item");

    userjid = jid_new(xmlnode_pool(xml), jid_full(jid_fix(user->room->id)));
    jid_set(userjid, xmlnode_get_data(user->nick), JID_RESOURCE);

    xmlnode_put_attrib(xml, "jid", jid_full(jid_fix(userjid)));
}

void con_room_outsider(cnr room, cnu from, jpacket jp)
{
    xmlnode q;

    log_debug(NAME, "[%s] handling request from outsider %s to room %s", FZONE, jid_full(jid_fix(jp->from)), jid_full(jid_fix(room->id)));

    /* any presence here is just fluff */
    if(jp->type == JPACKET_PRESENCE)
    {
	log_debug(NAME, "[%s] Dropping presence from outsider", FZONE);
        xmlnode_free(jp->x);
        return;
    }

    if(jp->type == JPACKET_MESSAGE)
    {
	log_debug(NAME, "[%s] Bouncing message from outsider", FZONE);
        jutil_error(jp->x, TERROR_FORBIDDEN);
        deliver(dpacket_new(jp->x), NULL);
        return;
    }

    /* public iq requests */
    if(jpacket_subtype(jp) == JPACKET__SET)
    {
	if(NSCHECK(jp->iq, NS_MUC_OWNER))
	{
	    log_debug(NAME, "[%s] IQ Set for owner function", FZONE);

	    if(from && is_owner(room, jp->from))
	    {       
	        xdata_room_config(room, from, room->locked, jp->x);

		jutil_iqresult(jp->x);
		deliver(dpacket_new(jp->x), NULL);
		return;
	    }   
	    else
	    {
                jutil_error(jp->x, TERROR_NOTALLOWED);
                deliver(dpacket_new(jp->x), NULL);
		return;
	    }
	}
	else if(NSCHECK(jp->iq, NS_REGISTER))
	{
	    log_debug(NAME, "[%s] IQ Set for Registration function", FZONE);

	    jutil_error(jp->x, TERROR_NOTALLOWED);
	    deliver(dpacket_new(jp->x), NULL);
	    return;
	}
    }

    if(jpacket_subtype(jp) == JPACKET__GET)
    {
        if(NSCHECK(jp->iq, NS_BROWSE))
        {
            jutil_iqresult(jp->x);
            q = xmlnode_insert_tag(jp->x,"item");
            xmlnode_put_attrib(q,"category","conference");

            if(room->public && room->invitation == 0)
            {
                xmlnode_put_attrib(q,"type","public");
                htb_walk(&room->local, con_room_browsewalk, (void*)q);
            }
            else if(room->public && is_member(room, jp->from))
            {
                xmlnode_put_attrib(q,"type","public");
                htb_walk(&room->local, con_room_browsewalk, (void*)q);
            }
            else
            {
                xmlnode_put_attrib(q,"type","private");
            }

            xmlnode_put_attrib(q,"xmlns",NS_BROWSE);
            xmlnode_put_attrib(q,"name",room->name);
            xmlnode_put_attrib(q,"version",VERSION);

            xmlnode_insert_cdata(xmlnode_insert_tag(q,"ns"),NS_MUC,-1);

            deliver(dpacket_new(jp->x), NULL);
            return;
        }
	else if(NSCHECK(jp->iq, NS_DISCO_INFO))
	{
	    log_debug(NAME, "[%s] Outside room packet - Disco Info Request", FZONE);

	    _con_room_discoinfo(room, jp);
	    return;
	}
	else if(NSCHECK(jp->iq, NS_DISCO_ITEMS))
	{
	    log_debug(NAME, "[%s] Outside room packet - Disco Items Request", FZONE);

	    jutil_iqresult(jp->x);
	    xmlnode_put_attrib(xmlnode_insert_tag(jp->x,"query"), "xmlns", NS_DISCO_ITEMS);
	    jpacket_reset(jp);

	    deliver(dpacket_new(jp->x), NULL);
	    return;
	}
	else if(NSCHECK(jp->iq, NS_MUC_OWNER))
        {
            if(j_strcmp(xmlnode_get_name(jp->iq),"query") == 0)
            {
	        log_debug(NAME, "[%s] IQ Get for owner: configuration", FZONE);

	        if(!is_owner(room, from->realid))
	        {
		    jutil_error(jp->x, TERROR_BAD);
		    deliver(dpacket_new(jp->x), NULL);
	            return;
	        }

	        xdata_room_config(room, from, 0, jp->x);
		return;
	    }
        }
	else if(NSCHECK(jp->iq, NS_REGISTER))
	{
	    log_debug(NAME, "[%s] IQ Get for Registration function", FZONE);

	    jutil_error(jp->x, TERROR_NOTALLOWED);
	    deliver(dpacket_new(jp->x), NULL);
	    return;
	}
    }

    jutil_error(jp->x, TERROR_NOTIMPL);
    deliver(dpacket_new(jp->x), NULL);
    return;

}

void con_room_process(cnr room, cnu from, jpacket jp)
{
    char *nick = NULL;
    char *key;
    xmlnode result, item, x, node;
    jid id;

    log_debug(NAME, "[%s] handling request from participant %s(%s/%s) to room %s", FZONE, jid_full(jid_fix(from->realid)), from->localid->resource, xmlnode_get_data(from->nick), jid_full(jid_fix(room->id)));

    /* presence is just stored and forwarded */
    if(jp->type == JPACKET_PRESENCE)
    {
        xmlnode_free(from->presence);
	from->presence = xmlnode_dup(jp->x);

	jutil_delay(from->presence, NULL);

        xmlnode_put_vattrib(jp->x, "cnu", (void*)from);
        htb_walk(&room->local, con_room_sendwalk, (void*)jp->x);

	xmlnode_free(jp->x);
        return;
    }

    if(jp->type == JPACKET_MESSAGE)
    {
	if(NSCHECK(xmlnode_get_tag(jp->x,"x"),NS_MUC_USER))
	{
	    /* Invite */
	    log_debug(NAME, "[%s] Found invite request", FZONE);

	    if(room->invitation == 1 && room->invites == 0 && !is_admin(room, from->realid))
	    {
	        log_debug(NAME, "[%s] Forbidden invitation request, returning error", FZONE);

	        jutil_error(jp->x,TERROR_FORBIDDEN);
		deliver(dpacket_new(jp->x),NULL);
		return;
	    }

	    item = xmlnode_dup(xmlnode_get_tag(jp->x,"x"));
	    nick = xmlnode_get_attrib(xmlnode_get_tag(item, "invite"), "to");

	    if( nick == NULL)
	    {
	        log_debug(NAME, "[%s] No receipient, returning error", FZONE);

	        jutil_error(jp->x,TERROR_BAD);
		deliver(dpacket_new(jp->x),NULL);

                xmlnode_free(item);
		return;
	    }

	    if(room->invitation == 1)
	    {
	        id = jid_new(xmlnode_pool(item), nick);

	        key = j_strdup(jid_full(jid_user(jid_fix(id))));
	        htb_put(&room->member, key, (void*)item);
		free(key);
	    }
            else
            {
                xmlnode_free(item);
            }

	    con_room_send_invite(from, xmlnode_get_tag(jp->x,"x"));
	    return;
	}

        /* if topic, store it */
        if((x = xmlnode_get_tag(jp->x,"subject")) != NULL )
        {

            /* catch the invite hack */
            if((nick = xmlnode_get_data(x)) != NULL && j_strncasecmp(nick,"invite:",7) == 0)
            {
                nick += 7;
                if((jp->to = jid_new(jp->p, nick)) == NULL)
                {
                    jutil_error(jp->x,TERROR_BAD);
                }else{
                    xmlnode_put_attrib(jp->x, "to", jid_full(jid_fix(jp->to)));
                    jp->from = jid_new(jp->p, jid_full(jid_user(jid_fix(from->localid))));
                    jid_set(jp->from, xmlnode_get_data(from->nick), JID_RESOURCE);
                    xmlnode_put_attrib(jp->x, "from", jid_full(jid_fix(jp->from)));
                }
                deliver(dpacket_new(jp->x), NULL);
                return;
            }

	    /* Disallow subject change if user does not have high enough level */
	    if((!is_admin(room, from->realid) && room->subjectlock == 0) || is_visitor(room, from->realid) )
	    {
		jutil_error(jp->x,TERROR_FORBIDDEN);
		deliver(dpacket_new(jp->x),NULL);
		return;
	    }

	    /* Save room topic for new users */
            xmlnode_free(room->topic);
            room->topic = xmlnode_new_tag("topic");
            xmlnode_put_attrib(room->topic, "subject", xmlnode_get_data(x));
            xmlnode_insert_cdata(room->topic, xmlnode_get_data(from->nick), -1);
            xmlnode_insert_cdata(room->topic, " has set the topic to: ", -1);
            xmlnode_insert_cdata(room->topic, xmlnode_get_data(x), -1);

	    /* Save the room topic if room is persistent */
	    if(room->persistant == 1)
	    {
	        xdb_room_set(room);
	    }
        }

	/* Check if allowed to talk */
	if(room->moderated == 1 && !is_participant(room, from->realid))
	{
	    /* Attempting to talk in a moderated room without voice intrinsic */
            jutil_error(jp->x,TERROR_MUC_VOICE);
            deliver(dpacket_new(jp->x),NULL);
            return;
        }

        /* ensure type="groupchat" */
        xmlnode_put_attrib(jp->x,"type","groupchat");

	/* Save copy of packet for history */
	node = xmlnode_dup(jp->x);

        /* broadcast */
        xmlnode_put_vattrib(jp->x,"cnu",(void*)from);
        htb_walk(&room->local, con_room_sendwalk, (void*)jp->x);

        /* log */
        con_room_log(room, xmlnode_get_data(from->nick), xmlnode_get_tag_data(jp->x, "body"));

	/* Save from address */
	id = jid_new(xmlnode_pool(node), jid_full(jid_user(jid_fix(from->localid))));
	jid_set(id, xmlnode_get_data(from->nick), JID_RESOURCE);
	xmlnode_put_attrib(node, "from", jid_full(jid_fix(id)));

        /* store in history */
        jutil_delay(node, jid_full(jid_fix(room->id)));

        if(room->master->history > 0)
        {
            if(++room->hlast == room->master->history)
                room->hlast = 0;
            xmlnode_free(room->history[room->hlast]);
            room->history[room->hlast] = node;
        }
            
	xmlnode_free(jp->x);
        return;
    }

    /* public iq requests */

    if(jpacket_subtype(jp) == JPACKET__SET)
    {
	if(NSCHECK(jp->iq, NS_MUC_ADMIN))
	{ 
	    log_debug(NAME, "[%s] IQ Set for admin function: >%s<", FZONE, xmlnode_get_name(jp->iq));

	    if(!is_moderator(room, from->realid))
	    {
	        jutil_error(jp->x, TERROR_FORBIDDEN);
	        deliver(dpacket_new(jp->x), NULL);
	        return;
	    }

            if(j_strcmp(xmlnode_get_name(jp->iq), "query") == 0)

⌨️ 快捷键说明

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