Mercurial > pidgin
comparison libpurple/protocols/null/nullprpl.c @ 24596: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
| 24595:024818afb013 | 24596: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) { |
