#include "conference.h"
xmlnode add_xdata_boolean(char *label, char *var, int data)
{
xmlnode node;
char value[4];
snprintf(value, 4, "%i", data);
node = xmlnode_new_tag("field");
xmlnode_put_attrib(node,"type","boolean");
xmlnode_put_attrib(node,"label", label);
xmlnode_put_attrib(node,"var", var);
xmlnode_insert_cdata(xmlnode_insert_tag(node,"value"), value, -1);
return node;
}
xmlnode add_xdata_text(char *label, int type, char *var, char *data)
{
xmlnode node;
node = xmlnode_new_tag("field");
if(type > 1)
xmlnode_put_attrib(node,"type","text-multi");
else if(type == 1)
xmlnode_put_attrib(node,"type","text-single");
else if(type == -1)
xmlnode_put_attrib(node,"type","text-private");
else
xmlnode_put_attrib(node,"type","hidden");
if(label != NULL)
xmlnode_put_attrib(node,"label", label);
xmlnode_put_attrib(node,"var", var);
xmlnode_insert_cdata(xmlnode_insert_tag(node,"value"), data, -1);
return node;
}
xmlnode add_xdata_desc(char *label)
{
xmlnode node;
node = xmlnode_new_tag("field");
xmlnode_put_attrib(node,"type","fixed");
xmlnode_insert_cdata(xmlnode_insert_tag(node,"value"), label, -1);
return node;
}
void xdata_handler(cnr room, cnu user, jpacket packet)
{
xmlnode results, element, value, current, node, message;
pool tp = pool_new();
spool sp = spool_new(tp);
int visible = room->visible;
char namespace[100];
log_debug(NAME, "[%s] xdata handler", FZONE);
results = xmlnode_get_tag(packet->x,"x");
if(results == NULL)
{
snprintf(namespace, 100, "?xmlns=%s", NS_MUC_ADMIN);
element = xmlnode_get_tag(packet->x, namespace);
results = xmlnode_get_tag(element,"x");
}
if(results == NULL)
{
snprintf(namespace, 100, "?xmlns=%s", NS_MUC_OWNER);
element = xmlnode_get_tag(packet->x, namespace);
results = xmlnode_get_tag(element,"x");
}
if(results == NULL)
{
snprintf(namespace, 100, "?xmlns=%s", NS_MUC_USER);
element = xmlnode_get_tag(packet->x, namespace);
results = xmlnode_get_tag(element,"x");
}
if(results == NULL)
{
log_debug(NAME, "[%s] No xdata results found", FZONE);
pool_free(tp);
return;
}
if(j_strcmp(xmlnode_get_attrib(results, "type"), "cancel") == 0)
{
log_debug(NAME, "[%s] xdata form was cancelled", FZONE);
if(room->locked == 1)
{
if(room->persistent == 1)
xdb_room_clear(room);
g_hash_table_foreach(room->remote, con_room_leaveall, (void*)NULL);
con_room_zap(room);
}
pool_free(tp);
return;
}
value = xmlnode_get_tag(results,"?var=form");
log_debug(NAME, "[%s] Form type: %s", FZONE, xmlnode_get_tag_data(value,"value"));
if(is_admin(room, user->realid))
{
log_debug(NAME, "[%s] Processing configuration form", FZONE);
if(room->locked == 1)
{
message = jutil_msgnew("groupchat", jid_full(jid_fix(user->realid)), NULL, spools(packet->p, "Configuration confirmed: This room is now unlocked.", packet->p));
xmlnode_put_attrib(message,"from", jid_full(jid_fix(room->id)));
deliver(dpacket_new(message), NULL);
room->locked = 0;
}
if(xmlnode_get_tag(results,"?var=muc#owner_roomname") != NULL)
{
free(room->name);
room->name = j_strdup(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_roomname"),"value"));
}
if(xmlnode_get_tag(results,"?var=leave") != NULL)
{
free(room->note_leave);
room->note_leave = j_strdup(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=leave"),"value"));
}
if(xmlnode_get_tag(results,"?var=join") != NULL)
{
free(room->note_join);
room->note_join = j_strdup(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=join"),"value"));
}
if(xmlnode_get_tag(results,"?var=rename") != NULL)
{
free(room->note_rename);
room->note_rename = j_strdup(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=rename"),"value"));
}
if((node = xmlnode_get_tag(results,"?var=muc#owner_roomdesc")) != NULL)
{
for(current = xmlnode_get_firstchild(node); current != NULL; current = xmlnode_get_nextsibling(current))
{
spooler(sp, xmlnode_get_data(current), sp);
}
free(room->description);
room->description = j_strdup(spool_print(sp));
}
room->subjectlock = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_changesubject"),"value"), room->subjectlock);
room->private = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=privacy"),"value"),room->private);
room->public = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_publicroom"),"value"),room->public);
room->maxusers = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_maxusers"),"value"),room->maxusers);
if(room->master->dynamic == 0 || is_sadmin(room->master, user->realid))
room->persistent = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_persistentroom"),"value"),room->persistent);
room->moderated = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_moderatedroom"),"value"),room->moderated);
room->defaulttype = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=defaulttype"),"value"),room->defaulttype);
room->privmsg = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=privmsg"),"value"),room->privmsg);
room->invitation = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_inviteonly"),"value"),room->invitation);
room->invites = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_allowinvites"),"value"),room->invites);
room->legacy = j_atoi(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=legacy"),"value"),room->legacy);
if(xmlnode_get_tag(results,"?var=muc#owner_passwordprotectedroom") != NULL && xmlnode_get_tag(results,"?var=muc#owner_roomsecret") != NULL)
{
if(j_strcmp(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_passwordprotectedroom"),"value"), "1") == 0 && xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_roomsecret"),"value") != NULL)
{
free(room->secret);
room->secret = j_strdup(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_roomsecret"),"value"));
log_debug(NAME ,"[%s] Switching on room password: %s", FZONE, room->secret);
}
else
{
log_debug(NAME, "[%s] Deactivating room password: %s %s", FZONE, xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_passwordprotectedroom"),"value"), xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_roomsecret"),"value"));
free(room->secret);
room->secret = NULL;
}
}
if(j_strcmp(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_whois"),"value"), "anyone") == 0)
room->visible = 1;
else
room->visible = 0;
if(room->visible == 1 && room->visible != visible)
con_send_room_status(room, STATUS_MUC_SHOWN_JID);
else if(room->visible == 0 && room->visible != visible)
con_send_room_status(room, STATUS_MUC_HIDDEN_JID);
if(xmlnode_get_tag(results,"?var=logformat"))
{
if(j_strcmp(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=logformat"),"value"), "xml") == 0)
{
if(room->logfile != NULL && room->logformat != LOG_XML)
{
fclose(room->logfile);
room->logformat = LOG_XML;
con_room_log_new(room);
}
else
{
room->logformat = LOG_XML;
}
}
else if(j_strcmp(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=logformat"),"value"), "xhtml") == 0)
{
if(room->logfile != NULL && room->logformat != LOG_XHTML)
{
fclose(room->logfile);
room->logformat = LOG_XHTML;
con_room_log_new(room);
}
else
{
room->logformat = LOG_XHTML;
}
}
else
{
if(room->logfile != NULL && room->logformat != LOG_TEXT)
{
fclose(room->logfile);
room->logformat = LOG_TEXT;
con_room_log_new(room);
}
else
{
room->logformat = LOG_TEXT;
}
}
}
if(room->logfile == NULL && j_strcmp(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_enablelogging"),"value"),"1") == 0)
{
con_room_log_new(room);
if (room->logfile == NULL)
log_alert(NULL, "cannot open log file for room %s", jid_full(jid_fix(room->id)));
else
con_room_log(room, NULL, "LOGGING STARTED");
}
if(room->logfile != NULL && j_strcmp(xmlnode_get_tag_data(xmlnode_get_tag(results,"?var=muc#owner_enablelogging"),"value"),"0") == 0)
{
con_room_log(room, NULL, "LOGGING STOPPED");
con_room_log_close(room);
}
if(room->persistent == 1)
{
xdb_room_set(room);
}
else
{
xdb_room_clear(room);
}
}
pool_free(tp);
}
void xdata_room_config(cnr room, cnu user, int new, xmlnode query)
{
xmlnode msg, iq, element, field, x;
char value[4];
if(user == NULL)
{
log_warn(NAME, "[%s] NULL attribute found", FZONE);
return;
}
log_debug(NAME, "[%s] Configuration form requested by %s", FZONE, jid_full(jid_fix(user->realid)));
if(!is_owner(room, user->realid))
{
log_debug(NAME, "[%s] Configuration form request denied", FZONE);
if(query != NULL)
{
jutil_error(query,TERROR_MUC_CONFIG);
deliver(dpacket_new(query),NULL);
}
return;
}
if(new == 1)
room->locked = 1;
if( query == NULL )
{
msg = xmlnode_new_tag("message");
xmlnode_put_attrib(msg, "to", jid_full(jid_fix(user->realid)));
xmlnode_put_attrib(msg,"from",jid_full(jid_fix(room->id)));
xmlnode_put_attrib(msg,"type","normal");
xmlnode_insert_cdata(xmlnode_insert_tag(msg,"subject"),"Please setup your room",-1);
element = xmlnode_insert_tag(msg,"body");
xmlnode_insert_cdata(element,"Channel ",-1);
xmlnode_insert_cdata(element,room->id->user,-1);
if(new == 1)
xmlnode_insert_cdata(element," has been created",-1);
else
xmlnode_insert_cdata(element," configuration setting",-1);
x = xmlnode_insert_tag(msg,"x");
}
else
{
msg = xmlnode_dup(query);
jutil_iqresult(msg);
iq = xmlnode_insert_tag(msg,"query");
xmlnode_put_attrib(iq, "xmlns", NS_MUC_OWNER);
x = xmlnode_insert_tag(iq,"x");
}
xmlnode_put_attrib(x,"xmlns",NS_DATA);
xmlnode_put_attrib(x,"type","form");
xmlnode_insert_cdata(xmlnode_insert_tag(x,"title"),"Room configuration",-1);
if(new == 1)
{
field = xmlnode_insert_tag(x,"instructions");
xmlnode_insert_cdata(field,"Your room \"",-1);
xmlnode_insert_cdata(field,room->id->user,-1);
xmlnode_insert_cdata(field,"\" has been created! The default configuration is as follows:\n", -1);
if(room->logfile == NULL)
xmlnode_insert_cdata(field,"- No logging\n", -1);
else
xmlnode_insert_cdata(field,"- logging\n", -1);
if(room->moderated == 1)
xmlnode_insert_cdata(field,"- Room moderation\n", -1);
else
xmlnode_insert_cdata(field,"- No moderation\n", -1);
if(room->maxusers > 0)
{
snprintf(value, 4, "%i", room->maxusers);
xmlnode_insert_cdata(field,"- Up to ", -1);
xmlnode_insert_cdata(field, value, -1);
xmlnode_insert_cdata(field, " participants\n", -1);
}
else
{
xmlnode_insert_cdata(field,"- Unlimited room size\n", -1);
}
if(room->secret == NULL)
xmlnode_insert_cdata(field,"- No password required\n", -1);
else
xmlnode_insert_cdata(field,"- Password required\n", -1);
if(room->invitation == 0)
xmlnode_insert_cdata(field,"- No invitation required\n", -1);
else
xmlnode_insert_cdata(field,"- Invitation required\n", -1);
if(room->persistent == 0)
xmlnode_insert_cdata(field,"- Room is not persistent\n", -1);
else
xmlnode_insert_cdata(field,"- Room is persistent\n", -1);
if(room->subjectlock == 0)
xmlnode_insert_cdata(field,"- Only admins may change the subject\n", -1);
else
xmlnode_insert_cdata(field,"- Anyone may change the subject\n", -1);
xmlnode_insert_cdata(field,"To accept the default configuration, click OK. To select a different configuration, please complete this form", -1);
}
else
xmlnode_insert_cdata(xmlnode_insert_tag(x,"instructions"),"Complete this form to make changes to the configuration of your room.",-1);
xmlnode_insert_node(x,add_xdata_text(NULL, 0, "form", "config"));
xmlnode_insert_node(x,add_xdata_text("Natural-Language Room Name", 1, "muc#owner_roomname", room->name));
xmlnode_insert_node(x,add_xdata_text("Short Description of Room", 2, "muc#owner_roomdesc", room->description));
xmlnode_insert_node(x,add_xdata_desc("The following messages are sent to legacy clients."));
xmlnode_insert_node(x,add_xdata_text("Message for user leaving room", 1, "leave", room->note_leave));
xmlnode_insert_node(x,add_xdata_text("Message for user joining room", 1, "join", room->note_join));
xmlnode_insert_node(x,add_xdata_text("Message for user renaming nickname in room", 1, "rename", room->note_rename));
xmlnode_insert_node(x,add_xdata_boolean("Allow Occupants to Change Subject", "muc#owner_changesubject", room->subjectlock));
field = xmlnode_insert_tag(x,"field");
xmlnode_put_attrib(field,"type","list-single");
xmlnode_put_attrib(field,"label","Maximum Number of Room Occupants");
xmlnode_put_attrib(field,"var","muc#owner_maxusers");
snprintf(value, 4, "%i", room->maxusers);
xmlnode_insert_cdata(xmlnode_insert_tag(field, "value"), value, -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "1");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "1", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "10");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "10", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "20");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "20", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "30");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "30", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "40");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "40", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "50");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "50", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "None");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "0", -1);
xmlnode_insert_node(x,add_xdata_boolean("Allow Occupants to query other Occupants?", "privacy", room->private));
xmlnode_insert_node(x,add_xdata_boolean("Allow Public Searching for Room", "muc#owner_publicroom", room->public));
if(room->master->dynamic == 0 || is_sadmin(room->master, user->realid))
xmlnode_insert_node(x,add_xdata_boolean("Make Room Persistent", "muc#owner_persistentroom", room->persistent));
xmlnode_insert_node(x,add_xdata_boolean("Consider all Clients as Legacy (shown messages)", "legacy", room->legacy));
xmlnode_insert_node(x,add_xdata_boolean("Make Room Moderated", "muc#owner_moderatedroom", room->moderated));
xmlnode_insert_node(x,add_xdata_desc("By default, new users entering a moderated room are only visitors"));
xmlnode_insert_node(x,add_xdata_boolean("Make Occupants in a Moderated Room Default to Participant", "defaulttype", room->defaulttype));
xmlnode_insert_node(x,add_xdata_boolean("Ban Private Messages between Occupants", "privmsg", room->privmsg));
xmlnode_insert_node(x,add_xdata_boolean("An Invitation is Required to Enter", "muc#owner_inviteonly", room->invitation));
xmlnode_insert_node(x,add_xdata_desc("By default, only admins can send invites in an invite-only room"));
xmlnode_insert_node(x,add_xdata_boolean("Allow Occupants to Invite Others", "muc#owner_allowinvites", room->invites));
if(room->secret == NULL)
xmlnode_insert_node(x,add_xdata_boolean("A Password is required to enter?", "muc#owner_passwordprotectedroom", 0));
else
xmlnode_insert_node(x,add_xdata_boolean("A Password required to enter", "muc#owner_passwordprotectedroom", 1));
xmlnode_insert_node(x,add_xdata_desc("If a password is required to enter this room, you must specify the password below."));
xmlnode_insert_node(x,add_xdata_text("The Room Password", -1, "muc#owner_roomsecret", room->secret));
field = xmlnode_insert_tag(x,"field");
xmlnode_put_attrib(field,"type","list-single");
xmlnode_put_attrib(field,"label","Affiliations that May Discover Real JIDs of Occupants");
xmlnode_put_attrib(field,"var","muc#owner_whois");
if(room->visible == 0)
xmlnode_insert_cdata(xmlnode_insert_tag(field, "value"),"admins", -1);
else
xmlnode_insert_cdata(xmlnode_insert_tag(field, "value"),"anyone", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "Room Owner and Admins Only");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "admins", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "Anyone");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "anyone", -1);
if(room->logfile == NULL)
xmlnode_insert_node(x,add_xdata_boolean("Enable Logging of Room Conversations", "muc#owner_enablelogging", 0));
else
xmlnode_insert_node(x,add_xdata_boolean("Enable Logging of Room Conversations", "muc#owner_enablelogging", 1));
field = xmlnode_insert_tag(x,"field");
xmlnode_put_attrib(field,"type","list-single");
xmlnode_put_attrib(field,"label","Logfile format");
xmlnode_put_attrib(field,"var","logformat");
if(room->logformat == LOG_XML)
xmlnode_insert_cdata(xmlnode_insert_tag(field, "value"),"xml", -1);
else if(room->logformat == LOG_XHTML)
xmlnode_insert_cdata(xmlnode_insert_tag(field, "value"),"xhtml", -1);
else
xmlnode_insert_cdata(xmlnode_insert_tag(field, "value"),"text", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "XML");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "xml", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "XHTML");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "xhtml", -1);
element = xmlnode_insert_tag(field, "option");
xmlnode_put_attrib(element, "label", "Plain Text");
xmlnode_insert_cdata(xmlnode_insert_tag(element, "value"), "text", -1);
deliver(dpacket_new(msg),NULL);
}