瀏覽代碼

corrected some bugs in libraries and added some functions
modified RLS processing - separated XCAP query and subscription handling, added some functions for that, improved debugging
improved PA and PRESENCE_B2B debugging

Vaclav Kubart 19 年之前
父節點
當前提交
72048db6f6

+ 2 - 1
lib/cds/logger.h

@@ -43,7 +43,8 @@
 
 #define ERROR_LOG(a,args...)		ERR(a,##args)
 #define DEBUG_LOG(a,args...)		DBG(a,##args)
-#define TRACE_LOG(a,args...)		DBG(a,##args)
+/* #define TRACE_LOG(a,args...)		ERR(a,##args) */
+#define TRACE_LOG(fmt, args...)     LOG(L_ERR, "TRACE: "  LOC_INFO fmt, ##args)
 #define WARN_LOG(a,args...)			WARN(a,##args)
 #define FLUSH_LOG()					do{}while(0)
 

+ 46 - 1
lib/cds/sstr.c

@@ -25,9 +25,11 @@
 
 #include <cds/sstr.h>
 #include <cds/memory.h>
+#include <cds/dstring.h>
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
+#include <cds/logger.h>
 
 /** returns 1 if the string is empty */
 int is_str_empty(const str_t *s)
@@ -216,7 +218,7 @@ char *str_str(const str_t *s, const str_t *search_for)
 		if (s->s[i] == search_for->s[j]) {
 			j++;
 			i++;
-			if (i == search_for->len) return s->s + i - j;
+			if (j == search_for->len) return s->s + i - j;
 		}
 		else {
 			i = i - j + 1;
@@ -256,3 +258,46 @@ int str_concat(str_t *dst, str_t *a, str_t *b)
 	
 	return 0;
 }
+
+int replace_str(const str_t *src, str_t *dst, const str_t *sample, const str_t *value)
+{
+	str_t s;
+	char *c;
+	dstring_t str;
+	int res, len;
+	
+	/* if (!dst) return -1;
+	 if (!src) {
+		str_clear(dst);
+		return -1; 
+	} */
+
+	if (is_str_empty(sample)) {
+		str_clear(dst);
+		return -1;
+	}
+
+	if (is_str_empty(src)) {
+		str_clear(dst);
+		return 0;
+	}
+	
+	s = *src;
+	dstr_init(&str, src->len + 32);
+	do {
+		c = str_str(&s, sample);
+		if (c) {
+			len = c - s.s;
+			dstr_append(&str, s.s, len);
+			dstr_append_str(&str, value);
+			s.len = s.len - len - sample->len;
+			s.s = c + sample->len;
+			if (s.len <= 0) break;
+		}
+		else dstr_append_str(&str, &s);
+	} while (c);
+	
+	res = dstr_get_str(&str, dst);
+	dstr_destroy(&str);
+	return res;
+}

+ 2 - 0
lib/cds/sstr.h

@@ -108,6 +108,8 @@ char *str_str(const str_t *s, const str_t *search_for);
 /* creates new string as concatenation of a and b */
 int str_concat(str_t *dst, str_t *a, str_t *b);
 
+int replace_str(const str_t *src, str_t *dst, const str_t *sample, const str_t *value);
+
 #ifdef __cplusplus
 }
 #endif

+ 36 - 6
lib/presence/notifier_domain.c

@@ -33,8 +33,19 @@
 #include <cds/list.h>
 #include <cds/cds.h>
 
-#define lock_subscription_data(s) if (s->mutex) cds_mutex_lock(s->mutex);
-#define unlock_subscription_data(s) if (s->mutex) cds_mutex_unlock(s->mutex);
+/*#define lock_subscription_data(s) if (s->mutex) cds_mutex_lock(s->mutex);
+#define unlock_subscription_data(s) if (s->mutex) cds_mutex_unlock(s->mutex);*/
+
+static void lock_subscription_data(subscription_t *s)
+{
+	/* is function due to debugging */
+	if (s->mutex) cds_mutex_lock(s->mutex);
+}
+
+static void unlock_subscription_data(subscription_t *s) {
+	/* is function due to debugging */
+	if (s->mutex) cds_mutex_unlock(s->mutex);
+}
 
 static void free_notifier(notifier_t *info);
 static void free_subscription(subscription_t *s);
