Mercurial > pidgin.yaz
comparison libpurple/protocols/null/nullprpl.c @ 24542:2cae2b346d72
Various nullprpl fixes. This stemmed from a complaint from a user in
#pidgin that it crashed if the user didn't change the room from "default"
to something else when joining.
Nothing big here, but here's the list:
* Make a bunch of strings const for good measure
* g_strdup strings that the caller is supposed to be freeing (one of
these almost certainly fixes the aforementioned crash)
* Use g_list_prepend/g_list_reverse
* Don't leak some strings
* g_* needs g_free, not free (this might also be the one fixing the
crash)
Fixes #7712.
committer: John Bailey <rekkanoryo@rekkanoryo.org>
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sat, 06 Dec 2008 05:05:02 +0000 |
parents | 7e85c6cbf7b0 |
children | c687fd9c379e |
comparison
equal
deleted
inserted
replaced
24541:024818afb013 | 24542:2cae2b346d72 |
---|---|
158 } | 158 } |
159 | 159 |
160 | 160 |
161 static void discover_status(PurpleConnection *from, PurpleConnection *to, | 161 static void discover_status(PurpleConnection *from, PurpleConnection *to, |
162 gpointer userdata) { | 162 gpointer userdata) { |
163 char *from_username = from->account->username; | 163 const char *from_username = from->account->username; |
164 char *to_username = to->account->username; | 164 const char *to_username = to->account->username; |
165 | 165 |
166 if (purple_find_buddy(from->account, to_username)) { | 166 if (purple_find_buddy(from->account, to_username)) { |
167 PurpleStatus *status = purple_account_get_active_status(to->account); | 167 PurpleStatus *status = purple_account_get_active_status(to->account); |
168 const char *status_id = purple_status_get_id(status); | 168 const char *status_id = purple_status_get_id(status); |
169 const char *message = purple_status_get_attr_string(status, "message"); | 169 const char *message = purple_status_get_attr_string(status, "message"); |
260 purple_debug_info("nullprpl", "%s's status text is %s\n", buddy->name, text); | 260 purple_debug_info("nullprpl", "%s's status text is %s\n", buddy->name, text); |
261 return text; | 261 return text; |
262 | 262 |
263 } else { | 263 } else { |
264 purple_debug_info("nullprpl", "...but %s is not logged in\n", buddy->name); | 264 purple_debug_info("nullprpl", "...but %s is not logged in\n", buddy->name); |
265 return "Not logged in"; | 265 return g_strdup("Not logged in"); |
266 } | 266 } |
267 } | 267 } |
268 | 268 |
269 static void nullprpl_tooltip_text(PurpleBuddy *buddy, | 269 static void nullprpl_tooltip_text(PurpleBuddy *buddy, |
270 PurpleNotifyUserInfo *info, | 270 PurpleNotifyUserInfo *info, |
287 | 287 |
288 } else { | 288 } else { |
289 /* they're not logged in */ | 289 /* they're not logged in */ |
290 purple_notify_user_info_add_pair(info, _("User info"), _("not logged in")); | 290 purple_notify_user_info_add_pair(info, _("User info"), _("not logged in")); |
291 } | 291 } |
292 | 292 |
293 purple_debug_info("nullprpl", "showing %s tooltip for %s\n", | 293 purple_debug_info("nullprpl", "showing %s tooltip for %s\n", |
294 (full) ? "full" : "short", buddy->name); | 294 (full) ? "full" : "short", buddy->name); |
295 } | 295 } |
296 | 296 |
297 static GList *nullprpl_status_types(PurpleAccount *acct) | 297 static GList *nullprpl_status_types(PurpleAccount *acct) |
305 | 305 |
306 type = purple_status_type_new(PURPLE_STATUS_AVAILABLE, NULL_STATUS_ONLINE, | 306 type = purple_status_type_new(PURPLE_STATUS_AVAILABLE, NULL_STATUS_ONLINE, |
307 NULL_STATUS_ONLINE, TRUE); | 307 NULL_STATUS_ONLINE, TRUE); |
308 purple_status_type_add_attr(type, "message", _("Online"), | 308 purple_status_type_add_attr(type, "message", _("Online"), |
309 purple_value_new(PURPLE_TYPE_STRING)); | 309 purple_value_new(PURPLE_TYPE_STRING)); |
310 types = g_list_append(types, type); | 310 types = g_list_prepend(types, type); |
311 | 311 |
312 type = purple_status_type_new(PURPLE_STATUS_AWAY, NULL_STATUS_AWAY, | 312 type = purple_status_type_new(PURPLE_STATUS_AWAY, NULL_STATUS_AWAY, |
313 NULL_STATUS_AWAY, TRUE); | 313 NULL_STATUS_AWAY, TRUE); |
314 purple_status_type_add_attr(type, "message", _("Away"), | 314 purple_status_type_add_attr(type, "message", _("Away"), |
315 purple_value_new(PURPLE_TYPE_STRING)); | 315 purple_value_new(PURPLE_TYPE_STRING)); |
316 types = g_list_append(types, type); | 316 types = g_list_prepend(types, type); |
317 | 317 |
318 type = purple_status_type_new(PURPLE_STATUS_OFFLINE, NULL_STATUS_OFFLINE, | 318 type = purple_status_type_new(PURPLE_STATUS_OFFLINE, NULL_STATUS_OFFLINE, |
319 NULL_STATUS_OFFLINE, TRUE); | 319 NULL_STATUS_OFFLINE, TRUE); |
320 purple_status_type_add_attr(type, "message", _("Offline"), | 320 purple_status_type_add_attr(type, "message", _("Offline"), |
321 purple_value_new(PURPLE_TYPE_STRING)); | 321 purple_value_new(PURPLE_TYPE_STRING)); |
322 types = g_list_append(types, type); | 322 types = g_list_prepend(types, type); |
323 | 323 |
324 return types; | 324 return g_list_reverse(types); |
325 } | 325 } |
326 | 326 |
327 static void blist_example_menu_item(PurpleBlistNode *node, gpointer userdata) { | 327 static void blist_example_menu_item(PurpleBlistNode *node, gpointer userdata) { |
328 purple_debug_info("nullprpl", "example menu item clicked on user %s\n", | 328 purple_debug_info("nullprpl", "example menu item clicked on user %s\n", |
329 ((PurpleBuddy *)node)->name); | 329 ((PurpleBuddy *)node)->name); |
353 struct proto_chat_entry *pce; /* defined in prpl.h */ | 353 struct proto_chat_entry *pce; /* defined in prpl.h */ |
354 | 354 |
355 purple_debug_info("nullprpl", "returning chat setting 'room'\n"); | 355 purple_debug_info("nullprpl", "returning chat setting 'room'\n"); |
356 | 356 |
357 pce = g_new0(struct proto_chat_entry, 1); | 357 pce = g_new0(struct proto_chat_entry, 1); |
358 pce->label = _(_("Chat _room")); | 358 pce->label = _("Chat _room"); |
359 pce->identifier = "room"; | 359 pce->identifier = "room"; |
360 pce->required = TRUE; | 360 pce->required = TRUE; |
361 | 361 |
362 return g_list_append(NULL, pce); | 362 return g_list_append(NULL, pce); |
363 } | 363 } |
475 static void nullprpl_set_info(PurpleConnection *gc, const char *info) { | 475 static void nullprpl_set_info(PurpleConnection *gc, const char *info) { |
476 purple_debug_info("nullprpl", "setting %s's user info to %s\n", | 476 purple_debug_info("nullprpl", "setting %s's user info to %s\n", |
477 gc->account->username, info); | 477 gc->account->username, info); |
478 } | 478 } |
479 | 479 |
480 static char *typing_state_to_string(PurpleTypingState typing) { | 480 static const char *typing_state_to_string(PurpleTypingState typing) { |
481 switch (typing) { | 481 switch (typing) { |
482 case PURPLE_NOT_TYPING: return "is not typing"; | 482 case PURPLE_NOT_TYPING: return "is not typing"; |
483 case PURPLE_TYPING: return "is typing"; | 483 case PURPLE_TYPING: return "is typing"; |
484 case PURPLE_TYPED: return "stopped typing momentarily"; | 484 case PURPLE_TYPED: return "stopped typing momentarily"; |
485 default: return "unknown typing state"; | 485 default: return "unknown typing state"; |
486 } | 486 } |
487 } | 487 } |
488 | 488 |
489 static void notify_typing(PurpleConnection *from, PurpleConnection *to, | 489 static void notify_typing(PurpleConnection *from, PurpleConnection *to, |
490 gpointer typing) { | 490 gpointer typing) { |
491 char *from_username = from->account->username; | 491 const char *from_username = from->account->username; |
492 char *action = typing_state_to_string((PurpleTypingState)typing); | 492 const char *action = typing_state_to_string((PurpleTypingState)typing); |
493 purple_debug_info("nullprpl", "notifying %s that %s %s\n", | 493 purple_debug_info("nullprpl", "notifying %s that %s %s\n", |
494 to->account->username, from_username, action); | 494 to->account->username, from_username, action); |
495 | 495 |
496 serv_got_typing(to, | 496 serv_got_typing(to, |
497 from_username, | 497 from_username, |
559 } | 559 } |
560 | 560 |
561 static void nullprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, | 561 static void nullprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, |
562 PurpleGroup *group) | 562 PurpleGroup *group) |
563 { | 563 { |
564 char *username = gc->account->username; | 564 const char *username = gc->account->username; |
565 PurpleConnection *buddy_gc = get_nullprpl_gc(buddy->name); | 565 PurpleConnection *buddy_gc = get_nullprpl_gc(buddy->name); |
566 | 566 |
567 purple_debug_info("nullprpl", "adding %s to %s's buddy list\n", buddy->name, | 567 purple_debug_info("nullprpl", "adding %s to %s's buddy list\n", buddy->name, |
568 username); | 568 username); |
569 | 569 |
677 FALSE); /* show a join message */ | 677 FALSE); /* show a join message */ |
678 } | 678 } |
679 } | 679 } |
680 | 680 |
681 static void nullprpl_join_chat(PurpleConnection *gc, GHashTable *components) { | 681 static void nullprpl_join_chat(PurpleConnection *gc, GHashTable *components) { |
682 char *username = gc->account->username; | 682 const char *username = gc->account->username; |
683 char *room = g_hash_table_lookup(components, "room"); | 683 const char *room = g_hash_table_lookup(components, "room"); |
684 int chat_id = g_str_hash(room); | 684 int chat_id = g_str_hash(room); |
685 purple_debug_info("nullprpl", "%s is joining chat room %s\n", username, room); | 685 purple_debug_info("nullprpl", "%s is joining chat room %s\n", username, room); |
686 | 686 |
687 if (!purple_find_chat(gc, chat_id)) { | 687 if (!purple_find_chat(gc, chat_id)) { |
688 serv_got_joined_chat(gc, chat_id, room); | 688 serv_got_joined_chat(gc, chat_id, room); |
689 | 689 |
690 /* tell everyone that we joined, and add them if they're already there */ | 690 /* tell everyone that we joined, and add them if they're already there */ |
691 foreach_gc_in_chat(joined_chat, gc, chat_id, NULL); | 691 foreach_gc_in_chat(joined_chat, gc, chat_id, NULL); |
692 } else { | 692 } else { |
693 char *tmp = g_strdup_printf(_("%s is already in chat room %s."), | |
694 username, | |
695 room); | |
693 purple_debug_info("nullprpl", "%s is already in chat room %s\n", username, | 696 purple_debug_info("nullprpl", "%s is already in chat room %s\n", username, |
694 room); | 697 room); |
695 purple_notify_info(gc, | 698 purple_notify_info(gc, _("Join chat"), _("Join chat"), tmp); |
696 _("Join chat"), | 699 g_free(tmp); |
697 _("Join chat"), | |
698 g_strdup_printf("%s is already in chat room %s.", | |
699 username, room)); | |
700 } | 700 } |
701 } | 701 } |
702 | 702 |
703 static void nullprpl_reject_chat(PurpleConnection *gc, GHashTable *components) { | 703 static void nullprpl_reject_chat(PurpleConnection *gc, GHashTable *components) { |
704 char *invited_by = g_hash_table_lookup(components, "invited_by"); | 704 const char *invited_by = g_hash_table_lookup(components, "invited_by"); |
705 char *room = g_hash_table_lookup(components, "room"); | 705 const char *room = g_hash_table_lookup(components, "room"); |
706 char *username = gc->account->username; | 706 const char *username = gc->account->username; |
707 PurpleConnection *invited_by_gc = get_nullprpl_gc(invited_by); | 707 PurpleConnection *invited_by_gc = get_nullprpl_gc(invited_by); |
708 char *message = g_strdup_printf( | 708 char *message = g_strdup_printf( |
709 "%s %s %s.", | 709 "%s %s %s.", |
710 username, | 710 username, |
711 _("has rejected your invitation to join the chat room"), | 711 _("has rejected your invitation to join the chat room"), |
717 | 717 |
718 purple_notify_info(invited_by_gc, | 718 purple_notify_info(invited_by_gc, |
719 _("Chat invitation rejected"), | 719 _("Chat invitation rejected"), |
720 _("Chat invitation rejected"), | 720 _("Chat invitation rejected"), |
721 message); | 721 message); |
722 g_free(message); | |
722 } | 723 } |
723 | 724 |
724 static char *nullprpl_get_chat_name(GHashTable *components) { | 725 static char *nullprpl_get_chat_name(GHashTable *components) { |
725 char *room = g_hash_table_lookup(components, "room"); | 726 const char *room = g_hash_table_lookup(components, "room"); |
726 purple_debug_info("nullprpl", "reporting chat room name '%s'\n", room); | 727 purple_debug_info("nullprpl", "reporting chat room name '%s'\n", room); |
727 return room; | 728 return g_strdup(room); |
728 } | 729 } |
729 | 730 |
730 static void nullprpl_chat_invite(PurpleConnection *gc, int id, | 731 static void nullprpl_chat_invite(PurpleConnection *gc, int id, |
731 const char *message, const char *who) { | 732 const char *message, const char *who) { |
732 char *username = gc->account->username; | 733 const char *username = gc->account->username; |
733 PurpleConversation *conv = purple_find_chat(gc, id); | 734 PurpleConversation *conv = purple_find_chat(gc, id); |
734 char *room = conv->name; | 735 const char *room = conv->name; |
735 PurpleAccount *to_acct = purple_accounts_find(who, NULLPRPL_ID); | 736 PurpleAccount *to_acct = purple_accounts_find(who, NULLPRPL_ID); |
736 | 737 |
737 purple_debug_info("nullprpl", "%s is inviting %s to join chat room %s\n", | 738 purple_debug_info("nullprpl", "%s is inviting %s to join chat room %s\n", |
738 username, who, room); | 739 username, who, room); |
739 | 740 |
740 if (to_acct) { | 741 if (to_acct) { |
741 PurpleConversation *to_conv = purple_find_chat(to_acct->gc, id); | 742 PurpleConversation *to_conv = purple_find_chat(to_acct->gc, id); |
742 if (to_conv) { | 743 if (to_conv) { |
744 char *tmp = g_strdup_printf("%s is already in chat room %s.", who, room); | |
743 purple_debug_info("nullprpl", | 745 purple_debug_info("nullprpl", |
744 "%s is already in chat room %s; " | 746 "%s is already in chat room %s; " |
745 "ignoring invitation from %s\n", | 747 "ignoring invitation from %s\n", |
746 who, room, username); | 748 who, room, username); |
747 purple_notify_info(gc, | 749 purple_notify_info(gc, _("Chat invitation"), _("Chat invitation"), tmp); |
748 _("Chat invitation"), | 750 g_free(tmp); |
749 _("Chat invitation"), | |
750 g_strdup_printf("%s is already in chat room %s.", | |
751 who, room)); | |
752 } else { | 751 } else { |
753 GHashTable *components; | 752 GHashTable *components; |
754 components = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free); | 753 components = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); |
755 g_hash_table_replace(components, "room", g_strdup(room)); | 754 g_hash_table_replace(components, "room", g_strdup(room)); |
756 g_hash_table_replace(components, "invited_by", g_strdup(username)); | 755 g_hash_table_replace(components, "invited_by", g_strdup(username)); |
757 serv_got_chat_invite(to_acct->gc, room, username, message, components); | 756 serv_got_chat_invite(to_acct->gc, room, username, message, components); |
758 } | 757 } |
759 } | 758 } |
831 } | 830 } |
832 } | 831 } |
833 | 832 |
834 static void nullprpl_chat_whisper(PurpleConnection *gc, int id, const char *who, | 833 static void nullprpl_chat_whisper(PurpleConnection *gc, int id, const char *who, |
835 const char *message) { | 834 const char *message) { |
836 char *username = gc->account->username; | 835 const char *username = gc->account->username; |
837 PurpleConversation *conv = purple_find_chat(gc, id); | 836 PurpleConversation *conv = purple_find_chat(gc, id); |
838 purple_debug_info("nullprpl", | 837 purple_debug_info("nullprpl", |
839 "%s receives whisper from %s in chat room %s: %s\n", | 838 "%s receives whisper from %s in chat room %s: %s\n", |
840 username, who, conv->name, message); | 839 username, who, conv->name, message); |
841 | 840 |
856 time(NULL)); | 855 time(NULL)); |
857 } | 856 } |
858 | 857 |
859 static int nullprpl_chat_send(PurpleConnection *gc, int id, const char *message, | 858 static int nullprpl_chat_send(PurpleConnection *gc, int id, const char *message, |
860 PurpleMessageFlags flags) { | 859 PurpleMessageFlags flags) { |
861 char *username = gc->account->username; | 860 const char *username = gc->account->username; |
862 PurpleConversation *conv = purple_find_chat(gc, id); | 861 PurpleConversation *conv = purple_find_chat(gc, id); |
863 | 862 |
864 if (conv) { | 863 if (conv) { |
865 purple_debug_info("nullprpl", | 864 purple_debug_info("nullprpl", |
866 "%s is sending message to chat room %s: %s\n", username, | 865 "%s is sending message to chat room %s: %s\n", username, |
979 purple_roomlist_set_in_progress((PurpleRoomlist *)roomlist, FALSE); | 978 purple_roomlist_set_in_progress((PurpleRoomlist *)roomlist, FALSE); |
980 return FALSE; | 979 return FALSE; |
981 } | 980 } |
982 | 981 |
983 static PurpleRoomlist *nullprpl_roomlist_get_list(PurpleConnection *gc) { | 982 static PurpleRoomlist *nullprpl_roomlist_get_list(PurpleConnection *gc) { |
984 char *username = gc->account->username; | 983 const char *username = gc->account->username; |
985 PurpleRoomlist *roomlist = purple_roomlist_new(gc->account); | 984 PurpleRoomlist *roomlist = purple_roomlist_new(gc->account); |
986 GList *fields = NULL; | 985 GList *fields = NULL; |
987 PurpleRoomlistField *field; | 986 PurpleRoomlistField *field; |
988 GList *chats; | 987 GList *chats; |
989 GList *seen_ids = NULL; | 988 GList *seen_ids = NULL; |
1003 /* add each chat room. the chat ids are cached in seen_ids so that each room | 1002 /* add each chat room. the chat ids are cached in seen_ids so that each room |
1004 * is only returned once, even if multiple users are in it. */ | 1003 * is only returned once, even if multiple users are in it. */ |
1005 for (chats = purple_get_chats(); chats; chats = g_list_next(chats)) { | 1004 for (chats = purple_get_chats(); chats; chats = g_list_next(chats)) { |
1006 PurpleConversation *conv = (PurpleConversation *)chats->data; | 1005 PurpleConversation *conv = (PurpleConversation *)chats->data; |
1007 PurpleRoomlistRoom *room; | 1006 PurpleRoomlistRoom *room; |
1008 char *name = conv->name; | 1007 const char *name = conv->name; |
1009 int id = purple_conversation_get_chat_data(conv)->id; | 1008 int id = purple_conversation_get_chat_data(conv)->id; |
1010 | 1009 |
1011 /* have we already added this room? */ | 1010 /* have we already added this room? */ |
1012 if (g_list_find_custom(seen_ids, name, (GCompareFunc)strcmp)) | 1011 if (g_list_find_custom(seen_ids, name, (GCompareFunc)strcmp)) |
1013 continue; /* yes! try the next one. */ | 1012 continue; /* yes! try the next one. */ |
1014 | 1013 |
1015 seen_ids = g_list_append(seen_ids, name); /* no, it's new. */ | 1014 /* This cast is OK because this list is only staying around for the life |
1015 * of this function and none of the conversations are being deleted | |
1016 * in that timespan. */ | |
1017 seen_ids = g_list_prepend(seen_ids, (char *)name); /* no, it's new. */ | |
1016 purple_debug_info("nullprpl", "%s (%d), ", name, id); | 1018 purple_debug_info("nullprpl", "%s (%d), ", name, id); |
1017 | 1019 |
1018 room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, NULL); | 1020 room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, NULL); |
1019 purple_roomlist_room_add_field(roomlist, room, name); | 1021 purple_roomlist_room_add_field(roomlist, room, name); |
1020 purple_roomlist_room_add_field(roomlist, room, &id); | 1022 purple_roomlist_room_add_field(roomlist, room, &id); |
1021 purple_roomlist_room_add(roomlist, room); | 1023 purple_roomlist_room_add(roomlist, room); |
1022 } | 1024 } |
1023 | 1025 |
1026 g_list_free(seen_ids); | |
1024 purple_timeout_add(1 /* ms */, nullprpl_finish_get_roomlist, roomlist); | 1027 purple_timeout_add(1 /* ms */, nullprpl_finish_get_roomlist, roomlist); |
1025 return roomlist; | 1028 return roomlist; |
1026 } | 1029 } |
1027 | 1030 |
1028 static void nullprpl_roomlist_cancel(PurpleRoomlist *list) { | 1031 static void nullprpl_roomlist_cancel(PurpleRoomlist *list) { |