#include "sm.h"
static user_t _user_alloc(sm_t sm, jid_t jid) {
pool p;
user_t user;
p = pool_new();
user = (user_t) pmalloco(p, sizeof(struct user_st));
user->p = p;
user->sm = sm;
user->jid = jid_dup(jid);
pool_cleanup(p, (void (*)(void *)) jid_free, user->jid);
user->module_data = (void **) pmalloco(p, sizeof(void *) * sm->mm->nindex);
return user;
}
user_t user_load(sm_t sm, jid_t jid) {
user_t user;
user = xhash_get(sm->users, jid_user(jid));
if(user != NULL) {
log_debug(ZONE, "returning previously-created user data for %s", jid_user(jid));
return user;
}
user = _user_alloc(sm, jid);
if(mm_user_load(sm->mm, user) != 0) {
log_debug(ZONE, "modules failed user load for %s", jid_user(jid));
pool_free(user->p);
return NULL;
}
xhash_put(sm->users, jid_user(user->jid), (void *) user);
log_debug(ZONE, "loaded user data for %s", jid_user(jid));
return user;
}
void user_free(user_t user) {
log_debug(ZONE, "freeing user %s", jid_user(user->jid));
xhash_zap(user->sm->users, jid_user(user->jid));
pool_free(user->p);
}
int user_create(sm_t sm, jid_t jid) {
user_t user;
log_debug(ZONE, "create user request for %s", jid_user(jid));
user = user_load(sm, jid);
if(user != NULL) {
log_write(sm->log, LOG_ERR, "request to create already-active user: jid=%s", jid_user(jid));
log_debug(ZONE, "user already active, not creating");
return 1;
}
if(mm_user_create(sm->mm, jid) != 0) {
log_write(sm->log, LOG_ERR, "user creation failed: jid=%s", jid_user(jid));
log_debug(ZONE, "user create failed, forcing deletion for cleanup");
mm_user_delete(sm->mm, jid);
return 1;
}
log_write(sm->log, LOG_NOTICE, "created user: jid=%s", jid_user(jid));
return 0;
}
void user_delete(sm_t sm, jid_t jid) {
user_t user;
sess_t scan, next;
log_debug(ZONE, "delete user request for %s", jid_user(jid));
user = user_load(sm, jid);
if(user == NULL) {
log_debug(ZONE, "user doesn't exist, can't delete");
return;
}
scan = user->sessions;
while(scan != NULL) {
next = scan->next;
sm_c2s_action(scan, "ended", NULL);
sess_end(scan);
scan = next;
}
mm_user_delete(sm->mm, jid);
log_write(sm->log, LOG_NOTICE, "deleted user: jid=%s", jid_user(jid));
}