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; }
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; }