Mercurial > pidgin.yaz
comparison src/protocols/msn/msg.c @ 9158:c30d81b4dd22
[gaim-migrate @ 9942]
Patch from Felipe Contreras to sync our MSN prpl with what's in his tree.
He says this may fix a couple bugs, but the important thing is the
restructuring of how MsnMessages work. Lots of style changes and other
stuff as well.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Tue, 01 Jun 2004 06:42:20 +0000 |
parents | 9e5a709c30a8 |
children | 502707ca1836 |
comparison
equal
deleted
inserted
replaced
9157:bd1ea0a717d7 | 9158:c30d81b4dd22 |
---|---|
52 (((*((buf)+1))<<16)&0x00ff0000) + \ | 52 (((*((buf)+1))<<16)&0x00ff0000) + \ |
53 (((*((buf)+2))<< 8)&0x0000ff00) + \ | 53 (((*((buf)+2))<< 8)&0x0000ff00) + \ |
54 (((*((buf)+3) )&0x000000ff))) | 54 (((*((buf)+3) )&0x000000ff))) |
55 | 55 |
56 | 56 |
57 /* | |
58 * "MIME-Version: 1.0\r\n" == 19 | |
59 * "Content-Type: " == 14 | |
60 * "\r\n" == 2 | |
61 * "\r\n" before body == 2 | |
62 * ---- | |
63 * 37 | |
64 * MATH PAYS OFF!! | |
65 */ | |
66 #define MSN_MESSAGE_BASE_SIZE 37 | |
67 | |
68 MsnMessage * | 57 MsnMessage * |
69 msn_message_new(void) | 58 msn_message_new(void) |
70 { | 59 { |
71 MsnMessage *msg; | 60 MsnMessage *msg; |
72 | 61 |
73 msg = g_new0(MsnMessage, 1); | 62 msg = g_new0(MsnMessage, 1); |
74 | 63 |
75 msg->attr_table = g_hash_table_new_full(g_str_hash, g_str_equal, | 64 msg->attr_table = g_hash_table_new_full(g_str_hash, g_str_equal, |
76 g_free, g_free); | 65 g_free, g_free); |
77 msg->size = MSN_MESSAGE_BASE_SIZE; | 66 |
78 | 67 msn_message_ref(msg); |
68 | |
69 return msg; | |
70 } | |
71 | |
72 MsnMessage * | |
73 msn_message_new_plain(const char *message) | |
74 { | |
75 MsnMessage *msg; | |
76 char *message_cr; | |
77 | |
78 msg = msn_message_new(); | |
79 msn_message_set_attr(msg, "User-Agent", "Gaim/" VERSION); | 79 msn_message_set_attr(msg, "User-Agent", "Gaim/" VERSION); |
80 msn_message_set_content_type(msg, "text/plain"); | 80 msn_message_set_content_type(msg, "text/plain"); |
81 msn_message_set_charset(msg, "UTF-8"); | 81 msn_message_set_charset(msg, "UTF-8"); |
82 msn_message_set_flag(msg, 'U'); | 82 msn_message_set_flag(msg, 'N'); |
83 | 83 msn_message_set_attr(msg, "X-MMS-IM-Format", |
84 msn_message_ref(msg); | 84 "FN=MS%20Sans%20Serif; EF=; CO=0; PF=0"); |
85 | |
86 message_cr = gaim_str_add_cr(message); | |
87 msn_message_set_bin_data(msg, message_cr, strlen(message_cr)); | |
88 g_free(message_cr); | |
85 | 89 |
86 return msg; | 90 return msg; |
87 } | 91 } |
88 | 92 |
89 MsnMessage * | 93 MsnMessage * |
94 msg = msn_message_new(); | 98 msg = msn_message_new(); |
95 | 99 |
96 msn_message_set_attr(msg, "User-Agent", NULL); | 100 msn_message_set_attr(msg, "User-Agent", NULL); |
97 | 101 |
98 msg->msnslp_message = TRUE; | 102 msg->msnslp_message = TRUE; |
99 msg->size += 52; | |
100 | 103 |
101 msn_message_set_flag(msg, 'D'); | 104 msn_message_set_flag(msg, 'D'); |
102 msn_message_set_content_type(msg, "application/x-msnmsgrp2p"); | 105 msn_message_set_content_type(msg, "application/x-msnmsgrp2p"); |
103 msn_message_set_charset(msg, NULL); | |
104 | 106 |
105 return msg; | 107 return msg; |
106 } | 108 } |
107 | 109 |
108 MsnMessage * | 110 MsnMessage * |
116 msg = msn_message_new_msnslp(); | 118 msg = msn_message_new_msnslp(); |
117 | 119 |
118 msg->msnslp_ack_message = TRUE; | 120 msg->msnslp_ack_message = TRUE; |
119 msg->acked_msg = msn_message_ref(acked_msg); | 121 msg->acked_msg = msn_message_ref(acked_msg); |
120 | 122 |
121 msg->msnslp_header.session_id = acked_msg->msnslp_header.session_id; | 123 msg->msnslp_header.session_id = acked_msg->msnslp_header.session_id; |
122 msg->msnslp_header.total_size_1 = acked_msg->msnslp_header.total_size_1; | 124 msg->msnslp_header.total_size = acked_msg->msnslp_header.total_size; |
123 msg->msnslp_header.total_size_2 = acked_msg->msnslp_header.total_size_2; | 125 msg->msnslp_header.flags = 0x02; |
124 msg->msnslp_header.flags = 0x02; | 126 msg->msnslp_header.ack_id = acked_msg->msnslp_header.id; |
125 msg->msnslp_header.ack_session_id = acked_msg->msnslp_header.session_id; | 127 msg->msnslp_header.ack_sub_id = acked_msg->msnslp_header.ack_id; |
126 msg->msnslp_header.ack_unique_id = acked_msg->msnslp_header.ack_session_id; | 128 msg->msnslp_header.ack_size = acked_msg->msnslp_header.total_size; |
127 msg->msnslp_header.ack_length_1 = acked_msg->msnslp_header.total_size_1; | |
128 msg->msnslp_header.ack_length_2 = acked_msg->msnslp_header.total_size_2; | |
129 | 129 |
130 return msg; | 130 return msg; |
131 } | 131 } |
132 | 132 |
133 void | 133 void |
134 msn_message_parse_payload(MsnMessage *msg, const char *payload, | 134 msn_message_parse_payload(MsnMessage *msg, |
135 size_t payload_len) | 135 const char *payload, size_t payload_len) |
136 { | 136 { |
137 char *tmp_base, *tmp, *c; | 137 char *tmp_base, *tmp; |
138 const char *content_type; | 138 const char *content_type; |
139 | 139 |
140 tmp_base = g_malloc(payload_len + 1); | 140 g_return_if_fail(payload != NULL); |
141 memcpy(tmp_base, payload, payload_len); | 141 |
142 tmp_base[payload_len] = '\0'; | 142 tmp_base = tmp = g_memdup(payload, payload_len); |
143 | |
144 tmp = tmp_base; | |
145 | 143 |
146 /* Back to the parsination. */ | 144 /* Back to the parsination. */ |
147 while (*tmp != '\r') | 145 while (*tmp != '\r') |
148 { | 146 { |
149 char *key, *value; | 147 char *key, *value, *c; |
150 | 148 |
151 key = tmp; | 149 key = tmp; |
152 | 150 |
153 GET_NEXT(tmp); /* Key */ | 151 GET_NEXT(tmp); /* Key */ |
154 | 152 |
156 | 154 |
157 GET_NEXT_LINE(tmp); /* Value */ | 155 GET_NEXT_LINE(tmp); /* Value */ |
158 | 156 |
159 if ((c = strchr(key, ':')) != NULL) | 157 if ((c = strchr(key, ':')) != NULL) |
160 *c = '\0'; | 158 *c = '\0'; |
159 | |
160 if (!g_ascii_strcasecmp(key, "MIME-Version")) | |
161 continue; | |
161 | 162 |
162 if (!g_ascii_strcasecmp(key, "Content-Type")) | 163 if (!g_ascii_strcasecmp(key, "Content-Type")) |
163 { | 164 { |
164 char *charset; | 165 char *charset; |
165 | 166 |
187 content_type = msn_message_get_content_type(msg); | 188 content_type = msn_message_get_content_type(msg); |
188 | 189 |
189 if (content_type != NULL && | 190 if (content_type != NULL && |
190 !strcmp(content_type, "application/x-msnmsgrp2p")) | 191 !strcmp(content_type, "application/x-msnmsgrp2p")) |
191 { | 192 { |
192 char header[48]; | 193 MsnSlpHeader header; |
193 char footer[4]; | 194 MsnSlpFooter footer; |
194 size_t body_len; | |
195 char *tmp2; | |
196 | 195 |
197 msg->msnslp_message = TRUE; | 196 msg->msnslp_message = TRUE; |
198 | 197 |
199 memcpy(header, tmp, 48); | |
200 | |
201 tmp += 48; | |
202 | |
203 body_len = payload_len - (tmp - tmp_base) - 4; | |
204 | |
205 if (body_len > 0) | |
206 { | |
207 msg->body = g_malloc(body_len + 1); | |
208 memcpy(msg->body, tmp, body_len); | |
209 msg->body[body_len] = '\0'; | |
210 | |
211 tmp++; | |
212 } | |
213 else | |
214 msg->body = NULL; | |
215 | |
216 memcpy(footer, tmp, 4); | |
217 | |
218 tmp += 4; | |
219 | |
220 /* Import the header. */ | 198 /* Import the header. */ |
221 tmp2 = header; | 199 memcpy(&header, tmp, sizeof(header)); |
222 msg->msnslp_header.session_id = msn_get32(tmp2); tmp2 += 4; | 200 tmp += sizeof(header); |
223 msg->msnslp_header.id = msn_get32(tmp2); tmp2 += 4; | 201 |
224 msg->msnslp_header.offset_1 = msn_get32(tmp2); tmp2 += 4; | 202 msg->msnslp_header.session_id = GUINT32_FROM_LE(header.session_id); |
225 msg->msnslp_header.offset_2 = msn_get32(tmp2); tmp2 += 4; | 203 msg->msnslp_header.id = GUINT64_FROM_LE(header.id); |
226 msg->msnslp_header.total_size_1 = msn_get32(tmp2); tmp2 += 4; | 204 msg->msnslp_header.offset = GUINT64_FROM_LE(header.offset); |
227 msg->msnslp_header.total_size_2 = msn_get32(tmp2); tmp2 += 4; | 205 msg->msnslp_header.total_size = GUINT32_FROM_LE(header.total_size); |
228 msg->msnslp_header.length = msn_get32(tmp2); tmp2 += 4; | 206 msg->msnslp_header.length = GUINT32_FROM_LE(header.length); |
229 msg->msnslp_header.flags = msn_get32(tmp2); tmp2 += 4; | 207 msg->msnslp_header.flags = GUINT32_FROM_LE(header.flags); |
230 msg->msnslp_header.ack_session_id = msn_get32(tmp2); tmp2 += 4; | 208 msg->msnslp_header.ack_id = GUINT32_FROM_LE(header.ack_id); |
231 msg->msnslp_header.ack_unique_id = msn_get32(tmp2); tmp2 += 4; | 209 msg->msnslp_header.ack_sub_id = GUINT32_FROM_LE(header.ack_sub_id); |
232 msg->msnslp_header.ack_length_1 = msn_get32(tmp2); tmp2 += 4; | 210 msg->msnslp_header.ack_size = GUINT64_FROM_LE(header.ack_size); |
233 msg->msnslp_header.ack_length_2 = msn_get32(tmp2); tmp2 += 4; | 211 |
234 | 212 /* Import the body. */ |
235 /* Convert to the right endianness */ | 213 msg->body_len = payload_len - (tmp - tmp_base) - sizeof(footer); |
236 msg->msnslp_header.session_id = ntohl(msg->msnslp_header.session_id); | 214 |
237 msg->msnslp_header.id = ntohl(msg->msnslp_header.id); | 215 if (msg->body_len > 0) |
238 msg->msnslp_header.length = ntohl(msg->msnslp_header.length); | 216 msg->body = g_memdup(tmp, msg->body_len); |
239 msg->msnslp_header.flags = ntohl(msg->msnslp_header.flags); | 217 |
240 msg->msnslp_header.ack_length_1 = | 218 tmp += msg->body_len; |
241 ntohl(msg->msnslp_header.ack_length_1); | |
242 msg->msnslp_header.ack_length_2 = | |
243 ntohl(msg->msnslp_header.ack_length_2); | |
244 msg->msnslp_header.ack_session_id = | |
245 ntohl(msg->msnslp_header.ack_session_id); | |
246 msg->msnslp_header.ack_unique_id = | |
247 ntohl(msg->msnslp_header.ack_unique_id); | |
248 | 219 |
249 /* Import the footer. */ | 220 /* Import the footer. */ |
250 msg->msnslp_footer.app_id = (long)footer; | 221 memcpy(&footer, tmp, sizeof(footer)); |
222 tmp += sizeof(footer); | |
223 | |
224 msg->msnslp_footer.value = GUINT32_FROM_BE(footer.value); | |
251 } | 225 } |
252 else | 226 else |
253 { | 227 { |
254 char *tmp2; | 228 msg->body_len = payload_len - (tmp - tmp_base); |
255 size_t body_len; | 229 msg->body = g_memdup(tmp, msg->body_len); |
256 | |
257 body_len = payload_len - (tmp - tmp_base); | |
258 | |
259 tmp2 = g_malloc(body_len + 1); | |
260 | |
261 if (body_len > 0) | |
262 memcpy(tmp2, tmp, body_len); | |
263 | |
264 tmp2[body_len] = '\0'; | |
265 | |
266 msn_message_set_body(msg, tmp2); | |
267 | |
268 g_free(tmp2); | |
269 } | 230 } |
270 | 231 |
271 g_free(tmp_base); | 232 g_free(tmp_base); |
272 | 233 |
273 /* Done! */ | 234 /* Done! */ |
298 g_list_free(msg->attr_list); | 259 g_list_free(msg->attr_list); |
299 | 260 |
300 if (msg->msnslp_ack_message) | 261 if (msg->msnslp_ack_message) |
301 msn_message_unref(msg->acked_msg); | 262 msn_message_unref(msg->acked_msg); |
302 | 263 |
303 gaim_debug(GAIM_DEBUG_INFO, "msn", "Destroying message\n"); | |
304 g_free(msg); | 264 g_free(msg); |
305 } | 265 } |
306 | 266 |
307 MsnMessage * | 267 MsnMessage * |
308 msn_message_ref(MsnMessage *msg) | 268 msn_message_ref(MsnMessage *msg) |
335 | 295 |
336 char * | 296 char * |
337 msn_message_gen_payload(const MsnMessage *msg, size_t *ret_size) | 297 msn_message_gen_payload(const MsnMessage *msg, size_t *ret_size) |
338 { | 298 { |
339 GList *l; | 299 GList *l; |
340 char *str; | 300 char *n, *base, *end; |
341 char buf[MSN_BUF_LEN]; | |
342 int len; | 301 int len; |
343 | 302 size_t body_len; |
344 /* | 303 const void *body; |
345 * Okay, how we do things here is just bad. I don't like writing to | 304 |
346 * a static buffer and then copying to the string. Unfortunately, | 305 g_return_val_if_fail(msg != NULL, NULL); |
347 * just trying to append to the string is causing issues.. Such as | 306 |
348 * the string you're appending to being erased. Ugh. So, this is | 307 len = MSN_BUF_LEN; |
349 * good enough for now. | 308 |
350 * | 309 base = n = end = g_malloc(len + 1); |
351 * -- ChipX86 | 310 end += len; |
352 */ | |
353 g_return_val_if_fail(msg != NULL, NULL); | |
354 | |
355 len = msg->size + 1; | |
356 | |
357 str = g_new0(char, len + 1); | |
358 | 311 |
359 /* Standard header. */ | 312 /* Standard header. */ |
360 if (msg->charset == NULL) | 313 if (msg->charset == NULL) |
361 { | 314 { |
362 g_snprintf(buf, sizeof(buf), | 315 g_snprintf(n, len, |
363 "MIME-Version: 1.0\r\n" | 316 "MIME-Version: 1.0\r\n" |
364 "Content-Type: %s\r\n", | 317 "Content-Type: %s\r\n", |
365 msg->content_type); | 318 msg->content_type); |
366 } | 319 } |
367 else | 320 else |
368 { | 321 { |
369 g_snprintf(buf, sizeof(buf), | 322 g_snprintf(n, len, |
370 "MIME-Version: 1.0\r\n" | 323 "MIME-Version: 1.0\r\n" |
371 "Content-Type: %s; charset=%s\r\n", | 324 "Content-Type: %s; charset=%s\r\n", |
372 msg->content_type, msg->charset); | 325 msg->content_type, msg->charset); |
373 } | 326 } |
374 | 327 |
375 g_strlcat(str, buf, len); | 328 n += strlen(n); |
376 | 329 |
377 for (l = msg->attr_list; l != NULL; l = l->next) | 330 for (l = msg->attr_list; l != NULL; l = l->next) |
378 { | 331 { |
379 const char *key = (char *)l->data; | 332 const char *key; |
380 const char *value; | 333 const char *value; |
381 | 334 |
335 key = l->data; | |
382 value = msn_message_get_attr(msg, key); | 336 value = msn_message_get_attr(msg, key); |
383 | 337 |
384 g_snprintf(buf, sizeof(buf), "%s: %s\r\n", key, value); | 338 g_snprintf(n, end - n, "%s: %s\r\n", key, value); |
385 | 339 n += strlen(n); |
386 g_strlcat(str, buf, len); | 340 } |
387 } | 341 |
388 | 342 n += g_strlcpy(n, "\r\n", end - n); |
389 g_strlcat(str, "\r\n", len); | 343 |
344 body = msn_message_get_bin_data(msg, &body_len); | |
390 | 345 |
391 if (msg->msnslp_message) | 346 if (msg->msnslp_message) |
392 { | 347 { |
393 char *c; | 348 MsnSlpHeader header; |
394 long session_id, id, offset_1, offset_2, total_size_1, total_size_2; | 349 MsnSlpFooter footer; |
395 long length, flags; | 350 |
396 long ack_session_id, ack_unique_id, ack_length_1, ack_length_2; | 351 header.session_id = GUINT32_TO_LE(msg->msnslp_header.session_id); |
397 | 352 header.id = GUINT64_TO_LE(msg->msnslp_header.id); |
398 c = str + strlen(str); | 353 header.offset = GUINT64_TO_LE(msg->msnslp_header.offset); |
399 | 354 header.total_size = GUINT32_TO_LE(msg->msnslp_header.total_size); |
400 session_id = htonl(msg->msnslp_header.session_id); | 355 header.length = GUINT32_TO_LE(msg->msnslp_header.length); |
401 id = htonl(msg->msnslp_header.id); | 356 header.flags = GUINT32_TO_LE(msg->msnslp_header.flags); |
402 offset_1 = htonl(msg->msnslp_header.offset_1); | 357 header.ack_id = GUINT32_TO_LE(msg->msnslp_header.ack_id); |
403 offset_2 = htonl(msg->msnslp_header.offset_2); | 358 header.ack_sub_id = GUINT32_TO_LE(msg->msnslp_header.ack_sub_id); |
404 total_size_1 = htonl(msg->msnslp_header.total_size_1); | 359 header.ack_size = GUINT64_TO_LE(msg->msnslp_header.ack_size); |
405 total_size_2 = htonl(msg->msnslp_header.total_size_2); | 360 |
406 length = htonl(msg->msnslp_header.length); | 361 memcpy(n, &header, 48); |
407 flags = htonl(msg->msnslp_header.flags); | 362 n += 48; |
408 ack_session_id = htonl(msg->msnslp_header.ack_session_id); | 363 |
409 ack_unique_id = htonl(msg->msnslp_header.ack_unique_id); | 364 if (body != NULL) |
410 ack_length_1 = htonl(msg->msnslp_header.ack_length_1); | |
411 ack_length_2 = htonl(msg->msnslp_header.ack_length_2); | |
412 | |
413 c += msn_put32(c, session_id); | |
414 c += msn_put32(c, id); | |
415 c += msn_put32(c, offset_1); | |
416 c += msn_put32(c, offset_2); | |
417 c += msn_put32(c, total_size_1); | |
418 c += msn_put32(c, total_size_2); | |
419 c += msn_put32(c, length); | |
420 c += msn_put32(c, flags); | |
421 c += msn_put32(c, ack_session_id); | |
422 c += msn_put32(c, ack_unique_id); | |
423 c += msn_put32(c, ack_length_1); | |
424 c += msn_put32(c, ack_length_2); | |
425 | |
426 if (msg->bin_content) | |
427 { | 365 { |
428 size_t bin_len; | 366 memcpy(n, body, body_len); |
429 const void *body = msn_message_get_bin_data(msg, &bin_len); | 367 n += body_len; |
430 | |
431 if (body != NULL) | |
432 { | |
433 memcpy(c, body, bin_len); | |
434 | |
435 c += bin_len; | |
436 } | |
437 } | 368 } |
438 else | 369 |
370 footer.value = GUINT32_TO_BE(msg->msnslp_footer.value); | |
371 | |
372 memcpy(n, &footer, 4); | |
373 n += 4; | |
374 } | |
375 else | |
376 { | |
377 if (body != NULL) | |
439 { | 378 { |
440 const char *body = msn_message_get_body(msg); | 379 memcpy(n, body, body_len); |
441 | 380 n += body_len; |
442 if (body != NULL) | |
443 { | |
444 g_strlcpy(c, body, msg->size - (c - str)); | |
445 | |
446 c += strlen(body); | |
447 | |
448 if (strlen(body) > 0) | |
449 *c++ = '\0'; | |
450 } | |
451 } | 381 } |
452 | |
453 c += msn_put32(c, msg->msnslp_footer.app_id); | |
454 | |
455 if (msg->size != (c - str)) | |
456 { | |
457 gaim_debug(GAIM_DEBUG_ERROR, "msn", | |
458 "Outgoing message size (%d) and data length (%d) " | |
459 "do not match!\n", msg->size, (c - str)); | |
460 } | |
461 } | |
462 else | |
463 { | |
464 const char *body = msn_message_get_body(msg); | |
465 | |
466 g_strlcat(str, body, len); | |
467 | |
468 if (msg->size != strlen(str)) | |
469 { | |
470 gaim_debug(GAIM_DEBUG_ERROR, "msn", | |
471 "Outgoing message size (%d) and string length (%d) " | |
472 "do not match!\n", msg->size, strlen(str)); | |
473 } | |
474 } | 382 } |
475 | 383 |
476 if (ret_size != NULL) | 384 if (ret_size != NULL) |
477 { | 385 { |
478 *ret_size = len - 1; | 386 *ret_size = n - base; |
479 | 387 |
480 if (*ret_size > 1664) | 388 if (*ret_size > 1664) |
481 *ret_size = 1664; | 389 *ret_size = 1664; |
482 } | 390 } |
483 | 391 |
484 return str; | 392 return base; |
485 } | 393 } |
486 | 394 |
487 void | 395 void |
488 msn_message_set_flag(MsnMessage *msg, char flag) | 396 msn_message_set_flag(MsnMessage *msg, char flag) |
489 { | 397 { |
500 | 408 |
501 return msg->flag; | 409 return msg->flag; |
502 } | 410 } |
503 | 411 |
504 void | 412 void |
505 msn_message_set_body(MsnMessage *msg, const char *body) | 413 msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len) |
506 { | 414 { |
507 const char *c; | 415 g_return_if_fail(msg != NULL); |
508 char *buf, *d; | 416 |
509 int newline_count = 0; | 417 /* There is no need to waste memory on data we cannot send anyway */ |
510 size_t new_len; | 418 if (len > 1664) |
511 | 419 len = 1664; |
512 g_return_if_fail(msg != NULL); | 420 |
513 | 421 if (msg->body != NULL) |
514 if (msg->bin_content) | |
515 { | |
516 msn_message_set_bin_data(msg, NULL, 0); | |
517 return; | |
518 } | |
519 | |
520 if (msg->body != NULL) { | |
521 msg->size -= strlen(msg->body); | |
522 g_free(msg->body); | 422 g_free(msg->body); |
523 | 423 |
524 if (msg->msnslp_message) | 424 if (data != NULL && len > 0) |
525 msg->size--; | 425 { |
526 } | 426 msg->body = g_memdup(data, len); |
527 | 427 msg->body_len = len; |
528 if (body != NULL) | |
529 { | |
530 for (c = body; *c != '\0'; c++) | |
531 { | |
532 if (*c == '\n' && (c == body || *(c - 1) != '\r')) | |
533 newline_count++; | |
534 } | |
535 | |
536 new_len = strlen(body) + newline_count; | |
537 | |
538 buf = g_new0(char, new_len + 1); | |
539 | |
540 for (c = body, d = buf; *c != '\0'; c++) { | |
541 if (*c == '\n' && (c == body || *(c - 1) != '\r')) { | |
542 *d++ = '\r'; | |
543 *d++ = '\n'; | |
544 } | |
545 else | |
546 *d++ = *c; | |
547 } | |
548 | |
549 msg->body = buf; | |
550 msg->size += new_len; | |
551 | |
552 msg->bin_content = FALSE; | |
553 | |
554 if (msg->msnslp_message) | |
555 msg->size++; | |
556 } | 428 } |
557 else | 429 else |
430 { | |
558 msg->body = NULL; | 431 msg->body = NULL; |
559 } | 432 msg->body_len = 0; |
560 | |
561 const char * | |
562 msn_message_get_body(const MsnMessage *msg) | |
563 { | |
564 g_return_val_if_fail(msg != NULL, NULL); | |
565 g_return_val_if_fail(!msg->bin_content, NULL); | |
566 | |
567 return msg->body; | |
568 } | |
569 | |
570 void | |
571 msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len) | |
572 { | |
573 g_return_if_fail(msg != NULL); | |
574 | |
575 if (!msg->bin_content) | |
576 msn_message_set_body(msg, NULL); | |
577 | |
578 msg->bin_content = TRUE; | |
579 | |
580 if (msg->body != NULL) | |
581 { | |
582 msg->size -= msg->bin_len; | |
583 g_free(msg->body); | |
584 } | |
585 | |
586 if (data != NULL && len > 0) | |
587 { | |
588 msg->body = g_memdup(data, len); | |
589 msg->bin_len = len; | |
590 | |
591 msg->size += len; | |
592 } | |
593 else | |
594 { | |
595 msg->body = NULL; | |
596 msg->bin_len = 0; | |
597 } | 433 } |
598 } | 434 } |
599 | 435 |
600 const void * | 436 const void * |
601 msn_message_get_bin_data(const MsnMessage *msg, size_t *len) | 437 msn_message_get_bin_data(const MsnMessage *msg, size_t *len) |
602 { | 438 { |
603 g_return_val_if_fail(msg != NULL, NULL); | 439 g_return_val_if_fail(msg != NULL, NULL); |
604 g_return_val_if_fail(len != NULL, NULL); | 440 |
605 g_return_val_if_fail(msg->bin_content, NULL); | 441 if (len) |
606 | 442 *len = msg->body_len; |
607 *len = msg->bin_len; | |
608 | 443 |
609 return msg->body; | 444 return msg->body; |
610 } | 445 } |
611 | 446 |
612 void | 447 void |
613 msn_message_set_content_type(MsnMessage *msg, const char *type) | 448 msn_message_set_content_type(MsnMessage *msg, const char *type) |
614 { | 449 { |
615 g_return_if_fail(msg != NULL); | 450 g_return_if_fail(msg != NULL); |
616 | 451 |
617 if (msg->content_type != NULL) { | 452 if (msg->content_type != NULL) |
618 msg->size -= strlen(msg->content_type); | |
619 g_free(msg->content_type); | 453 g_free(msg->content_type); |
620 } | 454 |
621 | 455 if (type != NULL) |
622 if (type != NULL) { | |
623 msg->content_type = g_strdup(type); | 456 msg->content_type = g_strdup(type); |
624 | |
625 msg->size += strlen(type); | |
626 } | |
627 else | 457 else |
628 msg->content_type = NULL; | 458 msg->content_type = NULL; |
629 } | 459 } |
630 | 460 |
631 const char * | 461 const char * |
639 void | 469 void |
640 msn_message_set_charset(MsnMessage *msg, const char *charset) | 470 msn_message_set_charset(MsnMessage *msg, const char *charset) |
641 { | 471 { |
642 g_return_if_fail(msg != NULL); | 472 g_return_if_fail(msg != NULL); |
643 | 473 |
644 if (msg->charset != NULL) { | 474 if (msg->charset != NULL) |
645 msg->size -= strlen(msg->charset) + strlen("; charset="); | |
646 g_free(msg->charset); | 475 g_free(msg->charset); |
647 } | 476 |
648 | 477 if (charset != NULL) |
649 if (charset != NULL) { | |
650 msg->charset = g_strdup(charset); | 478 msg->charset = g_strdup(charset); |
651 | |
652 msg->size += strlen(charset) + strlen("; charset="); | |
653 } | |
654 else | 479 else |
655 msg->charset = NULL; | 480 msg->charset = NULL; |
656 } | 481 } |
657 | 482 |
658 const char * | 483 const char * |
672 g_return_if_fail(msg != NULL); | 497 g_return_if_fail(msg != NULL); |
673 g_return_if_fail(attr != NULL); | 498 g_return_if_fail(attr != NULL); |
674 | 499 |
675 temp = msn_message_get_attr(msg, attr); | 500 temp = msn_message_get_attr(msg, attr); |
676 | 501 |
677 if (value == NULL) { | 502 if (value == NULL) |
678 if (temp != NULL) { | 503 { |
504 if (temp != NULL) | |
505 { | |
679 GList *l; | 506 GList *l; |
680 | 507 |
681 msg->size -= strlen(temp) + strlen(attr) + 4; | 508 for (l = msg->attr_list; l != NULL; l = l->next) |
682 | 509 { |
683 for (l = msg->attr_list; l != NULL; l = l->next) { | 510 if (!g_ascii_strcasecmp(l->data, attr)) |
684 if (!g_ascii_strcasecmp(l->data, attr)) { | 511 { |
685 msg->attr_list = g_list_remove(msg->attr_list, l->data); | 512 msg->attr_list = g_list_remove(msg->attr_list, l->data); |
686 | 513 |
687 break; | 514 break; |
688 } | 515 } |
689 } | 516 } |
696 | 523 |
697 new_attr = g_strdup(attr); | 524 new_attr = g_strdup(attr); |
698 | 525 |
699 g_hash_table_insert(msg->attr_table, new_attr, g_strdup(value)); | 526 g_hash_table_insert(msg->attr_table, new_attr, g_strdup(value)); |
700 | 527 |
701 if (temp == NULL) { | 528 if (temp == NULL) |
702 msg->attr_list = g_list_append(msg->attr_list, new_attr); | 529 msg->attr_list = g_list_append(msg->attr_list, new_attr); |
703 msg->size += strlen(attr) + 4; | |
704 } | |
705 else | |
706 msg->size -= strlen(temp); | |
707 | |
708 msg->size += strlen(value); | |
709 } | 530 } |
710 | 531 |
711 const char * | 532 const char * |
712 msn_message_get_attr(const MsnMessage *msg, const char *attr) | 533 msn_message_get_attr(const MsnMessage *msg, const char *attr) |
713 { | 534 { |
722 { | 543 { |
723 GHashTable *table; | 544 GHashTable *table; |
724 char *body, *s, *c; | 545 char *body, *s, *c; |
725 | 546 |
726 g_return_val_if_fail(msg != NULL, NULL); | 547 g_return_val_if_fail(msg != NULL, NULL); |
727 g_return_val_if_fail(msn_message_get_body(msg) != NULL, NULL); | 548 |
728 | 549 s = body = g_strdup(msn_message_get_bin_data(msg, NULL)); |
729 s = body = g_strdup(msn_message_get_body(msg)); | 550 |
551 g_return_val_if_fail(body != NULL, NULL); | |
730 | 552 |
731 table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | 553 table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); |
732 | 554 |
733 while (*s != '\r' && *s != '\0') { | 555 while (*s != '\r' && *s != '\0') |
556 { | |
734 char *key, *value; | 557 char *key, *value; |
735 | 558 |
736 key = s; | 559 key = s; |
737 | 560 |
738 GET_NEXT(s); | 561 GET_NEXT(s); |
739 | 562 |
740 value = s; | 563 value = s; |
741 | 564 |
742 GET_NEXT_LINE(s); | 565 GET_NEXT_LINE(s); |
743 | 566 |
744 if ((c = strchr(key, ':')) != NULL) { | 567 if ((c = strchr(key, ':')) != NULL) |
568 { | |
745 *c = '\0'; | 569 *c = '\0'; |
746 | 570 |
747 g_hash_table_insert(table, g_strdup(key), g_strdup(value)); | 571 g_hash_table_insert(table, g_strdup(key), g_strdup(value)); |
748 } | 572 } |
749 } | 573 } |
750 | 574 |
751 g_free(body); | 575 g_free(body); |
752 | 576 |
753 return table; | 577 return table; |
754 } | 578 } |
755 |