Quellcode durchsuchen

- XCAP queries moved into XCAP module, all other modules (and libs) are now
independent on libcurl3
- parameter settings which was done via AVP (like xcap_root) and output
variables (like subscription_status) changed to usage of global variables -
due to problems with AVPs if functions called from script send requests
(like NOTIFY from handle_subscripton - after sending it are AVPs cleared)

Vaclav Kubart vor 19 Jahren
Ursprung
Commit
a30fa2006a

+ 1 - 2
doc/presence/examples.xml

@@ -476,10 +476,9 @@ route{
 						}
 						else {
 							# new presence subscription
-							if ((@msg.event=~"presence") && (%subscription_status=="pending")) {
+							if ((@msg.event=~"presence") &&	(check_subscription_status("pending"))) {
 								# if offline user and new pending subscription 
 								if (!target_online("registrar")) {
-									#%subscription_status="waiting"; # store it as waiting subscription
 									xlog("L_ERR", "storing 'pending' winfo to: %tu, from: %fu\n");
 									store_winfo("registrar");
 								}

+ 1 - 1
lib/README

@@ -11,7 +11,7 @@ presence - Library holding common structures and functions abaut presence
 
 xcap - Common XCAP operations and structures (XCAP authorization documents
        and XCAP resource lists processing)
-       requires external libraries: libxml2, libcurl3
+       requires external libraries: libxml2, libcurl3 (nonSER version)
        requires internal libraries: cds
 
 Used by modules: pa, rls, dialog, rpa

+ 1 - 1
lib/xcap/Makefile.ser

@@ -2,7 +2,7 @@ LIBNAME  = xcap
 OUT_NAME = lib_ser_xcap.so
 OUT_TYPE = lib
 INCLUDES += -I/usr/include/libxml2
-LIBS     += -lxml2 -lcurl -l_ser_cds
+LIBS     += -lxml2 -l_ser_cds
 
 include ../Makefile.ser.defs
 

+ 1 - 1
lib/xcap/doc/xcap.xml

@@ -24,7 +24,7 @@
 	<listitem><para><application>libxml2</application> (external library for
 	parsing XML documents)</para></listitem>
 	<listitem><para><application>libcurl3</application> (external library for
-	HTTP operations)</para></listitem>
+	HTTP operations, used only in nonSER version!)</para></listitem>
 </itemizedlist>
 </para>
 </section>

+ 16 - 34
lib/xcap/msg_rules.c

@@ -33,49 +33,31 @@
 #include <cds/sstr.h>
 #include <string.h>
 
-char *xcap_uri_for_msg_rules(const char *xcap_root, const str_t *uri)
-{
-	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_append_zt(&s, "im-rules/users/");
-	dstr_append_str(&s, uri);
-	dstr_append_zt(&s, "/im-rules.xml");
-	
-	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;
-}
-
-int get_msg_rules(const char *xcap_root, const str_t *uri, xcap_query_params_t *xcap_params, msg_rules_t **dst)
+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 *xcap_uri;
+	char *uri = NULL;
 	int res = RES_OK;
 	
-	xcap_uri = xcap_uri_for_msg_rules(xcap_root, uri);
-	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
+	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", xcap_uri ? xcap_uri: "???");
+		DEBUG_LOG("XCAP problems for uri \'%s\'\n", uri);
 		if (data) cds_free(data);
-		if (xcap_uri) cds_free(xcap_uri);
+		cds_free(uri);
 		return RES_XCAP_QUERY_ERR;
 	}
-	if (xcap_uri) cds_free(xcap_uri);
+	cds_free(uri);
 	
 	/* parse input data */
 	res = parse_msg_rules(data, dsize, dst);

+ 2 - 2
lib/xcap/msg_rules.h

@@ -39,8 +39,8 @@ typedef enum {
 	msg_handling_allow
 } msg_handling_t;
 
-char *xcap_uri_for_msg_rules(const char *xcap_root, const str_t *uri);
-int get_msg_rules(const char *xcap_root, const str_t *uri, xcap_query_params_t *xcap_params, msg_rules_t **dst);
+int get_msg_rules(const str_t *username, const str_t *filename,
+		xcap_query_params_t *xcap_params, msg_rules_t **dst);
 void free_msg_rules(cp_ruleset_t *r);
 void free_msg_actions(cp_actions_t *a);
 

+ 15 - 34
lib/xcap/pres_rules.c

@@ -33,49 +33,30 @@
 #include <cds/sstr.h>
 #include <string.h>
 
-char *xcap_uri_for_pres_rules(const char *xcap_root, const str_t *uri)
-{
-	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_append_zt(&s, "pres-rules/users/");
-	dstr_append_str(&s, uri);
-	dstr_append_zt(&s, "/presence-rules.xml");
-	
-	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;
-}
-
-int get_pres_rules(const char *xcap_root, const str_t *uri, xcap_query_params_t *xcap_params, cp_ruleset_t **dst)
+int get_pres_rules(const str_t *username, const str_t *filename, 
+		xcap_query_params_t *xcap_params, cp_ruleset_t **dst)
 {
 	char *data = NULL;
 	int dsize = 0;
-	char *xcap_uri;
+	char *uri = NULL;
 	int res = RES_OK;
 	
-	xcap_uri = xcap_uri_for_pres_rules(xcap_root, uri);
-	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
+	uri = xcap_uri_for_users_document(xcap_doc_pres_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", xcap_uri ? xcap_uri: "???");
+		DEBUG_LOG("XCAP problems for uri \'%s\'\n", uri);
 		if (data) cds_free(data);
-		if (xcap_uri) cds_free(xcap_uri);
+		cds_free(uri);
 		return RES_XCAP_QUERY_ERR;
 	}
-	if (xcap_uri) cds_free(xcap_uri);
+	cds_free(uri);
 	
 	/* parse input data */
 	res = parse_pres_rules(data, dsize, dst);

+ 1 - 2
lib/xcap/pres_rules.h

@@ -40,8 +40,7 @@ typedef enum {
 	sub_handling_allow
 } sub_handling_t;
 
-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_params_t *xcap_params, cp_ruleset_t **dst);
+int get_pres_rules(const str_t *username, const str_t *filename, xcap_query_params_t *xcap_params, cp_ruleset_t **dst);
 void free_pres_rules(cp_ruleset_t *r);
 void free_pres_actions(cp_actions_t *a);
 

+ 51 - 57
lib/xcap/resource_list.c

@@ -430,13 +430,14 @@ 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_params_t *xcap_params, const str_t *xcap_root, flat_list_t **dst)
+static int create_flat_list(service_t *srv, 
+		xcap_query_params_t *xcap_params, 
+		flat_list_t **dst)
 {
 	process_params_t params;
 	int res = -1;
 	if (!srv) return RES_INTERNAL_ERR;
 
-	params.xcap_root = xcap_root;
 	params.xcap_params = xcap_params;
 	params.flat = NULL;
 	params.flat_last = NULL;
@@ -518,30 +519,36 @@ static service_t *find_service(rls_services_t *rls, const str_t *uri)
 
 /* ------- rls examining ------- */
 
-int get_rls(const str_t *xcap_root, const str_t *uri, xcap_query_params_t *xcap_params, const str_t *package, flat_list_t **dst)
+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;
+	char *xcap_uri = NULL;
+	str_t *filename = NULL;
 	int res;
 
 	if (!dst) return RES_INTERNAL_ERR;
 	
 	/* get basic document */
-	xcap_uri = xcap_uri_for_rls_resource(xcap_root, uri);
-	/* DEBUG_LOG("XCAP uri \'%s\'\n", xcap_uri ? xcap_uri: "???"); */
+	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 ? xcap_uri: "???");
+		ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri);
 		if (data) {
 			cds_free(data);
 		}
