Пример #1
0
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
static mod_ret_t _offline_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) {
    st_ret_t ret;
    os_t os;
    os_object_t o;
    nad_t nad;
    pkt_t queued;
    int ns, elem, attr;
    char cttl[15], cstamp[18];
    time_t ttl, stamp;

    /* if they're becoming available for the first time */
    if(pkt->type == pkt_PRESENCE && pkt->to == NULL && sess->user->top == NULL) {

        ret = storage_get(pkt->sm->st, "queue", jid_user(sess->jid), NULL, &os);
        if(ret != st_SUCCESS) {
            log_debug(ZONE, "storage_get returned %d", ret);
            return mod_PASS;
        }

        if(os_iter_first(os))
            do {
                o = os_iter_object(os);

                if(os_object_get_nad(os, o, "xml", &nad)) {
                    queued = pkt_new(pkt->sm, nad_copy(nad));
                    if(queued == NULL) {
                        log_debug(ZONE, "invalid queued packet, not delivering");
                    } else {
                        /* check expiry as necessary */
                        if((ns = nad_find_scoped_namespace(queued->nad, uri_EXPIRE, NULL)) >= 0 &&
                                (elem = nad_find_elem(queued->nad, 1, ns, "x", 1)) >= 0 &&
                                (attr = nad_find_attr(queued->nad, elem, -1, "seconds", NULL)) >= 0) {
                            snprintf(cttl, 15, "%.*s", NAD_AVAL_L(queued->nad, attr), NAD_AVAL(queued->nad, attr));
                            ttl = atoi(cttl);

                            /* it should have a x:delay stamp, because we stamp everything we store */
                            if((ns = nad_find_scoped_namespace(queued->nad, uri_DELAY, NULL)) >= 0 &&
                                    (elem = nad_find_elem(queued->nad, 1, ns, "x", 1)) >= 0 &&
                                    (attr = nad_find_attr(queued->nad, elem, -1, "stamp", NULL)) >= 0) {
                                snprintf(cstamp, 18, "%.*s", NAD_AVAL_L(queued->nad, attr), NAD_AVAL(queued->nad, attr));
                                stamp = datetime_in(cstamp);

                                if(stamp + ttl <= time(NULL)) {
                                    log_debug(ZONE, "queued packet has expired, dropping");
                                    pkt_free(queued);
                                    continue;
                                }
                            }
                        }

                        log_debug(ZONE, "delivering queued packet to %s", jid_full(sess->jid));
                        pkt_sess(queued, sess);
                    }
                }
            } while(os_iter_next(os));

        os_free(os);

        /* drop the spool */
        storage_delete(pkt->sm->st, "queue", jid_user(sess->jid), NULL);
    }

    /* pass it so that other modules and mod_presence can get it */
    return mod_PASS;
}