6 * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "sip-internal.h"
25 #include "gaim-compat.h"
26 #include "accountopt.h"
28 #include "conversation.h"
39 struct sipmsg
*sipmsg_parse_msg(const gchar
*msg
) {
40 const char *tmp
= strstr(msg
, "\r\n\r\n");
46 line
= g_strndup(msg
, tmp
- msg
);
48 smsg
= sipmsg_parse_header(line
);
49 smsg
->body
= g_strdup(tmp
+ 4);
55 struct sipmsg
*sipmsg_parse_header(const gchar
*header
) {
56 struct sipmsg
*msg
= g_new0(struct sipmsg
,1);
57 gchar
**lines
= g_strsplit(header
,"\r\n",0);
63 if(!lines
[0]) return NULL
;
64 parts
= g_strsplit(lines
[0], " ", 3);
65 if(!parts
[0] || !parts
[1] || !parts
[2]) {
71 if(strstr(parts
[0],"SIP")) { /* numeric response */
72 msg
->method
= g_strdup(parts
[2]);
73 msg
->response
= strtol(parts
[1],NULL
,10);
74 } else { /* request */
75 msg
->method
= g_strdup(parts
[0]);
76 msg
->target
= g_strdup(parts
[1]);
80 for(i
=1; lines
[i
] && strlen(lines
[i
])>2; i
++) {
81 parts
= g_strsplit(lines
[i
], ":", 2);
82 if(!parts
[0] || !parts
[1]) {
90 while(*dummy
==' ' || *dummy
=='\t') dummy
++;
91 dummy2
= g_strdup(dummy
);
92 while(lines
[i
+1] && (lines
[i
+1][0]==' ' || lines
[i
+1][0]=='\t')) {
95 while(*dummy
==' ' || *dummy
=='\t') dummy
++;
96 tmp
= g_strdup_printf("%s %s",dummy2
, dummy
);
100 sipmsg_add_header(msg
, parts
[0], dummy2
);
104 msg
->bodylen
= strtol(sipmsg_find_header(msg
, "Content-Length"),NULL
,10);
106 tmp
= sipmsg_find_header(msg
, "CSeq");
108 /* SHOULD NOT HAPPEN */
111 parts
= g_strsplit(tmp
, " ", 2);
112 msg
->method
= g_strdup(parts
[1]);
119 void sipmsg_print(const struct sipmsg
*msg
) {
121 struct siphdrelement
*elem
;
122 gaim_debug(GAIM_DEBUG_MISC
, "sipe", "SIP MSG\n");
123 gaim_debug(GAIM_DEBUG_MISC
, "sipe", "response: %d\nmethod: %s\nbodylen: %d\n",msg
->response
,msg
->method
,msg
->bodylen
);
124 if(msg
->target
) gaim_debug(GAIM_DEBUG_MISC
, "sipe", "target: %s\n",msg
->target
);
128 gaim_debug(GAIM_DEBUG_MISC
, "sipe", "name: %s value: %s\n",elem
->name
, elem
->value
);
129 cur
= g_slist_next(cur
);
133 char *sipmsg_to_string(const struct sipmsg
*msg
) {
135 GString
*outstr
= g_string_new("");
136 struct siphdrelement
*elem
;
139 g_string_append_printf(outstr
, "SIP/2.0 %d Unknown\r\n",
142 g_string_append_printf(outstr
, "%s %s SIP/2.0\r\n",
143 msg
->method
, msg
->target
);
148 g_string_append_printf(outstr
, "%s: %s\r\n", elem
->name
,
150 cur
= g_slist_next(cur
);
153 g_string_append_printf(outstr
, "\r\n%s", msg
->bodylen
? msg
->body
: "");
155 return g_string_free(outstr
, FALSE
);
157 void sipmsg_add_header(struct sipmsg
*msg
, const gchar
*name
, const gchar
*value
) {
158 struct siphdrelement
*element
= g_new0(struct siphdrelement
,1);
159 element
->name
= g_strdup(name
);
160 element
->value
= g_strdup(value
);
161 msg
->headers
= g_slist_append(msg
->headers
, element
);
164 void sipmsg_add_header_pos(struct sipmsg
*msg
, const gchar
*name
, const gchar
*value
, int pos
) {
165 struct siphdrelement
*element
= g_new0(struct siphdrelement
,1);
166 element
->name
= g_strdup(name
);
167 element
->value
= g_strdup(value
);
168 msg
->headers
= g_slist_insert(msg
->headers
, element
,pos
);
171 void sipmsg_free(struct sipmsg
*msg
) {
172 struct siphdrelement
*elem
;
173 while(msg
->headers
) {
174 elem
= msg
->headers
->data
;
175 msg
->headers
= g_slist_remove(msg
->headers
,elem
);
186 void sipmsg_remove_header(struct sipmsg
*msg
, const gchar
*name
) {
187 struct siphdrelement
*elem
;
188 GSList
*tmp
= msg
->headers
;
191 if(strcmp(elem
->name
, name
)==0) {
192 msg
->headers
= g_slist_remove(msg
->headers
, elem
);
198 tmp
= g_slist_next(tmp
);
203 gchar
*sipmsg_find_header(struct sipmsg
*msg
, const gchar
*name
) {
205 struct siphdrelement
*elem
;
209 if(strcmp(elem
->name
,name
)==0) {
212 tmp
= g_slist_next(tmp
);