-		if (xcap_uri) cds_free(xcap_uri);
+		cds_free(xcap_uri);
 		return RES_XCAP_QUERY_ERR;
 	}
-	if (xcap_uri) cds_free(xcap_uri);
-	xcap_uri = NULL;
+	cds_free(xcap_uri);
 	
 	/* parse document as a service element in rls-sources */
 	if (parse_service(data, dsize, &service) != 0) {
@@ -567,7 +574,7 @@ int get_rls(const str_t *xcap_root, const str_t *uri, xcap_query_params_t *xcap_
 	}
 	
 	/* create flat document */
-	res = create_flat_list(service, xcap_params, xcap_root, dst);
+	res = create_flat_list(service, xcap_params, dst);
 	if (res != RES_OK) {
 		ERROR_LOG("Flat list creation error\n");
 		free_service(service);
@@ -580,7 +587,10 @@ int get_rls(const str_t *xcap_root, const str_t *uri, xcap_query_params_t *xcap_
 	return RES_OK;
 }
 
-int get_rls_from_full_doc(const str_t *xcap_root, const str_t *uri, xcap_query_params_t *xcap_params, const str_t *package, flat_list_t **dst)
+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;
@@ -588,25 +598,30 @@ int get_rls_from_full_doc(const str_t *xcap_root, const str_t *uri, xcap_query_p
 	service_t *service = NULL;
 	str_t curi;
 	int res;
-	char *xcap_uri;
+	char *xcap_uri = NULL;
+	str_t *filename = NULL;
 
 	if (!dst) return RES_INTERNAL_ERR;
 	
 
 	/* get basic document */
-	xcap_uri = xcap_uri_for_rls_services(xcap_root);
-	DEBUG_LOG("XCAP uri \'%s\'\n", xcap_uri ? xcap_uri: "???");
+	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 ? xcap_uri: "???");
+		ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri);
 		if (data) {
 			cds_free(data);
 		}
-		if (xcap_uri) cds_free(xcap_uri);
+		cds_free(xcap_uri);
 		return RES_XCAP_QUERY_ERR;
 	}
