Browse code

- 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 authored on 07/04/2006 13:43:07
Showing 14 changed files
... ...
@@ -476,10 +476,9 @@ route{
476 476
 						}
477 477
 						else {
478 478
 							# new presence subscription
479
-							if ((@msg.event=~"presence") && (%subscription_status=="pending")) {
479
+							if ((@msg.event=~"presence") &&	(check_subscription_status("pending"))) {
480 480
 								# if offline user and new pending subscription 
481 481
 								if (!target_online("registrar")) {
482
-									#%subscription_status="waiting"; # store it as waiting subscription
483 482
 									xlog("L_ERR", "storing 'pending' winfo to: %tu, from: %fu\n");
484 483
 									store_winfo("registrar");
485 484
 								}
... ...
@@ -11,7 +11,7 @@ presence - Library holding common structures and functions abaut presence
11 11
 
12 12
 xcap - Common XCAP operations and structures (XCAP authorization documents
13 13
        and XCAP resource lists processing)
14
-       requires external libraries: libxml2, libcurl3
14
+       requires external libraries: libxml2, libcurl3 (nonSER version)
15 15
        requires internal libraries: cds
16 16
 
17 17
 Used by modules: pa, rls, dialog, rpa
... ...
@@ -2,7 +2,7 @@ LIBNAME  = xcap
2 2
 OUT_NAME = lib_ser_xcap.so
3 3
 OUT_TYPE = lib
4 4
 INCLUDES += -I/usr/include/libxml2
5
-LIBS     += -lxml2 -lcurl -l_ser_cds
5
+LIBS     += -lxml2 -l_ser_cds
6 6
 
7 7
 include ../Makefile.ser.defs
8 8
 
... ...
@@ -24,7 +24,7 @@
24 24
 	<listitem><para><application>libxml2</application> (external library for
25 25
 	parsing XML documents)</para></listitem>
26 26
 	<listitem><para><application>libcurl3</application> (external library for
27
-	HTTP operations)</para></listitem>
27
+	HTTP operations, used only in nonSER version!)</para></listitem>
28 28
 </itemizedlist>
29 29
 </para>
30 30
 </section>
... ...
@@ -33,49 +33,31 @@
33 33
 #include <cds/sstr.h>
34 34
 #include <string.h>
35 35
 
36
-char *xcap_uri_for_msg_rules(const char *xcap_root, const str_t *uri)
37
-{
38
-	dstring_t s;
39
-	int l;
40
-	char *dst = NULL;
41
-
42
-	if (!xcap_root) return NULL;
43
-	l = strlen(xcap_root);
44
-	dstr_init(&s, 2 * l + 32);
45
-	dstr_append(&s, xcap_root, l);
46
-	if (xcap_root[l - 1] != '/') dstr_append(&s, "/", 1);
47
-	dstr_append_zt(&s, "im-rules/users/");
48
-	dstr_append_str(&s, uri);
49
-	dstr_append_zt(&s, "/im-rules.xml");
50
-	
51
-	l = dstr_get_data_length(&s);
52
-	if (l > 0) {
53
-		dst = (char *)cds_malloc(l + 1);
54
-		if (dst) {
55
-			dstr_get_data(&s, dst);
56
-			dst[l] = 0;
57
-		}
58
-	}
59
-	dstr_destroy(&s);
60
-	return dst;
61
-}
62
-
63
-int get_msg_rules(const char *xcap_root, const str_t *uri, xcap_query_params_t *xcap_params, msg_rules_t **dst)
36
+int get_msg_rules(const str_t *username, const str_t *filename,
37
+		xcap_query_params_t *xcap_params, msg_rules_t **dst)
64 38
 {
65 39
 	char *data = NULL;
66 40
 	int dsize = 0;
67
-	char *xcap_uri;
41
+	char *uri = NULL;
68 42
 	int res = RES_OK;
69 43
 	
70
-	xcap_uri = xcap_uri_for_msg_rules(xcap_root, uri);
71
-	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
44
+	uri = xcap_uri_for_users_document(xcap_doc_im_rules,
45
+				username, filename,
46
+				xcap_params);
47
+	if (!uri) {
48
+		/* can't create XCAP uri */
49
+		ERROR_LOG("can't build XCAP uri\n");
50
+		return RES_XCAP_QUERY_ERR;
51
+	}
52
+	
53
+	res = xcap_query(uri, xcap_params, &data, &dsize);
72 54
 	if (res != RES_OK) {
73
-		DEBUG_LOG("XCAP problems for uri \'%s\'\n", xcap_uri ? xcap_uri: "???");
55
+		DEBUG_LOG("XCAP problems for uri \'%s\'\n", uri);
74 56
 		if (data) cds_free(data);
75
-		if (xcap_uri) cds_free(xcap_uri);
57
+		cds_free(uri);
76 58
 		return RES_XCAP_QUERY_ERR;
77 59
 	}
78
-	if (xcap_uri) cds_free(xcap_uri);
60
+	cds_free(uri);
79 61
 	
80 62
 	/* parse input data */
81 63
 	res = parse_msg_rules(data, dsize, dst);
... ...
@@ -39,8 +39,8 @@ typedef enum {
39 39
 	msg_handling_allow
40 40
 } msg_handling_t;
41 41
 
42
-char *xcap_uri_for_msg_rules(const char *xcap_root, const str_t *uri);
43
-int get_msg_rules(const char *xcap_root, const str_t *uri, xcap_query_params_t *xcap_params, msg_rules_t **dst);
42
+int get_msg_rules(const str_t *username, const str_t *filename,
43
+		xcap_query_params_t *xcap_params, msg_rules_t **dst);
44 44
 void free_msg_rules(cp_ruleset_t *r);
45 45
 void free_msg_actions(cp_actions_t *a);
46 46
 
... ...
@@ -33,49 +33,30 @@
33 33
 #include <cds/sstr.h>
34 34
 #include <string.h>
35 35
 
36
-char *xcap_uri_for_pres_rules(const char *xcap_root, const str_t *uri)
37
-{
38
-	dstring_t s;
39
-	int l;
40
-	char *dst = NULL;
41
-
42
-	if (!xcap_root) return NULL;
43
-	l = strlen(xcap_root);
44
-	dstr_init(&s, 2 * l + 32);
45
-	dstr_append(&s, xcap_root, l);
46
-	if (xcap_root[l - 1] != '/') dstr_append(&s, "/", 1);
47
-	dstr_append_zt(&s, "pres-rules/users/");
48
-	dstr_append_str(&s, uri);
49
-	dstr_append_zt(&s, "/presence-rules.xml");
50
-	
51
-	l = dstr_get_data_length(&s);
52
-	if (l > 0) {
53
-		dst = (char *)cds_malloc(l + 1);
54
-		if (dst) {
55
-			dstr_get_data(&s, dst);
56
-			dst[l] = 0;
57
-		}
58
-	}
59
-	dstr_destroy(&s);
60
-	return dst;
61
-}
62
-
63
-int get_pres_rules(const char *xcap_root, const str_t *uri, xcap_query_params_t *xcap_params, cp_ruleset_t **dst)
36
+int get_pres_rules(const str_t *username, const str_t *filename, 
37
+		xcap_query_params_t *xcap_params, cp_ruleset_t **dst)
64 38
 {
65 39
 	char *data = NULL;
66 40
 	int dsize = 0;
67
-	char *xcap_uri;
41
+	char *uri = NULL;
68 42
 	int res = RES_OK;
69 43
 	
70
-	xcap_uri = xcap_uri_for_pres_rules(xcap_root, uri);
71
-	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
44
+	uri = xcap_uri_for_users_document(xcap_doc_pres_rules,
45
+				username, filename, xcap_params);
46
+	if (!uri) {
47
+		/* can't create XCAP uri */
48
+		ERROR_LOG("can't build XCAP uri\n");
49
+		return RES_XCAP_QUERY_ERR;
50
+	}
51
+
52
+	res = xcap_query(uri, xcap_params, &data, &dsize);
72 53
 	if (res != RES_OK) {
73
-		DEBUG_LOG("XCAP problems for uri \'%s\'\n", xcap_uri ? xcap_uri: "???");
54
+		DEBUG_LOG("XCAP problems for uri \'%s\'\n", uri);
74 55
 		if (data) cds_free(data);
75
-		if (xcap_uri) cds_free(xcap_uri);
56
+		cds_free(uri);
76 57
 		return RES_XCAP_QUERY_ERR;
77 58
 	}
78
-	if (xcap_uri) cds_free(xcap_uri);
59
+	cds_free(uri);
79 60
 	
80 61
 	/* parse input data */
81 62
 	res = parse_pres_rules(data, dsize, dst);
... ...
@@ -40,8 +40,7 @@ typedef enum {
40 40
 	sub_handling_allow
41 41
 } sub_handling_t;
42 42
 
43
-char *xcap_uri_for_pres_rules(const char *xcap_root, const str_t *uri);
44
-int get_pres_rules(const char *xcap_root, const str_t *uri, xcap_query_params_t *xcap_params, cp_ruleset_t **dst);
43
+int get_pres_rules(const str_t *username, const str_t *filename, xcap_query_params_t *xcap_params, cp_ruleset_t **dst);
45 44
 void free_pres_rules(cp_ruleset_t *r);
46 45
 void free_pres_actions(cp_actions_t *a);
47 46
 
... ...
@@ -430,13 +430,14 @@ static int process_resource_list(const char *rl_uri, process_params_t *params)
430 430
 	return res;
431 431
 }
432 432
 
433
-static int create_flat_list(service_t *srv, xcap_query_params_t *xcap_params, const str_t *xcap_root, flat_list_t **dst)
433
+static int create_flat_list(service_t *srv, 
434
+		xcap_query_params_t *xcap_params, 
435
+		flat_list_t **dst)
434 436
 {
435 437
 	process_params_t params;
436 438
 	int res = -1;
437 439
 	if (!srv) return RES_INTERNAL_ERR;
438 440
 
439
-	params.xcap_root = xcap_root;
440 441
 	params.xcap_params = xcap_params;
441 442
 	params.flat = NULL;
442 443
 	params.flat_last = NULL;
... ...
@@ -518,30 +519,36 @@ static service_t *find_service(rls_services_t *rls, const str_t *uri)
518 519
 
519 520
 /* ------- rls examining ------- */
520 521
 
521
-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)
522
+int get_rls(const str_t *uri, xcap_query_params_t *xcap_params, 
523
+		const str_t *package, flat_list_t **dst)
522 524
 {
523 525
 	char *data = NULL;
524 526
 	int dsize = 0;
525 527
 	service_t *service = NULL;
526
-	char *xcap_uri;
528
+	char *xcap_uri = NULL;
529
+	str_t *filename = NULL;
527 530
 	int res;
528 531
 
529 532
 	if (!dst) return RES_INTERNAL_ERR;
530 533
 	
531 534
 	/* get basic document */
532
-	xcap_uri = xcap_uri_for_rls_resource(xcap_root, uri);
533
-	/* DEBUG_LOG("XCAP uri \'%s\'\n", xcap_uri ? xcap_uri: "???"); */
535
+	xcap_uri = xcap_uri_for_global_document(xcap_doc_rls_services, 
536
+			filename, xcap_params);
537
+	if (!xcap_uri) {
538
+		ERROR_LOG("can't get XCAP uri\n");
539
+		return RES_XCAP_QUERY_ERR;
540
+	}
541
+	
534 542
 	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
535 543
 	if (res != 0) {
536
-		ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri ? xcap_uri: "???");
544
+		ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri);
537 545
 		if (data) {
538 546
 			cds_free(data);
539 547
 		}
540
-		if (xcap_uri) cds_free(xcap_uri);
548
+		cds_free(xcap_uri);
541 549
 		return RES_XCAP_QUERY_ERR;
542 550
 	}
543
-	if (xcap_uri) cds_free(xcap_uri);
544
-	xcap_uri = NULL;
551
+	cds_free(xcap_uri);
545 552
 	
546 553
 	/* parse document as a service element in rls-sources */
547 554
 	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_
567 574
 	}
568 575
 	
569 576
 	/* create flat document */
570
-	res = create_flat_list(service, xcap_params, xcap_root, dst);
577
+	res = create_flat_list(service, xcap_params, dst);
571 578
 	if (res != RES_OK) {
572 579
 		ERROR_LOG("Flat list creation error\n");
573 580
 		free_service(service);
... ...
@@ -580,7 +587,10 @@ int get_rls(const str_t *xcap_root, const str_t *uri, xcap_query_params_t *xcap_
580 587
 	return RES_OK;
581 588
 }
582 589
 
583
-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)
590
+int get_rls_from_full_doc(const str_t *uri, 
591
+		/* const str_t *filename,  */
592
+		xcap_query_params_t *xcap_params, 
593
+		const str_t *package, flat_list_t **dst)
584 594
 {
585 595
 	char *data = NULL;
586 596
 	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
588 598
 	service_t *service = NULL;
589 599
 	str_t curi;
590 600
 	int res;
591
-	char *xcap_uri;
601
+	char *xcap_uri = NULL;
602
+	str_t *filename = NULL;
592 603
 
593 604
 	if (!dst) return RES_INTERNAL_ERR;
594 605
 	
595 606
 
596 607
 	/* get basic document */
597
-	xcap_uri = xcap_uri_for_rls_services(xcap_root);
598
-	DEBUG_LOG("XCAP uri \'%s\'\n", xcap_uri ? xcap_uri: "???");
608
+	xcap_uri = xcap_uri_for_global_document(xcap_doc_rls_services, 
609
+			filename, xcap_params);
610
+	if (!xcap_uri) {
611
+		ERROR_LOG("can't get XCAP uri\n");
612
+		return -1;
613
+	}
614
+	
599 615
 	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
600 616
 	if (res != 0) {
601
-		ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri ? xcap_uri: "???");
617
+		ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri);
602 618
 		if (data) {
603 619
 			cds_free(data);
604 620
 		}
605
-		if (xcap_uri) cds_free(xcap_uri);
621
+		cds_free(xcap_uri);
606 622
 		return RES_XCAP_QUERY_ERR;
607 623
 	}
