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