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

📄 conference.c

📁 AnyQ服务端源代码(2004/10/28)源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* --------------------------------------------------------------------------
 *
 * License
 *
 * The contents of this file are subject to the Jabber Open Source License
 * Version 1.0 (the "License").  You may not copy or use this file, in either
 * source code or executable form, except in compliance with the License.  You
 * may obtain a copy of the License at http://www.jabber.com/license/ or at
 * http://www.opensource.org/.  
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Copyrights
 * 
 * Portions created by or assigned to Jabber.com, Inc. are 
 * Copyright (c) 1999-2000 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.
 * 
 * --------------------------------------------------------------------------*/

#include "conference.h"
#include <sys/utsname.h>

void con_server_browsewalk(const char *key, void *data, void *arg)
{
    cnr room = (cnr)data;
    jpacket jp = (jpacket)arg;
    char users[10];
    char maxu[10];
    xmlnode x;

    /* if we're a private server, we can only show the rooms the user already knows about */
    if(room->public == 0 && !in_room(room, jp->to) && !is_admin(room, jp->to) && !is_member(room, jp->to))
        return;

    /* Unconfigured rooms don't exist either */
    if(room->locked == 1)
        return;

    x = xmlnode_insert_tag(jp->iq, "item");

    xmlnode_put_attrib(x, "category", "conference");

    if(room->public == 0)
        xmlnode_put_attrib(x, "type", "private");
    else
        xmlnode_put_attrib(x, "type", "public");

    xmlnode_put_attrib(x, "jid", jid_full(jid_fix(room->id)));

    if(room->maxusers > 0)
        xmlnode_put_attrib(x, "name", spools(jp->p, room->name, " (", itoa(room->count, users), "/", itoa(room->maxusers, maxu), ")", jp->p));
    else
        xmlnode_put_attrib(x, "name", spools(jp->p, room->name, " (", itoa(room->count, users), ")", jp->p));
}

void _server_discowalk(const char *key, void *data, void *arg)
{
    cnr room = (cnr)data;
    jpacket jp = (jpacket)arg;
    xmlnode x;

    /* if we're a private server, we can only show the rooms the user already knows about */
    if(room->public == 0 && !in_room(room, jp->to) && !is_admin(room, jp->to) && !is_member(room, jp->to))
        return;

    /* Unconfigured rooms don't exist either */
    if(room->locked == 1)
	return;

    x = xmlnode_insert_tag(jp->iq, "item");

    xmlnode_put_attrib(x, "jid", jid_full(jid_fix(room->id)));

    xmlnode_put_attrib(x, "name", spools(jp->p, room->name, jp->p));
}

void con_server(cni master, jpacket jp)
{
    char *str;
    struct utsname un;
    xmlnode x;
    int start, status;
    time_t t;
    char *from;
    char nstr[10];
    jid user;

    log_debug(NAME, "[%s] server packet", FZONE);

    if(jp->type == JPACKET_PRESENCE)
    {
        jutil_error(jp->x, TERROR_NOTIMPL);
        deliver(dpacket_new(jp->x),NULL);
	return;
    }

    if(jp->type != JPACKET_IQ)
    {
        xmlnode_free(jp->x);
        return;
    }

    if(jpacket_subtype(jp) == JPACKET__SET)
    {
	if(NSCHECK(jp->iq,NS_REGISTER))
	{
            log_debug(NAME, "[%s] Server packet - Registration Handler", FZONE);
	    str = xmlnode_get_tag_data(jp->iq, "name");
	    x = xmlnode_get_tag(jp->iq, "remove");

	    from = xmlnode_get_attrib(jp->x, "from");

	    user = jid_new(jp->p, from);
	    status = is_registered(master, jid_full(jid_user(jid_fix(user))), str);

	    if(x)
	    {
	        log_debug(NAME, "[%s] Server packet - UnReg Submission", FZONE);
		set_data(master, str, from, NULL, 1);
		jutil_iqresult(jp->x);
	    }
	    else if(status == -1)
	    {
                log_debug(NAME, "[%s] Server packet - Registration Submission : Already taken", FZONE);
		jutil_error(jp->x, TERROR_MUC_NICKREG);
	    }
	    else if(status == 0)
	    {
                log_debug(NAME, "[%s] Server packet - Registration Submission", FZONE);
		set_data(master, str, from, NULL, 0);
		jutil_iqresult(jp->x);
	    }
	    else
	    {
                log_debug(NAME, "[%s] Server packet - Registration Submission : already set", FZONE);
		jutil_iqresult(jp->x);
	    }

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

    if(jpacket_subtype(jp) == JPACKET__GET)
    {
        /* now we're all set */

	if(NSCHECK(jp->iq,NS_REGISTER))
	{
            log_debug(NAME, "[%s] Server packet - Registration Request", FZONE);

	    x = get_data_byjid(master, xmlnode_get_attrib(jp->x, "from"));
	    str = xmlnode_get_attrib(x, "nick") ? xmlnode_get_attrib(x, "nick") : "";
	    
	    jutil_iqresult(jp->x);
	    xmlnode_put_attrib(xmlnode_insert_tag(jp->x, "query"), "xmlns", NS_REGISTER);
	    jpacket_reset(jp);

            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq, "instructions"), "Enter the nickname you wish to reserve for this conference service", -1);
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq, "name"), str, -1);
	    xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq, "key"), jutil_regkey(NULL, jid_full(jp->to)), -1);

	    if(x != NULL) 
	        xmlnode_insert_tag(jp->iq, "registered");
	    
            deliver(dpacket_new(jp->x), NULL);
	    return;
													    
	}
	else if(NSCHECK(jp->iq,NS_TIME))
        {
            log_debug(NAME, "[%s] Server packet - Time Request", FZONE);

            jutil_iqresult(jp->x);
            xmlnode_put_attrib(xmlnode_insert_tag(jp->x,"query"),"xmlns",NS_TIME);
            jpacket_reset(jp);
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq,"utc"),jutil_timestamp(),-1);
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq,"tz"),tzname[0],-1);

            /* create nice display time */
            t = time(NULL);
            str = ctime(&t);
            str[strlen(str) - 1] = '\0'; /* cut off newline */
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq,"display"),str,-1);
            deliver(dpacket_new(jp->x),NULL);
            return;
        }
	else if(NSCHECK(jp->iq,NS_VERSION))
        {
            log_debug(NAME, "[%s] Server packet - Version Request", FZONE);

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

            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq,"name"),NAME,-1);
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq,"version"),VERSION,-1);

            uname(&un);
            x = xmlnode_insert_tag(jp->iq,"os");
            xmlnode_insert_cdata(x,un.sysname,-1);
            xmlnode_insert_cdata(x," ",1);
            xmlnode_insert_cdata(x,un.release,-1);

            deliver(dpacket_new(jp->x),NULL);
            return;
        }
	else if(NSCHECK(jp->iq,NS_BROWSE))
        {
            log_debug(NAME, "[%s] Server packet - Browse Request", FZONE);

            jutil_iqresult(jp->x);
            xmlnode_put_attrib(xmlnode_insert_tag(jp->x, "item"), "xmlns", NS_BROWSE);
            jpacket_reset(jp);

            xmlnode_put_attrib(jp->iq, "category", "conference");
            xmlnode_put_attrib(jp->iq, "type", "public");
            xmlnode_put_attrib(jp->iq, "jid", master->i->id);

            /* pull name from the server vCard */
            xmlnode_put_attrib(jp->iq, "name", xmlnode_get_tag_data(master->config, "vCard/FN"));
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq, "ns"), NS_MUC, -1);
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq, "ns"), NS_DISCO, -1);
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq, "ns"), NS_REGISTER, -1);
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq, "ns"), NS_VERSION, -1);
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq, "ns"), NS_TIME, -1);
            xmlnode_insert_cdata(xmlnode_insert_tag(jp->iq, "ns"), NS_LAST, -1);

            htb_walk(&master->rooms, con_server_browsewalk, (void*)jp);

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

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

	    x = xmlnode_insert_tag(jp->iq,"identity");
	    xmlnode_put_attrib(x, "category", "conference");
	    xmlnode_put_attrib(x, "type", "text");
	    xmlnode_put_attrib(x, "name", xmlnode_get_tag_data(master->config, "vCard/FN"));

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

            deliver(dpacket_new(jp->x),NULL);
            return;
	}
	else if(NSCHECK(jp->iq, NS_DISCO_ITEMS))
        { 
            log_debug(NAME, "[%s] Server 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);

            htb_walk(&master->rooms, _server_discowalk, (void*)jp);

            deliver(dpacket_new(jp->x),NULL);
            return;
        }
	else if(NSCHECK(jp->iq, NS_LAST))
        {
            log_debug(NAME, "[%s] Server packet - Last Request", FZONE);

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

            start = time(NULL) - master->start;
            sprintf(nstr,"%d",start);
            xmlnode_put_attrib(jp->iq,"seconds",nstr);

            deliver(dpacket_new(jp->x),NULL);
            return;
        }
	else if(NSCHECK(jp->iq,NS_VCARD))
        { 
            log_debug(NAME, "[%s] Server packet - VCard Request", FZONE);

            jutil_iqresult(jp->x);
            xmlnode_put_attrib(xmlnode_insert_tag(jp->x,"vCard"),"xmlns",NS_VCARD);
            jpacket_reset(jp);

            xmlnode_insert_node(jp->iq,xmlnode_get_firstchild(xmlnode_get_tag(master->config,"vCard")));

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

    log_debug(NAME, "[%s] TERROR_NOTIMPL", FZONE);
    jutil_error(jp->x, TERROR_NOTIMPL);
    deliver(dpacket_new(jp->x),NULL);
    return;
}


void _con_packets(void *arg)
{
    jpacket jp = (jpacket)arg;
    cni master = (cni)jp->aux1;
    cnr room;
    cnu u, u2;
    char *s, *reason;
    xmlnode node;
    int priority = -1;
    int created = 0;
    time_t now = time(NULL);

    /* first, handle all packets just to the server (browse, vcard, ping, etc) */
    if(jp->to->user == NULL)
    {
        con_server(master, jp);
        return;
    }

    log_debug(NAME, "[%s] processing packet %s", FZONE, xmlnode2str(jp->x));

    /* any other packets must have an associated room */
    for(s = jp->to->user; *s != '\0'; s++) 
	    *s = tolower(*s); /* lowercase the group name */

    if((room = htb_get(&master->rooms, jid_full(jid_user(jid_fix(jp->to))))) == NULL)
    {
	if((master->roomlock == 1 && !is_sadmin(master, jp->from)) || master->loader == 0)
	{
	    log_debug(NAME, "[%s] Room building request denied", FZONE);
	    jutil_error(jp->x, TERROR_MUC_ROOM);
	    deliver(dpacket_new(jp->x),NULL);
	    return;
	}
	else if(jp->type == JPACKET_IQ && jpacket_subtype(jp) == JPACKET__GET && NSCHECK(jp->iq, NS_MUC_OWNER))
        {
            room = con_room_new(master, jid_user(jp->to), jp->from, NULL, NULL, 1, 1, 0);
	    xmlnode_free(jp->x);
	    return;
	}
	else if(jp->to->resource == NULL)
	{
	    log_debug(NAME, "[%s] Room %s doesn't exist: Returning Bad Request", FZONE, jp->to->user);
	    jutil_error(jp->x, TERROR_BAD);
	    deliver(dpacket_new(jp->x),NULL);
	    return;
	}
	else if(jpacket_subtype(jp) == JPACKET__UNAVAILABLE)
	{
	    log_debug(NAME, "[%s] Room %s doesn't exist: dropping unavailable presence", FZONE, jp->to->user);
	    xmlnode_free(jp->x);
	    return;
	}
	else
	{
	    if(master->dynamic == -1)
                room = con_room_new(master, jid_user(jp->to), jp->from, NULL, NULL, 1, 0, 1);
	    else
                room = con_room_new(master, jid_user(jp->to), jp->from, NULL, NULL, 1, 0, 0);

            /* fall through, so the presence goes to the room like normal */
	    created = 1;
	}
    }

    /* get the sending user entry, if any */
    u = htb_get(&room->remote, jid_full(jid_fix(jp->from)));

    /* several things use this field below as a flag */
    if(jp->type == JPACKET_PRESENCE)
        priority = jutil_priority(jp->x);

    /* sending available presence will automatically get you a generic user, if you don't have one */
    if(u == NULL && priority >= 0)
        u = con_user_new(room, jp->from);

    /* update tracking stuff */
    room->last = now;
    room->packets++;

    if(u != NULL)
    {
        u->last = now;
        u->packets++;
    }

    /* handle join/rename */
    if(priority >= 0 && jp->to->resource != NULL)
    {
        u2 = con_room_usernick(room, jp->to->resource); /* existing user w/ this nick? */

        /* it's just us updating our presence */
        if(u2 == u)
        {
            jp->to = jid_user(jp->to);
            xmlnode_put_attrib(jp->x, "to", jid_full(jid_fix(jp->to)));

	    if(u)
            {
                xmlnode_free(u->presence);
	        u->presence = xmlnode_dup(jp->x);
            }

            con_room_process(room, u, jp);
            return;
        }

	/* User already exists, return conflict Error */
        if(u2 != NULL)
        {
            jutil_error(jp->x, TERROR_MUC_NICK);
            deliver(dpacket_new(jp->x),NULL);
            return;
        }

	/* Nick already registered, return conflict Error */
        if(is_registered(master, jid_full(jid_user(jid_fix(u->realid))), jp->to->resource) == -1)
        {
            jutil_error(jp->x, TERROR_MUC_NICKREG);
            deliver(dpacket_new(jp->x),NULL);
            return;
        }

        /* if from an existing user in the room, change the nick */
	if(is_outcast(room, u->realid) && !is_admin(room, u->realid))
	{
	    jutil_error(jp->x, TERROR_MUC_BANNED);
	    deliver(dpacket_new(jp->x),NULL);
	    return;
	}

	/* User is not invited, return invitation error */

⌨️ 快捷键说明

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