comparison libpurple/protocols/oscar/oscar.c @ 30794:9881f18b95b1

Got rid of family_icq.c -> oscar.c callbacks. Now it will be possible to add an error handler for SNAC_FAMILY_ICQ right inside family_icq.c, since all the necessary functions are there. I made a pretty large refactoring along the way, moving the authorization- and userinfo-related functions to separate files and renaming some of them. Hopefully, this will make oscar.c less of mess.
author ivan.komarov@soc.pidgin.im
date Sun, 30 May 2010 13:53:45 +0000
parents 8d5b0cbec844
children b7b399914d21
comparison
equal deleted inserted replaced
30793:2f25002c9464 30794:9881f18b95b1
49 49
50 #include "oscarcommon.h" 50 #include "oscarcommon.h"
51 #include "oscar.h" 51 #include "oscar.h"
52 #include "peer.h" 52 #include "peer.h"
53 53
54 #define OSCAR_STATUS_ID_INVISIBLE "invisible"
55 #define OSCAR_STATUS_ID_OFFLINE "offline"
56 #define OSCAR_STATUS_ID_AVAILABLE "available"
57 #define OSCAR_STATUS_ID_AWAY "away"
58 #define OSCAR_STATUS_ID_DND "dnd"
59 #define OSCAR_STATUS_ID_NA "na"
60 #define OSCAR_STATUS_ID_OCCUPIED "occupied"
61 #define OSCAR_STATUS_ID_FREE4CHAT "free4chat"
62 #define OSCAR_STATUS_ID_CUSTOM "custom"
63 #define OSCAR_STATUS_ID_MOBILE "mobile"
64 #define OSCAR_STATUS_ID_EVIL "evil"
65 #define OSCAR_STATUS_ID_DEPRESSION "depression"
66 #define OSCAR_STATUS_ID_ATHOME "athome"
67 #define OSCAR_STATUS_ID_ATWORK "atwork"
68 #define OSCAR_STATUS_ID_LUNCH "lunch"
69
70 #define AIMHASHDATA "http://pidgin.im/aim_data.php3" 54 #define AIMHASHDATA "http://pidgin.im/aim_data.php3"
71 55
72 #define OSCAR_CONNECT_STEPS 6 56 #define OSCAR_CONNECT_STEPS 6
73 57
74 static guint64 purple_caps = 58 static guint64 purple_caps =
97 { 81 {
98 OscarData *od; 82 OscarData *od;
99 char *who; 83 char *who;
100 }; 84 };
101 85
102 /*
103 * Various PRPL-specific buddy info that we want to keep track of
104 * Some other info is maintained by locate.c, and I'd like to move
105 * the rest of this to libfaim, mostly im.c
106 *
107 * TODO: More of this should use the status API.
108 */
109 struct buddyinfo {
110 gboolean typingnot;
111 guint32 ipaddr;
112
113 unsigned long ico_me_len;
114 unsigned long ico_me_csum;
115 time_t ico_me_time;
116 gboolean ico_informed;
117
118 unsigned long ico_len;
119 unsigned long ico_csum;
120 time_t ico_time;
121 gboolean ico_need;
122 gboolean ico_sent;
123 };
124
125 struct name_data {
126 PurpleConnection *gc;
127 gchar *name;
128 gchar *nick;
129 };
130
131 /* All the libfaim->purple callback functions */ 86 /* All the libfaim->purple callback functions */
132 87
133 /* Only used when connecting with the old-style BUCP login */ 88 /* Only used when connecting with the old-style BUCP login */
134 static int purple_parse_auth_resp (OscarData *, FlapConnection *, FlapFrame *, ...); 89 static int purple_parse_auth_resp (OscarData *, FlapConnection *, FlapFrame *, ...);
135 static int purple_parse_login (OscarData *, FlapConnection *, FlapFrame *, ...); 90 static int purple_parse_login (OscarData *, FlapConnection *, FlapFrame *, ...);
141 static int purple_parse_oncoming (OscarData *, FlapConnection *, FlapFrame *, ...); 96 static int purple_parse_oncoming (OscarData *, FlapConnection *, FlapFrame *, ...);
142 static int purple_parse_offgoing (OscarData *, FlapConnection *, FlapFrame *, ...); 97 static int purple_parse_offgoing (OscarData *, FlapConnection *, FlapFrame *, ...);
143 static int purple_parse_incoming_im(OscarData *, FlapConnection *, FlapFrame *, ...); 98 static int purple_parse_incoming_im(OscarData *, FlapConnection *, FlapFrame *, ...);
144 static int purple_parse_misses (OscarData *, FlapConnection *, FlapFrame *, ...); 99 static int purple_parse_misses (OscarData *, FlapConnection *, FlapFrame *, ...);
145 static int purple_parse_clientauto (OscarData *, FlapConnection *, FlapFrame *, ...); 100 static int purple_parse_clientauto (OscarData *, FlapConnection *, FlapFrame *, ...);
146 static int purple_parse_userinfo (OscarData *, FlapConnection *, FlapFrame *, ...);
147 static int purple_parse_motd (OscarData *, FlapConnection *, FlapFrame *, ...); 101 static int purple_parse_motd (OscarData *, FlapConnection *, FlapFrame *, ...);
148 static int purple_chatnav_info (OscarData *, FlapConnection *, FlapFrame *, ...); 102 static int purple_chatnav_info (OscarData *, FlapConnection *, FlapFrame *, ...);
149 static int purple_conv_chat_join (OscarData *, FlapConnection *, FlapFrame *, ...); 103 static int purple_conv_chat_join (OscarData *, FlapConnection *, FlapFrame *, ...);
150 static int purple_conv_chat_leave (OscarData *, FlapConnection *, FlapFrame *, ...); 104 static int purple_conv_chat_leave (OscarData *, FlapConnection *, FlapFrame *, ...);
151 static int purple_conv_chat_info_update (OscarData *, FlapConnection *, FlapFrame *, ...); 105 static int purple_conv_chat_info_update (OscarData *, FlapConnection *, FlapFrame *, ...);
163 static int purple_parse_buddyrights(OscarData *, FlapConnection *, FlapFrame *, ...); 117 static int purple_parse_buddyrights(OscarData *, FlapConnection *, FlapFrame *, ...);
164 static int purple_parse_locerr (OscarData *, FlapConnection *, FlapFrame *, ...); 118 static int purple_parse_locerr (OscarData *, FlapConnection *, FlapFrame *, ...);
165 static int purple_parse_genericerr (OscarData *, FlapConnection *, FlapFrame *, ...); 119 static int purple_parse_genericerr (OscarData *, FlapConnection *, FlapFrame *, ...);
166 static int purple_memrequest (OscarData *, FlapConnection *, FlapFrame *, ...); 120 static int purple_memrequest (OscarData *, FlapConnection *, FlapFrame *, ...);
167 static int purple_selfinfo (OscarData *, FlapConnection *, FlapFrame *, ...); 121 static int purple_selfinfo (OscarData *, FlapConnection *, FlapFrame *, ...);
168 static int purple_icqalias (OscarData *, FlapConnection *, FlapFrame *, ...);
169 static int purple_icqinfo (OscarData *, FlapConnection *, FlapFrame *, ...);
170 static int purple_popup (OscarData *, FlapConnection *, FlapFrame *, ...); 122 static int purple_popup (OscarData *, FlapConnection *, FlapFrame *, ...);
171 static int purple_ssi_parseerr (OscarData *, FlapConnection *, FlapFrame *, ...); 123 static int purple_ssi_parseerr (OscarData *, FlapConnection *, FlapFrame *, ...);
172 static int purple_ssi_parserights (OscarData *, FlapConnection *, FlapFrame *, ...); 124 static int purple_ssi_parserights (OscarData *, FlapConnection *, FlapFrame *, ...);
173 static int purple_ssi_parselist (OscarData *, FlapConnection *, FlapFrame *, ...); 125 static int purple_ssi_parselist (OscarData *, FlapConnection *, FlapFrame *, ...);
174 static int purple_ssi_parseack (OscarData *, FlapConnection *, FlapFrame *, ...); 126 static int purple_ssi_parseack (OscarData *, FlapConnection *, FlapFrame *, ...);
183 void oscar_set_info(PurpleConnection *gc, const char *info); 135 void oscar_set_info(PurpleConnection *gc, const char *info);
184 static void oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *rawinfo, gboolean setstatus, PurpleStatus *status); 136 static void oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *rawinfo, gboolean setstatus, PurpleStatus *status);
185 static void oscar_set_extendedstatus(PurpleConnection *gc); 137 static void oscar_set_extendedstatus(PurpleConnection *gc);
186 static gboolean purple_ssi_rerequestdata(gpointer data); 138 static gboolean purple_ssi_rerequestdata(gpointer data);
187 139
188 static void oscar_free_name_data(struct name_data *data) { 140 void oscar_free_name_data(struct name_data *data) {
189 g_free(data->name); 141 g_free(data->name);
190 g_free(data->nick); 142 g_free(data->nick);
191 g_free(data); 143 g_free(data);
192 } 144 }
193 145
332 } 284 }
333 285
334 return utf8; 286 return utf8;
335 } 287 }
336 288
337 static gchar * 289 gchar *
338 oscar_utf8_try_convert(PurpleAccount *account, OscarData *od, const gchar *msg) 290 oscar_utf8_try_convert(PurpleAccount *account, OscarData *od, const gchar *msg)
339 { 291 {
340 const char *charset = NULL; 292 const char *charset = NULL;
341 char *ret = NULL; 293 char *ret = NULL;
342 294
558 *msg = g_strdup(from); 510 *msg = g_strdup(from);
559 *msglen_int = strlen(*msg); 511 *msglen_int = strlen(*msg);
560 *charset = AIM_CHARSET_ASCII; 512 *charset = AIM_CHARSET_ASCII;
561 *charsubset = 0x0000; 513 *charsubset = 0x0000;
562 return; 514 return;
563 }
564
565 /**
566 * Looks for %n, %d, or %t in a string, and replaces them with the
567 * specified name, date, and time, respectively.
568 *
569 * @param str The string that may contain the special variables.
570 * @param name The sender name.
571 *
572 * @return A newly allocated string where the special variables are
573 * expanded. This should be g_free'd by the caller.
574 */
575 static gchar *
576 purple_str_sub_away_formatters(const char *str, const char *name)
577 {
578 char *c;
579 GString *cpy;
580 time_t t;
581 struct tm *tme;
582
583 g_return_val_if_fail(str != NULL, NULL);
584 g_return_val_if_fail(name != NULL, NULL);
585
586 /* Create an empty GString that is hopefully big enough for most messages */
587 cpy = g_string_sized_new(1024);
588
589 t = time(NULL);
590 tme = localtime(&t);
591
592 c = (char *)str;
593 while (*c) {
594 switch (*c) {
595 case '%':
596 if (*(c + 1)) {
597 switch (*(c + 1)) {
598 case 'n':
599 /* append name */
600 g_string_append(cpy, name);
601 c++;
602 break;
603 case 'd':
604 /* append date */
605 g_string_append(cpy, purple_date_format_short(tme));
606 c++;
607 break;
608 case 't':
609 /* append time */
610 g_string_append(cpy, purple_time_format(tme));
611 c++;
612 break;
613 default:
614 g_string_append_c(cpy, *c);
615 }
616 } else {
617 g_string_append_c(cpy, *c);
618 }
619 break;
620 default:
621 g_string_append_c(cpy, *c);
622 }
623 c++;
624 }
625
626 return g_string_free(cpy, FALSE);
627 }
628
629 static gchar *oscar_caps_to_string(guint64 caps)
630 {
631 GString *str;
632 const gchar *tmp;
633 guint64 bit = 1;
634
635 str = g_string_new("");
636
637 if (!caps) {
638 return NULL;
639 } else while (bit <= OSCAR_CAPABILITY_LAST) {
640 if (bit & caps) {
641 switch (bit) {
642 case OSCAR_CAPABILITY_BUDDYICON:
643 tmp = _("Buddy Icon");
644 break;
645 case OSCAR_CAPABILITY_TALK:
646 tmp = _("Voice");
647 break;
648 case OSCAR_CAPABILITY_DIRECTIM:
649 tmp = _("AIM Direct IM");
650 break;
651 case OSCAR_CAPABILITY_CHAT:
652 tmp = _("Chat");
653 break;
654 case OSCAR_CAPABILITY_GETFILE:
655 tmp = _("Get File");
656 break;
657 case OSCAR_CAPABILITY_SENDFILE:
658 tmp = _("Send File");
659 break;
660 case OSCAR_CAPABILITY_GAMES:
661 case OSCAR_CAPABILITY_GAMES2:
662 tmp = _("Games");
663 break;
664 case OSCAR_CAPABILITY_XTRAZ:
665 case OSCAR_CAPABILITY_NEWCAPS:
666 tmp = _("ICQ Xtraz");
667 break;
668 case OSCAR_CAPABILITY_ADDINS:
669 tmp = _("Add-Ins");
670 break;
671 case OSCAR_CAPABILITY_SENDBUDDYLIST:
672 tmp = _("Send Buddy List");
673 break;
674 case OSCAR_CAPABILITY_ICQ_DIRECT:
675 tmp = _("ICQ Direct Connect");
676 break;
677 case OSCAR_CAPABILITY_APINFO:
678 tmp = _("AP User");
679 break;
680 case OSCAR_CAPABILITY_ICQRTF:
681 tmp = _("ICQ RTF");
682 break;
683 case OSCAR_CAPABILITY_EMPTY:
684 tmp = _("Nihilist");
685 break;
686 case OSCAR_CAPABILITY_ICQSERVERRELAY:
687 tmp = _("ICQ Server Relay");
688 break;
689 case OSCAR_CAPABILITY_UNICODEOLD:
690 tmp = _("Old ICQ UTF8");
691 break;
692 case OSCAR_CAPABILITY_TRILLIANCRYPT:
693 tmp = _("Trillian Encryption");
694 break;
695 case OSCAR_CAPABILITY_UNICODE:
696 tmp = _("ICQ UTF8");
697 break;
698 case OSCAR_CAPABILITY_HIPTOP:
699 tmp = _("Hiptop");
700 break;
701 case OSCAR_CAPABILITY_SECUREIM:
702 tmp = _("Security Enabled");
703 break;
704 case OSCAR_CAPABILITY_VIDEO:
705 tmp = _("Video Chat");
706 break;
707 /* Not actually sure about this one... WinAIM doesn't show anything */
708 case OSCAR_CAPABILITY_ICHATAV:
709 tmp = _("iChat AV");
710 break;
711 case OSCAR_CAPABILITY_LIVEVIDEO:
712 tmp = _("Live Video");
713 break;
714 case OSCAR_CAPABILITY_CAMERA:
715 tmp = _("Camera");
716 break;
717 case OSCAR_CAPABILITY_ICHAT_SCREENSHARE:
718 tmp = _("Screen Sharing");
719 break;
720 default:
721 tmp = NULL;
722 break;
723 }
724 if (tmp)
725 g_string_append_printf(str, "%s%s", (*(str->str) == '\0' ? "" : ", "), tmp);
726 }
727 bit <<= 1;
728 }
729
730 return g_string_free(str, FALSE);
731 } 515 }
732 516
733 static char *oscar_icqstatus(int state) { 517 static char *oscar_icqstatus(int state) {
734 /* Make a cute little string that shows the status of the dude or dudet */ 518 /* Make a cute little string that shows the status of the dude or dudet */
735 if (state & AIM_ICQ_STATE_CHAT) 519 if (state & AIM_ICQ_STATE_CHAT)
756 return g_strdup(_("At work")); 540 return g_strdup(_("At work"));
757 else if (state & AIM_ICQ_STATE_LUNCH) 541 else if (state & AIM_ICQ_STATE_LUNCH)
758 return g_strdup(_("At lunch")); 542 return g_strdup(_("At lunch"));
759 else 543 else
760 return g_strdup(_("Online")); 544 return g_strdup(_("Online"));
761 }
762
763 static void
764 oscar_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *name, const char *value)
765 {
766 if (value && value[0]) {
767 purple_notify_user_info_add_pair(user_info, name, value);
768 }
769 }
770
771 static void
772 oscar_user_info_convert_and_add_pair(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info,
773 const char *name, const char *value)
774 {
775 gchar *utf8;
776
777 if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
778 purple_notify_user_info_add_pair(user_info, name, utf8);
779 g_free(utf8);
780 }
781 }
782
783 static void
784 oscar_user_info_convert_and_add(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info,
785 const char *name, const char *value)
786 {
787 gchar *utf8;
788
789 if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
790 purple_notify_user_info_add_pair(user_info, name, utf8);
791 g_free(utf8);
792 }
793 }
794
795 /**
796 * @brief Append the status information to a user_info struct
797 *
798 * The returned information is HTML-ready, appropriately escaped, as all information in a user_info struct should be HTML.
799 *
800 * @param gc The PurpleConnection
801 * @param user_info A PurpleNotifyUserInfo object to which status information will be added
802 * @param b The PurpleBuddy whose status is desired. This or the aim_userinfo_t (or both) must be passed to oscar_user_info_append_status().
803 * @param userinfo The aim_userinfo_t of the buddy whose status is desired. This or the PurpleBuddy (or both) must be passed to oscar_user_info_append_status().
804 * @param strip_html_tags If strip_html_tags is TRUE, tags embedded in the status message will be stripped, returning a non-formatted string. The string will still be HTML escaped.
805 */
806 static void oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean strip_html_tags)
807 {
808 PurpleAccount *account = purple_connection_get_account(gc);
809 OscarData *od;
810 PurplePresence *presence = NULL;
811 PurpleStatus *status = NULL;
812 gchar *message = NULL, *itmsurl = NULL, *tmp;
813 gboolean is_away;
814
815 od = purple_connection_get_protocol_data(gc);
816
817 if (b == NULL && userinfo == NULL)
818 return;
819
820 if (b == NULL)
821 b = purple_find_buddy(purple_connection_get_account(gc), userinfo->bn);
822 else
823 userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));
824
825 if (b) {
826 presence = purple_buddy_get_presence(b);
827 status = purple_presence_get_active_status(presence);
828 }
829
830 /* If we have both b and userinfo we favor userinfo, because if we're
831 viewing someone's profile then we want the HTML away message, and
832 the "message" attribute of the status contains only the plaintext
833 message. */
834 if (userinfo) {
835 if ((userinfo->flags & AIM_FLAG_AWAY)
836 && userinfo->away_len > 0
837 && userinfo->away != NULL
838 && userinfo->away_encoding != NULL)
839 {
840 /* Away message */
841 tmp = oscar_encoding_extract(userinfo->away_encoding);
842 message = oscar_encoding_to_utf8(account,
843 tmp, userinfo->away, userinfo->away_len);
844 g_free(tmp);
845 } else {
846 /*
847 * Available message or non-HTML away message (because that's
848 * all we have right now.
849 */
850 if ((userinfo->status != NULL) && userinfo->status[0] != '\0') {
851 message = oscar_encoding_to_utf8(account,
852 userinfo->status_encoding, userinfo->status,
853 userinfo->status_len);
854 }
855 #if defined (_WIN32) || defined (__APPLE__)
856 if (userinfo->itmsurl && (userinfo->itmsurl[0] != '\0'))
857 itmsurl = oscar_encoding_to_utf8(account, userinfo->itmsurl_encoding,
858 userinfo->itmsurl, userinfo->itmsurl_len);
859 #endif
860 }
861 } else {
862 message = g_strdup(purple_status_get_attr_string(status, "message"));
863 itmsurl = g_strdup(purple_status_get_attr_string(status, "itmsurl"));
864 }
865
866 is_away = ((status && !purple_status_is_available(status)) ||
867 (userinfo && (userinfo->flags & AIM_FLAG_AWAY)));
868
869 if (strip_html_tags) {
870 /* Away messages are HTML, but available messages were originally plain text.
871 * We therefore need to strip away messages but not available messages if we're asked to remove HTML tags.
872 */
873 /*
874 * It seems like the above comment no longer applies. All messages need
875 * to be escaped.
876 */
877 if (message) {
878 gchar *tmp2;
879 tmp = purple_markup_strip_html(message);
880 g_free(message);
881 tmp2 = g_markup_escape_text(tmp, -1);
882 g_free(tmp);
883 message = tmp2;
884 }
885
886 } else {
887 if (itmsurl) {
888 tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
889 itmsurl, message);
890 g_free(message);
891 message = tmp;
892 }
893 }
894 g_free(itmsurl);
895
896 if (message) {
897 tmp = purple_str_sub_away_formatters(message, purple_account_get_username(account));
898 g_free(message);
899 message = tmp;
900 }
901
902 if (b) {
903 if (purple_presence_is_online(presence)) {
904 if (oscar_util_valid_name_icq(purple_buddy_get_name(b)) || is_away || !message || !(*message)) {
905 /* Append the status name for online ICQ statuses, away AIM statuses, and for all buddies with no message.
906 * If the status name and the message are the same, only show one. */
907 const char *status_name = purple_status_get_name(status);
908 if (status_name && message && !strcmp(status_name, message))
909 status_name = NULL;
910
911 tmp = g_strdup_printf("%s%s%s",
912 status_name ? status_name : "",
913 ((status_name && message) && *message) ? ": " : "",
914 (message && *message) ? message : "");
915 g_free(message);
916 message = tmp;
917 }
918
919 } else if (aim_ssi_waitingforauth(od->ssi.local,
920 aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(b)),
921 purple_buddy_get_name(b)))
922 {
923 /* Note if an offline buddy is not authorized */
924 tmp = g_strdup_printf("%s%s%s",
925 _("Not Authorized"),
926 (message && *message) ? ": " : "",
927 (message && *message) ? message : "");
928 g_free(message);
929 message = tmp;
930 } else {
931 g_free(message);
932 message = g_strdup(_("Offline"));
933 }
934 }
935
936 if (presence) {
937 const char *mood;
938 const char *description;
939 status = purple_presence_get_status(presence, "mood");
940 mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
941 description = icq_get_custom_icon_description(mood);
942 if (description && *description)
943 purple_notify_user_info_add_pair(user_info, _("Mood"), _(description));
944 }
945
946 purple_notify_user_info_add_pair(user_info, _("Status"), message);
947 g_free(message);
948 }
949
950 static void oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo)
951 {
952 OscarData *od;
953 PurpleAccount *account;
954 PurplePresence *presence = NULL;
955 PurpleStatus *status = NULL;
956 PurpleGroup *g = NULL;
957 struct buddyinfo *bi = NULL;
958 char *tmp;
959 const char *bname = NULL, *gname = NULL;
960
961 od = purple_connection_get_protocol_data(gc);
962 account = purple_connection_get_account(gc);
963
964 if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL)))
965 return;
966
967 if (userinfo == NULL)
968 userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));
969
970 if (b == NULL)
971 b = purple_find_buddy(account, userinfo->bn);
972
973 if (b != NULL) {
974 bname = purple_buddy_get_name(b);
975 g = purple_buddy_get_group(b);
976 gname = purple_group_get_name(g);
977 presence = purple_buddy_get_presence(b);
978 status = purple_presence_get_active_status(presence);
979 }
980
981 if (userinfo != NULL)
982 bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn));
983
984 if ((bi != NULL) && (bi->ipaddr != 0)) {
985 tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
986 (bi->ipaddr & 0xff000000) >> 24,
987 (bi->ipaddr & 0x00ff0000) >> 16,
988 (bi->ipaddr & 0x0000ff00) >> 8,
989 (bi->ipaddr & 0x000000ff));
990 oscar_user_info_add_pair(user_info, _("IP Address"), tmp);
991 g_free(tmp);
992 }
993
994 if ((userinfo != NULL) && (userinfo->warnlevel != 0)) {
995 tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5));
996 oscar_user_info_add_pair(user_info, _("Warning Level"), tmp);
997 g_free(tmp);
998 }
999
1000 if ((b != NULL) && (bname != NULL) && (g != NULL) && (gname != NULL)) {
1001 tmp = aim_ssi_getcomment(od->ssi.local, gname, bname);
1002 if (tmp != NULL) {
1003 char *tmp2 = g_markup_escape_text(tmp, strlen(tmp));
1004 g_free(tmp);
1005
1006 oscar_user_info_convert_and_add_pair(account, od, user_info, _("Buddy Comment"), tmp2);
1007 g_free(tmp2);
1008 }
1009 }
1010 } 545 }
1011 546
1012 static char *extract_name(const char *name) { 547 static char *extract_name(const char *name) {
1013 char *tmp, *x; 548 char *tmp, *x;
1014 int i, j; 549 int i, j;
1491 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_INCOMING, purple_parse_incoming_im, 0); 1026 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_INCOMING, purple_parse_incoming_im, 0);
1492 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MISSEDCALL, purple_parse_misses, 0); 1027 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MISSEDCALL, purple_parse_misses, 0);
1493 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_CLIENTAUTORESP, purple_parse_clientauto, 0); 1028 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_CLIENTAUTORESP, purple_parse_clientauto, 0);
1494 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MTN, purple_parse_mtn, 0); 1029 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MTN, purple_parse_mtn, 0);
1495 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_ACK, purple_parse_msgack, 0); 1030 oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_ACK, purple_parse_msgack, 0);
1496 oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_ALIAS, purple_icqalias, 0);
1497 oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_INFO, purple_icqinfo, 0);
1498 oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_RIGHTSINFO, purple_parse_locaterights, 0); 1031 oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_RIGHTSINFO, purple_parse_locaterights, 0);
1499 oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_USERINFO, purple_parse_userinfo, 0);
1500 oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_ERROR, purple_parse_locerr, 0); 1032 oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_ERROR, purple_parse_locerr, 0);
1501 oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x0001, purple_parse_genericerr, 0); 1033 oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x0001, purple_parse_genericerr, 0);
1502 oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x000f, purple_selfinfo, 0); 1034 oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x000f, purple_selfinfo, 0);
1503 oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x001f, purple_memrequest, 0); 1035 oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x001f, purple_memrequest, 0);
1504 oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_REDIRECT, purple_handle_redirect, 0); 1036 oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_REDIRECT, purple_handle_redirect, 0);
2671 } 2203 }
2672 2204
2673 g_free(message); 2205 g_free(message);
2674 2206
2675 return 1; 2207 return 1;
2676 }
2677
2678 /*
2679 * Authorization Functions
2680 * Most of these are callbacks from dialogs. They're used by both
2681 * methods of authorization (SSI and old-school channel 4 ICBM)
2682 */
2683 /* When you ask other people for authorization */
2684 static void
2685 purple_auth_request(struct name_data *data, char *msg)
2686 {
2687 PurpleConnection *gc;
2688 OscarData *od;
2689 PurpleAccount *account;
2690 PurpleBuddy *buddy;
2691 PurpleGroup *group;
2692 const char *bname, *gname;
2693
2694 gc = data->gc;
2695 od = purple_connection_get_protocol_data(gc);
2696 account = purple_connection_get_account(gc);
2697 buddy = purple_find_buddy(account, data->name);
2698 if (buddy != NULL)
2699 group = purple_buddy_get_group(buddy);
2700 else
2701 group = NULL;
2702
2703 if (group != NULL)
2704 {
2705 bname = purple_buddy_get_name(buddy);
2706 gname = purple_group_get_name(group);
2707 purple_debug_info("oscar", "ssi: adding buddy %s to group %s\n",
2708 bname, gname);
2709 aim_ssi_sendauthrequest(od, data->name, msg ? msg : _("Please authorize me so I can add you to my buddy list."));
2710 if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY))
2711 {
2712 aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE);
2713
2714 /* Mobile users should always be online */
2715 if (bname[0] == '+') {
2716 purple_prpl_got_user_status(account,
2717 purple_buddy_get_name(buddy),
2718 OSCAR_STATUS_ID_AVAILABLE, NULL);
2719 purple_prpl_got_user_status(account,
2720 purple_buddy_get_name(buddy),
2721 OSCAR_STATUS_ID_MOBILE, NULL);
2722 }
2723 }
2724 }
2725
2726 oscar_free_name_data(data);
2727 }
2728
2729 static void
2730 purple_auth_sendrequest(PurpleConnection *gc, const char *name)
2731 {
2732 struct name_data *data;
2733
2734 data = g_new0(struct name_data, 1);
2735 data->gc = gc;
2736 data->name = g_strdup(name);
2737
2738 purple_request_input(data->gc, NULL, _("Authorization Request Message:"),
2739 NULL, _("Please authorize me!"), TRUE, FALSE, NULL,
2740 _("_OK"), G_CALLBACK(purple_auth_request),
2741 _("_Cancel"), G_CALLBACK(oscar_free_name_data),
2742 purple_connection_get_account(gc), name, NULL,
2743 data);
2744 }
2745
2746 static void
2747 purple_auth_sendrequest_menu(PurpleBlistNode *node, gpointer ignored)
2748 {
2749 PurpleBuddy *buddy;
2750 PurpleConnection *gc;
2751
2752 g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
2753
2754 buddy = (PurpleBuddy *) node;
2755 gc = purple_account_get_connection(purple_buddy_get_account(buddy));
2756 purple_auth_sendrequest(gc, purple_buddy_get_name(buddy));
2757 }
2758
2759 /* When other people ask you for authorization */
2760 static void
2761 purple_auth_grant(gpointer cbdata)
2762 {
2763 struct name_data *data = cbdata;
2764 PurpleConnection *gc = data->gc;
2765 OscarData *od = purple_connection_get_protocol_data(gc);
2766
2767 aim_ssi_sendauthreply(od, data->name, 0x01, NULL);
2768
2769 oscar_free_name_data(data);
2770 }
2771
2772 /* When other people ask you for authorization */
2773 static void
2774 purple_auth_dontgrant(struct name_data *data, char *msg)
2775 {
2776 PurpleConnection *gc = data->gc;
2777 OscarData *od = purple_connection_get_protocol_data(gc);
2778
2779 aim_ssi_sendauthreply(od, data->name, 0x00, msg ? msg : _("No reason given."));
2780 }
2781
2782 static void
2783 purple_auth_dontgrant_msgprompt(gpointer cbdata)
2784 {
2785 struct name_data *data = cbdata;
2786 purple_request_input(data->gc, NULL, _("Authorization Denied Message:"),
2787 NULL, _("No reason given."), TRUE, FALSE, NULL,
2788 _("_OK"), G_CALLBACK(purple_auth_dontgrant),
2789 _("_Cancel"), G_CALLBACK(oscar_free_name_data),
2790 purple_connection_get_account(data->gc), data->name, NULL,
2791 data);
2792 } 2208 }
2793 2209
2794 /* When someone sends you buddies */ 2210 /* When someone sends you buddies */
2795 static void 2211 static void
2796 purple_icq_buddyadd(struct name_data *data) 2212 purple_icq_buddyadd(struct name_data *data)
3352 /* 2768 /*
3353 * We get this error when there was an error in the locate family. This 2769 * We get this error when there was an error in the locate family. This
3354 * happens when you request info of someone who is offline. 2770 * happens when you request info of someone who is offline.
3355 */ 2771 */
3356 static int purple_parse_locerr(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { 2772 static int purple_parse_locerr(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
3357 gchar *buf;
3358 va_list ap; 2773 va_list ap;
3359 guint16 reason; 2774 guint16 reason;
3360 char *destn; 2775 char *destn;
3361 PurpleNotifyUserInfo *user_info;
3362 2776
3363 va_start(ap, fr); 2777 va_start(ap, fr);
3364 reason = (guint16) va_arg(ap, unsigned int); 2778 reason = (guint16) va_arg(ap, unsigned int);
3365 destn = va_arg(ap, char *); 2779 destn = va_arg(ap, char *);
3366 va_end(ap); 2780 va_end(ap);
3367 2781
3368 if (destn == NULL) 2782 if (destn == NULL)
3369 return 1; 2783 return 1;
3370 2784
3371 user_info = purple_notify_user_info_new(); 2785 oscar_user_info_display_error(od, reason, destn);
3372 buf = g_strdup_printf(_("User information not available: %s"), oscar_get_msgerr_reason(reason));
3373 purple_notify_user_info_add_pair(user_info, NULL, buf);
3374 purple_notify_userinfo(od->gc, destn, user_info, NULL, NULL);
3375 purple_notify_user_info_destroy(user_info);
3376 purple_conv_present_error(destn, purple_connection_get_account(od->gc), buf);
3377 g_free(buf);
3378
3379 return 1;
3380 }
3381
3382 static int purple_parse_userinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
3383 PurpleConnection *gc = od->gc;
3384 PurpleAccount *account = purple_connection_get_account(gc);
3385 PurpleNotifyUserInfo *user_info;
3386 gchar *tmp = NULL, *info_utf8 = NULL, *base_profile_url = NULL;
3387 va_list ap;
3388 aim_userinfo_t *userinfo;
3389
3390 va_start(ap, fr);
3391 userinfo = va_arg(ap, aim_userinfo_t *);
3392 va_end(ap);
3393
3394 user_info = purple_notify_user_info_new();
3395
3396 oscar_user_info_append_status(gc, user_info, /* PurpleBuddy */ NULL, userinfo, /* strip_html_tags */ FALSE);
3397
3398 if ((userinfo->present & AIM_USERINFO_PRESENT_IDLE) && userinfo->idletime != 0) {
3399 tmp = purple_str_seconds_to_string(userinfo->idletime*60);
3400 oscar_user_info_add_pair(user_info, _("Idle"), tmp);
3401 g_free(tmp);
3402 }
3403
3404 oscar_user_info_append_extra_info(gc, user_info, NULL, userinfo);
3405
3406 if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !oscar_util_valid_name_sms(userinfo->bn)) {
3407 /* An SMS contact is always online; its Online Since value is not useful */
3408 time_t t = userinfo->onlinesince;
3409 oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t)));
3410 }
3411
3412 if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) {
3413 time_t t = userinfo->membersince;
3414 oscar_user_info_add_pair(user_info, _("Member Since"), purple_date_format_full(localtime(&t)));
3415 }
3416
3417 if (userinfo->capabilities != 0) {
3418 tmp = oscar_caps_to_string(userinfo->capabilities);
3419 oscar_user_info_add_pair(user_info, _("Capabilities"), tmp);
3420 g_free(tmp);
3421 }
3422
3423 /* Info */
3424 if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) {
3425 tmp = oscar_encoding_extract(userinfo->info_encoding);
3426 info_utf8 = oscar_encoding_to_utf8(account, tmp, userinfo->info,
3427 userinfo->info_len);
3428 g_free(tmp);
3429 if (info_utf8 != NULL) {
3430 tmp = purple_str_sub_away_formatters(info_utf8, purple_account_get_username(account));
3431 purple_notify_user_info_add_section_break(user_info);
3432 oscar_user_info_add_pair(user_info, _("Profile"), tmp);
3433 g_free(tmp);
3434 g_free(info_utf8);
3435 }
3436 }
3437
3438 purple_notify_user_info_add_section_break(user_info);
3439 base_profile_url = oscar_util_valid_name_icq(userinfo->bn) ? "http://www.icq.com/people" : "http://profiles.aim.com";
3440 tmp = g_strdup_printf("<a href=\"%s/%s\">%s</a>",
3441 base_profile_url, purple_normalize(account, userinfo->bn), _("View web profile"));
3442 purple_notify_user_info_add_pair(user_info, NULL, tmp);
3443 g_free(tmp);
3444
3445 purple_notify_userinfo(gc, userinfo->bn, user_info, NULL, NULL);
3446 purple_notify_user_info_destroy(user_info);
3447
3448 return 1; 2786 return 1;
3449 } 2787 }
3450 2788
3451 static int purple_parse_motd(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) 2789 static int purple_parse_motd(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
3452 { 2790 {
4002 } 3340 }
4003 3341
4004 return 1; 3342 return 1;
4005 } 3343 }
4006 3344
4007 static int purple_icqinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
4008 {
4009 PurpleConnection *gc;
4010 PurpleAccount *account;
4011 PurpleBuddy *buddy;
4012 struct buddyinfo *bi;
4013 gchar who[16];
4014 PurpleNotifyUserInfo *user_info;
4015 gchar *utf8;
4016 gchar *buf;
4017 const gchar *alias;
4018 va_list ap;
4019 struct aim_icq_info *info;
4020
4021 gc = od->gc;
4022 account = purple_connection_get_account(gc);
4023
4024 va_start(ap, fr);
4025 info = va_arg(ap, struct aim_icq_info *);
4026 va_end(ap);
4027
4028 if (!info->uin)
4029 return 0;
4030
4031 user_info = purple_notify_user_info_new();
4032
4033 g_snprintf(who, sizeof(who), "%u", info->uin);
4034 buddy = purple_find_buddy(account, who);
4035 if (buddy != NULL)
4036 bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, purple_buddy_get_name(buddy)));
4037 else
4038 bi = NULL;
4039
4040 purple_notify_user_info_add_pair(user_info, _("UIN"), who);
4041 oscar_user_info_convert_and_add(account, od, user_info, _("Nick"), info->nick);
4042 if ((bi != NULL) && (bi->ipaddr != 0)) {
4043 char *tstr = g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
4044 (bi->ipaddr & 0xff000000) >> 24,
4045 (bi->ipaddr & 0x00ff0000) >> 16,
4046 (bi->ipaddr & 0x0000ff00) >> 8,
4047 (bi->ipaddr & 0x000000ff));
4048 purple_notify_user_info_add_pair(user_info, _("IP Address"), tstr);
4049 g_free(tstr);
4050 }
4051 oscar_user_info_convert_and_add(account, od, user_info, _("First Name"), info->first);
4052 oscar_user_info_convert_and_add(account, od, user_info, _("Last Name"), info->last);
4053 if (info->email && info->email[0] && (utf8 = oscar_utf8_try_convert(account, od, info->email))) {
4054 buf = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", utf8, utf8);
4055 purple_notify_user_info_add_pair(user_info, _("Email Address"), buf);
4056 g_free(buf);
4057 g_free(utf8);
4058 }
4059 if (info->numaddresses && info->email2) {
4060 int i;
4061 for (i = 0; i < info->numaddresses; i++) {
4062 if (info->email2[i] && info->email2[i][0] && (utf8 = oscar_utf8_try_convert(account, od, info->email2[i]))) {
4063 buf = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", utf8, utf8);
4064 purple_notify_user_info_add_pair(user_info, _("Email Address"), buf);
4065 g_free(buf);
4066 g_free(utf8);
4067 }
4068 }
4069 }
4070 oscar_user_info_convert_and_add(account, od, user_info, _("Mobile Phone"), info->mobile);
4071
4072 if (info->gender != 0)
4073 purple_notify_user_info_add_pair(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male")));
4074
4075 if ((info->birthyear > 1900) && (info->birthmonth > 0) && (info->birthday > 0)) {
4076 /* Initialize the struct properly or strftime() will crash
4077 * under some conditions (e.g. Debian sarge w/ LANG=en_HK). */
4078 time_t t = time(NULL);
4079 struct tm *tm = localtime(&t);
4080
4081 tm->tm_mday = (int)info->birthday;
4082 tm->tm_mon = (int)info->birthmonth - 1;
4083 tm->tm_year = (int)info->birthyear - 1900;
4084
4085 /* To be 100% sure that the fields are re-normalized.
4086 * If you're sure strftime() ALWAYS does this EVERYWHERE,
4087 * feel free to remove it. --rlaager */
4088 mktime(tm);
4089
4090 oscar_user_info_convert_and_add(account, od, user_info, _("Birthday"), purple_date_format_short(tm));
4091 }
4092 if ((info->age > 0) && (info->age < 255)) {
4093 char age[5];
4094 snprintf(age, sizeof(age), "%hhd", info->age);
4095 purple_notify_user_info_add_pair(user_info, _("Age"), age);
4096 }
4097 if (info->personalwebpage && info->personalwebpage[0] && (utf8 = oscar_utf8_try_convert(account, od, info->personalwebpage))) {
4098 buf = g_strdup_printf("<a href=\"%s\">%s</a>", utf8, utf8);
4099 purple_notify_user_info_add_pair(user_info, _("Personal Web Page"), buf);
4100 g_free(buf);
4101 g_free(utf8);
4102 }
4103
4104 if (buddy != NULL)
4105 oscar_user_info_append_status(gc, user_info, buddy, /* aim_userinfo_t */ NULL, /* strip_html_tags */ FALSE);
4106
4107 oscar_user_info_convert_and_add(account, od, user_info, _("Additional Information"), info->info);
4108 purple_notify_user_info_add_section_break(user_info);
4109
4110 if ((info->homeaddr && (info->homeaddr[0])) || (info->homecity && info->homecity[0]) || (info->homestate && info->homestate[0]) || (info->homezip && info->homezip[0])) {
4111 purple_notify_user_info_add_section_header(user_info, _("Home Address"));
4112
4113 oscar_user_info_convert_and_add(account, od, user_info, _("Address"), info->homeaddr);
4114 oscar_user_info_convert_and_add(account, od, user_info, _("City"), info->homecity);
4115 oscar_user_info_convert_and_add(account, od, user_info, _("State"), info->homestate);
4116 oscar_user_info_convert_and_add(account, od, user_info, _("Zip Code"), info->homezip);
4117 }
4118 if ((info->workaddr && info->workaddr[0]) || (info->workcity && info->workcity[0]) || (info->workstate && info->workstate[0]) || (info->workzip && info->workzip[0])) {
4119 purple_notify_user_info_add_section_header(user_info, _("Work Address"));
4120
4121 oscar_user_info_convert_and_add(account, od, user_info, _("Address"), info->workaddr);
4122 oscar_user_info_convert_and_add(account, od, user_info, _("City"), info->workcity);
4123 oscar_user_info_convert_and_add(account, od, user_info, _("State"), info->workstate);
4124 oscar_user_info_convert_and_add(account, od, user_info, _("Zip Code"), info->workzip);
4125 }
4126 if ((info->workcompany && info->workcompany[0]) || (info->workdivision && info->workdivision[0]) || (info->workposition && info->workposition[0]) || (info->workwebpage && info->workwebpage[0])) {
4127 purple_notify_user_info_add_section_header(user_info, _("Work Information"));
4128
4129 oscar_user_info_convert_and_add(account, od, user_info, _("Company"), info->workcompany);
4130 oscar_user_info_convert_and_add(account, od, user_info, _("Division"), info->workdivision);
4131 oscar_user_info_convert_and_add(account, od, user_info, _("Position"), info->workposition);
4132
4133 if (info->workwebpage && info->workwebpage[0] && (utf8 = oscar_utf8_try_convert(account, od, info->workwebpage))) {
4134 char *webpage = g_strdup_printf("<a href=\"%s\">%s</a>", utf8, utf8);
4135 purple_notify_user_info_add_pair(user_info, _("Web Page"), webpage);
4136 g_free(webpage);
4137 g_free(utf8);
4138 }
4139 }
4140
4141 if (buddy != NULL)
4142 alias = purple_buddy_get_alias(buddy);
4143 else
4144 alias = who;
4145 purple_notify_userinfo(gc, who, user_info, NULL, NULL);
4146 purple_notify_user_info_destroy(user_info);
4147
4148 return 1;
4149 }
4150
4151 static int purple_icqalias(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
4152 {
4153 PurpleConnection *gc = od->gc;
4154 PurpleAccount *account = purple_connection_get_account(gc);
4155 gchar who[16], *utf8;
4156 PurpleBuddy *b;
4157 va_list ap;
4158 struct aim_icq_info *info;
4159
4160 va_start(ap, fr);
4161 info = va_arg(ap, struct aim_icq_info *);
4162 va_end(ap);
4163
4164 if (info->nick[0] && (utf8 = oscar_utf8_try_convert(account, od, info->nick))) {
4165 if (info->for_auth_request) {
4166 struct name_data *data = g_new(struct name_data, 1);
4167
4168 data->gc = gc;
4169 data->name = g_strdup_printf("%u", info->uin);
4170 data->nick = utf8;
4171
4172 purple_account_request_authorization(account, data->name, NULL, data->nick,
4173 info->auth_request_reason, purple_find_buddy(account, data->name) != NULL,
4174 purple_auth_grant, purple_auth_dontgrant_msgprompt, data);
4175 } else {
4176 g_snprintf(who, sizeof(who), "%u", info->uin);
4177 serv_got_alias(gc, who, utf8);
4178 if ((b = purple_find_buddy(account, who))) {
4179 purple_blist_node_set_string((PurpleBlistNode*)b, "servernick", utf8);
4180 }
4181 g_free(utf8);
4182 }
4183 }
4184
4185 g_free(info->auth_request_reason);
4186 return 1;
4187 }
4188
4189 static int purple_popup(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) 3345 static int purple_popup(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
4190 { 3346 {
4191 PurpleConnection *gc = od->gc; 3347 PurpleConnection *gc = od->gc;
4192 gchar *text; 3348 gchar *text;
4193 va_list ap; 3349 va_list ap;
4518 ret = aim_icq_sendsms(od, name, message, purple_account_get_username(account)); 3674 ret = aim_icq_sendsms(od, name, message, purple_account_get_username(account));
4519 return (ret >= 0 ? 1 : ret); 3675 return (ret >= 0 ? 1 : ret);
4520 } 3676 }
4521 3677
4522 if (imflags & PURPLE_MESSAGE_AUTO_RESP) 3678 if (imflags & PURPLE_MESSAGE_AUTO_RESP)
4523 tmp1 = purple_str_sub_away_formatters(message, name); 3679 tmp1 = oscar_util_format_string(message, name);
4524 else 3680 else
4525 tmp1 = g_strdup(message); 3681 tmp1 = g_strdup(message);
4526 3682
4527 conn = peer_connection_find_by_type(od, name, OSCAR_CAPABILITY_DIRECTIM); 3683 conn = peer_connection_find_by_type(od, name, OSCAR_CAPABILITY_DIRECTIM);
4528 if ((conn != NULL) && (conn->ready)) 3684 if ((conn != NULL) && (conn->ready))
4985 } 4141 }
4986 } else if (aim_ssi_waitingforauth(od->ssi.local, 4142 } else if (aim_ssi_waitingforauth(od->ssi.local,
4987 aim_ssi_itemlist_findparentname(od->ssi.local, bname), 4143 aim_ssi_itemlist_findparentname(od->ssi.local, bname),
4988 bname)) { 4144 bname)) {
4989 /* Not authorized -- Re-request authorization */ 4145 /* Not authorized -- Re-request authorization */
4990 purple_auth_sendrequest(gc, bname); 4146 oscar_auth_sendrequest(gc, bname);
4991 } 4147 }
4992 } 4148 }
4993 4149
4994 /* XXX - Should this be done from AIM accounts, as well? */ 4150 /* XXX - Should this be done from AIM accounts, as well? */
4995 if (od->icq) 4151 if (od->icq)
5463 g_free(buf); 4619 g_free(buf);
5464 } 4620 }
5465 4621
5466 case 0x000e: { /* buddy requires authorization */ 4622 case 0x000e: { /* buddy requires authorization */
5467 if ((retval->action == SNAC_SUBTYPE_FEEDBAG_ADD) && (retval->name)) 4623 if ((retval->action == SNAC_SUBTYPE_FEEDBAG_ADD) && (retval->name))
5468 purple_auth_sendrequest(gc, retval->name); 4624 oscar_auth_sendrequest(gc, retval->name);
5469 } break; 4625 } break;
5470 4626
5471 default: { /* La la la */ 4627 default: { /* La la la */
5472 gchar *buf; 4628 gchar *buf;
5473 purple_debug_error("oscar", "ssi: Action 0x%04hx was unsuccessful with error 0x%04hx\n", retval->action, retval->ack); 4629 purple_debug_error("oscar", "ssi: Action 0x%04hx was unsuccessful with error 0x%04hx\n", retval->action, retval->ack);
6017 { 5173 {
6018 gchar *tmp1, *tmp2; 5174 gchar *tmp1, *tmp2;
6019 tmp1 = purple_markup_strip_html(message); 5175 tmp1 = purple_markup_strip_html(message);
6020 purple_util_chrreplace(tmp1, '\n', ' '); 5176 purple_util_chrreplace(tmp1, '\n', ' ');
6021 tmp2 = g_markup_escape_text(tmp1, -1); 5177 tmp2 = g_markup_escape_text(tmp1, -1);
6022 ret = purple_str_sub_away_formatters(tmp2, purple_account_get_username(account)); 5178 ret = oscar_util_format_string(tmp2, purple_account_get_username(account));
6023 g_free(tmp1); 5179 g_free(tmp1);
6024 g_free(tmp2); 5180 g_free(tmp2);
6025 } 5181 }
6026 else if (purple_status_is_available(status)) 5182 else if (purple_status_is_available(status))
6027 { 5183 {
6511 char *gname; 5667 char *gname;
6512 gname = aim_ssi_itemlist_findparentname(od->ssi.local, bname); 5668 gname = aim_ssi_itemlist_findparentname(od->ssi.local, bname);
6513 if (gname && aim_ssi_waitingforauth(od->ssi.local, gname, bname)) 5669 if (gname && aim_ssi_waitingforauth(od->ssi.local, gname, bname))
6514 { 5670 {
6515 act = purple_menu_action_new(_("Re-request Authorization"), 5671 act = purple_menu_action_new(_("Re-request Authorization"),
6516 PURPLE_CALLBACK(purple_auth_sendrequest_menu), 5672 PURPLE_CALLBACK(oscar_auth_sendrequest_menu),
6517 NULL, NULL); 5673 NULL, NULL);
6518 menu = g_list_prepend(menu, act); 5674 menu = g_list_prepend(menu, act);
6519 } 5675 }
6520 } 5676 }
6521 5677