Mercurial > pidgin.yaz
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 |