Mercurial > pidgin
comparison libpurple/protocols/msn/msg.c @ 30694:33b4ae796648
Rename "attribute" to "header" in a bunch of places. The SLP protocol
is fashioned after HTTP. Well, more accurately after SIP. And these
are generally referred to as headers pretty much everywhere.
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 08 Feb 2010 07:41:15 +0000 |
parents | 9262c8f306a6 |
children | a786d893df2b |
comparison
equal
deleted
inserted
replaced
30693:6376fc7a092e | 30694:33b4ae796648 |
---|---|
34 msg->type = type; | 34 msg->type = type; |
35 | 35 |
36 if (purple_debug_is_verbose()) | 36 if (purple_debug_is_verbose()) |
37 purple_debug_info("msn", "message new (%p)(%d)\n", msg, type); | 37 purple_debug_info("msn", "message new (%p)(%d)\n", msg, type); |
38 | 38 |
39 msg->attr_table = g_hash_table_new_full(g_str_hash, g_str_equal, | 39 msg->header_table = g_hash_table_new_full(g_str_hash, g_str_equal, |
40 g_free, g_free); | 40 g_free, g_free); |
41 | 41 |
42 msn_message_ref(msg); | 42 msn_message_ref(msg); |
43 | 43 |
44 return msg; | 44 return msg; |
62 g_free(msg->remote_user); | 62 g_free(msg->remote_user); |
63 g_free(msg->body); | 63 g_free(msg->body); |
64 g_free(msg->content_type); | 64 g_free(msg->content_type); |
65 g_free(msg->charset); | 65 g_free(msg->charset); |
66 | 66 |
67 g_hash_table_destroy(msg->attr_table); | 67 g_hash_table_destroy(msg->header_table); |
68 g_list_free(msg->attr_list); | 68 g_list_free(msg->header_list); |
69 | 69 |
70 g_free(msg); | 70 g_free(msg); |
71 } | 71 } |
72 | 72 |
73 MsnMessage * | 73 MsnMessage * |
110 MsnMessage *msg; | 110 MsnMessage *msg; |
111 char *message_cr; | 111 char *message_cr; |
112 | 112 |
113 msg = msn_message_new(MSN_MSG_TEXT); | 113 msg = msn_message_new(MSN_MSG_TEXT); |
114 msg->retries = 1; | 114 msg->retries = 1; |
115 msn_message_set_attr(msg, "User-Agent", PACKAGE_NAME "/" VERSION); | 115 msn_message_set_header(msg, "User-Agent", PACKAGE_NAME "/" VERSION); |
116 msn_message_set_content_type(msg, "text/plain"); | 116 msn_message_set_content_type(msg, "text/plain"); |
117 msn_message_set_charset(msg, "UTF-8"); | 117 msn_message_set_charset(msg, "UTF-8"); |
118 msn_message_set_flag(msg, 'A'); | 118 msn_message_set_flag(msg, 'A'); |
119 msn_message_set_attr(msg, "X-MMS-IM-Format", | 119 msn_message_set_header(msg, "X-MMS-IM-Format", |
120 "FN=Segoe%20UI; EF=; CO=0; CS=1;PF=0"); | 120 "FN=Segoe%20UI; EF=; CO=0; CS=1;PF=0"); |
121 | 121 |
122 message_cr = purple_str_add_cr(message); | 122 message_cr = purple_str_add_cr(message); |
123 msn_message_set_bin_data(msg, message_cr, strlen(message_cr)); | 123 msn_message_set_bin_data(msg, message_cr, strlen(message_cr)); |
124 g_free(message_cr); | 124 g_free(message_cr); |
131 { | 131 { |
132 MsnMessage *msg; | 132 MsnMessage *msg; |
133 | 133 |
134 msg = msn_message_new(MSN_MSG_SLP); | 134 msg = msn_message_new(MSN_MSG_SLP); |
135 | 135 |
136 msn_message_set_attr(msg, "User-Agent", NULL); | 136 msn_message_set_header(msg, "User-Agent", NULL); |
137 | 137 |
138 msg->msnslp_message = TRUE; | 138 msg->msnslp_message = TRUE; |
139 | 139 |
140 msn_message_set_flag(msg, 'D'); | 140 msn_message_set_flag(msg, 'D'); |
141 msn_message_set_content_type(msg, "application/x-msnmsgrp2p"); | 141 msn_message_set_content_type(msg, "application/x-msnmsgrp2p"); |
167 | 167 |
168 if (len < sizeof(header)) { | 168 if (len < sizeof(header)) { |
169 g_return_if_reached(); | 169 g_return_if_reached(); |
170 } | 170 } |
171 | 171 |
172 /* Import the header. */ | 172 /* Extract the binary SLP header */ |
173 memcpy(&header, tmp, sizeof(header)); | 173 memcpy(&header, tmp, sizeof(header)); |
174 tmp += sizeof(header); | 174 tmp += sizeof(header); |
175 | 175 |
176 msg->msnslp_header.session_id = GUINT32_FROM_LE(header.session_id); | 176 msg->msnslp_header.session_id = GUINT32_FROM_LE(header.session_id); |
177 msg->msnslp_header.id = GUINT32_FROM_LE(header.id); | 177 msg->msnslp_header.id = GUINT32_FROM_LE(header.id); |
181 msg->msnslp_header.flags = GUINT32_FROM_LE(header.flags); | 181 msg->msnslp_header.flags = GUINT32_FROM_LE(header.flags); |
182 msg->msnslp_header.ack_id = GUINT32_FROM_LE(header.ack_id); | 182 msg->msnslp_header.ack_id = GUINT32_FROM_LE(header.ack_id); |
183 msg->msnslp_header.ack_sub_id = GUINT32_FROM_LE(header.ack_sub_id); | 183 msg->msnslp_header.ack_sub_id = GUINT32_FROM_LE(header.ack_sub_id); |
184 msg->msnslp_header.ack_size = GUINT64_FROM_LE(header.ack_size); | 184 msg->msnslp_header.ack_size = GUINT64_FROM_LE(header.ack_size); |
185 | 185 |
186 /* Import the body. */ | 186 /* Extract the body */ |
187 body_len = len - (tmp - body); | 187 body_len = len - (tmp - body); |
188 /* msg->body_len = msg->msnslp_header.length; */ | 188 /* msg->body_len = msg->msnslp_header.length; */ |
189 | 189 |
190 if (body_len > 0) { | 190 if (body_len > 0) { |
191 msg->body_len = len - (tmp - body); | 191 msg->body_len = len - (tmp - body); |
209 g_return_if_fail(payload != NULL); | 209 g_return_if_fail(payload != NULL); |
210 tmp_base = tmp = g_malloc(payload_len + 1); | 210 tmp_base = tmp = g_malloc(payload_len + 1); |
211 memcpy(tmp_base, payload, payload_len); | 211 memcpy(tmp_base, payload, payload_len); |
212 tmp_base[payload_len] = '\0'; | 212 tmp_base[payload_len] = '\0'; |
213 | 213 |
214 /* Parse the attributes. */ | 214 /* Find the end of the headers */ |
215 end = strstr(tmp, body_dem); | 215 end = strstr(tmp, body_dem); |
216 /* TODO? some clients use \r delimiters instead of \r\n, the official client | 216 /* TODO? some clients use \r delimiters instead of \r\n, the official client |
217 * doesn't send such messages, but does handle receiving them. We'll just | 217 * doesn't send such messages, but does handle receiving them. We'll just |
218 * avoid crashing for now */ | 218 * avoid crashing for now */ |
219 if (end == NULL) { | 219 if (end == NULL) { |
220 g_free(tmp_base); | 220 g_free(tmp_base); |
221 g_return_if_reached(); | 221 g_return_if_reached(); |
222 } | 222 } |
223 *end = '\0'; | 223 *end = '\0'; |
224 | 224 |
225 /* Split the headers and parse each one */ | |
225 elems = g_strsplit(tmp, line_dem, 0); | 226 elems = g_strsplit(tmp, line_dem, 0); |
226 | |
227 for (cur = elems; *cur != NULL; cur++) | 227 for (cur = elems; *cur != NULL; cur++) |
228 { | 228 { |
229 const char *key, *value; | 229 const char *key, *value; |
230 | 230 |
231 /* If this line starts with whitespace, it's been folded from the | 231 /* If this line starts with whitespace, it's been folded from the |
238 /* The only one I care about is 'boundary' (which is folded from | 238 /* The only one I care about is 'boundary' (which is folded from |
239 the key 'Content-Type'), so only process that. */ | 239 the key 'Content-Type'), so only process that. */ |
240 if (!strcmp(key, "boundary")) { | 240 if (!strcmp(key, "boundary")) { |
241 char *end = strchr(value, '\"'); | 241 char *end = strchr(value, '\"'); |
242 *end = '\0'; | 242 *end = '\0'; |
243 msn_message_set_attr(msg, key, value); | 243 msn_message_set_header(msg, key, value); |
244 } | 244 } |
245 | 245 |
246 g_strfreev(tokens); | 246 g_strfreev(tokens); |
247 continue; | 247 continue; |
248 } | 248 } |
276 | 276 |
277 msn_message_set_content_type(msg, value); | 277 msn_message_set_content_type(msg, value); |
278 } | 278 } |
279 else | 279 else |
280 { | 280 { |
281 msn_message_set_attr(msg, key, value); | 281 msn_message_set_header(msg, key, value); |
282 } | 282 } |
283 | 283 |
284 g_strfreev(tokens); | 284 g_strfreev(tokens); |
285 } | 285 } |
286 | |
287 g_strfreev(elems); | 286 g_strfreev(elems); |
288 | 287 |
289 /* Proceed to the end of the "\r\n\r\n" */ | 288 /* Proceed to the end of the "\r\n\r\n" */ |
290 tmp = end + strlen(body_dem); | 289 tmp = end + strlen(body_dem); |
291 | 290 |
304 g_return_if_reached(); | 303 g_return_if_reached(); |
305 } | 304 } |
306 | 305 |
307 msg->msnslp_message = TRUE; | 306 msg->msnslp_message = TRUE; |
308 | 307 |
309 /* Import the header. */ | 308 /* Extract the binary SLP header */ |
310 memcpy(&header, tmp, sizeof(header)); | 309 memcpy(&header, tmp, sizeof(header)); |
311 tmp += sizeof(header); | 310 tmp += sizeof(header); |
312 | 311 |
313 msg->msnslp_header.session_id = GUINT32_FROM_LE(header.session_id); | 312 msg->msnslp_header.session_id = GUINT32_FROM_LE(header.session_id); |
314 msg->msnslp_header.id = GUINT32_FROM_LE(header.id); | 313 msg->msnslp_header.id = GUINT32_FROM_LE(header.id); |
320 msg->msnslp_header.ack_sub_id = GUINT32_FROM_LE(header.ack_sub_id); | 319 msg->msnslp_header.ack_sub_id = GUINT32_FROM_LE(header.ack_sub_id); |
321 msg->msnslp_header.ack_size = GUINT64_FROM_LE(header.ack_size); | 320 msg->msnslp_header.ack_size = GUINT64_FROM_LE(header.ack_size); |
322 | 321 |
323 body_len = payload_len - (tmp - tmp_base) - sizeof(footer); | 322 body_len = payload_len - (tmp - tmp_base) - sizeof(footer); |
324 | 323 |
325 /* Import the body. */ | 324 /* Extract the body */ |
326 if (body_len > 0) { | 325 if (body_len > 0) { |
327 msg->body_len = body_len; | 326 msg->body_len = body_len; |
328 g_free(msg->body); | 327 g_free(msg->body); |
329 msg->body = g_malloc(msg->body_len + 1); | 328 msg->body = g_malloc(msg->body_len + 1); |
330 memcpy(msg->body, tmp, msg->body_len); | 329 memcpy(msg->body, tmp, msg->body_len); |
331 msg->body[msg->body_len] = '\0'; | 330 msg->body[msg->body_len] = '\0'; |
332 tmp += body_len; | 331 tmp += body_len; |
333 } | 332 } |
334 | 333 |
335 /* Import the footer. */ | 334 /* Extract the footer */ |
336 if (body_len >= 0) { | 335 if (body_len >= 0) { |
337 memcpy(&footer, tmp, sizeof(footer)); | 336 memcpy(&footer, tmp, sizeof(footer)); |
338 tmp += sizeof(footer); | 337 tmp += sizeof(footer); |
339 msg->msnslp_footer.value = GUINT32_FROM_BE(footer.value); | 338 msg->msnslp_footer.value = GUINT32_FROM_BE(footer.value); |
340 } | 339 } |
346 g_free(msg->body); | 345 g_free(msg->body); |
347 msg->body = g_malloc(msg->body_len + 1); | 346 msg->body = g_malloc(msg->body_len + 1); |
348 memcpy(msg->body, tmp, msg->body_len); | 347 memcpy(msg->body, tmp, msg->body_len); |
349 msg->body[msg->body_len] = '\0'; | 348 msg->body[msg->body_len] = '\0'; |
350 } | 349 } |
351 | 350 |
352 if ((!content_type || !strcmp(content_type, "text/plain")) | 351 if ((!content_type || !strcmp(content_type, "text/plain")) |
353 && msg->charset == NULL) { | 352 && msg->charset == NULL) { |
354 char *body = g_convert(msg->body, msg->body_len, "UTF-8", | 353 char *body = g_convert(msg->body, msg->body_len, "UTF-8", |
355 "ISO-8859-1", NULL, &msg->body_len, NULL); | 354 "ISO-8859-1", NULL, &msg->body_len, NULL); |
356 g_free(msg->body); | 355 g_free(msg->body); |
452 msg->content_type, msg->charset); | 451 msg->content_type, msg->charset); |
453 } | 452 } |
454 | 453 |
455 n += strlen(n); | 454 n += strlen(n); |
456 | 455 |
457 for (l = msg->attr_list; l != NULL; l = l->next) | 456 for (l = msg->header_list; l != NULL; l = l->next) |
458 { | 457 { |
459 const char *key; | 458 const char *key; |
460 const char *value; | 459 const char *value; |
461 | 460 |
462 key = l->data; | 461 key = l->data; |
463 value = msn_message_get_attr(msg, key); | 462 value = msn_message_get_header_value(msg, key); |
464 | 463 |
465 g_snprintf(n, end - n, "%s: %s\r\n", key, value); | 464 g_snprintf(n, end - n, "%s: %s\r\n", key, value); |
466 n += strlen(n); | 465 n += strlen(n); |
467 } | 466 } |
468 | 467 |
608 | 607 |
609 return msg->charset; | 608 return msg->charset; |
610 } | 609 } |
611 | 610 |
612 void | 611 void |
613 msn_message_set_attr(MsnMessage *msg, const char *attr, const char *value) | 612 msn_message_set_header(MsnMessage *msg, const char *name, const char *value) |
614 { | 613 { |
615 const char *temp; | 614 const char *temp; |
616 char *new_attr; | 615 char *new_name; |
617 | 616 |
618 g_return_if_fail(msg != NULL); | 617 g_return_if_fail(msg != NULL); |
619 g_return_if_fail(attr != NULL); | 618 g_return_if_fail(name != NULL); |
620 | 619 |
621 temp = msn_message_get_attr(msg, attr); | 620 temp = msn_message_get_header_value(msg, name); |
622 | 621 |
623 if (value == NULL) | 622 if (value == NULL) |
624 { | 623 { |
625 if (temp != NULL) | 624 if (temp != NULL) |
626 { | 625 { |
627 GList *l; | 626 GList *l; |
628 | 627 |
629 for (l = msg->attr_list; l != NULL; l = l->next) | 628 for (l = msg->header_list; l != NULL; l = l->next) |
630 { | 629 { |
631 if (!g_ascii_strcasecmp(l->data, attr)) | 630 if (!g_ascii_strcasecmp(l->data, name)) |
632 { | 631 { |
633 msg->attr_list = g_list_remove(msg->attr_list, l->data); | 632 msg->header_list = g_list_remove(msg->header_list, l->data); |
634 | 633 |
635 break; | 634 break; |
636 } | 635 } |
637 } | 636 } |
638 | 637 |
639 g_hash_table_remove(msg->attr_table, attr); | 638 g_hash_table_remove(msg->header_table, name); |
640 } | 639 } |
641 | 640 |
642 return; | 641 return; |
643 } | 642 } |
644 | 643 |
645 new_attr = g_strdup(attr); | 644 new_name = g_strdup(name); |
646 | 645 |
647 g_hash_table_insert(msg->attr_table, new_attr, g_strdup(value)); | 646 g_hash_table_insert(msg->header_table, new_name, g_strdup(value)); |
648 | 647 |
649 if (temp == NULL) | 648 if (temp == NULL) |
650 msg->attr_list = g_list_append(msg->attr_list, new_attr); | 649 msg->header_list = g_list_append(msg->header_list, new_name); |
651 } | 650 } |
652 | 651 |
653 const char * | 652 const char * |
654 msn_message_get_attr(const MsnMessage *msg, const char *attr) | 653 msn_message_get_header_value(const MsnMessage *msg, const char *name) |
655 { | 654 { |
656 g_return_val_if_fail(msg != NULL, NULL); | 655 g_return_val_if_fail(msg != NULL, NULL); |
657 g_return_val_if_fail(attr != NULL, NULL); | 656 g_return_val_if_fail(name != NULL, NULL); |
658 | 657 |
659 return g_hash_table_lookup(msg->attr_table, attr); | 658 return g_hash_table_lookup(msg->header_table, name); |
660 } | 659 } |
661 | 660 |
662 GHashTable * | 661 GHashTable * |
663 msn_message_get_hashtable_from_body(const MsnMessage *msg) | 662 msn_message_get_hashtable_from_body(const MsnMessage *msg) |
664 { | 663 { |
739 "MIME-Version: 1.0\r\n" | 738 "MIME-Version: 1.0\r\n" |
740 "Content-Type: %s; charset=%s\r\n", | 739 "Content-Type: %s; charset=%s\r\n", |
741 msg->content_type, msg->charset); | 740 msg->content_type, msg->charset); |
742 } | 741 } |
743 | 742 |
744 for (l = msg->attr_list; l; l = l->next) | 743 for (l = msg->header_list; l; l = l->next) |
745 { | 744 { |
746 char *key; | 745 char *key; |
747 const char *value; | 746 const char *value; |
748 | 747 |
749 key = l->data; | 748 key = l->data; |
750 value = msn_message_get_attr(msg, key); | 749 value = msn_message_get_header_value(msg, key); |
751 | 750 |
752 g_string_append_printf(str, "%s: %s\r\n", key, value); | 751 g_string_append_printf(str, "%s: %s\r\n", key, value); |
753 } | 752 } |
754 | 753 |
755 g_string_append(str, "\r\n"); | 754 g_string_append(str, "\r\n"); |
838 { | 837 { |
839 return; | 838 return; |
840 } | 839 } |
841 | 840 |
842 #if 0 | 841 #if 0 |
843 if ((value = msn_message_get_attr(msg, "User-Agent")) != NULL) | 842 if ((value = msn_message_get_header_value(msg, "User-Agent")) != NULL) |
844 { | 843 { |
845 purple_debug_misc("msn", "User-Agent = '%s'\n", value); | 844 purple_debug_misc("msn", "User-Agent = '%s'\n", value); |
846 } | 845 } |
847 #endif | 846 #endif |
848 | 847 |
849 if ((value = msn_message_get_attr(msg, "X-MMS-IM-Format")) != NULL) | 848 if ((value = msn_message_get_header_value(msg, "X-MMS-IM-Format")) != NULL) |
850 { | 849 { |
851 char *pre, *post; | 850 char *pre, *post; |
852 | 851 |
853 msn_parse_format(value, &pre, &post); | 852 msn_parse_format(value, &pre, &post); |
854 | 853 |
912 char *passport; | 911 char *passport; |
913 | 912 |
914 gc = cmdproc->session->account->gc; | 913 gc = cmdproc->session->account->gc; |
915 passport = msg->remote_user; | 914 passport = msg->remote_user; |
916 | 915 |
917 if (msn_message_get_attr(msg, "TypingUser") == NULL) | 916 if (msn_message_get_header_value(msg, "TypingUser") == NULL) |
918 return; | 917 return; |
919 | 918 |
920 if (cmdproc->servconn->type == MSN_SERVCONN_SB) { | 919 if (cmdproc->servconn->type == MSN_SERVCONN_SB) { |
921 MsnSwitchBoard *swboard = cmdproc->data; | 920 MsnSwitchBoard *swboard = cmdproc->data; |
922 | 921 |