Mercurial > pidgin.yaz
comparison libpurple/protocols/msn/msg.c @ 15374:5fe8042783c1
Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sat, 20 Jan 2007 02:32:10 +0000 |
parents | |
children | 32c366eeeb99 |
comparison
equal
deleted
inserted
replaced
15373:f79e0f4df793 | 15374:5fe8042783c1 |
---|---|
1 /** | |
2 * @file msg.c Message functions | |
3 * | |
4 * gaim | |
5 * | |
6 * Gaim 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 */ | |
24 #include "msn.h" | |
25 #include "msg.h" | |
26 | |
27 MsnMessage * | |
28 msn_message_new(MsnMsgType type) | |
29 { | |
30 MsnMessage *msg; | |
31 | |
32 msg = g_new0(MsnMessage, 1); | |
33 msg->type = type; | |
34 | |
35 #ifdef MSN_DEBUG_MSG | |
36 gaim_debug_info("msn", "message new (%p)(%d)\n", msg, type); | |
37 #endif | |
38 | |
39 msg->attr_table = g_hash_table_new_full(g_str_hash, g_str_equal, | |
40 g_free, g_free); | |
41 | |
42 msn_message_ref(msg); | |
43 | |
44 return msg; | |
45 } | |
46 | |
47 void | |
48 msn_message_destroy(MsnMessage *msg) | |
49 { | |
50 g_return_if_fail(msg != NULL); | |
51 | |
52 if (msg->ref_count > 0) | |
53 { | |
54 msn_message_unref(msg); | |
55 | |
56 return; | |
57 } | |
58 | |
59 #ifdef MSN_DEBUG_MSG | |
60 gaim_debug_info("msn", "message destroy (%p)\n", msg); | |
61 #endif | |
62 | |
63 if (msg->remote_user != NULL) | |
64 g_free(msg->remote_user); | |
65 | |
66 if (msg->body != NULL) | |
67 g_free(msg->body); | |
68 | |
69 if (msg->content_type != NULL) | |
70 g_free(msg->content_type); | |
71 | |
72 if (msg->charset != NULL) | |
73 g_free(msg->charset); | |
74 | |
75 g_hash_table_destroy(msg->attr_table); | |
76 g_list_free(msg->attr_list); | |
77 | |
78 g_free(msg); | |
79 } | |
80 | |
81 MsnMessage * | |
82 msn_message_ref(MsnMessage *msg) | |
83 { | |
84 g_return_val_if_fail(msg != NULL, NULL); | |
85 | |
86 msg->ref_count++; | |
87 | |
88 #ifdef MSN_DEBUG_MSG | |
89 gaim_debug_info("msn", "message ref (%p)[%d]\n", msg, msg->ref_count); | |
90 #endif | |
91 | |
92 return msg; | |
93 } | |
94 | |
95 MsnMessage * | |
96 msn_message_unref(MsnMessage *msg) | |
97 { | |
98 g_return_val_if_fail(msg != NULL, NULL); | |
99 g_return_val_if_fail(msg->ref_count > 0, NULL); | |
100 | |
101 msg->ref_count--; | |
102 | |
103 #ifdef MSN_DEBUG_MSG | |
104 gaim_debug_info("msn", "message unref (%p)[%d]\n", msg, msg->ref_count); | |
105 #endif | |
106 | |
107 if (msg->ref_count == 0) | |
108 { | |
109 msn_message_destroy(msg); | |
110 | |
111 return NULL; | |
112 } | |
113 | |
114 return msg; | |
115 } | |
116 | |
117 MsnMessage * | |
118 msn_message_new_plain(const char *message) | |
119 { | |
120 MsnMessage *msg; | |
121 char *message_cr; | |
122 | |
123 msg = msn_message_new(MSN_MSG_TEXT); | |
124 msn_message_set_attr(msg, "User-Agent", PACKAGE_NAME "/" VERSION); | |
125 msn_message_set_content_type(msg, "text/plain"); | |
126 msn_message_set_charset(msg, "UTF-8"); | |
127 msn_message_set_flag(msg, 'A'); | |
128 msn_message_set_attr(msg, "X-MMS-IM-Format", | |
129 "FN=MS%20Sans%20Serif; EF=; CO=0; PF=0"); | |
130 | |
131 message_cr = gaim_str_add_cr(message); | |
132 msn_message_set_bin_data(msg, message_cr, strlen(message_cr)); | |
133 g_free(message_cr); | |
134 | |
135 return msg; | |
136 } | |
137 | |
138 MsnMessage * | |
139 msn_message_new_msnslp(void) | |
140 { | |
141 MsnMessage *msg; | |
142 | |
143 msg = msn_message_new(MSN_MSG_SLP); | |
144 | |
145 msn_message_set_attr(msg, "User-Agent", NULL); | |
146 | |
147 msg->msnslp_message = TRUE; | |
148 | |
149 msn_message_set_flag(msg, 'D'); | |
150 msn_message_set_content_type(msg, "application/x-msnmsgrp2p"); | |
151 | |
152 return msg; | |
153 } | |
154 | |
155 MsnMessage * | |
156 msn_message_new_nudge(void) | |
157 { | |
158 MsnMessage *msg; | |
159 | |
160 msg = msn_message_new(MSN_MSG_NUDGE); | |
161 msn_message_set_content_type(msg, "text/x-msnmsgr-datacast\r\n"); | |
162 msn_message_set_flag(msg, 'N'); | |
163 msn_message_set_attr(msg,"ID","1\r\n"); | |
164 | |
165 return msg; | |
166 } | |
167 | |
168 void | |
169 msn_message_parse_slp_body(MsnMessage *msg, const char *body, size_t len) | |
170 { | |
171 MsnSlpHeader header; | |
172 const char *tmp; | |
173 int body_len; | |
174 | |
175 tmp = body; | |
176 | |
177 if (len < sizeof(header)) { | |
178 g_return_if_reached(); | |
179 } | |
180 | |
181 /* Import the header. */ | |
182 memcpy(&header, tmp, sizeof(header)); | |
183 tmp += sizeof(header); | |
184 | |
185 msg->msnslp_header.session_id = GUINT32_FROM_LE(header.session_id); | |
186 msg->msnslp_header.id = GUINT32_FROM_LE(header.id); | |
187 msg->msnslp_header.offset = GUINT64_FROM_LE(header.offset); | |
188 msg->msnslp_header.total_size = GUINT64_FROM_LE(header.total_size); | |
189 msg->msnslp_header.length = GUINT32_FROM_LE(header.length); | |
190 msg->msnslp_header.flags = GUINT32_FROM_LE(header.flags); | |
191 msg->msnslp_header.ack_id = GUINT32_FROM_LE(header.ack_id); | |
192 msg->msnslp_header.ack_sub_id = GUINT32_FROM_LE(header.ack_sub_id); | |
193 msg->msnslp_header.ack_size = GUINT64_FROM_LE(header.ack_size); | |
194 | |
195 /* Import the body. */ | |
196 body_len = len - (tmp - body); | |
197 /* msg->body_len = msg->msnslp_header.length; */ | |
198 | |
199 if (body_len > 0) { | |
200 msg->body_len = len - (tmp - body); | |
201 msg->body = g_malloc0(msg->body_len + 1); | |
202 memcpy(msg->body, tmp, msg->body_len); | |
203 tmp += body_len; | |
204 } | |
205 } | |
206 | |
207 void | |
208 msn_message_parse_payload(MsnMessage *msg, | |
209 const char *payload, size_t payload_len) | |
210 { | |
211 char *tmp_base, *tmp; | |
212 const char *content_type; | |
213 char *end; | |
214 char **elems, **cur, **tokens; | |
215 | |
216 g_return_if_fail(payload != NULL); | |
217 | |
218 tmp_base = tmp = g_malloc0(payload_len + 1); | |
219 memcpy(tmp_base, payload, payload_len); | |
220 | |
221 /* Parse the attributes. */ | |
222 end = strstr(tmp, "\r\n\r\n"); | |
223 /* TODO? some clients use \r delimiters instead of \r\n, the official client | |
224 * doesn't send such messages, but does handle receiving them. We'll just | |
225 * avoid crashing for now */ | |
226 if (end == NULL) { | |
227 g_free(tmp_base); | |
228 g_return_if_reached(); | |
229 } | |
230 *end = '\0'; | |
231 | |
232 elems = g_strsplit(tmp, "\r\n", 0); | |
233 | |
234 for (cur = elems; *cur != NULL; cur++) | |
235 { | |
236 const char *key, *value; | |
237 | |
238 tokens = g_strsplit(*cur, ": ", 2); | |
239 | |
240 key = tokens[0]; | |
241 value = tokens[1]; | |
242 | |
243 if (!strcmp(key, "MIME-Version")) | |
244 { | |
245 g_strfreev(tokens); | |
246 continue; | |
247 } | |
248 | |
249 if (!strcmp(key, "Content-Type")) | |
250 { | |
251 char *charset, *c; | |
252 | |
253 if ((c = strchr(value, ';')) != NULL) | |
254 { | |
255 if ((charset = strchr(c, '=')) != NULL) | |
256 { | |
257 charset++; | |
258 msn_message_set_charset(msg, charset); | |
259 } | |
260 | |
261 *c = '\0'; | |
262 } | |
263 | |
264 msn_message_set_content_type(msg, value); | |
265 } | |
266 else | |
267 { | |
268 msn_message_set_attr(msg, key, value); | |
269 } | |
270 | |
271 g_strfreev(tokens); | |
272 } | |
273 | |
274 g_strfreev(elems); | |
275 | |
276 /* Proceed to the end of the "\r\n\r\n" */ | |
277 tmp = end + 4; | |
278 | |
279 /* Now we *should* be at the body. */ | |
280 content_type = msn_message_get_content_type(msg); | |
281 | |
282 if (content_type != NULL && | |
283 !strcmp(content_type, "application/x-msnmsgrp2p")) | |
284 { | |
285 MsnSlpHeader header; | |
286 MsnSlpFooter footer; | |
287 int body_len; | |
288 | |
289 if (payload_len - (tmp - tmp_base) < sizeof(header)) { | |
290 g_free(tmp_base); | |
291 g_return_if_reached(); | |
292 } | |
293 | |
294 msg->msnslp_message = TRUE; | |
295 | |
296 /* Import the header. */ | |
297 memcpy(&header, tmp, sizeof(header)); | |
298 tmp += sizeof(header); | |
299 | |
300 msg->msnslp_header.session_id = GUINT32_FROM_LE(header.session_id); | |
301 msg->msnslp_header.id = GUINT32_FROM_LE(header.id); | |
302 msg->msnslp_header.offset = GUINT64_FROM_LE(header.offset); | |
303 msg->msnslp_header.total_size = GUINT64_FROM_LE(header.total_size); | |
304 msg->msnslp_header.length = GUINT32_FROM_LE(header.length); | |
305 msg->msnslp_header.flags = GUINT32_FROM_LE(header.flags); | |
306 msg->msnslp_header.ack_id = GUINT32_FROM_LE(header.ack_id); | |
307 msg->msnslp_header.ack_sub_id = GUINT32_FROM_LE(header.ack_sub_id); | |
308 msg->msnslp_header.ack_size = GUINT64_FROM_LE(header.ack_size); | |
309 | |
310 body_len = payload_len - (tmp - tmp_base) - sizeof(footer); | |
311 | |
312 /* Import the body. */ | |
313 if (body_len > 0) { | |
314 msg->body_len = body_len; | |
315 msg->body = g_malloc0(msg->body_len + 1); | |
316 memcpy(msg->body, tmp, msg->body_len); | |
317 tmp += body_len; | |
318 } | |
319 | |
320 /* Import the footer. */ | |
321 if (body_len >= 0) { | |
322 memcpy(&footer, tmp, sizeof(footer)); | |
323 tmp += sizeof(footer); | |
324 msg->msnslp_footer.value = GUINT32_FROM_BE(footer.value); | |
325 } | |
326 } | |
327 else | |
328 { | |
329 if (payload_len - (tmp - tmp_base) > 0) { | |
330 msg->body_len = payload_len - (tmp - tmp_base); | |
331 msg->body = g_malloc0(msg->body_len + 1); | |
332 memcpy(msg->body, tmp, msg->body_len); | |
333 } | |
334 } | |
335 | |
336 g_free(tmp_base); | |
337 } | |
338 | |
339 MsnMessage * | |
340 msn_message_new_from_cmd(MsnSession *session, MsnCommand *cmd) | |
341 { | |
342 MsnMessage *msg; | |
343 | |
344 g_return_val_if_fail(cmd != NULL, NULL); | |
345 | |
346 msg = msn_message_new(MSN_MSG_UNKNOWN); | |
347 | |
348 msg->remote_user = g_strdup(cmd->params[0]); | |
349 /* msg->size = atoi(cmd->params[2]); */ | |
350 msg->cmd = cmd; | |
351 | |
352 return msg; | |
353 } | |
354 | |
355 char * | |
356 msn_message_gen_slp_body(MsnMessage *msg, size_t *ret_size) | |
357 { | |
358 MsnSlpHeader header; | |
359 | |
360 char *tmp, *base; | |
361 const void *body; | |
362 size_t len, body_len; | |
363 | |
364 g_return_val_if_fail(msg != NULL, NULL); | |
365 | |
366 len = MSN_BUF_LEN; | |
367 | |
368 base = tmp = g_malloc(len + 1); | |
369 | |
370 body = msn_message_get_bin_data(msg, &body_len); | |
371 | |
372 header.session_id = GUINT32_TO_LE(msg->msnslp_header.session_id); | |
373 header.id = GUINT32_TO_LE(msg->msnslp_header.id); | |
374 header.offset = GUINT64_TO_LE(msg->msnslp_header.offset); | |
375 header.total_size = GUINT64_TO_LE(msg->msnslp_header.total_size); | |
376 header.length = GUINT32_TO_LE(msg->msnslp_header.length); | |
377 header.flags = GUINT32_TO_LE(msg->msnslp_header.flags); | |
378 header.ack_id = GUINT32_TO_LE(msg->msnslp_header.ack_id); | |
379 header.ack_sub_id = GUINT32_TO_LE(msg->msnslp_header.ack_sub_id); | |
380 header.ack_size = GUINT64_TO_LE(msg->msnslp_header.ack_size); | |
381 | |
382 memcpy(tmp, &header, 48); | |
383 tmp += 48; | |
384 | |
385 if (body != NULL) | |
386 { | |
387 memcpy(tmp, body, body_len); | |
388 tmp += body_len; | |
389 } | |
390 | |
391 if (ret_size != NULL) | |
392 *ret_size = tmp - base; | |
393 | |
394 return base; | |
395 } | |
396 | |
397 char * | |
398 msn_message_gen_payload(MsnMessage *msg, size_t *ret_size) | |
399 { | |
400 GList *l; | |
401 char *n, *base, *end; | |
402 int len; | |
403 size_t body_len; | |
404 const void *body; | |
405 | |
406 g_return_val_if_fail(msg != NULL, NULL); | |
407 | |
408 len = MSN_BUF_LEN; | |
409 | |
410 base = n = end = g_malloc(len + 1); | |
411 end += len; | |
412 | |
413 /* Standard header. */ | |
414 if (msg->charset == NULL) | |
415 { | |
416 g_snprintf(n, len, | |
417 "MIME-Version: 1.0\r\n" | |
418 "Content-Type: %s\r\n", | |
419 msg->content_type); | |
420 } | |
421 else | |
422 { | |
423 g_snprintf(n, len, | |
424 "MIME-Version: 1.0\r\n" | |
425 "Content-Type: %s; charset=%s\r\n", | |
426 msg->content_type, msg->charset); | |
427 } | |
428 | |
429 n += strlen(n); | |
430 | |
431 for (l = msg->attr_list; l != NULL; l = l->next) | |
432 { | |
433 const char *key; | |
434 const char *value; | |
435 | |
436 key = l->data; | |
437 value = msn_message_get_attr(msg, key); | |
438 | |
439 g_snprintf(n, end - n, "%s: %s\r\n", key, value); | |
440 n += strlen(n); | |
441 } | |
442 | |
443 n += g_strlcpy(n, "\r\n", end - n); | |
444 | |
445 body = msn_message_get_bin_data(msg, &body_len); | |
446 | |
447 if (msg->msnslp_message) | |
448 { | |
449 MsnSlpHeader header; | |
450 MsnSlpFooter footer; | |
451 | |
452 header.session_id = GUINT32_TO_LE(msg->msnslp_header.session_id); | |
453 header.id = GUINT32_TO_LE(msg->msnslp_header.id); | |
454 header.offset = GUINT64_TO_LE(msg->msnslp_header.offset); | |
455 header.total_size = GUINT64_TO_LE(msg->msnslp_header.total_size); | |
456 header.length = GUINT32_TO_LE(msg->msnslp_header.length); | |
457 header.flags = GUINT32_TO_LE(msg->msnslp_header.flags); | |
458 header.ack_id = GUINT32_TO_LE(msg->msnslp_header.ack_id); | |
459 header.ack_sub_id = GUINT32_TO_LE(msg->msnslp_header.ack_sub_id); | |
460 header.ack_size = GUINT64_TO_LE(msg->msnslp_header.ack_size); | |
461 | |
462 memcpy(n, &header, 48); | |
463 n += 48; | |
464 | |
465 if (body != NULL) | |
466 { | |
467 memcpy(n, body, body_len); | |
468 | |
469 n += body_len; | |
470 } | |
471 | |
472 footer.value = GUINT32_TO_BE(msg->msnslp_footer.value); | |
473 | |
474 memcpy(n, &footer, 4); | |
475 n += 4; | |
476 } | |
477 else | |
478 { | |
479 if (body != NULL) | |
480 { | |
481 memcpy(n, body, body_len); | |
482 n += body_len; | |
483 } | |
484 } | |
485 | |
486 if (ret_size != NULL) | |
487 { | |
488 *ret_size = n - base; | |
489 | |
490 if (*ret_size > 1664) | |
491 *ret_size = 1664; | |
492 } | |
493 | |
494 return base; | |
495 } | |
496 | |
497 void | |
498 msn_message_set_flag(MsnMessage *msg, char flag) | |
499 { | |
500 g_return_if_fail(msg != NULL); | |
501 g_return_if_fail(flag != 0); | |
502 | |
503 msg->flag = flag; | |
504 } | |
505 | |
506 char | |
507 msn_message_get_flag(const MsnMessage *msg) | |
508 { | |
509 g_return_val_if_fail(msg != NULL, 0); | |
510 | |
511 return msg->flag; | |
512 } | |
513 | |
514 void | |
515 msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len) | |
516 { | |
517 g_return_if_fail(msg != NULL); | |
518 | |
519 /* There is no need to waste memory on data we cannot send anyway */ | |
520 if (len > 1664) | |
521 len = 1664; | |
522 | |
523 if (msg->body != NULL) | |
524 g_free(msg->body); | |
525 | |
526 if (data != NULL && len > 0) | |
527 { | |
528 msg->body = g_malloc0(len + 1); | |
529 memcpy(msg->body, data, len); | |
530 msg->body_len = len; | |
531 } | |
532 else | |
533 { | |
534 msg->body = NULL; | |
535 msg->body_len = 0; | |
536 } | |
537 } | |
538 | |
539 const void * | |
540 msn_message_get_bin_data(const MsnMessage *msg, size_t *len) | |
541 { | |
542 g_return_val_if_fail(msg != NULL, NULL); | |
543 | |
544 if (len) | |
545 *len = msg->body_len; | |
546 | |
547 return msg->body; | |
548 } | |
549 | |
550 void | |
551 msn_message_set_content_type(MsnMessage *msg, const char *type) | |
552 { | |
553 g_return_if_fail(msg != NULL); | |
554 | |
555 if (msg->content_type != NULL) | |
556 g_free(msg->content_type); | |
557 | |
558 msg->content_type = (type != NULL) ? g_strdup(type) : NULL; | |
559 } | |
560 | |
561 const char * | |
562 msn_message_get_content_type(const MsnMessage *msg) | |
563 { | |
564 g_return_val_if_fail(msg != NULL, NULL); | |
565 | |
566 return msg->content_type; | |
567 } | |
568 | |
569 void | |
570 msn_message_set_charset(MsnMessage *msg, const char *charset) | |
571 { | |
572 g_return_if_fail(msg != NULL); | |
573 | |
574 if (msg->charset != NULL) | |
575 g_free(msg->charset); | |
576 | |
577 msg->charset = (charset != NULL) ? g_strdup(charset) : NULL; | |
578 } | |
579 | |
580 const char * | |
581 msn_message_get_charset(const MsnMessage *msg) | |
582 { | |
583 g_return_val_if_fail(msg != NULL, NULL); | |
584 | |
585 return msg->charset; | |
586 } | |
587 | |
588 void | |
589 msn_message_set_attr(MsnMessage *msg, const char *attr, const char *value) | |
590 { | |
591 const char *temp; | |
592 char *new_attr; | |
593 | |
594 g_return_if_fail(msg != NULL); | |
595 g_return_if_fail(attr != NULL); | |
596 | |
597 temp = msn_message_get_attr(msg, attr); | |
598 | |
599 if (value == NULL) | |
600 { | |
601 if (temp != NULL) | |
602 { | |
603 GList *l; | |
604 | |
605 for (l = msg->attr_list; l != NULL; l = l->next) | |
606 { | |
607 if (!g_ascii_strcasecmp(l->data, attr)) | |
608 { | |
609 msg->attr_list = g_list_remove(msg->attr_list, l->data); | |
610 | |
611 break; | |
612 } | |
613 } | |
614 | |
615 g_hash_table_remove(msg->attr_table, attr); | |
616 } | |
617 | |
618 return; | |
619 } | |
620 | |
621 new_attr = g_strdup(attr); | |
622 | |
623 g_hash_table_insert(msg->attr_table, new_attr, g_strdup(value)); | |
624 | |
625 if (temp == NULL) | |
626 msg->attr_list = g_list_append(msg->attr_list, new_attr); | |
627 } | |
628 | |
629 const char * | |
630 msn_message_get_attr(const MsnMessage *msg, const char *attr) | |
631 { | |
632 g_return_val_if_fail(msg != NULL, NULL); | |
633 g_return_val_if_fail(attr != NULL, NULL); | |
634 | |
635 return g_hash_table_lookup(msg->attr_table, attr); | |
636 } | |
637 | |
638 GHashTable * | |
639 msn_message_get_hashtable_from_body(const MsnMessage *msg) | |
640 { | |
641 GHashTable *table; | |
642 size_t body_len; | |
643 const char *body; | |
644 char **elems, **cur, **tokens, *body_str; | |
645 | |
646 g_return_val_if_fail(msg != NULL, NULL); | |
647 | |
648 table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
649 | |
650 body = msn_message_get_bin_data(msg, &body_len); | |
651 | |
652 g_return_val_if_fail(body != NULL, NULL); | |
653 | |
654 body_str = g_strndup(body, body_len); | |
655 elems = g_strsplit(body_str, "\r\n", 0); | |
656 g_free(body_str); | |
657 | |
658 for (cur = elems; *cur != NULL; cur++) | |
659 { | |
660 if (**cur == '\0') | |
661 break; | |
662 | |
663 tokens = g_strsplit(*cur, ": ", 2); | |
664 | |
665 if (tokens[0] != NULL && tokens[1] != NULL) | |
666 g_hash_table_insert(table, tokens[0], tokens[1]); | |
667 | |
668 g_free(tokens); | |
669 } | |
670 | |
671 g_strfreev(elems); | |
672 | |
673 return table; | |
674 } | |
675 | |
676 char * | |
677 msn_message_to_string(MsnMessage *msg) | |
678 { | |
679 size_t body_len; | |
680 const char *body; | |
681 | |
682 g_return_val_if_fail(msg != NULL, NULL); | |
683 g_return_val_if_fail(msg->type == MSN_MSG_TEXT, NULL); | |
684 | |
685 body = msn_message_get_bin_data(msg, &body_len); | |
686 | |
687 return g_strndup(body, body_len); | |
688 } | |
689 | |
690 void | |
691 msn_message_show_readable(MsnMessage *msg, const char *info, | |
692 gboolean text_body) | |
693 { | |
694 GString *str; | |
695 size_t body_len; | |
696 const char *body; | |
697 GList *l; | |
698 | |
699 g_return_if_fail(msg != NULL); | |
700 | |
701 str = g_string_new(NULL); | |
702 | |
703 /* Standard header. */ | |
704 if (msg->charset == NULL) | |
705 { | |
706 g_string_append_printf(str, | |
707 "MIME-Version: 1.0\r\n" | |
708 "Content-Type: %s\r\n", | |
709 msg->content_type); | |
710 } | |
711 else | |
712 { | |
713 g_string_append_printf(str, | |
714 "MIME-Version: 1.0\r\n" | |
715 "Content-Type: %s; charset=%s\r\n", | |
716 msg->content_type, msg->charset); | |
717 } | |
718 | |
719 for (l = msg->attr_list; l; l = l->next) | |
720 { | |
721 char *key; | |
722 const char *value; | |
723 | |
724 key = l->data; | |
725 value = msn_message_get_attr(msg, key); | |
726 | |
727 g_string_append_printf(str, "%s: %s\r\n", key, value); | |
728 } | |
729 | |
730 g_string_append(str, "\r\n"); | |
731 | |
732 body = msn_message_get_bin_data(msg, &body_len); | |
733 | |
734 if (msg->msnslp_message) | |
735 { | |
736 g_string_append_printf(str, "Session ID: %u\r\n", msg->msnslp_header.session_id); | |
737 g_string_append_printf(str, "ID: %u\r\n", msg->msnslp_header.id); | |
738 g_string_append_printf(str, "Offset: %" G_GUINT64_FORMAT "\r\n", msg->msnslp_header.offset); | |
739 g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", msg->msnslp_header.total_size); | |
740 g_string_append_printf(str, "Length: %u\r\n", msg->msnslp_header.length); | |
741 g_string_append_printf(str, "Flags: 0x%x\r\n", msg->msnslp_header.flags); | |
742 g_string_append_printf(str, "ACK ID: %u\r\n", msg->msnslp_header.ack_id); | |
743 g_string_append_printf(str, "SUB ID: %u\r\n", msg->msnslp_header.ack_sub_id); | |
744 g_string_append_printf(str, "ACK Size: %" G_GUINT64_FORMAT "\r\n", msg->msnslp_header.ack_size); | |
745 | |
746 #ifdef MSN_DEBUG_SLP_VERBOSE | |
747 if (body != NULL) | |
748 { | |
749 if (text_body) | |
750 { | |
751 g_string_append_len(str, body, body_len); | |
752 if (body[body_len - 1] == '\0') | |
753 { | |
754 str->len--; | |
755 g_string_append(str, " 0x00"); | |
756 } | |
757 g_string_append(str, "\r\n"); | |
758 } | |
759 else | |
760 { | |
761 int i; | |
762 for (i = 0; i < msg->body_len; i++) | |
763 { | |
764 g_string_append_printf(str, "%.2hhX ", body[i]); | |
765 if ((i % 16) == 15) | |
766 g_string_append(str, "\r\n"); | |
767 } | |
768 g_string_append(str, "\r\n"); | |
769 } | |
770 } | |
771 #endif | |
772 | |
773 g_string_append_printf(str, "Footer: %u\r\n", msg->msnslp_footer.value); | |
774 } | |
775 else | |
776 { | |
777 if (body != NULL) | |
778 { | |
779 g_string_append_len(str, body, body_len); | |
780 g_string_append(str, "\r\n"); | |
781 } | |
782 } | |
783 | |
784 gaim_debug_info("msn", "Message %s:\n{%s}\n", info, str->str); | |
785 | |
786 g_string_free(str, TRUE); | |
787 } |