예제 #1
0
파일: mod_vacation.c 프로젝트: zipo/zipo
static mod_ret_t _vacation_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) {
    module_t mod = mi->mod;
    vacation_t v = sess->user->module_data[mod->index];
    int ns, start, end, msg;
    char dt[30];
    pkt_t res;
    os_t os;
    os_object_t o;

    /* we only want to play with vacation iq packets */
    if((pkt->type != pkt_IQ && pkt->type != pkt_IQ_SET) || pkt->ns != ns_VACATION)
        return mod_PASS;

    /* if it has a to, throw it out */
    if(pkt->to != NULL)
        return -stanza_err_BAD_REQUEST;

    /* get */
    if(pkt->type == pkt_IQ) {
        if(v->msg == NULL) {
            res = pkt_create(mod->mm->sm, "iq", "result", NULL, NULL);
            pkt_id(pkt, res);
            pkt_free(pkt);

            pkt_sess(res, sess);

            return mod_HANDLED;
        }

        ns = nad_find_scoped_namespace(pkt->nad, uri_VACATION, NULL);

        if(v->start != 0) {
            datetime_out(v->start, dt_DATETIME, dt, 30);
            nad_insert_elem(pkt->nad, 2, ns, "start", dt);
        } else
            nad_insert_elem(pkt->nad, 2, ns, "start", NULL);

        if(v->end != 0) {
            datetime_out(v->end, dt_DATETIME, dt, 30);
            nad_insert_elem(pkt->nad, 2, ns, "end", dt);
        } else
            nad_insert_elem(pkt->nad, 2, ns, "end", NULL);

        nad_insert_elem(pkt->nad, 2, ns, "message", v->msg);

        pkt_tofrom(pkt);
        nad_set_attr(pkt->nad, 1, -1, "type", "result", 6);
            
        pkt_sess(pkt, sess);

        return mod_HANDLED;
    }

    /* set */
    ns = nad_find_scoped_namespace(pkt->nad, uri_VACATION, NULL);

    start = nad_find_elem(pkt->nad, 2, ns, "start", 1);
    end = nad_find_elem(pkt->nad, 2, ns, "end", 1);
    msg = nad_find_elem(pkt->nad, 2, ns, "message", 1);

    if(start < 0 || end < 0 || msg < 0) {
        /* forget */
        if(v->msg != NULL) {
            free(v->msg);
            v->msg = NULL;
        }
        v->start = 0;
        v->end = 0;

        storage_delete(mi->sm->st, "vacation-settings", jid_user(sess->jid), NULL);

        res = pkt_create(mod->mm->sm, "iq", "result", NULL, NULL);
        pkt_id(pkt, res);
        pkt_free(pkt);

        pkt_sess(res, sess);

        return mod_HANDLED;
    }

    if(NAD_CDATA_L(pkt->nad, start) > 0) {
        strncpy(dt, NAD_CDATA(pkt->nad, start), (30 < NAD_CDATA_L(pkt->nad, start) ? 30 : NAD_CDATA_L(pkt->nad, start)));
        v->start = datetime_in(dt);
    } else
        v->start = 0;

    if(NAD_CDATA_L(pkt->nad, end) > 0) {
        strncpy(dt, NAD_CDATA(pkt->nad, end), (30 < NAD_CDATA_L(pkt->nad, end) ? 30 : NAD_CDATA_L(pkt->nad, end)));
        v->end = datetime_in(dt);
    } else
        v->end = 0;

    v->msg = (char *) malloc(sizeof(char) * (NAD_CDATA_L(pkt->nad, msg) + 1));
    strncpy(v->msg, NAD_CDATA(pkt->nad, msg), NAD_CDATA_L(pkt->nad, msg));
    v->msg[NAD_CDATA_L(pkt->nad, msg)] = '\0';

    os = os_new();
    o = os_object_new(os);
    os_object_put(o, "start", &v->start, os_type_INTEGER);
    os_object_put(o, "end", &v->end, os_type_INTEGER);
    os_object_put(o, "message", v->msg, os_type_STRING);

    if(storage_replace(mod->mm->sm->st, "vacation-settings", jid_user(sess->user->jid), NULL, os) != st_SUCCESS) {
        free(v->msg);
        v->msg = NULL;
        v->start = 0;
        v->end = 0;
        return -stanza_err_INTERNAL_SERVER_ERROR;
    }
    
    res = pkt_create(mod->mm->sm, "iq", "result", NULL, NULL);
    pkt_id(pkt, res);
    pkt_free(pkt);

    pkt_sess(res, sess);

    return mod_HANDLED;
}
예제 #2
0
파일: sess.c 프로젝트: 6wei/jabberd2
sess_t sess_start(sm_t sm, jid_t jid) {
    pool_t p;
    user_t user;
    sess_t sess, scan;
    sha1_state_t sha1;
    unsigned char hash[20];
    int replaced = 0;

    log_debug(ZONE, "session requested for %s", jid_full(jid));

    /* check whether it is to serviced domain */
    if(xhash_get(sm->hosts, jid->domain) == NULL) {
        log_write(sm->log, LOG_ERR, "request to start session in non-serviced domain: jid=%s", jid_full(jid));
        return NULL;
    }

    /* get user data for this guy */
    user = user_load(sm, jid);

    /* unknown user */
    if(user == NULL) {
        if(config_get(sm->config, "user.auto-create") == NULL) {
            log_write(sm->log, LOG_NOTICE, "user not found and user.auto-create not enabled, can't start session: jid=%s", jid_full(jid));
            return NULL;
        }

        log_debug(ZONE, "auto-creating user %s", jid_user(jid));

        if(user_create(sm, jid) != 0)
            return NULL;

        user = user_load(sm, jid);
        if(user == NULL) {
            log_write(sm->log, LOG_NOTICE, "couldn't load user, can't start session: jid=%s", jid_full(jid));
            return NULL;
        }
    }

    /* kill their old session if they have one */
    for(scan = user->sessions; scan != NULL; scan = scan->next)
        if(jid_compare_full(scan->jid, jid) == 0) {
            log_debug(ZONE, "replacing session %s (%s)", jid_full(jid), scan->c2s_id);

            /* !!! this "replaced" stuff is a hack - its really a subaction of "ended".
             *     hurrah, another control protocol rewrite is needed :(
             */
            sm_c2s_action(scan, "replaced", NULL);

            _sess_end_guts(scan);

            pool_free(scan->p);

            replaced = 1;

            break;
        }

    /* make a new session */
    p = pool_new();

    sess = (sess_t) pmalloco(p, sizeof(struct sess_st));
    sess->p = p;

    /* fill it out */
    sess->pri = 0;
    sess->user = user;

    sess->jid = jid_dup(jid);
    pool_cleanup(sess->p, (void (*))(void *) jid_free, sess->jid);

    /* a place for modules to store stuff */
    sess->module_data = (void **) pmalloco(sess->p, sizeof(void *) * sess->user->sm->mm->nindex);

    /* add it to the list */
    sess->next = user->sessions;
    user->sessions = sess;

    /* who c2s should address things to */
    sha1_init(&sha1);
    datetime_out(time(NULL), dt_DATETIME, sess->sm_id, 41);
    sha1_append(&sha1, sess->sm_id, strlen(sess->sm_id));
    sha1_append(&sha1, jid_full(sess->jid), strlen(jid_full(sess->jid)));
    sha1_finish(&sha1, hash);
    hex_from_raw(hash, 20, sess->sm_id);

    log_debug(ZONE, "smid is %s", sess->sm_id);

    /* remember it */
    xhash_put(sm->sessions, sess->sm_id, sess);

    /* inform the modules */
    /* !!! catch the return value - if its 1, don't let them in */
    mm_sess_start(sm->mm, sess);

    if(replaced)
        log_write(sm->log, LOG_NOTICE, "session replaced: jid=%s", jid_full(sess->jid));
    else
        log_write(sm->log, LOG_NOTICE, "session started: jid=%s", jid_full(sess->jid));
            
    return sess;
}