📄 conference_room.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"
//extern int deliver__flag;
void con_room_log(cnr room, char *nick, char *message)
{
time_t t;
xmlnode xml;
jid user;
char *tstr;
char *output;
FILE *logfile = room->logfile;
pool p;
if(logfile == NULL || message == NULL)
return;
p = pool_heap(1024);
/* nicked from mod_time */
t = time(NULL);
tstr = ctime(&t);
tstr[j_strlen(tstr) - 1] = '\0'; /* cut off newline */
if(room->logformat == LOG_XML)
{
xml = jutil_msgnew("groupchat", jid_full(jid_fix(room->id)) , NULL, message);
user = jid_new(xmlnode_pool(xml), jid_full(jid_fix(room->id)));
jid_set(user, nick, JID_RESOURCE);
xmlnode_put_attrib(xml, "from", jid_full(jid_fix(user)));
jutil_delay(xml, NULL);
fprintf(logfile, "%s\n", xmlnode2str(xml));
xmlnode_free(xml);
}
else if(room->logformat == LOG_XHTML)
{
if(nick)
{
if(j_strncmp(message, "/me", 3) == 0)
{
output = extractAction(message, p);
fprintf(logfile, "%s * %s%s<br />\n", tstr, nick, output);
}
else
{
fprintf(logfile, "%s >%s< %s<br />\n", tstr, nick, message);
}
}
else
{
fprintf(logfile, "%s --- %s<br />\n", tstr, message);
}
}
else
{
if(nick)
{
if(j_strncmp(message, "/me", 3) == 0)
{
output = extractAction(message, p);
fprintf(logfile, "%s * %s%s\n", tstr, nick, output);
}
else
{
fprintf(logfile, "%s <%s> %s\n", tstr, nick, message);
}
}
else
{
fprintf(logfile, "%s --- %s\n", tstr, message);
}
}
fflush(logfile);
pool_free(p);
return;
}
void con_room_log_new(cnr room)
{
char *filename;
struct stat fileinfo;
time_t now = time(NULL);
char *curdate;
pool p = pool_heap(1024);
int type = room->logformat;
char *dirname = jid_full(jid_fix(room->id));
spool sp = spool_new(p);
if(room->master->logdir)
{
spooler(sp, room->master->logdir, "/", dirname, sp);
}
else
{
spooler(sp, "./", dirname, sp);
}
filename = spool_print(sp);
if(stat(filename,&fileinfo) < 0 && mkdir(filename, S_IRWXU) < 0)
{
log_error(NAME, "[%s] ERR: unable to open log directory >%s<", FZONE, filename);
return;
}
curdate = dateget(now);
if(type == LOG_XML)
spooler(sp, "/", curdate, ".xml", sp);
else if(type == LOG_XHTML)
spooler(sp, "/", curdate, ".html", sp);
else
spooler(sp, "/", curdate, ".txt", sp);
filename = spool_print(sp);
if(stat(filename,&fileinfo) < 0)
{
log_debug(NAME, "[%s] New logfile >%s<", FZONE, filename);
room->logfile = fopen(filename, "a");
if(type == LOG_XHTML)
{
fprintf(room->logfile, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n<title>Logs for %s, %s</title>\n</head>\n<body>\n", jid_full(jid_fix(room->id)), curdate);
fflush(room->logfile);
}
}
else
{
room->logfile = fopen(filename, "a");
}
if(room->logfile == NULL)
log_error(NAME, "[%s] ERR: unable to open log file >%s<", FZONE, filename);
else
log_debug(NAME, "[%s] Opened logfile >%s<", FZONE, filename);
pool_free(p);
free(curdate);
return;
}
void con_room_log_close(cnr room)
{
int type = room->logformat;
FILE *logfile = room->logfile;
if(logfile == NULL)
return;
log_debug(NAME, "[%s] Closing logfile for room >%s<", FZONE, jid_full(jid_fix(room->id)));
if(type == LOG_XHTML)
{
fprintf(logfile, "</body>\n</html>\n");
fflush(logfile);
}
fclose(room->logfile);
room->logfile = NULL;
}
void con_room_send_invite(cnu sender, xmlnode node)
{
xmlnode result;
xmlnode element;
xmlnode invite;
char *body, *user, *reason, *inviter;
cnr room;
jid from;
pool p;
if(sender == NULL || node == NULL)
return;
log_debug(NAME, "[%s] Sending room invite", FZONE);
room = sender->room;
from = sender->realid;
invite = xmlnode_get_tag(node, "invite");
user = xmlnode_get_attrib(invite, "to");
reason = xmlnode_get_tag_data(invite, "reason");
if(room->public == 1)
{
inviter = jid_full(jid_user(jid_fix(from)));
}
else
{
inviter = xmlnode_get_data(sender->nick);
}
xmlnode_put_attrib(invite, "from", inviter);
xmlnode_hide_attrib(invite, "to");
p = xmlnode_pool(node);
if(reason == NULL)
{
reason = spools(p, "None given", p);
}
body = spools(p, "You have been invited to the ", jid_full(jid_fix(room->id)), " room by ", inviter, "\nReason: ", reason, p);
result = jutil_msgnew("normal", user , "Invitation", body);
xmlnode_put_attrib(result, "from", jid_full(jid_fix(room->id)));
if(room->secret != NULL)
{
xmlnode_insert_cdata(xmlnode_insert_tag(invite, "password"), room->secret, -1);
}
xmlnode_insert_node(result, node);
element = xmlnode_insert_tag(result, "x");
xmlnode_put_attrib(element, "jid", jid_full(jid_fix(room->id)));
xmlnode_put_attrib(element, "xmlns", NS_X_CONFERENCE);
xmlnode_insert_cdata(element, reason, -1);
log_debug(NAME, "[%s] >>>%s<<<", FZONE, xmlnode2str(result));
deliver(dpacket_new(result), NULL);
xmlnode_free(node);
return;
}
void con_room_leaveall(const char *key, void *data, void *arg)
{
cnu user = (cnu)data;
xmlnode info = (xmlnode)arg;
char *alt, *reason;
xmlnode presence;
xmlnode tag;
xmlnode element;
xmlnode node;
xmlnode destroy;
presence = jutil_presnew(JPACKET__UNAVAILABLE, NULL, NULL);
tag = xmlnode_insert_tag(presence,"x");
xmlnode_put_attrib(tag, "xmlns", NS_MUC_USER);
element = xmlnode_insert_tag(tag, "item");
xmlnode_put_attrib(element, "role", "none");
xmlnode_put_attrib(element, "affiliation", "none");
if (info != NULL)
{
destroy = xmlnode_insert_tag(tag, "destroy");
reason = xmlnode_get_tag_data(info, "reason");
node = xmlnode_insert_tag(destroy, "reason");
if(reason != NULL)
{
xmlnode_insert_cdata(node, reason, -1);
}
alt = xmlnode_get_attrib(info, "jid");
if (alt != NULL)
{
xmlnode_put_attrib(destroy, "jid", alt);
}
}
con_user_send(user, user, presence);
}
void _con_room_usernick(const char *key, void *data, void *arg)
{
cnu u = (cnu)data;
xmlnode x = (xmlnode)arg;
if(j_strcmp(xmlnode_get_data(x),xmlnode_get_data(u->nick)) == 0)
xmlnode_put_vattrib(x, "u", (void*)u);
}
cnu con_room_usernick(cnr room, char *nick)
{
cnu user;
xmlnode node = xmlnode_new_tag("nick");
log_debug(NAME, "[%s] searching for nick %s in room %s", FZONE, nick, jid_full(jid_fix(room->id)));
if(room == NULL)
{
return NULL;
}
xmlnode_insert_cdata(node, nick, -1);
htb_walk(&room->local, _con_room_usernick, (void *)node);
user = (cnu)xmlnode_get_vattrib(node,"u");
xmlnode_free(node);
return user;
}
/* returns a valid nick from the list, x is the first <nick>foo</nick> xmlnode, checks siblings */
char *con_room_nick(cnr room, cnu user, xmlnode x)
{
char *nick = NULL;
xmlnode cur;
int count = 1;
log_debug(NAME, "[%s] looking for valid nick in room %s from starter %s", FZONE, jid_full(jid_fix(room->id)), xmlnode2str(x));
/* make-up-a-nick phase */
if(x == NULL)
{
nick = pmalloco(user->p, j_strlen(user->realid->user) + 10);
log_debug(NAME, "[%s] Malloc: Nick = %d", FZONE, j_strlen(user->realid->user) + 10);
sprintf(nick, "%s", user->realid->user);
while(con_room_usernick(room, nick) != NULL)
sprintf(nick, "%s%d", user->realid->user,count++);
return nick;
}
/* scan the list */
for(cur = x; cur != NULL; cur = xmlnode_get_nextsibling(cur))
{
if(j_strcmp(xmlnode_get_name(cur),"nick") == 0 && (nick = xmlnode_get_data(cur)) != NULL)
if(con_room_usernick(room, nick) == NULL)
break;
}
if(is_registered(room->master, jid_full(jid_user(jid_fix(user->realid))), nick) == -1)
nick = NULL;
return nick;
}
void con_room_sendwalk(const char *key, void *data, void *arg)
{
xmlnode x = (xmlnode)arg;
cnu to = (cnu)data;
cnu from = (cnu)xmlnode_get_vattrib(x,"cnu");
xmlnode output;
if(j_strncmp(xmlnode_get_name(x),"presence",8) == 0)
output = add_extended_presence(from, to, x, NULL, NULL, NULL);
else
output = x;
con_user_send(to, from, xmlnode_dup(output)); /* Need to send duplicate */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -