annotate sip-manual-out/uac.c @ 240:c7a3ba56c636

themwi-short-dial: fix bug in printf arguments
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 14 Aug 2023 15:37:59 -0800
parents 10a4b0b0a239
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * Here we implement processing of SIP responses to the requests we sent out.
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 */
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 #include <sys/types.h>
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 #include <sys/socket.h>
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 #include <netinet/in.h>
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 #include <arpa/inet.h>
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <stdio.h>
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <stdlib.h>
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <string.h>
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <strings.h>
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include "../libsip/parse.h"
118
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
14 #include "../libsip/resp_ident.h"
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include "../libsip/out_msg.h"
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 #define MAX_TO_TAG 63
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 extern char *get_single_header();
73
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
20 extern char *extract_to_tag();
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 extern struct in_addr sip_bind_ip;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 extern unsigned sip_bind_port;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 extern char call_id[], from_uri[], to_uri[];
120
c62d0f28da6f sip-manual-out: make Max-Forwards configurable
Mychaela Falconia <falcon@freecalypso.org>
parents: 118
diff changeset
25 extern unsigned max_forwards;
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 char to_tag[MAX_TO_TAG+1];
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28
123
a36b731bfef9 sip-manual-out: implement sending BYE and CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents: 120
diff changeset
29 add_req_boilerplate(msg, cseq, add_to_tag)
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 struct sip_msg_out *msg;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 char *cseq;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 {
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 char strbuf[256];
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 int rc;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 sprintf(strbuf, "SIP/2.0/UDP %s:%u",
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 inet_ntoa(sip_bind_ip), sip_bind_port);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 rc = out_msg_add_header(msg, "Via", strbuf);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 if (rc < 0)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 return rc;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 rc = out_msg_add_header(msg, "From", from_uri);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 if (rc < 0)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 return rc;
123
a36b731bfef9 sip-manual-out: implement sending BYE and CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents: 120
diff changeset
44 if (add_to_tag && to_tag[0]) {
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 sprintf(strbuf, "<%s>;tag=%s", to_uri, to_tag);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 rc = out_msg_add_header(msg, "To", strbuf);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 } else
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 rc = out_msg_add_header(msg, "To", to_uri);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 if (rc < 0)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 return rc;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 rc = out_msg_add_header(msg, "Call-ID", call_id);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 if (rc < 0)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 return rc;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 rc = out_msg_add_header(msg, "CSeq", cseq);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 if (rc < 0)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 return rc;
120
c62d0f28da6f sip-manual-out: make Max-Forwards configurable
Mychaela Falconia <falcon@freecalypso.org>
parents: 118
diff changeset
57 sprintf(strbuf, "%u", max_forwards);
c62d0f28da6f sip-manual-out: make Max-Forwards configurable
Mychaela Falconia <falcon@freecalypso.org>
parents: 118
diff changeset
58 return out_msg_add_header(msg, "Max-Forwards", strbuf);
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 }
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 add_contact_header(msg)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 struct sip_msg_out *msg;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 {
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 char strbuf[80];
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 sprintf(strbuf, "<sip:%s:%u;transport=udp>",
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 inet_ntoa(sip_bind_ip), sip_bind_port);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 return out_msg_add_header(msg, "Contact", strbuf);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 }
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 static void
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 send_ack(sin)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 struct sockaddr_in *sin;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 {
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 struct sip_msg_out msg;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 int rc;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 rc = start_request_out_msg(&msg, "ACK", to_uri);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 if (rc < 0) {
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 msg_size_err: fprintf(stderr, "composing ACK message: size error\n");
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 return;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 }
123
a36b731bfef9 sip-manual-out: implement sending BYE and CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents: 120
diff changeset
83 rc = add_req_boilerplate(&msg, "1 ACK", 1);
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 if (rc < 0)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 goto msg_size_err;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 out_msg_finish(&msg);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 sip_tx_packet(&msg, sin);
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 }
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 static void
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 handle_invite_response(msg, sin)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 struct sip_pkt_rx *msg;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 struct sockaddr_in *sin;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 {
73
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
95 char *tag;
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
96
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 printf("Response to INVITE: %s\n", msg->status_str);
73
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
98 tag = extract_to_tag(msg, to_uri);
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
99 if (tag) {
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
100 printf("To tag: %s\n", tag);
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
101 if (strlen(tag) <= MAX_TO_TAG)
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
102 strcpy(to_tag, tag);
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
103 else
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
104 printf("To tag exceeds length limit!\n");
d7b6b8973a83 sip-manual-out: handle To tag
Mychaela Falconia <falcon@freecalypso.org>
parents: 71
diff changeset
105 }
214
10a4b0b0a239 sip-manual-out: parse SDP for all responses, not just 200
Mychaela Falconia <falcon@freecalypso.org>
parents: 191
diff changeset
106 extract_resp_sdp(msg);
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 if (msg->status_code >= 200) {
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 printf("Sending ACK\n");
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 send_ack(sin);
191
6ac96217c442 sip-manual-out: add SDP response parsing
Mychaela Falconia <falcon@freecalypso.org>
parents: 123
diff changeset
110 if (msg->status_code <= 299)
214
10a4b0b0a239 sip-manual-out: parse SDP for all responses, not just 200
Mychaela Falconia <falcon@freecalypso.org>
parents: 191
diff changeset
111 invite_200_rtpout();
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 }
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 }
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 void
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 process_sip_response(msg, sin)
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 struct sip_pkt_rx *msg;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 struct sockaddr_in *sin;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119 {
118
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
120 struct sip_resp_ident rid;
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
121 int rc;
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122
118
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
123 rc = sip_resp_extract_ident(msg, &rid);
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
124 if (rc < 0) {
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
125 printf("SIP %03u response: bad or missing %s header\n",
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
126 msg->status_code, rid.error_field);
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
127 return;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
128 }
118
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
129 if (strcmp(rid.call_id, call_id)) {
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
130 printf("Got SIP response with wrong Call-ID\n");
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
131 return;
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
132 }
118
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
133 if (rid.cseq_num == 1 && !strcmp(rid.cseq_method, "INVITE"))
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
134 handle_invite_response(msg, sin);
123
a36b731bfef9 sip-manual-out: implement sending BYE and CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents: 120
diff changeset
135 else if (rid.cseq_num == 1 && !strcmp(rid.cseq_method, "CANCEL"))
a36b731bfef9 sip-manual-out: implement sending BYE and CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents: 120
diff changeset
136 printf("Response to CANCEL: %s\n", msg->status_str);
a36b731bfef9 sip-manual-out: implement sending BYE and CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents: 120
diff changeset
137 else if (rid.cseq_num == 2 && !strcmp(rid.cseq_method, "BYE"))
a36b731bfef9 sip-manual-out: implement sending BYE and CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents: 120
diff changeset
138 printf("Response to BYE: %s\n", msg->status_str);
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
139 else
118
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
140 printf("Got SIP resp for our Call-ID with unknown CSeq %u %s\n",
a4450ae8fd09 sip-manual-out UAC: use the new CSeq parsing function
Mychaela Falconia <falcon@freecalypso.org>
parents: 73
diff changeset
141 rid.cseq_num, rid.cseq_method);
71
d74b545a3c2a sip-manual-out: new test program
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
142 }