-	if (xcap_uri) cds_free(xcap_uri);
-	xcap_uri = NULL;
+	cds_free(xcap_uri);
 	
 	/* parse document as a service element in rls-sources */
 	if (parse_rls_services_xml(data, dsize, &rls) != 0) {
@@ -638,7 +653,7 @@ int get_rls_from_full_doc(const str_t *xcap_root, const str_t *uri, xcap_query_p
 	}
 	
 	/* create flat document */
-	res = create_flat_list(service, xcap_params, xcap_root, dst);
+	res = create_flat_list(service, xcap_params, dst);
 	if (res != RES_OK) {
 		ERROR_LOG("Flat list creation error\n");
 		free_rls_services(rls);
@@ -651,32 +666,6 @@ int get_rls_from_full_doc(const str_t *xcap_root, const str_t *uri, xcap_query_p
 	return RES_OK;
 }
 
-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;
-	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");
-	
-	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 list_t *find_list(list_t *root, const char *name)
 {
 	list_content_t *c;
@@ -702,8 +691,9 @@ static list_t *find_list(list_t *root, const char *name)
 }
 
 /* catches and processes user's resource list as rls-services document */
-int get_resource_list_from_full_doc(const str_t *xcap_root, 
-		const str_t *user, xcap_query_params_t *xcap_params, 
+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;
@@ -711,24 +701,28 @@ int get_resource_list_from_full_doc(const str_t *xcap_root,
 	service_t *service = NULL; 
 	list_t *list = NULL, *right = NULL;
 	int res;
-	char *xcap_uri;
+	char *uri = NULL;
 
 	if (!dst) return RES_INTERNAL_ERR;
 	
 	/* get basic document */
-	xcap_uri = xcap_uri_for_resource_list(xcap_root, user);
-	DEBUG_LOG("XCAP uri \'%s\'\n", xcap_uri ? xcap_uri: "???");
-	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
+	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", xcap_uri ? xcap_uri: "???");
+		ERROR_LOG("XCAP problems for uri \'%s\'\n", uri);
 		if (data) {
 			cds_free(data);
 		}
-		if (xcap_uri) cds_free(xcap_uri);
+		cds_free(uri);
 		return RES_XCAP_QUERY_ERR;
 	}
-	if (xcap_uri) cds_free(xcap_uri);
-	xcap_uri = NULL;
+	cds_free(uri);
 	
 	/* parse document as a list element in resource-lists */
 	if (parse_as_list_content_xml(data, dsize, &list) != 0) {
@@ -763,7 +757,7 @@ int get_resource_list_from_full_doc(const str_t *xcap_root,
 	/*service->uri = ??? */
 
 	/* create flat document */
-	res = create_flat_list(service, xcap_params, xcap_root, dst);
+	res = create_flat_list(service, xcap_params, dst);
 
 	service->content.list = list; /* free whole document not only "right" list */
 	free_service(service);

+ 6 - 2
lib/xcap/resource_list.h

@@ -42,8 +42,12 @@ typedef struct _flat_list_t {
 
 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 str_t *xcap_root, const str_t *uri, xcap_query_params_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_params_t *xcap_params, const str_t *package, flat_list_t **dst);
+int get_rls(const str_t *uri, xcap_query_params_t *xcap_params, 
+		const str_t *package, flat_list_t **dst);
+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);
 int get_resource_list_from_full_doc(const str_t *xcap_root, const str_t *user, xcap_query_params_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);

+ 0 - 189
lib/xcap/test_pres_rules.c

@@ -1,189 +0,0 @@
-/* 
- * Copyright (C) 2005 iptelorg GmbH
- *
- * This file is part of ser, a free SIP server.
- *
- * ser is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * For a license to use the ser software under conditions
- * other than those described here, or to purchase support for this
- * software, please contact iptel.org by e-mail at the following addresses:
- *    [email protected]
- *
- * ser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libxml/parser.h>
-#include <curl/curl.h>
-#include <xcap/xcap_client.h>
-#include <xcap/pres_rules.h>
-#include <xcap/parse_pres_rules.h>
-#include <xcap/common_policy.h>
-#include <cds/sstr.h>
-#include <cds/dstring.h>
-#include <cds/memory.h>
-
-void trace_conditions(cp_conditions_t *c)
-{
-	cp_sphere_t *s;
-	cp_id_t *i;
-	cp_domain_t *d;
-	cp_except_t *e;
-	
-	printf(" - conditions: \n"); 
-	if (!c) return;
-
-	printf("   +- validity: "); 
-	if (c->validity) 
-		printf("from %s to %s", 
-				ctime(&c->validity->from), 
-				ctime(&c->validity->to));
-	printf("\n");
-	
-	printf("   +- identity: \n"); 
-	if (c->identity) {
-		printf("      +- ids: "); 
-		i = c->identity->ids;
-		while (i) {
-			if (i != c->identity->ids) printf(", ");
-			printf("%.*s", FMT_STR(i->entity));
-			i = i->next;
-		}
-		printf("\n");
-		
-		printf("      +- domains: "); 
-		d = c->identity->domains;
-		while (d) {
-			if (d != c->identity->domains) printf(", ");
-			printf("%.*s", FMT_STR(d->domain));
-			d = d->next;
-		}
-		printf("\n");
-
-		printf("      +- except: "); 
-		e = c->identity->excepts;
-		while (e) {
-			if (e != c->identity->excepts) printf(", ");
-			printf("%.*s", FMT_STR(e->entity));
-			e = e->next;
-		}
-		printf("\n");
-	}
-	
-	printf("   +- spheres: "); 
-	s = c->spheres;
-	while (s) {
-		if (s != c->spheres) printf(", ");
-		printf("%.*s", FMT_STR(s->value));
-		s = s->next;
-	}
-	printf("\n");
-}
-
-void trace_actions(cp_actions_t *a)
-{
-	printf(" - actions: \n"); 
-	if (!a) return;
-	if (a->unknown) {
-		printf("    sub-handling: ");
-		sub_handling_t *sh = (sub_handling_t*)a->unknown->data;
-		switch (*sh) {
-			case sub_handling_block: printf("block"); break;
-			case sub_handling_confirm: printf("confirm"); break;
-			case sub_handling_polite_block: printf("polite block"); break;
-			case sub_handling_allow: printf("allow"); break;
-		}
-		printf("\n");
-	}
-}
-
-void trace_transformations(cp_transformations_t *c)
-{
-	printf(" - transformations: \n"); 
-}
-
-void trace_pres_rules(cp_ruleset_t *rules)
-{
-	cp_rule_t *r;
-	
-	if (!rules) {
-		printf("null ruleset!\n");
-		return;
-	}
-
-	r = rules->rules;
-	while (r) {
-		printf("rule \'%.*s\'\n", FMT_STR(r->id));
-		trace_conditions(r->conditions);
-		trace_actions(r->actions);
-		trace_transformations(r->transformations);
-		r = r->next;
-	}
-	
-}
-		
-void test_rules(cp_ruleset_t *pres_rules, const char *uri)
-{
-	sub_handling_t sh;
-	str_t s = zt2str((char *)uri);
-
-	sh = sub_handling_confirm;
-	get_pres_rules_action(pres_rules, &s, &sh);
-
-	printf("rules for %s: ", uri);
-	switch (sh) {
-		case sub_handling_block: printf("block"); break;
-		case sub_handling_confirm: printf("confirm"); break;
-		case sub_handling_polite_block: printf("polite block"); break;
-		case sub_handling_allow: printf("allow"); break;
-	}
-	printf("\n");
-}
-
-int pres_rules_test(const char *xcap_root, const char *uri)
-{
-	cp_ruleset_t *pres_rules = NULL;
-	xcap_query_params_t xcap;
-	int res;
-	str_t u;
-	
-	u.s = (char *)uri;
-	u.len = u.s ? strlen(u.s): 0;
-	
-	/* XCAP test */
-	memset(&xcap, 0, sizeof(xcap));
-	xcap.auth_user = "smith";
-	xcap.auth_pass = "pass";
-	xcap.enable_unverified_ssl_peer = 1;
-	res = get_pres_rules(xcap_root, &u, &xcap, &pres_rules);
-	if (res != 0) {
-		printf("XCAP problems!\n");
-		return -1;
-	}
-
-	if (pres_rules) {
-		trace_pres_rules(pres_rules);
-		test_rules(pres_rules, "[email protected]");
-		test_rules(pres_rules, "[email protected]");
-		test_rules(pres_rules, "all:[email protected]");
-
-		free_pres_rules(pres_rules);
-	}
-	
-	return 0;
-}
-

+ 0 - 265
lib/xcap/test_rls.c

@@ -1,265 +0,0 @@
-/* 
- * Copyright (C) 2005 iptelorg GmbH
- *
- * This file is part of ser, a free SIP server.
- *
- * ser is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * For a license to use the ser software under conditions
- * other than those described here, or to purchase support for this
- * software, please contact iptel.org by e-mail at the following addresses:
- *    [email protected]
- *
- * ser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libxml/parser.h>
-#include <curl/curl.h>
-
-#include <xcap/resource_list.h>
-#include <xcap/resource_lists_parser.h>
-#include <xcap/rls_services_parser.h>
-#include <xcap/xcap_client.h>
-
-#define STR_OK(s)	(s)?(s):""
-
-void print_indent(int indent)
-{
-	int i;
-	
-	for (i = 0; i < indent; i++) printf("  ");
-	if (indent > 0) printf(" + ");
-}
-
-void trace_entry(entry_t *e, int indent)
-{
-	if (!e) return;
-	
-	print_indent(indent);
-	if (e->uri) printf("%s\n", e->uri);
-	else printf("???\n");
-}
-
-void trace_entry_ref(entry_ref_t *e, int indent)
-{
-	if (!e) return;
-	
-	print_indent(indent);
-	if (e->ref) printf("ref: %s\n", e->ref);
-	else printf("ref: ???\n");
-}
-
-void trace_external(external_t *e, int indent)
-{
-	if (!e) return;
-	
-	print_indent(indent);
-	if (e->anchor) printf("ext: %s\n", e->anchor);
-	else printf("ext: ???\n");
-}
-
-void trace_list(list_t *l, int indent)
-{
-	list_content_t *e;
-
-	if (!l) return;
-	
-	print_indent(indent);
-	
-	if (l->name) printf("%s\n", l->name);
-	else printf("???\n");
-
-	e = SEQUENCE_FIRST(l->content);
-	while (e) {
-		switch (e->type) {
-			case lct_list: trace_list(e->u.list, indent + 1); break;
-			case lct_entry: trace_entry(e->u.entry, indent + 1); break;
-			case lct_entry_ref: trace_entry_ref(e->u.entry_ref, indent + 1); break;
-			case lct_external: trace_external(e->u.external, indent + 1); break;
-		}
-		e = SEQUENCE_NEXT(e);
-	}
-}
-
-void trace_resource_lists(resource_lists_t *rl)
-{
-	list_t *e;
-	if (!rl) {
-		printf("empty list\n");
-		return;
-	}
-	
-	e = SEQUENCE_FIRST(rl->lists);
-	while (e) {
-		trace_list(e, 0);
-		e = SEQUENCE_NEXT(e);
-	}
-}
-
-void trace_packages(packages_t *p)
-{
-	package_t *e;
-	int first = 1;
-	
-	printf(" [packages: ");
-	if (p) {
-		e = SEQUENCE_FIRST(p->package);
-		while (e) {
-			if (!first) printf(" ");
-			else first = 0;
-			printf("%s", e->name);
-			e = SEQUENCE_NEXT(e);
-		}
-	}
-	printf("]");
-}
-
-void trace_service(service_t *l, int indent)
-{
-	if (!l) return;
-	
-	print_indent(indent);
-	
-	if (l->uri) printf("%s", l->uri);
-	else printf("???");
-	if (l->packages) trace_packages(l->packages);
-	printf("\n");
-
-	switch (l->content_type) {
-		case stc_list: trace_list(l->content.list, indent + 1); break;
-		case stc_resource_list: print_indent(indent + 1);
-								printf("@ %s\n", STR_OK(l->content.resource_list));
-								break;
-	}
-}
-
-void trace_rls_services(rls_services_t *rl)
-{
-	service_t *e;
-	if (!rl) {
-		printf("empty rls-services\n");
-		return;
-	}
-	
-	e = SEQUENCE_FIRST(rl->rls_services);
-	while (e) {
-		trace_service(e, 0);
-		e = SEQUENCE_NEXT(e);
-	}
-}
-
-void trace_flat_list(flat_list_t *list)
-{
-	flat_list_t *e = list;
-	
-	while (e) {
-		if (e->uri) printf("%s\n", e->uri);
-		else printf("???\n");
-		e = e->next;
-	}
-}
-
-/* -------------------------------------------------------------------------------- */
-
-#if 0
-
-static int xcap_test(const char *xcap_root, const char *uri)
-{
-	char *data = NULL;
-	int dsize = 0;
-	/* resource_lists_t *res_list = NULL; */
-	rls_services_t *rls = NULL;
-	service_t *service = NULL;
-	xcap_query_t xcap;
-	int res;
-	str_t u = zt2str((char *)uri);
-	
-	/* XCAP test */
-	xcap.uri = xcap_uri_for_rls_resource(xcap_root, &u);
-	xcap.auth_user = "smith";
-	xcap.auth_pass = "pass";
-	xcap.enable_unverified_ssl_peer = 1;
-	res = xcap_query(&xcap, &data, &dsize);
-	if (res != 0) {
-		printf("XCAP problems!\n");
-		if (xcap.uri) printf("URI = %s\n", xcap.uri);
-		else printf("XCAP URI not defined!\n");
-		if (data) {
-			printf("%s\n", data);
-			free(data);
-		}
-		return -1;
-	}
-
-/*	printf("%s\n", data);*/
-
-	/* parse input data */
-	/*if (parse_resource_lists_xml(data, dsize, &res_list) != 0) {
-		printf("Error occured during document parsing!\n");
-	}
-	else { 
-		trace_resource_lists(res_list);
-		if (res_list) free_resource_lists(res_list);
-	}*/
-	
-	if (parse_rls_services_xml(data, dsize, &rls) == 0) {
-		trace_rls_services(rls);
-		if (rls) free_rls_services(rls);
-	}
-	else {
-		/* try to take it as a service */
-		if (parse_service(data, dsize, &service) == 0) {
-			if (service) {
-				trace_service(service, 0);
-				free_service(service);
-			}
-		}
-		else {
-			printf("Error occured during document parsing! It is not rls-services nor service.\n");
-			if (dsize > 0) printf("%.*s\n", dsize, data);
-		}
-	}
-
-	if (data) free(data);
-	return 0;
-}
-
-#endif
-
-int test_flat(const str_t *xcap_root, const char *uri)
-{
-	str_t u = zt2str((char *)uri);
-	xcap_query_params_t xcap;
-	flat_list_t *list = NULL;
-	str_t p = zt2str("presence");
-	
-	xcap.auth_user = "smith";
-	xcap.auth_pass = "pass";
-	xcap.enable_unverified_ssl_peer = 1;
-	
-	if (get_rls(xcap_root, &u, &xcap, &p, &list) != 0) {
-		if (list) free_flat_list(list);
-		printf("Failed !\n");
-		return -1;
-	}
-
-	trace_flat_list(list);
-	free_flat_list(list);
-	
-	return 0;
-}
-

+ 183 - 12
lib/xcap/xcap_client.c

@@ -31,6 +31,159 @@
 #include <cds/dstring.h>
 #include <cds/memory.h>
 #include <cds/logger.h>
+
+static const str_t *get_xcap_doc_dir(xcap_document_type_t doc_type)
+{
+	static str_t pres_rules = STR_STATIC_INIT("pres-rules");
+	static str_t im_rules = STR_STATIC_INIT("im-rules");
+	static str_t rls_services = STR_STATIC_INIT("rls-services");
+	static str_t resource_lists = STR_STATIC_INIT("resource-lists");
+
+	switch (doc_type) {
+		case xcap_doc_pres_rules: return &pres_rules;
+		case xcap_doc_im_rules: return &im_rules;
+		case xcap_doc_rls_services: return &rls_services;
+		case xcap_doc_resource_lists: return &resource_lists;
+		/* when new doc_type added, there will be a warning -> add it there */
+	}
+	WARN_LOG("unknow XCAP document type\n");
+	return NULL;
+}
+
+static const str_t *get_default_user_doc(xcap_document_type_t doc_type)
+{
+	static str_t pres_rules = STR_STATIC_INIT("presence-rules.xml");
+	static str_t im_rules = STR_STATIC_INIT("im-rules.xml");
+	static str_t rls_services = STR_STATIC_INIT("rls-services.xml");
+	static str_t resource_lists = STR_STATIC_INIT("resource-list.xml");
+
+	switch (doc_type) {
+		case xcap_doc_pres_rules: return &pres_rules;
+		case xcap_doc_im_rules: return &im_rules;
+		case xcap_doc_rls_services: return &rls_services;
+		case xcap_doc_resource_lists: return &resource_lists;
+		/* when new doc_type added, there will be a warning -> add it there */
+	}
+	WARN_LOG("unknow XCAP document type\n");
+	return NULL;
+}
+
+static int ends_with_separator(str_t *s)
+{
+	if (!is_str_empty(s))
+		if (s->s[s->len - 1] == '/') return 1;
+	return 0;
+}
+
+char *xcap_uri_for_users_document(xcap_document_type_t doc_type,
+		const str_t *username, 
+		const str_t*filename,
+		xcap_query_params_t *params)
+{
+	dstring_t s;
+	/* int res = RES_OK; */
+	int l = 0;
+	char *dst = NULL;
+
+	dstr_init(&s, 128);
+	if (params) {
+		dstr_append_str(&s, &params->xcap_root);
+		if (!ends_with_separator(&params->xcap_root))
+			dstr_append(&s, "/", 1);
+	}
+	else dstr_append(&s, "/", 1);
+	dstr_append_str(&s, get_xcap_doc_dir(doc_type));
+	dstr_append_zt(&s, "/users/");
+	dstr_append_str(&s, username);
+	dstr_append(&s, "/", 1);
+	if (filename) dstr_append_str(&s, filename);
+	else {
+		/* default filename if NULL */
+		dstr_append_str(&s, get_default_user_doc(doc_type));
+	}
+	/* res = dstr_get_str(&s, dst); */
+	
+	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;
+		}
+		else ERROR_LOG("can't allocate memory (%d bytes)\n", l);
+	}
+	
+	dstr_destroy(&s);
+	return dst;
+}
+
+
+char *xcap_uri_for_global_document(xcap_document_type_t doc_type,
+		const str_t *filename, 
+		xcap_query_params_t *params)
+{
+	dstring_t s;
+	/* int res = RES_OK; */
+	char *dst = NULL;
+	int l = 0;
+
+	dstr_init(&s, 128);
+	if (params) {
+		dstr_append_str(&s, &params->xcap_root);
+		if (!ends_with_separator(&params->xcap_root))
+			dstr_append(&s, "/", 1);
+	}
+	else dstr_append(&s, "/", 1);
+	dstr_append_str(&s, get_xcap_doc_dir(doc_type));
+	if (filename) {
+		dstr_append_zt(&s, "/global/");
+		dstr_append_str(&s, filename);
+	}
+	else {
+		/* default filename if NULL */
+		dstr_append_zt(&s, "/global/index");
+	}
+	/* res = dstr_get_str(&s, dst); */
+	
+	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;
+}
+
+#ifdef SER
+
+#include "sr_module.h"
+
+int xcap_query(const char *uri, 
+		xcap_query_params_t *params, char **buf, int *bsize)
+{
+	static xcap_query_func query = NULL;
+	static int initialized = 0;
+
+	if (!initialized) {
+		query = (xcap_query_func)find_export("xcap_query", 0, -1);
+		initialized = 1;
+		if (!query) WARN_LOG("No XCAP query support! (Missing module?)\n");
+	}
+	if (!query) {
+		/* no function for doing XCAP queries */
+		return -1;
+	}
+	
+	/* all XCAP queries are done through XCAP module */
+	return query(uri, params, buf, bsize);
+}
+
+#else /* compiled WITHOUT SER */
+
 #include <curl/curl.h>
 
 static size_t write_data_func(void *ptr, size_t size, size_t nmemb, void *stream)
@@ -46,10 +199,11 @@ static size_t write_data_func(void *ptr, size_t size, size_t nmemb, void *stream
 	return s;
 }
 
-int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bsize)
+
+int xcap_query(const str_t *uri, xcap_query_params_t *params, char **buf, int *bsize)
 {
 	CURLcode res = -1;
-	static CURL *handle = NULL; /*FIXME: experimental*/
+	static CURL *handle = NULL;
 	dstring_t data;
 	char *auth = NULL;
 	int i;
@@ -75,7 +229,7 @@ int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bs
 	
 	dstr_init(&data, 512);
 	
-	if (!handle) handle = curl_easy_init(); /*FIXME: experimental*/
+	if (!handle) handle = curl_easy_init(); 
 	if (handle) {
 		curl_easy_setopt(handle, CURLOPT_URL, uri);
 		/* TRACE_LOG("uri: %s\n", uri ? uri : "<null>"); */
@@ -106,7 +260,6 @@ int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bs
 		/* follow redirects (needed for apache mod_speling - case insesitive names) */
 		curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
 		
-		/* FIXME: experimetns */
 	/*	curl_easy_setopt(handle, CURLOPT_TCP_NODELAY, 1);
 		curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 10);*/
 		
@@ -134,9 +287,12 @@ int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bs
 	return res;
 }
 
+#endif
+
 void free_xcap_params_content(xcap_query_params_t *params)
 {
 	if (params) {
+		str_free_content(&params->xcap_root);
 		if (params->auth_user) cds_free(params->auth_user);
 		if (params->auth_pass) cds_free(params->auth_pass);
 		memset(params, 0, sizeof(*params));
@@ -145,22 +301,37 @@ void free_xcap_params_content(xcap_query_params_t *params)
 
 int dup_xcap_params(xcap_query_params_t *dst, xcap_query_params_t *src)
 {
+	int res = -10;
+	
 	if (dst) memset(dst, 0, sizeof(*dst));
 	
 	if (src && dst) {
-		if (src->auth_user) {
+		res = 0;
+		
+		res = str_dup(&dst->xcap_root, &src->xcap_root);
+		
+		if ((res == 0) && (src->auth_user)) {
 			dst->auth_user = zt_strdup(src->auth_user);
-			if (!dst->auth_user) return -1;
+			if (!dst->auth_user) res = -1;
 		}
-		if (src->auth_pass) {
+		if ((res == 0) && (src->auth_pass)) {
 			dst->auth_pass = zt_strdup(src->auth_pass);
-			if (!dst->auth_pass) {
-				free_xcap_params_content(dst);
-				return -2;
-			}
+			if (!dst->auth_pass) res= -2;
 		}
+
+		if (res != 0) free_xcap_params_content(dst);
 	}
 	
-	return 0;
+	return res;
+}
+
+int str2xcap_params(xcap_query_params_t *dst, const str_t *src)
+{
+	return -1;
+}
+
+int xcap_params2str(str_t *dst, const xcap_query_params_t *src)
+{
+	return -1;
 }
 

+ 31 - 2
lib/xcap/xcap_client.h

@@ -26,7 +26,12 @@
 #ifndef __XCAP_CLIENT_H
 #define __XCAP_CLIENT_H
 
+#include <cds/sstr.h>
+#include <xcap/xcap_result_codes.h>
+
 typedef struct {
+	/* "prefix" for XCAP query */
+	str_t xcap_root;
 	/** username for authentication */
 	char *auth_user;
 	/** password used for authentication */
@@ -37,13 +42,37 @@ typedef struct {
 	int enable_unverified_ssl_peer;
 } xcap_query_params_t;
 
+typedef enum {
+	xcap_doc_pres_rules,
+	xcap_doc_im_rules,
+	xcap_doc_rls_services,
+	xcap_doc_resource_lists
+} xcap_document_type_t;
+
+char *xcap_uri_for_users_document(xcap_document_type_t doc_type,
+		const str_t *username, 
+		const str_t*filename,
+		xcap_query_params_t *params);
+
+char *xcap_uri_for_global_document(xcap_document_type_t doc_type,
+		const str_t *filename,
+		xcap_query_params_t *params);
+
 /** Sends a XCAP query to the destination and using parameters from 
  * query variable a returns received data in output variables buf
  * and bsize. */
-/* URI is full HTTP/HTTPS uri for the query */
-int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bsize);
+/* URI is absolute HTTP/HTTPS uri for the query  */
+int xcap_query(const char *uri, xcap_query_params_t *params, 
+		char **buf, int *bsize);
+
+typedef int (*xcap_query_func)(const char *uri, 
+		xcap_query_params_t *params, 
+		char **buf, int *bsize);
 
 void free_xcap_params_content(xcap_query_params_t *params);
 int dup_xcap_params(xcap_query_params_t *dst, xcap_query_params_t *src);
 
+int str2xcap_params(xcap_query_params_t *dst, const str_t *src);
+int xcap_params2str(str_t *dst, const xcap_query_params_t *src);
+
 #endif