static char *test_q_read() { packet *q = q_create(); packet p = pkt_create(REFERENCE, 0, 0, 0, 0); packet p2 = pkt_create(ERROR, 0, 0, 0, 0); q_write(p, 0, q, N); q_read(&p2, 0, q, N); mu_assert("FAIL: test_q_read [1]", (p.x == p2.x) && (p.y == p2.y)); q_read(&p2, 0, q, N); mu_assert("FAIL: test_q_read [2]", !q_read(&p2, 0, q, N)); q_destroy(q); return NULL; }
static mod_ret_t _vacation_pkt_user(mod_instance_t mi, user_t user, pkt_t pkt) { module_t mod = mi->mod; vacation_t v = user->module_data[mod->index]; time_t t; pkt_t res; if(v->msg == NULL) return mod_PASS; /* only want messages, and only if they're offline */ if(!(pkt->type & pkt_MESSAGE) || user->top != NULL) return mod_PASS; /* reply only to real, human users - they always have full JIDs in 'from' */ jid_expand(pkt->from); if(pkt->from->node[0] == '\0' || pkt->from->resource[0] == '\0') { pkt_free(pkt); return mod_HANDLED; } t = time(NULL); if(v->start < t && (t < v->end || v->end == 0)) { res = pkt_create(mod->mm->sm, "message", NULL, jid_full(pkt->from), mod->mm->sm->id); nad_insert_elem(res->nad, 1, NAD_ENS(res->nad, 1), "subject", "Automated reply"); nad_insert_elem(res->nad, 1, NAD_ENS(res->nad, 1), "body", v->msg); pkt_router(res); /* !!! remember that we sent this */ } return mod_PASS; }
static char *test_pkt_create() { packet p = pkt_create(ERROR, 1, 2, 3, 4); mu_assert("FAIL: test_pkt_create [1]", pkt_get_type(p) == ERROR); mu_assert("FAIL: test_pkt_create [2]", pkt_get_source(p) == 1); mu_assert("FAIL: test_pkt_create [3]", pkt_get_arg_pos(p) == 2); mu_assert("FAIL: test_pkt_create [4]", pkt_get_sub(p) == 3); mu_assert("FAIL: test_pkt_create [6]", pkt_get_payload(p) == 4); return NULL; }
/* presence packets to the sm */ static mod_ret_t _presence_pkt_sm(mod_instance_t mi, pkt_t pkt) { module_t mod = mi->mod; jid_t smjid; /* only check presence/subs to server JID */ if(!(pkt->type & pkt_PRESENCE || pkt->type & pkt_S10N)) return mod_PASS; smjid = jid_new(jid_user(pkt->to), -1); /* handle subscription requests */ if(pkt->type == pkt_S10N) { log_debug(ZONE, "accepting subscription request from %s", jid_full(pkt->from)); /* accept request */ pkt_router(pkt_create(mod->mm->sm, "presence", "subscribed", jid_user(pkt->from), jid_user(smjid))); /* and subscribe back to theirs */ pkt_router(pkt_create(mod->mm->sm, "presence", "subscribe", jid_user(pkt->from), jid_user(smjid))); pkt_free(pkt); jid_free(smjid); return mod_HANDLED; } /* handle unsubscribe requests */ if(pkt->type == pkt_S10N_UN) { log_debug(ZONE, "accepting unsubscribe request from %s", jid_full(pkt->from)); /* ack the request */ pkt_router(pkt_create(mod->mm->sm, "presence", "unsubscribed", jid_user(pkt->from), jid_user(smjid))); pkt_free(pkt); jid_free(smjid); return mod_HANDLED; } /* drop the rest */ log_debug(ZONE, "dropping presence from %s", jid_full(pkt->from)); pkt_free(pkt); jid_free(smjid); return mod_HANDLED; }
static char *test_q_is_empty() { packet *q = q_create(); packet p = pkt_create(ERROR, 0, 0, 0, 0); mu_assert("FAIL: test_q_is_empty [1]", q_is_empty(0, 0, q, N)); q_write(p, 0, q, N); mu_assert("FAIL: test_q_is_empty [2]", !q_is_empty(0, 0, q, N)); q_read(&p, 0, q, N); mu_assert("FAIL: test_q_is_empty [3]", q_is_empty(0, 0, q, N)); q_destroy(q); return NULL; }
void test_packet_create_destroy(void** state) { uint8_t data[5] = {1,2,3,4,5}; KAD_PACKET* kp = NULL; assert_true(pkt_create(data, 5, PACKET_EMIT_TYPE_TCP, KADEMLIA2_PING, &kp)); assert_true(pkt_destroy(kp)); }
static char *test_q_size() { packet *q = q_create(); packet p = pkt_create(ERROR, 0, 0, 0, 0); mu_assert("FAIL: test_q_size [1]", q_size(0, 0, q, N) == 0); for (int i = 0; i < 20; i++) { q_write(p, 0, q, N); } mu_assert("FAIL: test_q_size [2]", q_size(0, 0, q, N) == 16); q_read(&p, 0, q, N); mu_assert("FAIL: test_q_size [3]", q_size(0, 0, q, N) == 15); q_destroy(q); return NULL; }
static char *test_q_is_full() { packet *q = q_create(); packet p = pkt_create(ERROR, 0, 0, 0, 0); mu_assert("FAIL: test_q_is_full [1]", !q_is_full(0, 0, q, N)); for (int i = 0; i < 16; i++) { q_write(p, 0, q, N); } mu_assert("FAIL: test_q_is_full [2]", q_is_full(0, 0, q, N)); q_read(&p, 0, q, N); mu_assert("FAIL: test_q_is_full [3]", !q_is_full(0, 0, q, N)); q_destroy(q); return NULL; }
static char *test_q_transfer() { packet *q = q_create(); packet *rq = q_create(); packet p = pkt_create(DATA, 1, 2, 3, 4); packet p2; q_write(p, 0, rq, 4); q_transfer(rq, q, 4); q_read(&p2, 0, q, 4); mu_assert("FAIL: test_q_transfer", (p.x == p2.x) && (p.y == p2.y)); q_destroy(q); q_destroy(rq); return NULL; }
static char *test_q_write() { packet *q = q_create(); packet p = pkt_create(DATA, 1, 2, 3, 4); q_write(p, 0, q, N); mu_assert("FAIL: test_q_write [1]", !q_is_empty(0, 0, q, N)); q_write(p, 0, q, N); mu_assert("FAIL: test_q_write [2]", q_size(0, 0, q, N) == 2); for (int i = 0; i < 14; i++) { q_write(p, 0, q, N); } mu_assert("FAIL: test_q_write [3]", !q_write(p, 0, q, N)); q_destroy(q); return NULL; }
void test_packet_emit(void** state) { uint8_t data[5] = {1,2,3,4,5}; KAD_PACKET* kp = NULL; uint8_t* emit_buf; uint32_t io_bytes = 0; emit_buf = mem_alloc(20); assert_true(pkt_create(data, 5, PACKET_EMIT_TYPE_TCP, KADEMLIA2_PING, &kp)); assert_true(pkt_emit(kp, emit_buf, 20, &io_bytes)); assert_int_equal(7, io_bytes); assert_true(pkt_destroy(kp)); mem_free(emit_buf); }
// Rate limit check: Prevent denial-of-service due to excessive database queries // Make sure owner is responsible for the query! int sm_storage_rate_limit(sm_t sm, const char *owner) { rate_t rt; user_t user; sess_t sess; item_t item; if (sm->query_rate_total == 0 || owner == NULL) return FALSE; user = xhash_get(sm->users, owner); if (user != NULL) { rt = (rate_t) xhash_get(sm->query_rates, owner); if (rt == NULL) { rt = rate_new(sm->query_rate_total, sm->query_rate_seconds, sm->query_rate_wait); xhash_put(sm->query_rates, pstrdup(xhash_pool(sm->query_rates), owner), (void *) rt); pool_cleanup(xhash_pool(sm->query_rates), (void (*)(void *)) rate_free, rt); } if(rate_check(rt) == 0) { log_write(sm->log, LOG_WARNING, "[%s] is being disconnected, too many database queries within %d seconds", owner, sm->query_rate_seconds); user = xhash_get(sm->users, owner); for (sess = user->sessions; sess != NULL; sess = sess->next) { sm_c2s_action(sess, "ended", NULL); } if(xhash_iter_first(user->roster)) do { xhash_iter_get(user->roster, NULL, NULL, (void *) &item); if(item->to) { pkt_router(pkt_create(user->sm, "presence", "unavailable", jid_full(item->jid), jid_full(user->jid))); } } while(xhash_iter_next(user->roster)); return TRUE; } else { rate_add(rt, 1); } } else { log_debug(ZONE, "Error: could not get user data for %s", owner); } return FALSE; }
/* * Create new packet file */ FILE *pkt_open(char *name, Node *node, char *flav, int bsy) { if(name && !name[0]) name = NULL; if(node && !name) /* * Open packet in Binkley outbound */ return pkt_open_node(node, flav, bsy); else { /* * Open packet in FIDOGATE outbound directory or named packet */ pkt_newname(name); return pkt_create( node ? node : cf_uplink() ); } /**NOT REACHED**/ return NULL; }
static void _sess_end_guts(sess_t sess) { sess_t scan; /* fake an unavailable presence from this session, so that modules and externals know we're gone */ if(sess->available || sess->A != NULL) mm_in_sess(sess->user->sm->mm, sess, pkt_create(sess->user->sm, "presence", "unavailable", NULL, NULL)); /* inform the modules */ mm_sess_end(sess->user->sm->mm, sess); /* unlink it from this users sessions */ if(sess->user->sessions == sess) sess->user->sessions = sess->next; else { for(scan = sess->user->sessions; scan != NULL && scan->next != sess; scan = scan->next); if(scan != NULL) scan->next = sess->next; } /* and from global sessions */ xhash_zap(sess->user->sm->sessions, sess->sm_id); }
pkt_t amp_build_response_pkt(pkt_t pkt, amp_rule_t rule) { if (!pkt || !rule) return NULL; if (rule->result == AMP_TRIGGERED) { int ns; pkt_t res = pkt_create(pkt->sm, "message", NULL, jid_full(pkt->from), jid_full(pkt->to)); pkt_id(pkt, res); ns = nad_add_namespace(res->nad, uri_AMP, NULL); nad_append_elem(res->nad, ns, "amp", 2); nad_append_attr(res->nad, -1, "status", rule->action); nad_append_attr(res->nad, -1, "from", jid_full(pkt->from)); nad_append_attr(res->nad, -1, "to", jid_full(pkt->to)); nad_append_elem(res->nad, ns, "rule", 3); nad_append_attr(res->nad, -1, "condition", rule->condition); nad_append_attr(res->nad, -1, "value", rule->value); nad_append_attr(res->nad, -1, "action", rule->action); return res; } return NULL; }
static mod_ret_t _iq_private_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) { module_t mod = mi->mod; int ns, elem, target, targetns; st_ret_t ret; char filter[4096]; os_t os; os_object_t o; nad_t nad; pkt_t result; sess_t sscan; /* only handle private sets and gets */ if((pkt->type != pkt_IQ && pkt->type != pkt_IQ_SET) || pkt->ns != ns_PRIVATE) return mod_PASS; /* we're only interested in no to, to our host, or to us */ if(pkt->to != NULL && jid_compare_user(sess->jid, pkt->to) != 0 && strcmp(sess->jid->domain, jid_user(pkt->to)) != 0) return mod_PASS; ns = nad_find_scoped_namespace(pkt->nad, uri_PRIVATE, NULL); elem = nad_find_elem(pkt->nad, 1, ns, "query", 1); /* find the first child */ target = elem + 1; while(target < pkt->nad->ecur) { if(pkt->nad->elems[target].depth > pkt->nad->elems[elem].depth) break; target++; } /* not found, so we're done */ if(target == pkt->nad->ecur) return -stanza_err_BAD_REQUEST; /* find the target namespace */ targetns = NAD_ENS(pkt->nad, target); /* gotta have a namespace */ if(targetns < 0) { log_debug(ZONE, "no namespace specified"); return -stanza_err_BAD_REQUEST; } log_debug(ZONE, "processing private request for %.*s", NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns)); /* get */ if(pkt->type == pkt_IQ) { #ifdef ENABLE_EXPERIMENTAL /* remember that this resource requested the namespace */ if(sess->module_data[mod->index] == NULL) { /* create new hash if necesary */ sess->module_data[mod->index] = xhash_new(101); pool_cleanup(sess->p, (void (*))(void *) xhash_free, sess->module_data[mod->index]); } xhash_put(sess->module_data[mod->index], pstrdupx(sess->p, NAD_NURI(pkt->nad, targetns), NAD_NURI_L(pkt->nad, targetns)), (void *) 1); #endif snprintf(filter, 4096, "(ns=%i:%.*s)", NAD_NURI_L(pkt->nad, targetns), NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns)); ret = storage_get(sess->user->sm->st, "private", jid_user(sess->jid), filter, &os); switch(ret) { case st_SUCCESS: if(os_iter_first(os)) { o = os_iter_object(os); if(os_object_get_nad(os, o, "xml", &nad)) { result = pkt_new(sess->user->sm, nad_copy(nad)); if(result != NULL) { nad_set_attr(result->nad, 1, -1, "type", "result", 6); pkt_id(pkt, result); pkt_sess(result, sess); pkt_free(pkt); os_free(os); return mod_HANDLED; } } } os_free(os); /* drop through */ log_debug(ZONE, "storage_get succeeded, but couldn't make packet, faking st_NOTFOUND"); case st_NOTFOUND: log_debug(ZONE, "namespace not found, returning"); /* * !!! really, we should just return a 404. 1.4 just slaps a * result on the packet and sends it back. hurrah for * legacy namespaces. */ nad_set_attr(pkt->nad, 1, -1, "type", "result", 6); pkt_sess(pkt_tofrom(pkt), sess); return mod_HANDLED; case st_FAILED: return -stanza_err_INTERNAL_SERVER_ERROR; case st_NOTIMPL: return -stanza_err_FEATURE_NOT_IMPLEMENTED; } } os = os_new(); o = os_object_new(os); snprintf(filter, 4096, "%.*s", NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns)); os_object_put(o, "ns", filter, os_type_STRING); os_object_put(o, "xml", pkt->nad, os_type_NAD); snprintf(filter, 4096, "(ns=%i:%.*s)", NAD_NURI_L(pkt->nad, targetns), NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns)); ret = storage_replace(sess->user->sm->st, "private", jid_user(sess->jid), filter, os); os_free(os); switch(ret) { case st_FAILED: return -stanza_err_INTERNAL_SERVER_ERROR; case st_NOTIMPL: return -stanza_err_FEATURE_NOT_IMPLEMENTED; default: /* create result packet */ result = pkt_create(sess->user->sm, "iq", "result", NULL, NULL); pkt_id(pkt, result); /* and flush it to the session */ pkt_sess(result, sess); #ifdef ENABLE_EXPERIMENTAL /* push it to all resources that read this xmlns item */ snprintf(filter, 4096, "%.*s", NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns)); for(sscan = sess->user->sessions; sscan != NULL; sscan = sscan->next) { /* skip our resource and those that didn't read any private-storage */ if(sscan == sess || sscan->module_data[mod->index] == NULL) continue; /* check whether namespace was read */ if(xhash_get(sscan->module_data[mod->index], filter)) { result = pkt_dup(pkt, jid_full(sscan->jid), NULL); if(result->from != NULL) { jid_free(result->from); nad_set_attr(result->nad, 1, -1, "from", NULL, 0); } pkt_id_new(result); pkt_sess(result, sscan); } } #endif /* finally free the packet */ pkt_free(pkt); return mod_HANDLED; } /* we never get here */ return 0; }
/** main packet dispatcher */ void dispatch(sm_t sm, pkt_t pkt) { user_t user; mod_ret_t ret; /* handle broadcasts */ if(pkt->rtype == route_BROADCAST) { log_debug(ZONE, "can't handle broadcast routes (yet), dropping"); pkt_free(pkt); return; } /* routing errors, add a im error */ if(pkt->rtype & route_ERROR) { int i, aerror, stanza_err; aerror = nad_find_attr(pkt->nad, 0, -1, "error", NULL); stanza_err = stanza_err_REMOTE_SERVER_NOT_FOUND; if(aerror >= 0) { for(i=0; _stanza_errors[i].code != NULL; i++) if(strncmp(_stanza_errors[i].code, NAD_AVAL(pkt->nad, aerror), NAD_AVAL_L(pkt->nad, aerror)) == 0) { stanza_err = stanza_err_BAD_REQUEST + i; break; } } if(pkt_error(pkt, stanza_err) == NULL) return; } /* * - if its from the router (non-route) it goes straight to pkt_router * - hand it to in_router chain * - if its for the sm itself (no user), hand it to the pkt_sm chain * - find the user * - hand to pkt_user */ /* non route packets are special-purpose things from the router */ if(!(pkt->rtype & route_UNICAST)) { ret = mm_pkt_router(pkt->sm->mm, pkt); switch(ret) { case mod_HANDLED: break; case mod_PASS: default: /* don't ever bounce these */ pkt_free(pkt); break; } return; } /* preprocessing */ if (pkt != NULL && pkt->sm != NULL) { ret = mm_in_router(pkt->sm->mm, pkt); switch(ret) { case mod_HANDLED: return; case mod_PASS: break; default: pkt_router(pkt_error(pkt, -ret)); return; } } /* has to come from someone and be directed to someone */ if(pkt->from == NULL || pkt->to == NULL) { pkt_router(pkt_error(pkt, stanza_err_BAD_REQUEST)); return; } /* packet is for the sm itself */ if(*pkt->to->node == '\0') { ret = mm_pkt_sm(pkt->sm->mm, pkt); switch(ret) { case mod_HANDLED: break; case mod_PASS: /* ignore IQ result packets that haven't been handled - XMPP 9.2.3.4 */ if(pkt->type == pkt_IQ_RESULT) { pkt_free(pkt); break; } else ret = -stanza_err_FEATURE_NOT_IMPLEMENTED; default: pkt_router(pkt_error(pkt, -ret)); break; } return; } /* get the user */ user = user_load(sm, pkt->to); if(user == NULL) { if(pkt->type & pkt_PRESENCE && pkt->type != pkt_PRESENCE_PROBE) { pkt_free(pkt); return; } if(pkt->type == pkt_PRESENCE_PROBE) { pkt_router(pkt_create(pkt->sm, "presence", "unsubscribed", jid_full(pkt->from), jid_full(pkt->to))); pkt_free(pkt); return; } pkt_router(pkt_error(pkt, stanza_err_SERVICE_UNAVAILABLE)); return; } if (pkt->sm != NULL) { ret = mm_pkt_user(pkt->sm->mm, user, pkt); switch(ret) { case mod_HANDLED: break; case mod_PASS: /* ignore IQ result packets that haven't been handled - XMPP 9.2.3.4 */ if(pkt->type == pkt_IQ_RESULT) { pkt_free(pkt); break; } else ret = -stanza_err_FEATURE_NOT_IMPLEMENTED; default: pkt_router(pkt_error(pkt, -ret)); break; } } /* if they have no sessions, they were only loaded to do delivery, so free them */ if(user->sessions == NULL) user_free(user); }
/** Send archiving preferences */ void send_arch_prefs(mod_instance_t mi, sess_t sess, pkt_t pkt) { module_t mod = mi->mod; int prefs; int archive=default_mode; int section; int check; char buff[2060]; // 2048 is jid_user maximum length char* ret_str=buff; os_t os = NULL; os_object_t o = NULL; pkt_t reply; // Create a new packet log_debug(ZONE, "Construction of reply with current settings"); reply = pkt_create(sess->user->sm, "iq", "result", NULL, NULL); // Defaults log_debug(ZONE, "Getting defaults"); prefs = nad_append_elem(reply->nad, nad_add_namespace(reply->nad, archive_uri, NULL), "prefs", 2); // Load defaults snprintf(buff, 2060, "(jid=%s)", jid_user(sess->jid)); if((storage_get(sess->user->sm->st, tbl_name "_settings", jid_user(sess->jid), buff, &os) == st_SUCCESS) && (os_iter_first(os)) && ((o=os_iter_object(os))!=NULL)) os_object_get_int(os, o, "setting", &archive); // Set defaults switch(archive) { case A_ALWAYS: nad_set_attr(reply->nad, prefs, -1,"default", "always", 6); break; case A_ROSTER: nad_set_attr(reply->nad, prefs, -1,"default", "roster", 6); break; default: nad_set_attr(reply->nad, prefs, -1,"default", "never", 5); break; } // Cleanup if(o != NULL) { os_object_free(o); o=NULL; } if(os != NULL) { os_free(os); os=NULL; } // Always archiving log_debug(ZONE, "Getting what to archive always"); section = nad_append_elem(reply->nad, -1, "always", 3); if(storage_get(sess->user->sm->st, tbl_name "_settings", jid_user(sess->jid), "(setting=1)", &os) == st_SUCCESS) if(os_iter_first(os)) do { o = os_iter_object(os); if((o != NULL) && (os_object_get_str(os, o, "jid", &ret_str)) && (ret_str != NULL)) { nad_append_elem(reply->nad, -1, "jid", 4); nad_append_cdata(reply->nad, ret_str, strlen(ret_str), 5); } } while(os_iter_next(os)); // Cleanup if(o != NULL) { os_object_free(o); o=NULL; } if(os != NULL) { os_free(os); os=NULL; } // Never archiving log_debug(ZONE, "Getting what to never archive"); section = nad_append_elem(reply->nad, -1, "never", 3); if(storage_get(sess->user->sm->st, tbl_name "_settings", jid_user(sess->jid), "(setting=0)", &os) == st_SUCCESS) if(os_iter_first(os)) do { o = os_iter_object(os); if((o != NULL) && (os_object_get_str(os, o, "jid", &ret_str)) && (ret_str != NULL)) { nad_append_elem(reply->nad, -1, "jid", 4); nad_append_cdata(reply->nad, ret_str, strlen(ret_str), 5); } } while(os_iter_next(os)); // Cleanup if(o != NULL) { os_object_free(o); o=NULL; } if(os != NULL) { os_free(os); os=NULL; } // Send packet pkt_id(pkt, reply); pkt_sess(reply, sess); pkt_free(pkt); }
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 char *test_pkt_set_type() { packet p = pkt_create(REFERENCE, 1, 2, 3, 4); pkt_set_type(&p, ERROR); mu_assert("FAIL: test_pkt_set_type [1]", pkt_get_type(p) == ERROR); return NULL; }
static char *test_pkt_set_sub() { packet p = pkt_create(REFERENCE, 1, 2, 3, 4); pkt_set_sub(&p, 7); mu_assert("FAIL: test_pkt_set_sub [1]", pkt_get_sub(p) == 7); return NULL; }
static char *test_pkt_get_payload() { packet p = pkt_create(REFERENCE, 1, 2, 3, 4); mu_assert("FAIL: test_pkt_get_payload [1]", pkt_get_payload(p) == 4); return NULL; }
static char *test_pkt_get_arg_pos() { packet p = pkt_create(REFERENCE, 1, 2, 3, 4); mu_assert("FAIL: test_pkt_get_arg_pos [1]", pkt_get_arg_pos(p) == 2); return NULL; }
static char *test_pkt_get_source() { packet p = pkt_create(REFERENCE, 1, 2, 3, 4); mu_assert("FAIL: test_pkt_get_source [1]", pkt_get_source(p) == 1); return NULL; }