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 }