src/protocols/simple/sipmsg.c

branch
cpw.khc.msnp14
changeset 20472
6a6d2ef151e6
parent 13912
463b4fa9f067
parent 20469
b2836a24d81e
child 20473
91e1b3a49d10
equal deleted inserted replaced
13912:463b4fa9f067 20472:6a6d2ef151e6
1 /**
2 * @file sipmsg.c
3 *
4 * gaim
5 *
6 * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de>
7 *
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.
12 *
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.
17 *
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
21 */
22
23 #include "internal.h"
24
25 #include "accountopt.h"
26 #include "blist.h"
27 #include "conversation.h"
28 #include "debug.h"
29 #include "notify.h"
30 #include "prpl.h"
31 #include "plugin.h"
32 #include "util.h"
33 #include "version.h"
34
35 #include "simple.h"
36 #include "sipmsg.h"
37
38 struct sipmsg *sipmsg_parse_msg(gchar *msg) {
39 char *tmp = strstr(msg, "\r\n\r\n");
40 struct sipmsg *smsg;
41 if(!tmp) return NULL;
42 tmp[0]=0;
43 smsg = sipmsg_parse_header(msg);
44 tmp[0]='\r';
45 smsg->body = g_strdup(tmp+4);
46 return smsg;
47 }
48
49 struct sipmsg *sipmsg_parse_header(gchar *header) {
50 struct sipmsg *msg = g_new0(struct sipmsg,1);
51 gchar **lines = g_strsplit(header,"\r\n",0);
52 gchar **parts;
53 gchar *dummy;
54 gchar *dummy2;
55 gchar *tmp;
56 int i=1;
57 if(!lines[0]) return NULL;
58 parts = g_strsplit(lines[0], " ", 3);
59 if(!parts[0] || !parts[1] || !parts[2]) {
60 g_strfreev(parts);
61 g_strfreev(lines);
62 g_free(msg);
63 return NULL;
64 }
65 if(strstr(parts[0],"SIP")) { /* numeric response */
66 msg->method = g_strdup(parts[2]);
67 msg->response = strtol(parts[1],NULL,10);
68 } else { /* request */
69 msg->method = g_strdup(parts[0]);
70 msg->target = g_strdup(parts[1]);
71 msg->response = 0;
72 }
73 g_strfreev(parts);
74 for(i=1; lines[i] && strlen(lines[i])>2; i++) {
75 parts = g_strsplit(lines[i], ":", 2);
76 if(!parts[0] || !parts[1]) {
77 g_strfreev(parts);
78 g_strfreev(lines);
79 g_free(msg);
80 return NULL;
81 }
82 dummy = parts[1];
83 dummy2 = 0;
84 while(*dummy==' ' || *dummy=='\t') dummy++;
85 dummy2 = g_strdup(dummy);
86 while(lines[i+1] && (lines[i+1][0]==' ' || lines[i+1][0]=='\t')) {
87 i++;
88 dummy = lines[i];
89 while(*dummy==' ' || *dummy=='\t') dummy++;
90 tmp = g_strdup_printf("%s %s",dummy2, dummy);
91 g_free(dummy2);
92 dummy2 = tmp;
93 }
94 sipmsg_add_header(msg, parts[0], dummy2);
95 g_strfreev(parts);
96 }
97 g_strfreev(lines);
98 msg->bodylen = strtol(sipmsg_find_header(msg, "Content-Length"),NULL,10);
99 if(msg->response) {
100 tmp = sipmsg_find_header(msg, "CSeq");
101 if(!tmp) {
102 /* SHOULD NOT HAPPEN */
103 msg->method = 0;
104 } else {
105 parts = g_strsplit(tmp, " ", 2);
106 msg->method = g_strdup(parts[1]);
107 g_strfreev(parts);
108 }
109 }
110 return msg;
111 }
112
113 void sipmsg_print(struct sipmsg *msg) {
114 GSList *cur;
115 struct siphdrelement *elem;
116 gaim_debug(GAIM_DEBUG_MISC, "simple", "SIP MSG\n");
117 gaim_debug(GAIM_DEBUG_MISC, "simple", "response: %d\nmethod: %s\nbodylen: %d\n",msg->response,msg->method,msg->bodylen);
118 if(msg->target) gaim_debug(GAIM_DEBUG_MISC, "simple", "target: %s\n",msg->target);
119 cur = msg->headers;
120 while(cur) {
121 elem = cur->data;
122 gaim_debug(GAIM_DEBUG_MISC, "simple", "name: %s value: %s\n",elem->name, elem->value);
123 cur = g_slist_next(cur);
124 }
125 }
126
127 char *sipmsg_to_string(struct sipmsg *msg) {
128 GSList *cur;
129 GString *outstr = g_string_new("");
130 struct siphdrelement *elem;
131
132 if(msg->response)
133 g_string_append_printf(outstr, "SIP/2.0 %d Unknown\r\n",
134 msg->response);
135 else
136 g_string_append_printf(outstr, "%s %s SIP/2.0\r\n",
137 msg->method, msg->target);
138
139 cur = msg->headers;
140 while(cur) {
141 elem = cur->data;
142 g_string_append_printf(outstr, "%s: %s\r\n", elem->name,
143 elem->value);
144 cur = g_slist_next(cur);
145 }
146
147 g_string_append_printf(outstr, "\r\n%s", msg->bodylen ? msg->body : "");
148
149 return g_string_free(outstr, FALSE);
150 }
151 void sipmsg_add_header(struct sipmsg *msg, gchar *name, gchar *value) {
152 struct siphdrelement *element = g_new0(struct siphdrelement,1);
153 element->name = g_strdup(name);
154 element->value = g_strdup(value);
155 msg->headers = g_slist_append(msg->headers, element);
156 }
157
158 void sipmsg_free(struct sipmsg *msg) {
159 struct siphdrelement *elem;
160 while(msg->headers) {
161 elem = msg->headers->data;
162 msg->headers = g_slist_remove(msg->headers,elem);
163 g_free(elem->name);
164 g_free(elem->value);
165 g_free(elem);
166 }
167 g_free(msg->method);
168 g_free(msg->target);
169 g_free(msg->body);
170 g_free(msg);
171 }
172
173 void sipmsg_remove_header(struct sipmsg *msg, gchar *name) {
174 struct siphdrelement *elem;
175 GSList *tmp = msg->headers;
176 while(tmp) {
177 elem = tmp->data;
178 if(strcmp(elem->name, name)==0) {
179 msg->headers = g_slist_remove(msg->headers, elem);
180 return;
181 }
182 tmp = g_slist_next(tmp);
183 }
184 return;
185 }
186
187 gchar *sipmsg_find_header(struct sipmsg *msg, gchar *name) {
188 GSList *tmp;
189 struct siphdrelement *elem;
190 tmp = msg->headers;
191 while(tmp) {
192 elem = tmp->data;
193 if(strcmp(elem->name,name)==0) {
194 return elem->value;
195 }
196 tmp = g_slist_next(tmp);
197 }
198 return NULL;
199 }
200

mercurial