static int process_resource_list(const char *rl_uri, process_params_t *params) { char *data = NULL; int dsize = 0; int res = 0; list_t *list = NULL; /* DEBUG_LOG("processing resource list\n"); */ /* do an xcap query */ if (xcap_query(rl_uri, params->xcap_params, &data, &dsize) != 0) { ERROR_LOG("XCAP problems for uri \'%s\'\n", rl_uri ? rl_uri: "???"); if (data) cds_free(data); return RES_BAD_GATEWAY_ERR; /* -> 502 Bad GW */ } /* parse query result */ if (parse_list_xml(data, dsize, &list) != 0) { if (data) cds_free(data); return RES_BAD_GATEWAY_ERR; /* -> 502 Bad GW */ } if (data) { cds_free(data); } if (!list) return RES_INTERNAL_ERR; /* ??? */ res = process_list(list, params); if (list) { free_list(list); } return res; }
void free_display_name(display_name_t *n) { if (!n) return; if (n->name) cds_free(n->name); if (n->lang) cds_free(n->lang); cds_free(n); }
int get_msg_rules(const str_t *username, const str_t *filename, xcap_query_params_t *xcap_params, msg_rules_t **dst) { char *data = NULL; int dsize = 0; char *uri = NULL; int res = RES_OK; uri = xcap_uri_for_users_document(xcap_doc_im_rules, username, filename, xcap_params); if (!uri) { /* can't create XCAP uri */ ERROR_LOG("can't build XCAP uri\n"); return RES_XCAP_QUERY_ERR; } res = xcap_query(uri, xcap_params, &data, &dsize); if (res != RES_OK) { DEBUG_LOG("XCAP problems for uri \'%s\'\n", uri); if (data) cds_free(data); cds_free(uri); return RES_XCAP_QUERY_ERR; } cds_free(uri); /* parse input data */ res = parse_msg_rules(data, dsize, dst); if (res != RES_OK) { ERROR_LOG("Error occured during document parsing!\n"); } if (data) cds_free(data); return res; }
void free_entry(entry_t *e) { if (!e) return; if (e->uri) cds_free(e->uri); free_display_names(e->display_names); cds_free(e); }
cds_result cds_slnode_delete_all(cds_slnode **node) { if (*node) { cds_free((*node)->data); cds_free(*node); *node = NULL; return CDS_OK; } else { return CDS_NULL_ARGUMENT; } }
void free_traversed_list(traversed_list_t *list) { traversed_list_t *f, *e; e = list; while (e) { f = e->next; if (e->uri) cds_free(e->uri); cds_free(e); e = f; } }
void free_flat_list(flat_list_t *list) { flat_list_t *f, *e; e = list; while (e) { f = e->next; if (e->uri) cds_free(e->uri); free_display_names(e->names); cds_free(e); e = f; } }
cds_result cds_hash_node_delete(cds_hash_node **node, cds_hash_node_deletion_behavoir db) { if (*node) { if (db & CDS_DELETE_KEY) cds_free((*node)->key); if (db & CDS_DELETE_VALUE) cds_free((*node)->value); cds_free(*node); *node = NULL; return CDS_OK; } else { return CDS_NULL_ARGUMENT; } }
cds_result cds_hash_table_delete(cds_hash_table **table, cds_hash_node_deletion_behavoir db) { if (table && *table) { cds_result cr = cds_hash_table_clear(*table, db); if (cr == CDS_OK) { cds_free((*table)->buckets); cds_free(*table); *table = NULL; } return cr; } else { return CDS_NULL_ARGUMENT; } }
void free_msg_actions(cp_actions_t *a) { cp_unknown_t *u, *nu; if (!a) return; u = a->unknown; while (u) { nu = u->next; cds_free(u); u = nu; } cds_free(a); }
void free_service(service_t *s) { if (!s) return; if (s->uri) cds_free(s->uri); switch (s->content_type) { case stc_list: free_list(s->content.list); break; case stc_resource_list: cds_free(s->content.resource_list); break; } free_packages(s->packages); cds_free(s); }
char *xcap_uri_for_rls_resource(const str_t *xcap_root, const str_t *uri) { dstring_t s; int l; str_t c_uri; char *dst = NULL; if (!xcap_root) return NULL; dstr_init(&s, 2 * xcap_root->len + 32); dstr_append_str(&s, xcap_root); if (xcap_root->s[xcap_root->len - 1] != '/') dstr_append(&s, "/", 1); dstr_append_zt(&s, "rls-services/global/index/~~/rls-services/service[@uri=%22"); canonicalize_uri(uri, &c_uri); dstr_append_str(&s, &c_uri); if (c_uri.s) cds_free(c_uri.s); dstr_append_zt(&s, "%22]"); l = dstr_get_data_length(&s); if (l > 0) { dst = (char *)cds_malloc(l + 1); if (dst) { dstr_get_data(&s, dst); dst[l] = 0; } } dstr_destroy(&s); return dst; }
static cds_result cds_hash_table_resize(cds_hash_table *table) { /** @todo custom growth rates for hash tables */ unsigned int nsize = (table->size) ? table->size * CDS_DEFAULT_HASH_TABLE_GROWTH_MULTIPLIER : CDS_DEFAULT_HASH_TABLE_SIZE; cds_hash_node **buckets = (cds_hash_node **) cds_alloc(nsize * sizeof(cds_hash_node **)); if (buckets) { unsigned int i; for (i = 0; i < nsize; ++i) { buckets[i] = NULL; } cds_result cr; const cds_hash_node *node; for (i = 0; i < table->size; ++i) { for (node = table->buckets[i]; node != NULL; node = node->next) { cr = cds_hash_table_add_internal(buckets, nsize, table->value_cmp_func, table->hash_func, node->key, node->value); if (cr != CDS_OK) return cr; /** @todo do we keep going?? how do we handle this exactly? */ } } cds_free(table->buckets); table->buckets = buckets; table->size = nsize; return CDS_OK; } else { return CDS_BAD_ALLOC; } }
cds_result cds_hash_table_create(cds_hash_table **table, unsigned int size, cds_cmp_func key_cmp, cds_cmp_func val_cmp, cds_hash_func hash_func) { if (table && key_cmp && val_cmp && hash_func) { if (size) { *table = (cds_hash_table *) cds_alloc(sizeof(cds_hash_table)); if (*table) { (*table)->buckets = (cds_hash_node **) cds_alloc(size * sizeof(cds_hash_node **)); if ((*table)->buckets) { unsigned int i; for (i = 0; i < size; ++i) { (*table)->buckets[i] = NULL; } (*table)->hash_func = hash_func; (*table)->key_cmp_func = key_cmp; (*table)->value_cmp_func = val_cmp; (*table)->count = 0; (*table)->size = size; return CDS_OK; } else { cds_free(*table); *table = NULL; return CDS_BAD_ALLOC; } } else { return CDS_BAD_ALLOC; } } else { return CDS_INVALID_ARGUMENT; } } else { return CDS_NULL_ARGUMENT; } }
void vector_destroy(vector_t *vector) { if (vector) { if (vector->data) cds_free(vector->data); vector->data = NULL; vector->allocation_count = 0; vector->element_count = 0; } }
static int process_entry_ref(entry_ref_t *entry_ref, process_params_t *params) { char *data = NULL; int dsize = 0; entry_t *entry = NULL; char *xcap_uri; int res; /* DEBUG_LOG("processing entry-ref with ref \'%s\'\n", STR_OK(entry_ref->ref)); */ if (!entry_ref) return RES_OK; if (!entry_ref->ref) return RES_OK; if (add_uri_to_traversed(params, entry_ref->ref) != 0) { /* It is existing yet? */ ERROR_LOG("Duplicate URI in traversed set\n"); return RES_BAD_GATEWAY_ERR; /* 502 Bad GW */ } /* XCAP query for the ref uri */ xcap_uri = relative2absolute_uri(params->xcap_root, entry_ref->ref); res = xcap_query(xcap_uri, params->xcap_params, &data, &dsize); if (res != 0) { ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri ? xcap_uri: "???"); if (data) cds_free(data); if (xcap_uri) cds_free(xcap_uri); return RES_BAD_GATEWAY_ERR; /* 502 Bad GW */ } if (xcap_uri) cds_free(xcap_uri); /* parse document as an entry element */ if (parse_entry_xml(data, dsize, &entry) != 0) { ERROR_LOG("Parsing problems!\n"); if (entry) free_entry(entry); if (data) cds_free(data); return RES_BAD_GATEWAY_ERR; /* 502 Bad GW */ } if (data) cds_free(data); if (!entry) return RES_INTERNAL_ERR; /* ??? */ res = process_entry(entry, params); free_entry(entry); return res; }
static int process_external(external_t *external, process_params_t *params) { char *data = NULL; int dsize = 0; list_t *list = NULL; int res; /* DEBUG_LOG("processing external with anchor \'%s\'\n", STR_OK(external->anchor)); */ if (!external) return RES_OK; if (!external->anchor) return RES_OK; if (add_uri_to_traversed(params, external->anchor) != 0) { /* It is existing yet? */ ERROR_LOG("Duplicate URI in traversed set\n"); return RES_BAD_GATEWAY_ERR; /* 502 Bad GW */ } /* XCAP query for the ref uri */ res = xcap_query(external->anchor, params->xcap_params, &data, &dsize); if (res != 0) { ERROR_LOG("XCAP problems for uri \'%s\'\n", external->anchor ? external->anchor: "???"); if (data) cds_free(data); return RES_BAD_GATEWAY_ERR; /* 502 Bad GW */ } /* parse document as an entry element */ if (parse_list_xml(data, dsize, &list) != 0) { ERROR_LOG("Parsing problems!\n"); if (list) free_list(list); if (data) cds_free(data); return RES_BAD_GATEWAY_ERR; /* 502 Bad GW */ } if (data) cds_free(data); if (!list) return RES_INTERNAL_ERR; /* ??? */ res = process_list(list, params); free_list(list); return res; }
static void free_packages(packages_t *p) { package_t *e, *f; if (!p) return; e = SEQUENCE_FIRST(p->package); while (e) { f = SEQUENCE_NEXT(e); free_package(e); e = f; } cds_free(p); }
void free_resource_lists(resource_lists_t *rl) { list_t *e, *f; if (!rl) return; e = SEQUENCE_FIRST(rl->lists); while (e) { f = SEQUENCE_NEXT(e); free_list(e); e = f; } cds_free(rl); }
void free_rls_services(rls_services_t *rls) { service_t *e, *f; if (!rls) return; e = SEQUENCE_FIRST(rls->rls_services); while (e) { f = SEQUENCE_NEXT(e); free_service(e); e = f; } cds_free(rls); }
void free_list(list_t *l) { list_content_t *e, *f; if (!l) return; if (l->name) cds_free(l->name); e = SEQUENCE_FIRST(l->content); while (e) { switch (e->type) { case lct_list: free_list(e->u.list); break; case lct_entry: free_entry(e->u.entry); break; case lct_entry_ref: free_entry_ref(e->u.entry_ref); break; case lct_external: free_external(e->u.external); break; } f = e; e = SEQUENCE_NEXT(e); /* TRACE_LOG("freeing %p\n", f); */ cds_free(f); } cds_free(l); }
void qsa_cleanup() { if (init) { if (--init->init_cnt == 0) { DEBUG_LOG("cleaning the content\n"); /* !!! put the real destruction here !!! */ if (init->dm) destroy_domain_maintainer(init->dm); cds_free(init); init = NULL; } } }
void destroy_domain_maintainer(domain_maintainer_t *dm) { int i, cnt; notifier_domain_t *d; if (!dm) return; DEBUG_LOG("destroying domain maintainer\n"); cnt = ptr_vector_size(&dm->registered_domains); for (i = 0; i < cnt; i++) { d = ptr_vector_get(&dm->registered_domains, i); if (!d) continue; if (remove_reference(&d->ref)) { DEBUG_LOG("freeing domain: \'%.*s\'\n", FMT_STR(d->name)); destroy_notifier_domain(d); } } ptr_vector_destroy(&dm->registered_domains); cds_mutex_destroy(&dm->mutex); cds_free(dm); }
int vector_add(vector_t *vector, void *element) { if (vector->element_count >= vector->allocated_count) { void *new_data; int new_size = vector->allocated_count + vector->allocation_count; if (new_size <= vector->allocated_count) return -1; new_data = (void *)cds_malloc(vector->element_size * new_size); if (!new_data) return -1; if (vector->data) { memcpy(new_data, vector->data, vector->element_size * vector->allocated_count); cds_free(vector->data); } vector->data = new_data; vector->allocated_count = new_size; } memcpy(vector->data + (vector->element_count * vector->element_size), element, vector->element_size); vector->element_count++; return 0; }
int get_rls_from_full_doc(const str_t *uri, /* const str_t *filename, */ xcap_query_params_t *xcap_params, const str_t *package, flat_list_t **dst) { char *data = NULL; int dsize = 0; rls_services_t *rls = NULL; service_t *service = NULL; str_t curi; int res; char *xcap_uri = NULL; str_t *filename = NULL; if (!dst) return RES_INTERNAL_ERR; /* get basic document */ xcap_uri = xcap_uri_for_global_document(xcap_doc_rls_services, filename, xcap_params); if (!xcap_uri) { ERROR_LOG("can't get XCAP uri\n"); return -1; } res = xcap_query(xcap_uri, xcap_params, &data, &dsize); if (res != 0) { ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri); if (data) { cds_free(data); } cds_free(xcap_uri); return RES_XCAP_QUERY_ERR; } cds_free(xcap_uri); /* parse document as a service element in rls-sources */ if (parse_rls_services_xml(data, dsize, &rls) != 0) { ERROR_LOG("Parsing problems!\n"); if (rls) free_rls_services(rls); if (data) { cds_free(data); } return RES_XCAP_PARSE_ERR; } /* DEBUG_LOG("%.*s\n", dsize, data);*/ if (data) cds_free(data); /* try to find given service according to uri */ canonicalize_uri(uri, &curi); service = find_service(rls, &curi); if (!service) DEBUG_LOG("Service %.*s not found!\n", FMT_STR(curi)); str_free_content(&curi); if (!service) { if (rls) free_rls_services(rls); return RES_XCAP_QUERY_ERR; } /* verify the package */ if (verify_package(service, package) != 0) { free_rls_services(rls); return RES_BAD_EVENT_PACKAGE_ERR; } /* create flat document */ res = create_flat_list(service, xcap_params, dst); if (res != RES_OK) { ERROR_LOG("Flat list creation error\n"); free_rls_services(rls); free_flat_list(*dst); *dst = NULL; return res; } free_rls_services(rls); return RES_OK; }
static int rls_generate_notify_ext(rl_subscription_t *s, int full_info) { /* !!! the main mutex must be locked here !!! */ int res; str doc; dstring_t dstr; str headers, content_type; static str method = STR_STATIC_INIT(METHOD_NOTIFY); dlg_t *dlg; int exp_time = 0; char expiration[32]; str body = STR_STATIC_INIT(""); int removed = 0; dlg = s->u.external.dialog; if (!dlg) return -1; DEBUG("generating external notify\n"); str_clear(&doc); str_clear(&content_type); if (sm_subscription_pending(&s->u.external) != 0) { /* create the document only for non-pending subscriptions */ if (create_rlmi_document(&doc, &content_type, s, full_info) != 0) { return -1; } } exp_time = sm_subscription_expires_in(rls_manager, &s->u.external); sprintf(expiration, ";expires=%d\r\n", exp_time); dstr_init(&dstr, 256); dstr_append_zt(&dstr, "Subscription-State: "); switch (s->u.external.status) { case subscription_active: dstr_append_zt(&dstr, "active"); dstr_append_zt(&dstr, expiration); break; case subscription_pending: dstr_append_zt(&dstr, "pending"); dstr_append_zt(&dstr, expiration); break; case subscription_terminated_pending: case subscription_terminated: dstr_append_zt(&dstr, "terminated\r\n"); break; case subscription_terminated_pending_to: case subscription_terminated_to: dstr_append_zt(&dstr, "terminated;reason=timeout\r\n"); break; case subscription_uninitialized: dstr_append_zt(&dstr, "pending\r\n"); /* this is an error ! */ LOG(L_ERR, "sending NOTIFY for an unitialized subscription!\n"); break; } dstr_append_str(&dstr, &s->u.external.contact); /* required by RFC 3261 */ dstr_append_zt(&dstr, "Max-Forwards: 70\r\n"); dstr_append_zt(&dstr, "Event: "); dstr_append_str(&dstr, rls_get_package(s)); dstr_append_zt(&dstr, "\r\n"); dstr_append_zt(&dstr, "Require: eventlist\r\nContent-Type: "); dstr_append_str(&dstr, &content_type); dstr_append_zt(&dstr, "\r\n"); res = dstr_get_str(&dstr, &headers); dstr_destroy(&dstr); if (res >= 0) { /* DEBUG("sending NOTIFY message to %.*s (subscription %p)\n", dlg->rem_uri.len, ZSW(dlg->rem_uri.s), s); */ if (!is_str_empty(&doc)) body = doc; if (sm_subscription_terminated(&s->u.external) == 0) { /* doesn't matter if delivered or not, it will be freed otherwise !!! */ res = tmb.t_request_within(&method, &headers, &body, dlg, 0, 0); if (res >= 0) clear_change_flags(s); } else { rls_notify_cb_param_t *cbd = create_notify_cb_param(s); if (!cbd) { ERR("Can't create notify cb data! Freeing RL subscription.\n"); rls_remove(s); /* ?????? */ removed = 1; res = -13; } else { /* the subscritpion will be destroyed if NOTIFY delivery problems */ /* rls_unlock(); the callback locks this mutex ! */ /* !!!! FIXME: callbacks can't be safely used (may be called or not, * may free memory automaticaly or not) !!! */ res = tmb.t_request_within(&method, &headers, &body, dlg, rls_notify_cb, cbd); /* res = tmb.t_request_within(&method, &headers, &body, dlg, rls_notify_cb, s); */ /* rls_lock(); the callback locks this mutex ! */ if (res < 0) { /* does this mean, that the callback was not called ??? */ ERR("t_request_within FAILED: %d! Freeing RL subscription.\n", res); rls_remove(s); /* ?????? */ removed = 1; } else clear_change_flags(s); } } } if (doc.s) cds_free(doc.s); if (content_type.s) cds_free(content_type.s); if (headers.s) cds_free(headers.s); if ((!removed) && use_db) rls_db_update(s); if (res < 0) DEBUG("external notify NOT generated\n"); else DEBUG("external notify generated\n"); return res; }
void free_external(external_t *e) { if (!e) return; if (e->anchor) cds_free(e->anchor); cds_free(e); }
int get_rls(const str_t *uri, xcap_query_params_t *xcap_params, const str_t *package, flat_list_t **dst) { char *data = NULL; int dsize = 0; service_t *service = NULL; char *xcap_uri = NULL; str_t *filename = NULL; int res; if (!dst) return RES_INTERNAL_ERR; /* get basic document */ xcap_uri = xcap_uri_for_global_document(xcap_doc_rls_services, filename, xcap_params); if (!xcap_uri) { ERROR_LOG("can't get XCAP uri\n"); return RES_XCAP_QUERY_ERR; } res = xcap_query(xcap_uri, xcap_params, &data, &dsize); if (res != 0) { ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri); if (data) { cds_free(data); } cds_free(xcap_uri); return RES_XCAP_QUERY_ERR; } cds_free(xcap_uri); /* parse document as a service element in rls-sources */ if (parse_service(data, dsize, &service) != 0) { ERROR_LOG("Parsing problems!\n"); if (service) free_service(service); if (data) { cds_free(data); } return RES_XCAP_PARSE_ERR; } /* DEBUG_LOG("%.*s\n", dsize, data);*/ if (data) cds_free(data); if (!service) { DEBUG_LOG("Empty service!\n"); return RES_XCAP_QUERY_ERR; } /* verify the package */ if (verify_package(service, package) != 0) { free_service(service); return RES_BAD_EVENT_PACKAGE_ERR; } /* create flat document */ res = create_flat_list(service, xcap_params, dst); if (res != RES_OK) { ERROR_LOG("Flat list creation error\n"); free_service(service); free_flat_list(*dst); *dst = NULL; return res; } free_service(service); return RES_OK; }
/* catches and processes user's resource list as rls-services document */ int get_resource_list_from_full_doc(const str_t *user, const str_t *filename, xcap_query_params_t *xcap_params, const char *list_name, flat_list_t **dst) { char *data = NULL; int dsize = 0; service_t *service = NULL; list_t *list = NULL, *right = NULL; int res; char *uri = NULL; if (!dst) return RES_INTERNAL_ERR; /* get basic document */ uri = xcap_uri_for_users_document(xcap_doc_resource_lists, user, filename, xcap_params); if (!uri) { ERROR_LOG("can't get XCAP uri\n"); return -1; } DEBUG_LOG("XCAP uri \'%s\'\n", uri); res = xcap_query(uri, xcap_params, &data, &dsize); if (res != 0) { ERROR_LOG("XCAP problems for uri \'%s\'\n", uri); if (data) { cds_free(data); } cds_free(uri); return RES_XCAP_QUERY_ERR; } cds_free(uri); /* parse document as a list element in resource-lists */ if (parse_as_list_content_xml(data, dsize, &list) != 0) { ERROR_LOG("Parsing problems!\n"); if (list) free_list(list); if (data) { cds_free(data); } return RES_XCAP_PARSE_ERR; } /* DEBUG_LOG("%.*s\n", dsize, data);*/ if (data) cds_free(data); /* rs -> list */ if (!list) { ERROR_LOG("Empty resource list!\n"); *dst = NULL; return 0; /* this is not error! */ /* return RES_INTERNAL_ERR; */ } /* search for right list element */ right = find_list(list, list_name); service = (service_t*)cds_malloc(sizeof(*service)); if (!service) { ERROR_LOG("Can't allocate memory!\n"); return RES_MEMORY_ERR; } memset(service, 0, sizeof(*service)); service->content_type = stc_list; service->content.list = right; /*service->uri = ??? */ /* create flat document */ res = create_flat_list(service, xcap_params, dst); service->content.list = list; /* free whole document not only "right" list */ free_service(service); if (res != RES_OK) { ERROR_LOG("Flat list creation error\n"); free_flat_list(*dst); *dst = NULL; return res; } return RES_OK; }
void free_entry_ref(entry_ref_t *e) { if (!e) return; if (e->ref) cds_free(e->ref); cds_free(e); }