@@ -71,7 +82,11 @@ static notifier_package_t *create_package(const str_t *name)
 		p->next = NULL;
 		p->prev = NULL;
 		p->domain = NULL;
-		str_dup(&p->name, name);
+		if (str_dup(&p->name, name) < 0) {
+			cds_free(p);
+			ERROR_LOG("can't allocate memory\n");
+			return NULL;
+		}
 	}
 	return p;
 }
@@ -173,7 +188,11 @@ notifier_domain_t *create_notifier_domain(const str_t *name)
 	if (d) {
 		d->first_package = NULL;
 		d->last_package = NULL;
-		str_dup(&d->name, name);
+		if (str_dup(&d->name, name) < 0) {
+			cds_free(d);
+			ERROR_LOG("can't allocate memory\n");
+			return NULL;
+		}
 		cds_mutex_init(&d->mutex);
 		cds_mutex_init(&d->data_mutex);
 		init_reference_counter(&d->ref);
@@ -301,6 +320,7 @@ subscription_t *subscribe(notifier_domain_t *domain,
 	notifier_t *e;
 	notifier_package_t *p;
 	int cnt = 0;
+	int res;
 
 	lock_notifier_domain(domain);
 	p = get_package(domain, package);
@@ -313,6 +333,7 @@ subscription_t *subscribe(notifier_domain_t *domain,
 	s = cds_malloc(sizeof(subscription_t));
 	if (!s) {
 		ERROR_LOG("can't allocate memory\n");
+		unlock_notifier_domain(domain);
 		return s;
 	}
 
@@ -320,8 +341,17 @@ subscription_t *subscribe(notifier_domain_t *domain,
 	s->dst = dst;
 	s->mutex = &domain->data_mutex;
 	s->subscriber_data = subscriber_data;
-	str_dup(&s->record_id, record_id);
-	str_dup(&s->subscriber_id, subscriber_id);
+	res = str_dup(&s->record_id, record_id);
+	if (res == 0) res = str_dup(&s->subscriber_id, subscriber_id);
+	else str_clear(&s->subscriber_id);
+	if (res != 0) {
+		str_free_content(&s->record_id);
+		str_free_content(&s->subscriber_id);
+		cds_free(s);
+		ERROR_LOG("can't allocate memory\n");
+		unlock_notifier_domain(domain);
+		return NULL;
+	}
 	init_reference_counter(&s->ref);
 
 	DOUBLE_LINKED_LIST_ADD(p->first_subscription, p->last_subscription, s);

+ 18 - 6
lib/presence/pidf.c

@@ -327,6 +327,9 @@ static int read_tuple(xmlNode *tuple, presence_tuple_info_t **dst, int ignore_ns
 
 static int get_whole_node_content(xmlNode *n, str_t *dst, xmlDocPtr doc)
 {
+	int res = 0;
+
+	str_clear(dst);
 	if (n) {
 		n = xmlCopyNode(n, 1); /* this inserts namespaces into element correctly */
 		if (!n) {
@@ -341,17 +344,17 @@ static int get_whole_node_content(xmlNode *n, str_t *dst, xmlDocPtr doc)
 			ERROR_LOG("Error creating the xml buffer\n");
 			return -1;
 		}
-		xmlNodeDump(buf, doc, n, 0, 0);
-		if (buf->use > 0) {
+		if (xmlNodeDump(buf, doc, n, 0, 0) < 0) res = -1;
+		if ((res == 0) && (buf->use > 0)) {
 			str_t s;
 			s.s = (char *)buf->content;
 			s.len = buf->use;
-			str_dup(dst, &s);
+			res = str_dup(dst, &s);
 		}
 		xmlBufferFree(buf);
 		xmlFreeNode(n); /* was duplicated due to namespaces! */
 	}
-	return 0;
+	return res;
 }
 
 static int read_person(xmlNode *person, person_t **dst, xmlDocPtr doc)
@@ -370,7 +373,11 @@ static int read_person(xmlNode *person, person_t **dst, xmlDocPtr doc)
 
 	TRACE_LOG("reading person ()\n");
 	
-	str_dup_zt(&p->id, get_attr_value(find_attr(person->properties, "id")));
+	if (str_dup_zt(&p->id, get_attr_value(find_attr(person->properties, "id"))) < 0) {
+		cds_free(p);
+		*dst = NULL;
+		return -1;
+	}
 	
 	/* try to find mood */
 /*	n = find_node(person, "mood", rpid_ns);
@@ -381,7 +388,12 @@ static int read_person(xmlNode *person, person_t **dst, xmlDocPtr doc)
 	if (n) get_whole_node_content(n, &p->activities, doc);
 */
 	/* do not care about internals of person - take whole element ! */
-	get_whole_node_content(person, &p->person_element, doc);
+	if (get_whole_node_content(person, &p->person_element, doc) != 0) {
+		str_free_content(&p->id);
+		cds_free(p);
+		*dst = NULL;
+		return -1;
+	}
 	
 	return 0;
 }

+ 16 - 7
lib/presence/xml_utils.c

@@ -34,23 +34,32 @@
 
 int xml_parser_flags = XML_PARSE_NOERROR | XML_PARSE_NOWARNING;
 
-static void str2int(const char *s, int *dst)
+static int str2int(const char *s, int *dst)
 {
 	/* if not null sets the given integer to value */
-	if (!s) return;
+	if (!s) {
+		*dst = 0;
+		return -1;
+	}
 	else *dst = atoi(s);
+	return 0;
 }
 
-void get_int_attr(xmlNode *n, const char *attr_name, int *dst)
+int get_int_attr(xmlNode *n, const char *attr_name, int *dst)
 {
-	str2int(get_attr_value(find_attr(n->properties, attr_name)), dst);
+	const char *s = get_attr_value(find_attr(n->properties, attr_name));
+	if (!s) return 1;
+	return str2int(s, dst);
 }
 
-void get_str_attr(xmlNode *n, const char *attr_name, str_t *dst)
+int get_str_attr(xmlNode *n, const char *attr_name, str_t *dst)
 {
 	const char *s = get_attr_value(find_attr(n->properties, attr_name));
-	if (!s) str_clear(dst);
-	else str_dup_zt(dst, s);
+	if (!s) {
+		str_clear(dst);
+		return 1;
+	}
+	else return str_dup_zt(dst, s);
 }
 
 int xmlstrcmp(const xmlChar *xmls, const char *name)

+ 25 - 21
lib/xcap/parse_pres_rules.c

@@ -76,7 +76,7 @@ static int read_actions(xmlNode *an, cp_actions_t **dst)
 	if ((!an) || (!dst)) return RES_INTERNAL_ERR;
 	
 	*dst = (cp_actions_t*)cds_malloc(sizeof(cp_actions_t));
-	if (!dst) return RES_MEMORY_ERR;
+	if (!(*dst)) return RES_MEMORY_ERR;
 	memset(*dst, 0, sizeof(cp_actions_t));
 
 	n = find_node(an, "sub-handling", common_policy_ns);
@@ -94,7 +94,8 @@ static int read_actions(xmlNode *an, cp_actions_t **dst)
 static int read_sphere(xmlNode *n, cp_sphere_t **dst)
 {
 	*dst = (cp_sphere_t*)cds_malloc(sizeof(cp_sphere_t));
-	if (!*dst) return RES_MEMORY_ERR;
+	if (!(*dst)) return RES_MEMORY_ERR;
+	memset(*dst, 0, sizeof(**dst));
 	(*dst)->next = NULL;
 	
 	str_dup_zt(&(*dst)->value, get_node_value(n));
@@ -105,7 +106,8 @@ static int read_validity(xmlNode *n, cp_validity_t **dst)
 {
 	const char *from, *to;
 	*dst = (cp_validity_t*)cds_malloc(sizeof(cp_validity_t));
-	if (!*dst) return RES_MEMORY_ERR;
+	if (!(*dst)) return RES_MEMORY_ERR;
+	memset(*dst, 0, sizeof(**dst));
 	
 	from = get_node_value(find_node(n, "from", common_policy_ns));
 	to = get_node_value(find_node(n, "to", common_policy_ns));
@@ -118,7 +120,8 @@ static int read_validity(xmlNode *n, cp_validity_t **dst)
 static int read_id(xmlNode *n, cp_id_t **dst)
 {
 	*dst = (cp_id_t*)cds_malloc(sizeof(cp_id_t));
-	if (!*dst) return RES_MEMORY_ERR;
+	if (!(*dst)) return RES_MEMORY_ERR;
+	memset(*dst, 0, sizeof(**dst));
 	(*dst)->next = NULL;
 	
 	get_str_attr(n, "entity", &(*dst)->entity);
@@ -133,7 +136,8 @@ static int read_id(xmlNode *n, cp_id_t **dst)
 static int read_domain(xmlNode *n, cp_domain_t **dst)
 {
 	*dst = (cp_domain_t*)cds_malloc(sizeof(cp_domain_t));
-	if (!*dst) return RES_MEMORY_ERR;
+	if (!(*dst)) return RES_MEMORY_ERR;
+	memset(*dst, 0, sizeof(**dst));
 	(*dst)->next = NULL;
 	
 	get_str_attr(n, "domain", &(*dst)->domain);
@@ -143,7 +147,8 @@ static int read_domain(xmlNode *n, cp_domain_t **dst)
 static int read_except(xmlNode *n, cp_except_t **dst)
 {
 	*dst = (cp_except_t*)cds_malloc(sizeof(cp_except_t));
-	if (!*dst) return RES_MEMORY_ERR;
+	if (!(*dst)) return RES_MEMORY_ERR;
+	memset(*dst, 0, sizeof(**dst));
 	(*dst)->next = NULL;
 	
 	get_str_attr(n, "entity", &(*dst)->entity);
@@ -154,6 +159,7 @@ static int read_except_domain(xmlNode *n, cp_except_domain_t **dst)
 {
 	*dst = (cp_except_domain_t*)cds_malloc(sizeof(cp_except_domain_t));
 	if (!*dst) return RES_MEMORY_ERR;
+	memset(*dst, 0, sizeof(**dst));
 	(*dst)->next = NULL;
 	
 	get_str_attr(n, "domain", &(*dst)->domain);
@@ -169,6 +175,7 @@ static int read_any_identity(xmlNode *an, cp_any_identity_t **dst)
 	
 	*dst = (cp_any_identity_t*)cds_malloc(sizeof(cp_any_identity_t));
 	if (!*dst) return RES_MEMORY_ERR;
+	memset(*dst, 0, sizeof(**dst));
 	
 	n = an->children;
 	while (n) {
@@ -240,7 +247,7 @@ static int read_conditions(xmlNode *cn, cp_conditions_t **dst)
 	if ((!cn) || (!dst)) return RES_INTERNAL_ERR;
 	
 	*dst = (cp_conditions_t*)cds_malloc(sizeof(cp_conditions_t));
-	if (!dst) return RES_MEMORY_ERR;
+	if (!(*dst)) return RES_MEMORY_ERR;
 	memset(*dst, 0, sizeof(cp_conditions_t));
 	
 	n = cn->children;
@@ -280,7 +287,7 @@ static int read_transformations(xmlNode *tn, cp_transformations_t **dst)
 	if ((!tn) || (!dst)) return RES_INTERNAL_ERR;
 	
 	*dst = (cp_transformations_t*)cds_malloc(sizeof(cp_transformations_t));
-	if (!dst) return RES_MEMORY_ERR;
+	if (!*dst) return RES_MEMORY_ERR;
 	memset(*dst, 0, sizeof(cp_transformations_t));
 
 	DEBUG_LOG("transformations for pres_rules not used\n");
@@ -295,30 +302,27 @@ static int read_rule(xmlNode *rn, cp_rule_t **dst)
 	if ((!rn) || (!dst)) return RES_INTERNAL_ERR;
 	
 	*dst = (cp_rule_t*)cds_malloc(sizeof(cp_rule_t));
-	if (!dst) return RES_MEMORY_ERR;
+	if (!*dst) return RES_MEMORY_ERR;
 	memset(*dst, 0, sizeof(cp_rule_t));
 
 	get_str_attr(rn, "id", &(*dst)->id);
 
 	n = find_node(rn, "actions", common_policy_ns);
-	if (n) {
-		res = read_actions(n, &(*dst)->actions);
-		if (res != 0) return res;
-	}
+	if (n && (res == 0)) res = read_actions(n, &(*dst)->actions);
 	
 	n = find_node(rn, "conditions", common_policy_ns);
-	if (n) {
-		res = read_conditions(n, &(*dst)->conditions);
-		if (res != 0) return res;
-	}
+	if (n && (res == 0)) res = read_conditions(n, &(*dst)->conditions);
 	
 	n = find_node(rn, "transformations", common_policy_ns);
-	if (n) {
-		res = read_transformations(n, &(*dst)->transformations);
-		if (res != 0) return res;
+	if (n && (res == 0)) res = read_transformations(n, &(*dst)->transformations);
+	
+	if (res != 0) {
+		free_rule(*dst);
+		*dst = NULL;
+		return res;
 	}
 
-	return res;
+	return 0;
 }
 
 static int read_pres_rules(xmlNode *root, cp_ruleset_t **dst)

+ 1 - 1
lib/xcap/pres_rules.c

@@ -326,7 +326,7 @@ static void free_transformations(cp_transformations_t *t)
 	cds_free(t);
 }
 
-static void free_rule(cp_rule_t *r)
+void free_rule(cp_rule_t *r)
 {
 	if (!r) return;
 	if (r->conditions) free_conditions(r->conditions);

+ 1 - 0
lib/xcap/pres_rules.h

@@ -43,6 +43,7 @@ typedef enum {
 char *xcap_uri_for_pres_rules(const char *xcap_root, const str_t *uri);
 int get_pres_rules(const char *xcap_root, const str_t *uri, xcap_query_t *xcap_params, cp_ruleset_t **dst);
 void free_pres_rules(cp_ruleset_t *r);
+void free_rule(cp_rule_t *r);
 
 /* returns 0 if rule found, 1 if not found and -1 on error */
 int get_pres_rules_action(cp_ruleset_t *r, const str_t *wuri, sub_handling_t *dst_action);

+ 57 - 29
lib/xcap/resource_list.c

@@ -45,7 +45,7 @@ typedef struct _traversed_list_t {
 } traversed_list_t;
 
 typedef struct {
-	const char *xcap_root;
+	const str_t *xcap_root;
 	xcap_query_t *xcap_params;
 	traversed_list_t *traversed;
 	traversed_list_t *traversed_last;
@@ -78,7 +78,7 @@ void canonicalize_uri(const str_t *uri, str_t *dst)
 	/* DEBUG_LOG("canonicalized uri: \'%.*s\'\n", dst->len, dst->s); */
 }
 
-char *xcap_uri_for_rls_resource(const char *xcap_root, const str_t *uri)
+char *xcap_uri_for_rls_resource(const str_t *xcap_root, const str_t *uri)
 {
 	dstring_t s;
 	int l;
@@ -86,10 +86,9 @@ char *xcap_uri_for_rls_resource(const char *xcap_root, const str_t *uri)
 	char *dst = NULL;
 
 	if (!xcap_root) return NULL;
-	l = strlen(xcap_root);
-	dstr_init(&s, 2 * l + 32);
-	dstr_append(&s, xcap_root, l);
-	if (xcap_root[l - 1] != '/') dstr_append(&s, "/", 1);
+	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);
@@ -108,17 +107,16 @@ char *xcap_uri_for_rls_resource(const char *xcap_root, const str_t *uri)
 	return dst;
 }
 
-char *xcap_uri_for_rls_services(const char *xcap_root)
+char *xcap_uri_for_rls_services(const str_t *xcap_root)
 {
 	dstring_t s;
 	int l;
 	char *dst = NULL;
 
 	if (!xcap_root) return NULL;
-	l = strlen(xcap_root);
-	dstr_init(&s, 2 * l + 32);
-	dstr_append(&s, xcap_root, l);
-	if (xcap_root[l - 1] != '/') dstr_append(&s, "/", 1);
+	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");
 	
 	l = dstr_get_data_length(&s);
@@ -160,7 +158,7 @@ void free_traversed_list(traversed_list_t *list)
 
 /* ------- helper functions (doing flat list) ------- */
 
-static char *relative2absolute_uri(const char *xcap_root, const char *relative)
+static char *relative2absolute_uri(const str_t *xcap_root, const char *relative)
 {
 	/* FIXME: do absolute uri from ref (RFC 3986, section 5.2) */
 	int len;
@@ -170,8 +168,8 @@ static char *relative2absolute_uri(const char *xcap_root, const char *relative)
 	char *dst = NULL;
 
 	if (xcap_root) {
-		root_len = strlen(xcap_root);
-		if (xcap_root[root_len - 1] != '/') slash_len = 1;
+		root_len = xcap_root->len;
+		if (xcap_root->s[root_len - 1] != '/') slash_len = 1;
 	}
 	if (relative) rel_len = strlen(relative);
 	len = root_len + slash_len + rel_len + 1;
@@ -179,7 +177,7 @@ static char *relative2absolute_uri(const char *xcap_root, const char *relative)
 	dst = (char *)cds_malloc(len);
 	if (!dst) return NULL;
 
-	if (xcap_root) memcpy(dst, xcap_root, root_len);
+	if (xcap_root) memcpy(dst, xcap_root->s, root_len);
 	if (slash_len) dst[root_len] = '/';
 	if (relative) memcpy(dst + root_len + slash_len, relative, rel_len);
 	dst[len - 1] = 0;
@@ -446,7 +444,7 @@ static int process_resource_list(const char *rl_uri, process_params_t *params)
 	return res;
 }
 
-static int create_flat_list(service_t *srv, xcap_query_t *xcap_params, const char *xcap_root, flat_list_t **dst)
+static int create_flat_list(service_t *srv, xcap_query_t *xcap_params, const str_t *xcap_root, flat_list_t **dst)
 {
 	process_params_t params;
 	int res = -1;
@@ -534,7 +532,7 @@ static service_t *find_service(rls_services_t *rls, const str_t *uri)
 
 /* ------- rls examining ------- */
 
-int get_rls(const char *xcap_root, const str_t *uri, xcap_query_t *xcap_params, const str_t *package, flat_list_t **dst)
+int get_rls(const str_t *xcap_root, const str_t *uri, xcap_query_t *xcap_params, const str_t *package, flat_list_t **dst)
 {
 	char *data = NULL;
 	int dsize = 0;
@@ -601,7 +599,7 @@ int get_rls(const char *xcap_root, const str_t *uri, xcap_query_t *xcap_params,
 	return RES_OK;
 }
 
-int get_rls_from_full_doc(const char *xcap_root, const str_t *uri, xcap_query_t *xcap_params, const str_t *package, flat_list_t **dst)
+int get_rls_from_full_doc(const str_t *xcap_root, const str_t *uri, xcap_query_t *xcap_params, const str_t *package, flat_list_t **dst)
 {
 	char *data = NULL;
 	int dsize = 0;
@@ -676,17 +674,16 @@ int get_rls_from_full_doc(const char *xcap_root, const str_t *uri, xcap_query_t
 	return RES_OK;
 }
 
-char *xcap_uri_for_resource_list(const char *xcap_root, const str_t *user)
+char *xcap_uri_for_resource_list(const str_t *xcap_root, const str_t *user)
 {
 	dstring_t s;
 	int l;
 	char *dst = NULL;
 
 	if (!xcap_root) return NULL;
-	l = strlen(xcap_root);
-	dstr_init(&s, 2 * l + 32);
-	dstr_append(&s, xcap_root, l);
-	if (xcap_root[l - 1] != '/') dstr_append(&s, "/", 1);
+	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, "resource-lists/users/");
 	dstr_append_str(&s, user);
 	dstr_append_zt(&s, "/resource-list.xml");
@@ -703,13 +700,39 @@ char *xcap_uri_for_resource_list(const char *xcap_root, const str_t *user)
 	return dst;
 }
 
+static list_t *find_list(list_t *root, const char *name)
+{
+	list_content_t *c;
+	
+	if (!root) return root;
+	if (!name) return root;
+	if (!*name) return root; /* empty name = whole doc */
+
+	c = root->content;
+	while (c) {
+		if (c->type == lct_list) {
+			if (c->u.list) {
+				if (strcmp(name, c->u.list->name) == 0) 
+					return c->u.list;
+			}
+		}
+		c = SEQUENCE_NEXT(c);
+	}
+
+	ERROR_LOG("list \'%s\' not found\n", name);
+	
+	return NULL;
+}
+
 /* catches and processes user's resource list as rls-services document */
-int get_resource_list_as_rls(const char *xcap_root, const str_t *user, xcap_query_t *xcap_params, flat_list_t **dst)
+int get_resource_list_from_full_doc(const str_t *xcap_root, 
+		const str_t *user, xcap_query_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;
+	list_t *list = NULL, *right = NULL;
 	xcap_query_t xcap;
 	int res;
 
@@ -754,6 +777,9 @@ int get_resource_list_as_rls(const char *xcap_root, const str_t *user, xcap_quer
 		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");
@@ -761,19 +787,21 @@ int get_resource_list_as_rls(const char *xcap_root, const str_t *user, xcap_quer
 	}
 	memset(service, 0, sizeof(*service));
 	service->content_type = stc_list;
-	service->content.list = list;
+	service->content.list = right;
 	/*service->uri = ??? */
-	
+
 	/* create flat document */
 	res = create_flat_list(service, &xcap, xcap_root, 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_service(service);
 		free_flat_list(*dst);
 		*dst = NULL;
 		return res;
 	}
-	free_service(service);
 	
 	return RES_OK;
 }

+ 5 - 4
lib/xcap/resource_list.h

@@ -40,11 +40,12 @@ typedef struct _flat_list_t {
 	SEQUENCE(display_name_t) names;
 } flat_list_t;
 
-char *xcap_uri_for_rls_resource(const char *xcap_root, const str_t *uri);
+char *xcap_uri_for_rls_resource(const str_t *xcap_root, const str_t *uri);
 void canonicalize_uri(const str_t *uri, str_t *dst);
-int get_rls(const char *xcap_root, const str_t *uri, xcap_query_t *xcap_params, const str_t *package, flat_list_t **dst);
-int get_rls_from_full_doc(const char *xcap_root, const str_t *uri, xcap_query_t *xcap_params, const str_t *package, flat_list_t **dst);
-int get_resource_list_as_rls(const char *xcap_root, const str_t *user, xcap_query_t *xcap_params, flat_list_t **dst);
+int get_rls(const str_t *xcap_root, const str_t *uri, xcap_query_t *xcap_params, const str_t *package, flat_list_t **dst);
+int get_rls_from_full_doc(const str_t *xcap_root, const str_t *uri, xcap_query_t *xcap_params, const str_t *package, flat_list_t **dst);
+int get_resource_list_from_full_doc(const str_t *xcap_root, const str_t *user, xcap_query_t *xcap_params, const char *list_name, flat_list_t **dst);
+/* TODO: int get_resource_list(const str_t *xcap_root, const str_t *user, xcap_query_t *xcap_params, const str_t *list_name, flat_list_t **dst); */
 void free_flat_list(flat_list_t *list);
 
 #endif

+ 1 - 0
lib/xcap/resource_lists_parser.c

@@ -418,6 +418,7 @@ void free_list(list_t *l)
 		}
 		f = e;
 		e = SEQUENCE_NEXT(e);
+		/* TRACE_LOG("freeing %p\n", f); */
 		cds_free(f);
 	}
 	cds_free(l);

+ 1 - 1
lib/xcap/test_rls.c

@@ -240,7 +240,7 @@ static int xcap_test(const char *xcap_root, const char *uri)
 
 #endif
 
-int test_flat(const char *xcap_root, const char *uri)
+int test_flat(const str_t *xcap_root, const char *uri)
 {
 	str_t u = zt2str((char *)uri);
 	xcap_query_t xcap;

+ 16 - 7
lib/xcap/xml_utils.c

@@ -34,23 +34,32 @@
 
 int xml_parser_flags = XML_PARSE_NOERROR | XML_PARSE_NOWARNING;
 
-static void str2int(const char *s, int *dst)
+static int str2int(const char *s, int *dst)
 {
 	/* if not null sets the given integer to value */
-	if (!s) return;
+	if (!s) {
+		*dst = 0;
+		return -1;
+	}
 	else *dst = atoi(s);
+	return 0;
 }
 
-void get_int_attr(xmlNode *n, const char *attr_name, int *dst)
+int get_int_attr(xmlNode *n, const char *attr_name, int *dst)
 {
-	str2int(get_attr_value(find_attr(n->properties, attr_name)), dst);
+	const char *s = get_attr_value(find_attr(n->properties, attr_name));
+	if (!s) return 1;
+	return str2int(s, dst);
 }
 
-void get_str_attr(xmlNode *n, const char *attr_name, str_t *dst)
+int get_str_attr(xmlNode *n, const char *attr_name, str_t *dst)
 {
 	const char *s = get_attr_value(find_attr(n->properties, attr_name));
-	if (!s) str_clear(dst);
-	else str_dup_zt(dst, s);
+	if (!s) {
+		str_clear(dst);
+		return 1;
+	}
+	else return str_dup_zt(dst, s);
 }
 
 int xmlstrcmp(const xmlChar *xmls, const char *name)

+ 2 - 2
lib/xcap/xml_utils.h

@@ -35,8 +35,8 @@ const char *get_node_value(xmlNode *n);
 xmlNode *find_node(xmlNode *parent, const char *name, const char *nspace);
 const char *get_attr_value(xmlAttr *a);
 int cmp_node(xmlNode *node, const char *name, const char *nspace);
-void get_int_attr(xmlNode *n, const char *attr_name, int *dst);
-void get_str_attr(xmlNode *n, const char *attr_name, str_t *dst);
+int get_int_attr(xmlNode *n, const char *attr_name, int *dst);
+int get_str_attr(xmlNode *n, const char *attr_name, str_t *dst);
 
 time_t xmltime2time(const char *xt);