📄 conference.c
字号:
/* --------------------------------------------------------------------------
*
* 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 + -