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) {