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