608
-	if (xcap_uri) cds_free(xcap_uri);
609
-	xcap_uri = NULL;
624
+	cds_free(xcap_uri);
610 625
 	
611 626
 	/* parse document as a service element in rls-sources */
612 627
 	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
638 653
 	}
639 654
 	
640 655
 	/* create flat document */
641
-	res = create_flat_list(service, xcap_params, xcap_root, dst);
656
+	res = create_flat_list(service, xcap_params, dst);
642 657
 	if (res != RES_OK) {
643 658
 		ERROR_LOG("Flat list creation error\n");
644 659
 		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
651 666
 	return RES_OK;
652 667
 }
653 668
 
654
-char *xcap_uri_for_resource_list(const str_t *xcap_root, const str_t *user)
655
-{
656
-	dstring_t s;
657
-	int l;
658
-	char *dst = NULL;
659
-
660
-	if (!xcap_root) return NULL;
661
-	dstr_init(&s, 2 * xcap_root->len + 32);
662
-	dstr_append_str(&s, xcap_root);
663
-	if (xcap_root->s[xcap_root->len - 1] != '/') dstr_append(&s, "/", 1);
664
-	dstr_append_zt(&s, "resource-lists/users/");
665
-	dstr_append_str(&s, user);
666
-	dstr_append_zt(&s, "/resource-list.xml");
667
-	
668
-	l = dstr_get_data_length(&s);
669
-	if (l > 0) {
670
-		dst = (char *)cds_malloc(l + 1);
671
-		if (dst) {
672
-			dstr_get_data(&s, dst);
673
-			dst[l] = 0;
674
-		}
675
-	}
676
-	dstr_destroy(&s);
677
-	return dst;
678
-}
679
-
680 669
 static list_t *find_list(list_t *root, const char *name)
