Mercurial > pidgin
comparison libpurple/protocols/msnp9/slpmsg.c @ 21312:a07cfce78345
Add MSNP9 back as an alternative alongside the existing MSN prpl. Cowardly
old fools like me who prefer the stability of our MSNP9 code over the
features of MSNP14 can enable this using the --disable-msnp14 ./configure
option.
If we want to release from i.p.p and MSN stability is the only blocker, we
can trivially flick the default to use MSNP9 in configure.ac
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Sun, 11 Nov 2007 12:57:52 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
21311:7d031cec5ba2 | 21312:a07cfce78345 |
---|---|
1 /** | |
2 * @file slpmsg.h SLP Message functions | |
3 * | |
4 * purple | |
5 * | |
6 * Purple is the legal property of its developers, whose names are too numerous | |
7 * to list here. Please refer to the COPYRIGHT file distributed with this | |
8 * source distribution. | |
9 * | |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
23 */ | |
24 #include "msn.h" | |
25 #include "slpmsg.h" | |
26 #include "slplink.h" | |
27 | |
28 /************************************************************************** | |
29 * SLP Message | |
30 **************************************************************************/ | |
31 | |
32 MsnSlpMessage * | |
33 msn_slpmsg_new(MsnSlpLink *slplink) | |
34 { | |
35 MsnSlpMessage *slpmsg; | |
36 | |
37 slpmsg = g_new0(MsnSlpMessage, 1); | |
38 | |
39 #ifdef MSN_DEBUG_SLPMSG | |
40 purple_debug_info("msn", "slpmsg new (%p)\n", slpmsg); | |
41 #endif | |
42 | |
43 slpmsg->slplink = slplink; | |
44 | |
45 slplink->slp_msgs = | |
46 g_list_append(slplink->slp_msgs, slpmsg); | |
47 | |
48 return slpmsg; | |
49 } | |
50 | |
51 void | |
52 msn_slpmsg_destroy(MsnSlpMessage *slpmsg) | |
53 { | |
54 MsnSlpLink *slplink; | |
55 GList *cur; | |
56 | |
57 g_return_if_fail(slpmsg != NULL); | |
58 | |
59 #ifdef MSN_DEBUG_SLPMSG | |
60 purple_debug_info("msn", "slpmsg destroy (%p)\n", slpmsg); | |
61 #endif | |
62 | |
63 slplink = slpmsg->slplink; | |
64 | |
65 if (slpmsg->fp != NULL) | |
66 fclose(slpmsg->fp); | |
67 | |
68 purple_imgstore_unref(slpmsg->img); | |
69 | |
70 /* We don't want to free the data of the PurpleStoredImage, | |
71 * but to avoid code duplication, it's sharing buffer. */ | |
72 if (slpmsg->img == NULL) | |
73 g_free(slpmsg->buffer); | |
74 | |
75 #ifdef MSN_DEBUG_SLP | |
76 /* | |
77 if (slpmsg->info != NULL) | |
78 g_free(slpmsg->info); | |
79 */ | |
80 #endif | |
81 | |
82 for (cur = slpmsg->msgs; cur != NULL; cur = cur->next) | |
83 { | |
84 /* Something is pointing to this slpmsg, so we should remove that | |
85 * pointer to prevent a crash. */ | |
86 /* Ex: a user goes offline and after that we receive an ACK */ | |
87 | |
88 MsnMessage *msg = cur->data; | |
89 | |
90 #ifdef MSN_DEBUG_SLPMSG | |
91 purple_debug_info("msn", "Unlink slpmsg callbacks.\n"); | |
92 #endif | |
93 | |
94 msg->ack_cb = NULL; | |
95 msg->nak_cb = NULL; | |
96 msg->ack_data = NULL; | |
97 } | |
98 | |
99 slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg); | |
100 | |
101 g_free(slpmsg); | |
102 } | |
103 | |
104 void | |
105 msn_slpmsg_set_body(MsnSlpMessage *slpmsg, const char *body, | |
106 long long size) | |
107 { | |
108 /* We can only have one data source at a time. */ | |
109 g_return_if_fail(slpmsg->buffer == NULL); | |
110 g_return_if_fail(slpmsg->img == NULL); | |
111 g_return_if_fail(slpmsg->fp == NULL); | |
112 | |
113 if (body != NULL) | |
114 slpmsg->buffer = g_memdup(body, size); | |
115 else | |
116 slpmsg->buffer = g_new0(guchar, size); | |
117 | |
118 slpmsg->size = size; | |
119 } | |
120 | |
121 void | |
122 msn_slpmsg_set_image(MsnSlpMessage *slpmsg, PurpleStoredImage *img) | |
123 { | |
124 /* We can only have one data source at a time. */ | |
125 g_return_if_fail(slpmsg->buffer == NULL); | |
126 g_return_if_fail(slpmsg->img == NULL); | |
127 g_return_if_fail(slpmsg->fp == NULL); | |
128 | |
129 slpmsg->img = purple_imgstore_ref(img); | |
130 slpmsg->buffer = (guchar *)purple_imgstore_get_data(img); | |
131 slpmsg->size = purple_imgstore_get_size(img); | |
132 } | |
133 | |
134 void | |
135 msn_slpmsg_open_file(MsnSlpMessage *slpmsg, const char *file_name) | |
136 { | |
137 struct stat st; | |
138 | |
139 /* We can only have one data source at a time. */ | |
140 g_return_if_fail(slpmsg->buffer == NULL); | |
141 g_return_if_fail(slpmsg->img == NULL); | |
142 g_return_if_fail(slpmsg->fp == NULL); | |
143 | |
144 slpmsg->fp = g_fopen(file_name, "rb"); | |
145 | |
146 if (g_stat(file_name, &st) == 0) | |
147 slpmsg->size = st.st_size; | |
148 } | |
149 | |
150 #ifdef MSN_DEBUG_SLP | |
151 void | |
152 msn_slpmsg_show(MsnMessage *msg) | |
153 { | |
154 const char *info; | |
155 gboolean text; | |
156 guint32 flags; | |
157 | |
158 text = FALSE; | |
159 | |
160 flags = GUINT32_TO_LE(msg->msnslp_header.flags); | |
161 | |
162 switch (flags) | |
163 { | |
164 case 0x0: | |
165 info = "SLP CONTROL"; | |
166 text = TRUE; | |
167 break; | |
168 case 0x2: | |
169 info = "SLP ACK"; break; | |
170 case 0x20: | |
171 case 0x1000030: | |
172 info = "SLP DATA"; break; | |
173 default: | |
174 info = "SLP UNKNOWN"; break; | |
175 } | |
176 | |
177 msn_message_show_readable(msg, info, text); | |
178 } | |
179 #endif | |
180 | |
181 MsnSlpMessage * | |
182 msn_slpmsg_sip_new(MsnSlpCall *slpcall, int cseq, | |
183 const char *header, const char *branch, | |
184 const char *content_type, const char *content) | |
185 { | |
186 MsnSlpLink *slplink; | |
187 MsnSlpMessage *slpmsg; | |
188 char *body; | |
189 gsize body_len; | |
190 gsize content_len; | |
191 | |
192 g_return_val_if_fail(slpcall != NULL, NULL); | |
193 g_return_val_if_fail(header != NULL, NULL); | |
194 | |
195 slplink = slpcall->slplink; | |
196 | |
197 /* Let's remember that "content" should end with a 0x00 */ | |
198 | |
199 content_len = (content != NULL) ? strlen(content) + 1 : 0; | |
200 | |
201 body = g_strdup_printf( | |
202 "%s\r\n" | |
203 "To: <msnmsgr:%s>\r\n" | |
204 "From: <msnmsgr:%s>\r\n" | |
205 "Via: MSNSLP/1.0/TLP ;branch={%s}\r\n" | |
206 "CSeq: %d\r\n" | |
207 "Call-ID: {%s}\r\n" | |
208 "Max-Forwards: 0\r\n" | |
209 "Content-Type: %s\r\n" | |
210 "Content-Length: %" G_GSIZE_FORMAT "\r\n" | |
211 "\r\n", | |
212 header, | |
213 slplink->remote_user, | |
214 slplink->local_user, | |
215 branch, | |
216 cseq, | |
217 slpcall->id, | |
218 content_type, | |
219 content_len); | |
220 | |
221 body_len = strlen(body); | |
222 | |
223 if (content_len > 0) | |
224 { | |
225 body_len += content_len; | |
226 body = g_realloc(body, body_len); | |
227 g_strlcat(body, content, body_len); | |
228 } | |
229 | |
230 slpmsg = msn_slpmsg_new(slplink); | |
231 msn_slpmsg_set_body(slpmsg, body, body_len); | |
232 | |
233 slpmsg->sip = TRUE; | |
234 slpmsg->slpcall = slpcall; | |
235 | |
236 g_free(body); | |
237 | |
238 return slpmsg; | |
239 } |