#include "conference.h"
xmlnode add_extended_presence(cnu from, cnu to, xmlnode presence, char *status, char *reason, char *actor)
{
xmlnode tag;
xmlnode element;
xmlnode item;
xmlnode output;
taffil useraffil;
trole userrole;
jid user;
cnr room;
if(presence == NULL)
{
output = xmlnode_dup(from->presence);
}
else
{
output = xmlnode_dup(presence);
}
if(from == NULL)
{
log_warn(NAME, "[%s] ERR: Missing user variable in add_extended_presence", FZONE);
return output;
}
user = from->realid;
room = from->room;
tag = xmlnode_insert_tag(output,"x");
xmlnode_put_attrib(tag, "xmlns", NS_MUC_USER);
item = xmlnode_insert_tag(tag, "item");
if(room->visible == 1 || is_admin(room, to->realid))
{
xmlnode_put_attrib(item, "jid", jid_full(user));
}
useraffil = affiliation_level(room, user);
xmlnode_put_attrib(item, "affiliation", useraffil.msg);
userrole = role_level(room, user);
xmlnode_put_attrib(item, "role", userrole.msg);
log_debug(NAME, "[%s] status check: status >%s<", FZONE, status);
if(j_strcmp(status, STATUS_MUC_CREATED) == 0)
{
room->locked = 1;
}
if(status != NULL)
{
log_debug(NAME, "[%s] Adding to epp: status >%s<, reason >%s<", FZONE, status, reason);
if(j_strcmp(status, STATUS_MUC_NICKCHANGE) == 0)
if(xmlnode_get_data(from->nick) != NULL)
xmlnode_put_attrib(item, "nick", xmlnode_get_data(from->nick));
if(reason != NULL)
{
element = xmlnode_insert_tag(item, "reason");
xmlnode_insert_cdata(element, reason, -1);
}
if(actor != NULL)
{
element = xmlnode_insert_tag(item, "actor");
xmlnode_put_attrib(element, "jid", actor);
}
element = xmlnode_insert_tag(tag, "status");
xmlnode_put_attrib(element,"code", status);
}
return output;
}
int is_sadmin(cni master, jid user)
{
char ujid[256];
if(master == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_sadmin", FZONE);
return 0;
}
snprintf(ujid, 256, "%s@%s", user->user, user->server);
log_debug(NAME, "[%s] Is sadmin? >%s/%s<", FZONE, jid_full(user), ujid);
if(g_hash_table_lookup(master->sadmin, ujid) != NULL )
return 1;
else
return 0;
}
int is_owner(cnr room, jid user)
{
char ujid[256];
char cjid[256];
if(room == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_owner", FZONE);
return 0;
}
snprintf(ujid, 256, "%s@%s", user->user, user->server);
if(room->creator)
{
snprintf(cjid, 256, "%s@%s", room->creator->user, room->creator->server);
}
else
{
snprintf(cjid, 256, "@");
}
log_debug(NAME, "[%s] Is Owner? >%s<", FZONE, jid_full(user));
if(is_sadmin(room->master, user))
return 2;
else if(j_strcmp(cjid, ujid) == 0)
return 1;
else if(g_hash_table_lookup(room->owner, ujid) != NULL )
return 1;
else
return 0;
}
int is_admin(cnr room, jid user)
{
char ujid[256];
if(room == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_admin", FZONE);
return 0;
}
snprintf(ujid, 256, "%s@%s", user->user, user->server);
log_debug(NAME, "[%s] Is Admin? >%s<", FZONE, jid_full(user));
if(is_owner(room, user))
return 2;
if(g_hash_table_lookup(room->admin, ujid) != NULL )
return 1;
else if(g_hash_table_lookup(room->admin, user->server) != NULL )
return 1;
else
return 0;
}
int is_moderator(cnr room, jid user)
{
if(room == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_moderator", FZONE);
return 0;
}
if(is_owner(room, user))
{
log_debug(NAME, "[%s] Is Moderator? >%s< - Owner", FZONE, jid_full(user));
return 2;
}
if(g_hash_table_lookup(room->moderator, jid_full(user)) != NULL )
{
log_debug(NAME, "[%s] Is Moderator? >%s< - Moderator", FZONE, jid_full(user));
return 1;
}
else
{
log_debug(NAME, "[%s] Is Moderator? >%s< - No", FZONE, jid_full(user));
return 0;
}
}
int is_participant(cnr room, jid user)
{
if(room == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_participant", FZONE);
return 0;
}
if(room->moderated == 0)
return 1;
if(is_moderator(room, user))
return 2;
if(g_hash_table_lookup(room->participant, jid_full(user)) != NULL )
return 1;
else
return 0;
}
int is_member(cnr room, jid user)
{
char ujid[256];
if(room == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_member", FZONE);
return 0;
}
snprintf(ujid, 256, "%s@%s", user->user, user->server);
if(is_owner(room, user))
{
log_debug(NAME, "[%s] Is Member? >%s< - Owner", FZONE, jid_full(user));
return 1;
}
if(is_admin(room, user))
{
log_debug(NAME, "[%s] Is Member? >%s< - Admin", FZONE, jid_full(user));
return 1;
}
if(g_hash_table_lookup(room->member, ujid) != NULL )
{
log_debug(NAME, "[%s] Is Member? >%s< - Yes (case 1)", FZONE, jid_full(user));
return 1;
}
else if(g_hash_table_lookup(room->member, user->server) != NULL )
{
log_debug(NAME, "[%s] Is Member? >%s< - Yes (case 2)", FZONE, jid_full(user));
return 1;
}
else
{
log_debug(NAME, "[%s] Is Member? >%s< - No", FZONE, jid_full(user));
return 0;
}
}
int is_outcast(cnr room, jid user)
{
char ujid[256];
if(room == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_outcast", FZONE);
return 0;
}
snprintf(ujid, 256, "%s@%s", user->user, user->server);
if(g_hash_table_lookup(room->outcast, ujid) != NULL )
return 1;
else if(g_hash_table_lookup(room->outcast, user->server) != NULL )
return 1;
else
return 0;
}
int is_visitor(cnr room, jid user)
{
if(room == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_visitor", FZONE);
return 0;
}
if(is_moderator(room, user))
return 0;
else if(is_participant(room, user))
return 0;
else if(g_hash_table_lookup(room->remote, jid_full(user)) != NULL )
return 1;
else
return 0;
}
int in_room(cnr room, jid user)
{
if(room == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in in_room", FZONE);
return 0;
}
if(g_hash_table_lookup(room->remote, jid_full(user)) != NULL )
return 1;
else
return 0;
}
int is_legacy(cnu user)
{
cnr room;
if(user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_legacy", FZONE);
return 0;
}
room = user->room;
if(room->legacy)
return 1;
else if(user->legacy)
return 1;
else
return 0;
}
int is_leaving(cnr room, jid user)
{
cnu target;
if(room == NULL || user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_leaving", FZONE);
return 0;
}
target = g_hash_table_lookup(room->remote, jid_full(user));
if(target != NULL )
{
if(target->leaving == 1)
{
return 1;
}
}
return 0;
}
int is_registered(cni master, char *user, char *nick)
{
xmlnode results;
if(user == NULL || nick == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable in is_registered", FZONE);
return 0;
}
results = get_data_bynick(master, nick);
if(results != NULL)
{
log_debug(NAME, "[%s] Found %s in Registered Nicks - checking [%s/%s]", FZONE, nick, user, xmlnode_get_attrib(results, "jid"));
if(j_strcmp(user, xmlnode_get_attrib(results, "jid")) != 0)
{
xmlnode_free(results);
return -1;
}
else
{
xmlnode_free(results);
return 1;
}
}
else
{
xmlnode_free(results);
return 0;
}
}
xmlnode _con_send_alert(cnu user, char *text, char *subject, char *status)
{
xmlnode msg;
xmlnode element;
char body[256];
char reason[128];
char *type = NULL;
cnr room;
char *room_id;
if(user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable", FZONE);
return NULL;
}
room = user->room;
room_id = jid_full(room->id);
if(is_legacy(user) == 0)
{
return NULL;
}
if(status == NULL)
{
snprintf(body, 256, "%s", text);
}
else
{
if(text == NULL)
strcpy(reason, "None given");
else
snprintf(reason, 128, "%s", text);
if(j_strcmp(status, STATUS_MUC_KICKED) == 0)
{
type = "normal";
snprintf(body, 256, "You have been kicked from the room %s. \n Reason: %s", room_id, reason);
}
if(j_strcmp(status, STATUS_MUC_BANNED) == 0)
{
type = "normal";
snprintf(body, 256, "You have been kicked and outcast from the room %s. \n Reason: %s", room_id, reason);
}
if(j_strcmp(status, STATUS_MUC_SHOWN_JID) == 0)
{
type = "groupchat";
snprintf(body, 256, "This room (%s) is not anonymous", room_id);
}
if(j_strcmp(status, STATUS_MUC_HIDDEN_JID) == 0)
{
type = "groupchat";
snprintf(body, 256, "This room (%s) is anonymous, except for admins", room_id);
status = STATUS_MUC_SHOWN_JID;
}
}
msg = jutil_msgnew(type, jid_full(user->realid) , subject, body);
xmlnode_put_attrib(msg, "from", room_id);
if(status != NULL)
{
element = xmlnode_insert_tag(msg,"x");
xmlnode_put_attrib(element, "xmlns", NS_MUC_USER);
xmlnode_put_attrib(xmlnode_insert_tag(element, "status"), "code", status);
}
return msg;
}
void con_send_alert(cnu user, char *text, char *subject, char *status)
{
xmlnode msg = _con_send_alert(user, text, subject, status);
if(msg)
{
deliver(dpacket_new(msg), NULL);
}
}
void _con_send_room_status(gpointer key, gpointer data, gpointer arg)
{
char *status = (char*)arg;
cnu user = (cnu)data;
xmlnode msg = _con_send_alert(user, NULL, NULL, status);
if(msg)
{
deliver(dpacket_new(msg), NULL);
}
}
void con_send_room_status(cnr room, char *status)
{
if(room == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable", FZONE);
return;
}
g_hash_table_foreach(room->local, _con_send_room_status, (void*)status);
}
char *linesplit(char **entry)
{
char *line;
char *point;
char *str = "\n";
if(!(*entry))
return NULL;
line = *entry;
if((point = strstr(*entry, str)))
{
*point = 0;
*entry = point+strlen(str);
}
else
*entry = NULL;
return line;
}
char *itoa(int number, char *result)
{
sprintf(result, "%d", number);
return result;
}
char *funcstr(char *file, char *function, int line)
{
static char buff[128];
int i;
i = snprintf(buff,127,"%s:%d (%s)",file,line,function);
buff[i] = '\0';
return buff;
}
int minuteget(time_t tin)
{
time_t timef;
char timestr[50];
size_t timelen = 49;
int results;
if(tin)
timef = tin;
else
timef = time(NULL);
strftime(timestr, timelen, "%M", localtime(&timef));
results = j_atoi(timestr, -1);
return results;
}
char *timeget(time_t tin)
{
time_t timef;
char timestr[50];
size_t timelen = 49;
if(tin)
timef = tin;
else
timef = time(NULL);
strftime(timestr, timelen, "%H:%M", localtime(&timef));
return j_strdup(timestr);
}
char *dateget(time_t tin)
{
time_t timef;
char timestr[50];
size_t timelen = 49;
if(tin)
timef = tin;
else
timef = time(NULL);
strftime(timestr, timelen, "%Y-%m-%d", localtime(&timef));
return j_strdup(timestr);
}
void update_presence(cnu user)
{
xmlnode result;
cnr room;
if(user == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable", FZONE);
return;
}
room = user->room;
result = xmlnode_dup(user->presence);
xmlnode_put_vattrib(result,"cnu",(void*)user);
g_hash_table_foreach(room->local, con_room_sendwalk, (void*)result);
xmlnode_free(result);
return;
}
void insert_item_error(xmlnode node, char *code, char *msg)
{
xmlnode element;
element = xmlnode_insert_tag(node, "error");
xmlnode_put_attrib(element, "code", code);
xmlnode_insert_cdata(element, msg, -1);
}
int add_roster(cnr room, jid userid)
{
xmlnode store;
xmlnode node;
xmlnode old;
char *key;
char ujid[256];
if(room == NULL || userid == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable", FZONE);
return -1;
}
snprintf(ujid, 256, "%s@%s", userid->user, userid->server);
key = j_strdup(ujid);
old = g_hash_table_lookup(room->roster, key);
if(old == NULL)
{
store = xmlnode_new_tag("users");
}
else
{
store = xmlnode_dup(old);
node = xmlnode_get_tag(store, spools(xmlnode_pool(store), "item?jid=", jid_full(userid), xmlnode_pool(store)));
if(node != NULL)
{
log_debug(NAME, "[%s] DBG: Already in node, ignoring\n", FZONE);
xmlnode_free(store);
free(key);
return 0;
}
}
if(userid->resource != NULL)
{
log_debug(NAME, "[%s] adding entry (%s) for jid (%s)", FZONE, jid_full(userid), ujid);
node = xmlnode_new_tag("item");
xmlnode_put_attrib(node, "jid", jid_full(userid));
xmlnode_insert_node(store, node);
xmlnode_free(node);
}
g_hash_table_insert(room->roster, key, store);
return 1;
}
int remove_roster(cnr room, jid userid)
{
xmlnode store;
xmlnode old;
xmlnode node;
char *key;
char ujid[256];
if(room == NULL || userid == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable", FZONE);
return -1;
}
snprintf(ujid, 256, "%s@%s", userid->user, userid->server);
key = j_strdup(ujid);
old = g_hash_table_lookup(room->roster, key);
if(old == NULL)
{
free(key);
return 1;
}
store = xmlnode_dup(old);
node = xmlnode_get_tag(store, spools(xmlnode_pool(store), "item?jid=", jid_full(userid), xmlnode_pool(store)));
if(node == NULL)
{
log_debug(NAME, "[%s] DBG: Already removed from node, ignoring\n", FZONE);
xmlnode_free(store);
free(key);
return 1;
}
xmlnode_hide(node);
node = xmlnode_get_tag(store, "item");
if(node == NULL)
{
log_debug(NAME, "[%s] Removing empty entry for jid (%s)", FZONE, ujid);
g_hash_table_remove(room->roster, key);
xmlnode_free(store);
free(key);
}
else
{
log_debug(NAME, "[%s] Removing entry (%s) for jid (%s)", FZONE, jid_full(userid), ujid);
g_hash_table_insert(room->roster, key, store);
}
return 1;
}
xmlnode get_roster(cnr room, jid userid)
{
xmlnode store;
char *key;
char ujid[256];
if(room == NULL || userid == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable", FZONE);
return NULL;
}
snprintf(ujid, 256, "%s@%s", userid->user, userid->server);
key = j_strdup(ujid);
store = g_hash_table_lookup(room->roster, key);
free(key);
return store;
}
char *extractAction(char *origin, pool p)
{
int i;
int end;
spool sp;
char *output;
char in[2];
if(origin == NULL || p == NULL)
{
log_warn(NAME, "[%s] ERR: Missing variable", FZONE);
return NULL;
}
sp = spool_new(p);
end = j_strlen(origin);
for (i = 3 ; i <= end ; i++)
{
in[0] = origin[i];
in[1] = '\0';
log_debug(NAME, "[%s] >%s< saved", FZONE, in);
spooler(sp, in, sp);
}
output = spool_print(sp);
return output;
}
int isPrime(unsigned long n)
{
int prime = 1;
unsigned long p1,p2 , s;
if(n > 3)
{
p1 = 3;
p2 = n - 3;
s = 9;
while((prime = p2 % p1 ) && (s <= p2))
{
p1 += 2;
p2 -= 2;
s <<= 2;
s++;
}
}
return prime;
}
jid jid_fix(jid id)
{
unsigned char *str;
if(id == NULL)
{
log_warn(NAME, "[%s] ERR - id NULL", FZONE);
return NULL;
}
if(id->server == NULL || j_strlen(id->server) == 0 || j_strlen(id->server) > 255)
return NULL;
for(str = id->server; *str != '\0'; str++)
{
*str = tolower(*str);
}
return id;
}