681 670
 {
682 671
 	list_content_t *c;
... ...
@@ -702,8 +691,9 @@ static list_t *find_list(list_t *root, const char *name)
702 691
 }
703 692
 
704 693
 /* catches and processes user's resource list as rls-services document */
705
-int get_resource_list_from_full_doc(const str_t *xcap_root, 
706
-		const str_t *user, xcap_query_params_t *xcap_params, 
694
+int get_resource_list_from_full_doc(const str_t *user, 
695
+		const str_t *filename, 
696
+		xcap_query_params_t *xcap_params, 
707 697
 		const char *list_name, flat_list_t **dst)
708 698
 {
709 699
 	char *data = NULL;
... ...
@@ -711,24 +701,28 @@ int get_resource_list_from_full_doc(const str_t *xcap_root,
711 701
 	service_t *service = NULL; 
712 702
 	list_t *list = NULL, *right = NULL;
713 703
 	int res;
714
-	char *xcap_uri;
704
+	char *uri = NULL;
715 705
 
716 706
 	if (!dst) return RES_INTERNAL_ERR;
717 707
 	
718 708
 	/* get basic document */
719
-	xcap_uri = xcap_uri_for_resource_list(xcap_root, user);
720
-	DEBUG_LOG("XCAP uri \'%s\'\n", xcap_uri ? xcap_uri: "???");
721
-	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
709
+	uri = xcap_uri_for_users_document(xcap_doc_resource_lists,
710
+			user, filename, xcap_params);
711
+	if (!uri) {
712
+		ERROR_LOG("can't get XCAP uri\n");
713
+		return -1;
714
+	}
715
+	DEBUG_LOG("XCAP uri \'%s\'\n", uri);
716
+	res = xcap_query(uri, xcap_params, &data, &dsize);
722 717
 	if (res != 0) {
723
-		ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri ? xcap_uri: "???");
718
+		ERROR_LOG("XCAP problems for uri \'%s\'\n", uri);
724 719
 		if (data) {
725 720
 			cds_free(data);
726 721
 		}
727
-		if (xcap_uri) cds_free(xcap_uri);
722
+		cds_free(uri);
728 723
 		return RES_XCAP_QUERY_ERR;
729 724
 	}
730
-	if (xcap_uri) cds_free(xcap_uri);
731
-	xcap_uri = NULL;
725
+	cds_free(uri);
732 726
 	
733 727
 	/* parse document as a list element in resource-lists */
734 728
 	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,
763 757
 	/*service->uri = ??? */
764 758
 
765 759
 	/* create flat document */
766
-	res = create_flat_list(service, xcap_params, xcap_root, dst);
760
+	res = create_flat_list(service, xcap_params, dst);
767 761
 
768 762
 	service->content.list = list; /* free whole document not only "right" list */
769 763
 	free_service(service);
... ...
@@ -42,8 +42,12 @@ typedef struct _flat_list_t {
42 42
 
43 43
 char *xcap_uri_for_rls_resource(const str_t *xcap_root, const str_t *uri);
44 44
 void canonicalize_uri(const str_t *uri, str_t *dst);
45
-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);
46
-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);
45
+int get_rls(const str_t *uri, xcap_query_params_t *xcap_params, 
46
+		const str_t *package, flat_list_t **dst);
47
+int get_rls_from_full_doc(const str_t *uri, 
48
+		/* const str_t *filename,  */
49
+		xcap_query_params_t *xcap_params, 
50
+		const str_t *package, flat_list_t **dst);
47 51
 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);
48 52
 /* 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); */
49 53
 void free_flat_list(flat_list_t *list);
50 54
deleted file mode 100644
... ...
@@ -1,189 +0,0 @@
1
-/* 
2
- * Copyright (C) 2005 iptelorg GmbH
3
- *
4
- * This file is part of ser, a free SIP server.
5
- *
6
- * ser is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * For a license to use the ser software under conditions
12
- * other than those described here, or to purchase support for this
13
- * software, please contact iptel.org by e-mail at the following addresses:
14
- *    info@iptel.org
15
- *
16
- * ser is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
- * GNU General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program; if not, write to the Free Software
23
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
- */
25
-
26
-#include <stdio.h>
27
-#include <stdlib.h>
28
-#include <string.h>
29
-
30
-#include <libxml/parser.h>
31
-#include <curl/curl.h>
32
-#include <xcap/xcap_client.h>
33
-#include <xcap/pres_rules.h>
34
-#include <xcap/parse_pres_rules.h>
35
-#include <xcap/common_policy.h>
36
-#include <cds/sstr.h>
37
-#include <cds/dstring.h>
38
-#include <cds/memory.h>
39
-
40
-void trace_conditions(cp_conditions_t *c)
41
-{
42
-	cp_sphere_t *s;
43
-	cp_id_t *i;
44
-	cp_domain_t *d;
45
-	cp_except_t *e;
46
-	
47
-	printf(" - conditions: \n"); 
48
-	if (!c) return;
49
-
50
-	printf("   +- validity: "); 
51
-	if (c->validity) 
52
-		printf("from %s to %s", 
53
-				ctime(&c->validity->from), 
54
-				ctime(&c->validity->to));
55
-	printf("\n");
56
-	
57
-	printf("   +- identity: \n"); 
58
-	if (c->identity) {
59
-		printf("      +- ids: "); 
60
-		i = c->identity->ids;
61
-		while (i) {
62
-			if (i != c->identity->ids) printf(", ");
63
-			printf("%.*s", FMT_STR(i->entity));
64
-			i = i->next;
65
-		}
66
-		printf("\n");
67
-		
68
-		printf("      +- domains: "); 
69
-		d = c->identity->domains;
70
-		while (d) {
71
-			if (d != c->identity->domains) printf(", ");
72
-			printf("%.*s", FMT_STR(d->domain));
73
-			d = d->next;
74
-		}
75
-		printf("\n");
76
-
77
-		printf("      +- except: "); 
78
-		e = c->identity->excepts;
79
-		while (e) {
80
-			if (e != c->identity->excepts) printf(", ");
81
-			printf("%.*s", FMT_STR(e->entity));
82
-			e = e->next;
83
-		}
84
-		printf("\n");
85
-	}
86
-	
87
-	printf("   +- spheres: "); 
88
-	s = c->spheres;
89
-	while (s) {
90
-		if (s != c->spheres) printf(", ");
91
-		printf("%.*s", FMT_STR(s->value));
92
-		s = s->next;
93
-	}
94
-	printf("\n");
95
-}
96
-
97
-void trace_actions(cp_actions_t *a)
98
-{
99
-	printf(" - actions: \n"); 
100
-	if (!a) return;
101
-	if (a->unknown) {
102
-		printf("    sub-handling: ");
103
-		sub_handling_t *sh = (sub_handling_t*)a->unknown->data;
104
-		switch (*sh) {
105
-			case sub_handling_block: printf("block"); break;
106
-			case sub_handling_confirm: printf("confirm"); break;
107
-			case sub_handling_polite_block: printf("polite block"); break;
108
-			case sub_handling_allow: printf("allow"); break;
109
-		}
110
-		printf("\n");
111
-	}
112
-}
113
-
114
-void trace_transformations(cp_transformations_t *c)
115
-{
116
-	printf(" - transformations: \n"); 
117
-}
118
-
119
-void trace_pres_rules(cp_ruleset_t *rules)
120
-{
121
-	cp_rule_t *r;
122
-	
123
-	if (!rules) {
124
-		printf("null ruleset!\n");
125
-		return;
126
-	}
127
-
128
-	r = rules->rules;
129
-	while (r) {
130
-		printf("rule \'%.*s\'\n", FMT_STR(r->id));
131
-		trace_conditions(r->conditions);
132
-		trace_actions(r->actions);
133
-		trace_transformations(r->transformations);
134
-		r = r->next;
135
-	}
136
-	
137
-}
138
-		
139
-void test_rules(cp_ruleset_t *pres_rules, const char *uri)
140
-{
141
-	sub_handling_t sh;
142
-	str_t s = zt2str((char *)uri);
143
-
144
-	sh = sub_handling_confirm;
145
-	get_pres_rules_action(pres_rules, &s, &sh);
146
-
147
-	printf("rules for %s: ", uri);
148
-	switch (sh) {
149
-		case sub_handling_block: printf("block"); break;
150
-		case sub_handling_confirm: printf("confirm"); break;
151
-		case sub_handling_polite_block: printf("polite block"); break;
152
-		case sub_handling_allow: printf("allow"); break;
153
-	}
154
-	printf("\n");
155
-}
156
-
157
-int pres_rules_test(const char *xcap_root, const char *uri)
158
-{
159
-	cp_ruleset_t *pres_rules = NULL;
160
-	xcap_query_params_t xcap;
161
-	int res;
162
-	str_t u;
163
-	
164
-	u.s = (char *)uri;
165
-	u.len = u.s ? strlen(u.s): 0;
166
-	
167
-	/* XCAP test */
168
-	memset(&xcap, 0, sizeof(xcap));
169
-	xcap.auth_user = "smith";
170
-	xcap.auth_pass = "pass";
171
-	xcap.enable_unverified_ssl_peer = 1;
172
-	res = get_pres_rules(xcap_root, &u, &xcap, &pres_rules);
173
-	if (res != 0) {
174
-		printf("XCAP problems!\n");
175
-		return -1;
176
-	}
177
-
178
-	if (pres_rules) {
179
-		trace_pres_rules(pres_rules);
180
-		test_rules(pres_rules, "pavel@iptel.org");
181
-		test_rules(pres_rules, "nekdo@neco.cz");
182
-		test_rules(pres_rules, "all:n@neco.cz");
183
-
184
-		free_pres_rules(pres_rules);
185
-	}
186
-	
187
-	return 0;
188
-}
189
-
190 0
deleted file mode 100644
... ...
@@ -1,265 +0,0 @@
1
-/* 
2
- * Copyright (C) 2005 iptelorg GmbH
3
- *
4
- * This file is part of ser, a free SIP server.
5
- *
6
- * ser is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * For a license to use the ser software under conditions
12
- * other than those described here, or to purchase support for this
13
- * software, please contact iptel.org by e-mail at the following addresses:
14
- *    info@iptel.org
15
- *
16
- * ser is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
- * GNU General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program; if not, write to the Free Software
23
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
- */
25
-
26
-#include <stdio.h>
27
-#include <stdlib.h>
28
-#include <string.h>
29
-
30
-#include <libxml/parser.h>
31
-#include <curl/curl.h>
32
-
33
-#include <xcap/resource_list.h>
34
-#include <xcap/resource_lists_parser.h>
35
-#include <xcap/rls_services_parser.h>
36
-#include <xcap/xcap_client.h>
37
-
38
-#define STR_OK(s)	(s)?(s):""
39
-
40
-void print_indent(int indent)
41
-{
42
-	int i;
43
-	
44
-	for (i = 0; i < indent; i++) printf("  ");
45
-	if (indent > 0) printf(" + ");
46
-}
47
-
48
-void trace_entry(entry_t *e, int indent)
49
-{
50
-	if (!e) return;
51
-	
52
-	print_indent(indent);
53
-	if (e->uri) printf("%s\n", e->uri);
54
-	else printf("???\n");
55
-}
56
-
57
-void trace_entry_ref(entry_ref_t *e, int indent)
58
-{
59
-	if (!e) return;
60
-	
61
-	print_indent(indent);
62
-	if (e->ref) printf("ref: %s\n", e->ref);
63
-	else printf("ref: ???\n");
64
-}
65
-
66
-void trace_external(external_t *e, int indent)
67
-{
68
-	if (!e) return;
69
-	
70
-	print_indent(indent);
71
-	if (e->anchor) printf("ext: %s\n", e->anchor);
72
-	else printf("ext: ???\n");
73
-}
74
-
75
-void trace_list(list_t *l, int indent)
76
-{
77
-	list_content_t *e;
78
-
79
-	if (!l) return;
80
-	
81
-	print_indent(indent);
82
-	
83
-	if (l->name) printf("%s\n", l->name);
84
-	else printf("???\n");
85
-
86
-	e = SEQUENCE_FIRST(l->content);
87
-	while (e) {
88
-		switch (e->type) {
89
-			case lct_list: trace_list(e->u.list, indent + 1); break;
90
-			case lct_entry: trace_entry(e->u.entry, indent + 1); break;
91
-			case lct_entry_ref: trace_entry_ref(e->u.entry_ref, indent + 1); break;
92
-			case lct_external: trace_external(e->u.external, indent + 1); break;
93
-		}
94
-		e = SEQUENCE_NEXT(e);
95
-	}
96
-}
97
-
98
-void trace_resource_lists(resource_lists_t *rl)
99
-{
100
-	list_t *e;
101
-	if (!rl) {
102
-		printf("empty list\n");
103
-		return;
104
-	}
105
-	
106
-	e = SEQUENCE_FIRST(rl->lists);
107
-	while (e) {
108
-		trace_list(e, 0);
109
-		e = SEQUENCE_NEXT(e);
110
-	}
111
-}
112
-
113
-void trace_packages(packages_t *p)
114
-{
115
-	package_t *e;
116
-	int first = 1;
117
-	
118
-	printf(" [packages: ");
119
-	if (p) {
120
-		e = SEQUENCE_FIRST(p->package);
121
-		while (e) {
122
-			if (!first) printf(" ");
123
-			else first = 0;
124
-			printf("%s", e->name);
125
-			e = SEQUENCE_NEXT(e);
126
-		}
127
-	}
128
-	printf("]");
129
-}
130
-
131
-void trace_service(service_t *l, int indent)
132
-{
133
-	if (!l) return;
134
-	
135
-	print_indent(indent);
136
-	
137
-	if (l->uri) printf("%s", l->uri);
138
-	else printf("???");
139
-	if (l->packages) trace_packages(l->packages);
140
-	printf("\n");
141
-
142
-	switch (l->content_type) {
143
-		case stc_list: trace_list(l->content.list, indent + 1); break;
144
-		case stc_resource_list: print_indent(indent + 1);
145
-								printf("@ %s\n", STR_OK(l->content.resource_list));
146
-								break;
147
-	}
148
-}
149
-
150
-void trace_rls_services(rls_services_t *rl)
151
-{
152
-	service_t *e;
153
-	if (!rl) {
154
-		printf("empty rls-services\n");
155
-		return;
156
-	}
157
-	
158
-	e = SEQUENCE_FIRST(rl->rls_services);
159
-	while (e) {
160
-		trace_service(e, 0);
161
-		e = SEQUENCE_NEXT(e);
162
-	}
163
-}
164
-
165
-void trace_flat_list(flat_list_t *list)
166
-{
167
-	flat_list_t *e = list;
168
-	
169
-	while (e) {
170
-		if (e->uri) printf("%s\n", e->uri);
171
-		else printf("???\n");
172
-		e = e->next;
173
-	}
174
-}
175
-
176
-/* -------------------------------------------------------------------------------- */
177
-
178
-#if 0
179
-
180
-static int xcap_test(const char *xcap_root, const char *uri)
181
-{
182
-	char *data = NULL;
183
-	int dsize = 0;
184
-	/* resource_lists_t *res_list = NULL; */
185
-	rls_services_t *rls = NULL;
186
-	service_t *service = NULL;
187
-	xcap_query_t xcap;
188
-	int res;
189
-	str_t u = zt2str((char *)uri);
190
-	
191
-	/* XCAP test */
192
-	xcap.uri = xcap_uri_for_rls_resource(xcap_root, &u);
193
-	xcap.auth_user = "smith";
194
-	xcap.auth_pass = "pass";
195
-	xcap.enable_unverified_ssl_peer = 1;
196
-	res = xcap_query(&xcap, &data, &dsize);
197
-	if (res != 0) {
198
-		printf("XCAP problems!\n");
199
-		if (xcap.uri) printf("URI = %s\n", xcap.uri);
200
-		else printf("XCAP URI not defined!\n");
201
-		if (data) {
202
-			printf("%s\n", data);
203
-			free(data);
204
-		}
205
-		return -1;
206
-	}
207
-
208
-/*	printf("%s\n", data);*/
209
-
210
-	/* parse input data */
211
-	/*if (parse_resource_lists_xml(data, dsize, &res_list) != 0) {
212
-		printf("Error occured during document parsing!\n");
213
-	}
214
-	else { 
215
-		trace_resource_lists(res_list);
216
-		if (res_list) free_resource_lists(res_list);
217
-	}*/
218
-	
219
-	if (parse_rls_services_xml(data, dsize, &rls) == 0) {
220
-		trace_rls_services(rls);
221
-		if (rls) free_rls_services(rls);
222
-	}
223
-	else {
224
-		/* try to take it as a service */
225
-		if (parse_service(data, dsize, &service) == 0) {
226
-			if (service) {
227
-				trace_service(service, 0);
228
-				free_service(service);
229
-			}
230
-		}
231
-		else {
232
-			printf("Error occured during document parsing! It is not rls-services nor service.\n");
233
-			if (dsize > 0) printf("%.*s\n", dsize, data);
234
-		}
235
-	}
236
-
237
-	if (data) free(data);
238
-	return 0;
239
-}
240
-
241
-#endif
242
-
243
-int test_flat(const str_t *xcap_root, const char *uri)
244
-{
245
-	str_t u = zt2str((char *)uri);
246
-	xcap_query_params_t xcap;
247
-	flat_list_t *list = NULL;
248
-	str_t p = zt2str("presence");
249
-	
250
-	xcap.auth_user = "smith";
251
-	xcap.auth_pass = "pass";
252
-	xcap.enable_unverified_ssl_peer = 1;
253
-	
254
-	if (get_rls(xcap_root, &u, &xcap, &p, &list) != 0) {
255
-		if (list) free_flat_list(list);
256
-		printf("Failed !\n");
257
-		return -1;
258
-	}
259
-
260
-	trace_flat_list(list);
261
-	free_flat_list(list);
262
-	
263
-	return 0;
264
-}
265
-
... ...
@@ -31,6 +31,159 @@
31 31
 #include <cds/dstring.h>
32 32
 #include <cds/memory.h>
33 33
 #include <cds/logger.h>
34
+
35
+static const str_t *get_xcap_doc_dir(xcap_document_type_t doc_type)
36
+{
37
+	static str_t pres_rules = STR_STATIC_INIT("pres-rules");
38
+	static str_t im_rules = STR_STATIC_INIT("im-rules");
39
+	static str_t rls_services = STR_STATIC_INIT("rls-services");
40
+	static str_t resource_lists = STR_STATIC_INIT("resource-lists");
41
+
42
+	switch (doc_type) {
43
+		case xcap_doc_pres_rules: return &pres_rules;
44
+		case xcap_doc_im_rules: return &im_rules;
45
+		case xcap_doc_rls_services: return &rls_services;
46
+		case xcap_doc_resource_lists: return &resource_lists;
47
+		/* when new doc_type added, there will be a warning -> add it there */
48
+	}
49
+	WARN_LOG("unknow XCAP document type\n");
50
+	return NULL;
51
+}
52
+
53
+static const str_t *get_default_user_doc(xcap_document_type_t doc_type)
54
+{
55
+	static str_t pres_rules = STR_STATIC_INIT("presence-rules.xml");
56
+	static str_t im_rules = STR_STATIC_INIT("im-rules.xml");
57
+	static str_t rls_services = STR_STATIC_INIT("rls-services.xml");
58
+	static str_t resource_lists = STR_STATIC_INIT("resource-list.xml");
59
+
60
+	switch (doc_type) {
61
+		case xcap_doc_pres_rules: return &pres_rules;
62
+		case xcap_doc_im_rules: return &im_rules;
63
+		case xcap_doc_rls_services: return &rls_services;
64
+		case xcap_doc_resource_lists: return &resource_lists;
65
+		/* when new doc_type added, there will be a warning -> add it there */
66
+	}
67
+	WARN_LOG("unknow XCAP document type\n");
68
+	return NULL;
69
+}
70
+
71
+static int ends_with_separator(str_t *s)
72
+{
73
+	if (!is_str_empty(s))
74
+		if (s->s[s->len - 1] == '/') return 1;
75
+	return 0;
76
+}
77
+
78
+char *xcap_uri_for_users_document(xcap_document_type_t doc_type,
79
+		const str_t *username, 
80
+		const str_t*filename,
81
+		xcap_query_params_t *params)
82
+{
83
+	dstring_t s;
84
+	/* int res = RES_OK; */
85
+	int l = 0;
86
+	char *dst = NULL;
87
+
88
+	dstr_init(&s, 128);
89
+	if (params) {
90
+		dstr_append_str(&s, &params->xcap_root);
91
+		if (!ends_with_separator(&params->xcap_root))
92
+			dstr_append(&s, "/", 1);
93
+	}
94
+	else dstr_append(&s, "/", 1);
95
+	dstr_append_str(&s, get_xcap_doc_dir(doc_type));
96
+	dstr_append_zt(&s, "/users/");
97
+	dstr_append_str(&s, username);
98
+	dstr_append(&s, "/", 1);
99
+	if (filename) dstr_append_str(&s, filename);
100
+	else {
101
+		/* default filename if NULL */
102
+		dstr_append_str(&s, get_default_user_doc(doc_type));
103
+	}
104
+	/* res = dstr_get_str(&s, dst); */
105
+	
106
+	l = dstr_get_data_length(&s);
107
+	if (l > 0) {
108
+		dst = (char *)cds_malloc(l + 1);
109
+		if (dst) {
110
+			dstr_get_data(&s, dst);
111
+			dst[l] = 0;
112
+		}
113
+		else ERROR_LOG("can't allocate memory (%d bytes)\n", l);
114
+	}
115
+	
116
+	dstr_destroy(&s);
117
+	return dst;
118
+}
119
+
120
+
121
+char *xcap_uri_for_global_document(xcap_document_type_t doc_type,
122
+		const str_t *filename, 
123
+		xcap_query_params_t *params)
124
+{
125
+	dstring_t s;
126
+	/* int res = RES_OK; */
127
+	char *dst = NULL;
128
+	int l = 0;
129
+
130
+	dstr_init(&s, 128);
131
+	if (params) {
132
+		dstr_append_str(&s, &params->xcap_root);
133
+		if (!ends_with_separator(&params->xcap_root))
134
+			dstr_append(&s, "/", 1);
135
+	}
136
+	else dstr_append(&s, "/", 1);
137
+	dstr_append_str(&s, get_xcap_doc_dir(doc_type));
138
+	if (filename) {
139
+		dstr_append_zt(&s, "/global/");
140
+		dstr_append_str(&s, filename);
141
+	}
142
+	else {
143
+		/* default filename if NULL */
144
+		dstr_append_zt(&s, "/global/index");
145
+	}
146
+	/* res = dstr_get_str(&s, dst); */
147
+	
148
+	l = dstr_get_data_length(&s);
149
+	if (l > 0) {
150
+		dst = (char *)cds_malloc(l + 1);
151
+		if (dst) {
152
+			dstr_get_data(&s, dst);
153
+			dst[l] = 0;
154
+		}
155
+	}
156
+	
157
+	dstr_destroy(&s);
158
+	return dst;
159
+}
160
+
161
+#ifdef SER
162
+
163
+#include "sr_module.h"
164
+
165
+int xcap_query(const char *uri, 
166
+		xcap_query_params_t *params, char **buf, int *bsize)
167
+{
168
+	static xcap_query_func query = NULL;
169
+	static int initialized = 0;
170
+
171
+	if (!initialized) {
172
+		query = (xcap_query_func)find_export("xcap_query", 0, -1);
173
+		initialized = 1;
174
+		if (!query) WARN_LOG("No XCAP query support! (Missing module?)\n");
175
+	}
176
+	if (!query) {
177
+		/* no function for doing XCAP queries */
178
+		return -1;
179
+	}
180
+	
181
+	/* all XCAP queries are done through XCAP module */
182
+	return query(uri, params, buf, bsize);
183
+}
184
+
185
+#else /* compiled WITHOUT SER */
186
+
34 187
 #include <curl/curl.h>
35 188
 
36 189
 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
46 199
 	return s;
47 200
 }
48 201
 
49
-int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bsize)
202
+
203
+int xcap_query(const str_t *uri, xcap_query_params_t *params, char **buf, int *bsize)
50 204
 {
51 205
 	CURLcode res = -1;
52
-	static CURL *handle = NULL; /*FIXME: experimental*/
206
+	static CURL *handle = NULL;
53 207
 	dstring_t data;
54 208
 	char *auth = NULL;
55 209
 	int i;
... ...
@@ -75,7 +229,7 @@ int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bs
75 229
 	
76 230
 	dstr_init(&data, 512);
77 231
 	
78
-	if (!handle) handle = curl_easy_init(); /*FIXME: experimental*/
232
+	if (!handle) handle = curl_easy_init(); 
79 233
 	if (handle) {
80 234
 		curl_easy_setopt(handle, CURLOPT_URL, uri);
81 235
 		/* 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
106 260
 		/* follow redirects (needed for apache mod_speling - case insesitive names) */
107 261
 		curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
108 262
 		
109
-		/* FIXME: experimetns */
110 263
 	/*	curl_easy_setopt(handle, CURLOPT_TCP_NODELAY, 1);
111 264
 		curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 10);*/
112 265
 		
... ...
@@ -134,9 +287,12 @@ int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bs
134 287
 	return res;
135 288
 }
136 289
 
290
+#endif
291
+
137 292
 void free_xcap_params_content(xcap_query_params_t *params)
138 293
 {
139 294
 	if (params) {
295
+		str_free_content(&params->xcap_root);
140 296
 		if (params->auth_user) cds_free(params->auth_user);
141 297
 		if (params->auth_pass) cds_free(params->auth_pass);
142 298
 		memset(params, 0, sizeof(*params));
... ...
@@ -145,22 +301,37 @@ void free_xcap_params_content(xcap_query_params_t *params)
145 301
 
146 302
 int dup_xcap_params(xcap_query_params_t *dst, xcap_query_params_t *src)
147 303
 {
304
+	int res = -10;
305
+	
148 306
 	if (dst) memset(dst, 0, sizeof(*dst));
149 307
 	
150 308
 	if (src && dst) {
151
-		if (src->auth_user) {
309
+		res = 0;
310
+		
311
+		res = str_dup(&dst->xcap_root, &src->xcap_root);
312
+		
313
+		if ((res == 0) && (src->auth_user)) {
152 314
 			dst->auth_user = zt_strdup(src->auth_user);
153
-			if (!dst->auth_user) return -1;
315
+			if (!dst->auth_user) res = -1;
154 316
 		}
155
-		if (src->auth_pass) {
317
+		if ((res == 0) && (src->auth_pass)) {
156 318
 			dst->auth_pass = zt_strdup(src->auth_pass);
157
-			if (!dst->auth_pass) {
158
-				free_xcap_params_content(dst);
159
-				return -2;
160
-			}
319
+			if (!dst->auth_pass) res= -2;
161 320
 		}
321
+
322
+		if (res != 0) free_xcap_params_content(dst);
162 323
 	}
163 324
 	
164
-	return 0;
325
+	return res;
326
+}
327
+
328
+int str2xcap_params(xcap_query_params_t *dst, const str_t *src)
329
+{
330
+	return -1;
331
+}
332
+
333
+int xcap_params2str(str_t *dst, const xcap_query_params_t *src)
334
+{
335
+	return -1;
165 336
 }
166 337
 
... ...
@@ -26,7 +26,12 @@
26 26
 #ifndef __XCAP_CLIENT_H
27 27
 #define __XCAP_CLIENT_H
28 28
 
29
+#include <cds/sstr.h>
30
+#include <xcap/xcap_result_codes.h>
31
+
29 32
 typedef struct {
33
+	/* "prefix" for XCAP query */
34
+	str_t xcap_root;
30 35
 	/** username for authentication */
31 36
 	char *auth_user;
32 37
 	/** password used for authentication */
... ...
@@ -37,13 +42,37 @@ typedef struct {
37 42
 	int enable_unverified_ssl_peer;
38 43
 } xcap_query_params_t;
39 44
 
45
+typedef enum {
46
+	xcap_doc_pres_rules,
47
+	xcap_doc_im_rules,
48
+	xcap_doc_rls_services,
49
+	xcap_doc_resource_lists
50
+} xcap_document_type_t;
51
+
52
+char *xcap_uri_for_users_document(xcap_document_type_t doc_type,
53
+		const str_t *username, 
54
+		const str_t*filename,
55
+		xcap_query_params_t *params);
56
+
57
+char *xcap_uri_for_global_document(xcap_document_type_t doc_type,
58
+		const str_t *filename,
59
+		xcap_query_params_t *params);
60
+
40 61
 /** Sends a XCAP query to the destination and using parameters from 
41 62
  * query variable a returns received data in output variables buf
42 63
  * and bsize. */
43
-/* URI is full HTTP/HTTPS uri for the query */
44
-int xcap_query(const char *uri, xcap_query_params_t *params, char **buf, int *bsize);
64
+/* URI is absolute HTTP/HTTPS uri for the query  */
65
+int xcap_query(const char *uri, xcap_query_params_t *params, 
66
+		char **buf, int *bsize);
67
+
68
+typedef int (*xcap_query_func)(const char *uri, 
69
+		xcap_query_params_t *params, 
70
+		char **buf, int *bsize);
45 71
 
46 72
 void free_xcap_params_content(xcap_query_params_t *params);
47 73
 int dup_xcap_params(xcap_query_params_t *dst, xcap_query_params_t *src);
48 74
 
75
+int str2xcap_params(xcap_query_params_t *dst, const str_t *src);
76
+int xcap_params2str(str_t *dst, const xcap_query_params_t *src);
77
+
49 78
 #endif