Mercurial > pidgin
comparison src/protocols/oscar/oscar.c @ 7011:4375bf2d9020
[gaim-migrate @ 7574]
The user-visible changes? Gaim now shows peep's away messages in their
tooltip for AIM over oscar.
Things to do:
-Make sure this doesn't screw up with huge buddy lists
-Replace %n with your screen name, etc. in the tooltip
-Leave in b, i, u tags in the tooltip
-Fix the 2 8 byte memleaks in locate.c
Client authors that aren't me will want to read the following pretty
closely...
I made some internal libfaim changes. I desire to make libfaim cleaner.
I don't know if this really helps or not. Here's what I've done:
Changed all the SNAC-sending functions in info.c to NOT take a conn
argument. The connection is looked up from the session. I'm trying
to make oscar.c less-aware of connections.
Added aim_locate_finduserinfo() - Use for getting the aim_userinfo_t for the
given screenname.
Added aim_locate_getinfoshort() - Use this to request that the servers send
you profile info, away message, caps, or a combination of the above. It's
like aim_locate_getinfo() but less rate limited.
Renamed aim_bos_reqlocaterights() to aim_locate_reqrights()
Renamed aim_getinfo() to aim_locate_getinfo()
Renamed aim_setdirectoryinfo() to aim_locate_setdirinfo()
Renamed aim_0002_000b() to aim_locate_000b()
Renamed aim_setuserinterests() to aim_locate_setinterests()
Removed aim_userinfo_sn()
Removed aim_userinfo_flags()
Removed aim_userinfo_idle()
Removed aim_userinfo_warnlevel()
Removed aim_userinfo_createtime()
Removed aim_userinfo_membersince()
Removed aim_userinfo_onlinesince()
Removed aim_userinfo_sessionlen()
Removed aim_userinfo_hascap()
Renamed info.c to locate.c
Made locate.c keep a static, linked list of nodes of sn, away message,
available message, user info. This list is maintained by libfaim
automatically. Now clients don't have to keep track of all this stuff
themselves, and users won't have to wait for away message/info retrieval
if the person is in your buddy list. libfaim uses the iChat way of
retrieving stuff, which is not nearly as rate limited as the old way.
I actually have a feeling WinAIM uses the same SNAC now (although I
didn't check), but I like pluggin iChat because it's innovative.
Moved sess->emailinfo to a static variable inside email.c.
Removed evilhack from oscar.c
I think that's about everything...
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 29 Sep 2003 12:30:03 +0000 |
parents | 083d1e4a9c78 |
children | dece74f05509 |
comparison
equal
deleted
inserted
replaced
7010:eb3ed649252e | 7011:4375bf2d9020 |
---|---|
98 GHashTable *buddyinfo; | 98 GHashTable *buddyinfo; |
99 GSList *requesticon; | 99 GSList *requesticon; |
100 | 100 |
101 gboolean killme; | 101 gboolean killme; |
102 gboolean icq; | 102 gboolean icq; |
103 GSList *evilhack; | |
104 guint icontimer; | 103 guint icontimer; |
105 guint getblisttimer; | 104 guint getblisttimer; |
106 | 105 |
107 struct { | 106 struct { |
108 guint maxwatchers; /* max users who can watch you */ | 107 guint maxwatchers; /* max users who can watch you */ |
148 char *sn; | 147 char *sn; |
149 char ip[64]; | 148 char ip[64]; |
150 fu8_t cookie[8]; | 149 fu8_t cookie[8]; |
151 }; | 150 }; |
152 | 151 |
153 /* Various PRPL-specific buddy info that we want to keep track of */ | 152 /* |
153 * Various PRPL-specific buddy info that we want to keep track of | |
154 * Some other info is maintained by locate.c, and I'd like to move | |
155 * the rest of this to libfaim, mostly im.c | |
156 */ | |
154 struct buddyinfo { | 157 struct buddyinfo { |
155 time_t signon; | |
156 int caps; | |
157 gboolean typingnot; | 158 gboolean typingnot; |
158 gchar *availmsg; | 159 gchar *availmsg; |
159 fu32_t ipaddr; | 160 fu32_t ipaddr; |
160 | 161 |
161 unsigned long ico_me_len; | 162 unsigned long ico_me_len; |
165 | 166 |
166 unsigned long ico_len; | 167 unsigned long ico_len; |
167 unsigned long ico_csum; | 168 unsigned long ico_csum; |
168 time_t ico_time; | 169 time_t ico_time; |
169 gboolean ico_need; | 170 gboolean ico_need; |
170 | |
171 fu16_t iconcsumlen; | |
172 fu8_t *iconcsum; | |
173 }; | 171 }; |
174 | 172 |
175 struct name_data { | 173 struct name_data { |
176 GaimConnection *gc; | 174 GaimConnection *gc; |
177 gchar *name; | 175 gchar *name; |
216 static int gaim_parse_oncoming (aim_session_t *, aim_frame_t *, ...); | 214 static int gaim_parse_oncoming (aim_session_t *, aim_frame_t *, ...); |
217 static int gaim_parse_offgoing (aim_session_t *, aim_frame_t *, ...); | 215 static int gaim_parse_offgoing (aim_session_t *, aim_frame_t *, ...); |
218 static int gaim_parse_incoming_im(aim_session_t *, aim_frame_t *, ...); | 216 static int gaim_parse_incoming_im(aim_session_t *, aim_frame_t *, ...); |
219 static int gaim_parse_misses (aim_session_t *, aim_frame_t *, ...); | 217 static int gaim_parse_misses (aim_session_t *, aim_frame_t *, ...); |
220 static int gaim_parse_clientauto (aim_session_t *, aim_frame_t *, ...); | 218 static int gaim_parse_clientauto (aim_session_t *, aim_frame_t *, ...); |
221 static int gaim_parse_user_info (aim_session_t *, aim_frame_t *, ...); | 219 static int gaim_parse_userinfo (aim_session_t *, aim_frame_t *, ...); |
222 static int gaim_parse_motd (aim_session_t *, aim_frame_t *, ...); | 220 static int gaim_parse_motd (aim_session_t *, aim_frame_t *, ...); |
223 static int gaim_chatnav_info (aim_session_t *, aim_frame_t *, ...); | 221 static int gaim_chatnav_info (aim_session_t *, aim_frame_t *, ...); |
224 static int gaim_chat_join (aim_session_t *, aim_frame_t *, ...); | 222 static int gaim_chat_join (aim_session_t *, aim_frame_t *, ...); |
225 static int gaim_chat_leave (aim_session_t *, aim_frame_t *, ...); | 223 static int gaim_chat_leave (aim_session_t *, aim_frame_t *, ...); |
226 static int gaim_chat_info_update (aim_session_t *, aim_frame_t *, ...); | 224 static int gaim_chat_info_update (aim_session_t *, aim_frame_t *, ...); |
292 } | 290 } |
293 | 291 |
294 static void oscar_free_buddyinfo(void *data) { | 292 static void oscar_free_buddyinfo(void *data) { |
295 struct buddyinfo *bi = data; | 293 struct buddyinfo *bi = data; |
296 g_free(bi->availmsg); | 294 g_free(bi->availmsg); |
297 g_free(bi->iconcsum); | |
298 g_free(bi); | 295 g_free(bi); |
299 } | 296 } |
300 | 297 |
301 static fu32_t oscar_encoding_check(const char *utf8) | 298 static fu32_t oscar_encoding_check(const char *utf8) |
302 { | 299 { |
730 char *sn = od->requesticon->data; | 727 char *sn = od->requesticon->data; |
731 od->requesticon = g_slist_remove(od->requesticon, sn); | 728 od->requesticon = g_slist_remove(od->requesticon, sn); |
732 free(sn); | 729 free(sn); |
733 } | 730 } |
734 g_hash_table_destroy(od->buddyinfo); | 731 g_hash_table_destroy(od->buddyinfo); |
735 while (od->evilhack) { | |
736 g_free(od->evilhack->data); | |
737 od->evilhack = g_slist_remove(od->evilhack, od->evilhack->data); | |
738 } | |
739 while (od->create_rooms) { | 732 while (od->create_rooms) { |
740 struct create_room *cr = od->create_rooms->data; | 733 struct create_room *cr = od->create_rooms->data; |
741 g_free(cr->name); | 734 g_free(cr->name); |
742 od->create_rooms = g_slist_remove(od->create_rooms, cr); | 735 od->create_rooms = g_slist_remove(od->create_rooms, cr); |
743 g_free(cr); | 736 g_free(cr); |
1133 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, gaim_parse_evilnotify, 0); | 1126 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, gaim_parse_evilnotify, 0); |
1134 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, AIM_CB_LOK_ERROR, gaim_parse_searcherror, 0); | 1127 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, AIM_CB_LOK_ERROR, gaim_parse_searcherror, 0); |
1135 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, 0x0003, gaim_parse_searchreply, 0); | 1128 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, 0x0003, gaim_parse_searchreply, 0); |
1136 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, gaim_parse_msgerr, 0); | 1129 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, gaim_parse_msgerr, 0); |
1137 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parse_mtn, 0); | 1130 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parse_mtn, 0); |
1138 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parse_user_info, 0); | 1131 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parse_userinfo, 0); |
1139 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, gaim_parse_msgack, 0); | 1132 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, gaim_parse_msgack, 0); |
1140 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, gaim_parse_motd, 0); | 1133 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, gaim_parse_motd, 0); |
1141 aim_conn_addhandler(sess, bosconn, 0x0004, 0x0005, gaim_icbm_param_info, 0); | 1134 aim_conn_addhandler(sess, bosconn, 0x0004, 0x0005, gaim_icbm_param_info, 0); |
1142 aim_conn_addhandler(sess, bosconn, 0x0001, 0x0001, gaim_parse_genericerr, 0); | 1135 aim_conn_addhandler(sess, bosconn, 0x0001, 0x0001, gaim_parse_genericerr, 0); |
1143 aim_conn_addhandler(sess, bosconn, 0x0003, 0x0001, gaim_parse_genericerr, 0); | 1136 aim_conn_addhandler(sess, bosconn, 0x0003, 0x0001, gaim_parse_genericerr, 0); |
1340 | 1333 |
1341 return 1; | 1334 return 1; |
1342 } | 1335 } |
1343 | 1336 |
1344 static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) { | 1337 static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) { |
1345 char *key; | |
1346 va_list ap; | |
1347 GaimConnection *gc = sess->aux_data; | 1338 GaimConnection *gc = sess->aux_data; |
1348 GaimAccount *account = gaim_connection_get_account(gc); | 1339 GaimAccount *account = gaim_connection_get_account(gc); |
1349 GaimAccount *ac = gaim_connection_get_account(gc); | 1340 GaimAccount *ac = gaim_connection_get_account(gc); |
1350 struct oscar_data *od = gc->proto_data; | 1341 struct oscar_data *od = gc->proto_data; |
1342 va_list ap; | |
1343 char *key; | |
1351 | 1344 |
1352 va_start(ap, fr); | 1345 va_start(ap, fr); |
1353 key = va_arg(ap, char *); | 1346 key = va_arg(ap, char *); |
1354 va_end(ap); | 1347 va_end(ap); |
1355 | 1348 |
1807 bi = g_hash_table_lookup(od->buddyinfo, normalize(info->sn)); | 1800 bi = g_hash_table_lookup(od->buddyinfo, normalize(info->sn)); |
1808 if (!bi) { | 1801 if (!bi) { |
1809 bi = g_new0(struct buddyinfo, 1); | 1802 bi = g_new0(struct buddyinfo, 1); |
1810 g_hash_table_insert(od->buddyinfo, g_strdup(normalize(info->sn)), bi); | 1803 g_hash_table_insert(od->buddyinfo, g_strdup(normalize(info->sn)), bi); |
1811 } | 1804 } |
1812 bi->signon = info->onlinesince ? info->onlinesince : (info->sessionlen + time(NULL)); | |
1813 if (caps) | |
1814 bi->caps = caps; | |
1815 bi->typingnot = FALSE; | 1805 bi->typingnot = FALSE; |
1816 bi->ico_informed = FALSE; | 1806 bi->ico_informed = FALSE; |
1817 bi->ipaddr = info->icqinfo.ipaddr; | 1807 bi->ipaddr = info->icqinfo.ipaddr; |
1818 | 1808 |
1819 /* Available message stuff */ | 1809 /* Available message stuff */ |
1820 free(bi->availmsg); | 1810 free(bi->availmsg); |
1821 if (info->availmsg) | 1811 if (info->avail != NULL) |
1822 if (info->availmsg_encoding) { | 1812 if (info->avail_encoding) { |
1823 gchar *enc = g_strdup_printf("charset=\"%s\"", info->availmsg_encoding); | 1813 gchar *enc = g_strdup_printf("charset=\"%s\"", info->avail_encoding); |
1824 bi->availmsg = oscar_encoding_to_utf8(enc, info->availmsg, info->availmsg_len); | 1814 bi->availmsg = oscar_encoding_to_utf8(enc, info->avail, info->avail_len); |
1825 g_free(enc); | 1815 g_free(enc); |
1826 } else { | 1816 } else { |
1827 /* No explicit encoding means utf8. Yay. */ | 1817 /* No explicit encoding means utf8. Yay. */ |
1828 bi->availmsg = g_strdup(info->availmsg); | 1818 bi->availmsg = g_strdup(info->avail); |
1829 } | 1819 } |
1830 else | 1820 else |
1831 bi->availmsg = NULL; | 1821 bi->availmsg = NULL; |
1832 | 1822 |
1833 /* Server stored icon stuff */ | 1823 /* Server stored icon stuff */ |
1834 if (info->iconcsumlen) { | 1824 if (info->iconcsumlen) { |
1835 char *b16, *saved_b16; | 1825 char *b16, *saved_b16; |
1836 GaimBuddy *b; | 1826 GaimBuddy *b; |
1837 | 1827 |
1838 free(bi->iconcsum); | 1828 b16 = tobase16(info->iconcsum, info->iconcsumlen); |
1839 bi->iconcsum = malloc(info->iconcsumlen); | |
1840 memcpy(bi->iconcsum, info->iconcsum, info->iconcsumlen); | |
1841 bi->iconcsumlen = info->iconcsumlen; | |
1842 b16 = tobase16(bi->iconcsum, bi->iconcsumlen); | |
1843 b = gaim_find_buddy(gc->account, info->sn); | 1829 b = gaim_find_buddy(gc->account, info->sn); |
1844 saved_b16 = gaim_buddy_get_setting(b, "icon_checksum"); | 1830 saved_b16 = gaim_buddy_get_setting(b, "icon_checksum"); |
1845 if (!b16 || !saved_b16 || strcmp(b16, saved_b16)) { | 1831 if (!b16 || !saved_b16 || strcmp(b16, saved_b16)) { |
1846 GSList *cur = od->requesticon; | 1832 GSList *cur = od->requesticon; |
1847 while (cur && aim_sncmp((char *)cur->data, info->sn)) | 1833 while (cur && aim_sncmp((char *)cur->data, info->sn)) |
2878 | 2864 |
2879 switch(reason) { | 2865 switch(reason) { |
2880 case 0x0003: { /* Reply from an ICQ status message request */ | 2866 case 0x0003: { /* Reply from an ICQ status message request */ |
2881 char *status_msg = gaim_icq_status(state); | 2867 char *status_msg = gaim_icq_status(state); |
2882 char *dialog_msg, **splitmsg; | 2868 char *dialog_msg, **splitmsg; |
2883 struct oscar_data *od = gc->proto_data; | |
2884 GSList *l = od->evilhack; | |
2885 gboolean evilhack = FALSE; | |
2886 | 2869 |
2887 /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ | 2870 /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ |
2888 splitmsg = g_strsplit(msg, "\r\n", 0); | 2871 splitmsg = g_strsplit(msg, "\r\n", 0); |
2889 | 2872 |
2890 /* If who is in od->evilhack, then we're just getting the away message, otherwise this | 2873 dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<HR>%s"), who, status_msg, g_strjoinv("<BR>", splitmsg)); |
2891 * will just get appended to the info box (which is already showing). */ | |
2892 while (l) { | |
2893 char *x = l->data; | |
2894 if (!strcmp(x, normalize(who))) { | |
2895 evilhack = TRUE; | |
2896 g_free(x); | |
2897 od->evilhack = g_slist_remove(od->evilhack, x); | |
2898 break; | |
2899 } | |
2900 l = l->next; | |
2901 } | |
2902 | |
2903 if (evilhack) | |
2904 dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<HR>%s"), who, status_msg, g_strjoinv("<BR>", splitmsg)); | |
2905 else | |
2906 dialog_msg = g_strdup_printf(_("<B>Status:</B> %s<HR>%s"), status_msg, g_strjoinv("<BR>", splitmsg)); | |
2907 g_show_info_text(gc, who, 2, dialog_msg, NULL); | 2874 g_show_info_text(gc, who, 2, dialog_msg, NULL); |
2908 | 2875 |
2909 g_free(status_msg); | 2876 g_free(status_msg); |
2910 g_free(dialog_msg); | 2877 g_free(dialog_msg); |
2911 g_strfreev(splitmsg); | 2878 g_strfreev(splitmsg); |
3154 bit <<= 1; | 3121 bit <<= 1; |
3155 } | 3122 } |
3156 return buf; | 3123 return buf; |
3157 } | 3124 } |
3158 | 3125 |
3159 static int gaim_parse_user_info(aim_session_t *sess, aim_frame_t *fr, ...) { | 3126 static int gaim_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...) { |
3160 GaimConnection *gc = sess->aux_data; | 3127 GaimConnection *gc = sess->aux_data; |
3161 struct oscar_data *od = gc->proto_data; | 3128 GString *text; |
3162 gchar *header; | 3129 char *info_utf8 = NULL, *away_utf8 = NULL; |
3163 GSList *l = od->evilhack; | |
3164 gboolean evilhack = FALSE; | |
3165 gchar *membersince = NULL, *onlinesince = NULL, *idle = NULL; | |
3166 va_list ap; | 3130 va_list ap; |
3167 aim_userinfo_t *info; | 3131 aim_userinfo_t *userinfo; |
3168 fu16_t infotype; | |
3169 char *text_enc = NULL, *text = NULL, *utf8 = NULL; | |
3170 int text_len; | |
3171 const char *username = gaim_account_get_username(gaim_connection_get_account(gc)); | |
3172 | 3132 |
3173 va_start(ap, fr); | 3133 va_start(ap, fr); |
3174 info = va_arg(ap, aim_userinfo_t *); | 3134 userinfo = va_arg(ap, aim_userinfo_t *); |
3175 infotype = (fu16_t) va_arg(ap, unsigned int); | |
3176 text_enc = va_arg(ap, char *); | |
3177 text = va_arg(ap, char *); | |
3178 text_len = va_arg(ap, int); | |
3179 va_end(ap); | 3135 va_end(ap); |
3180 | 3136 |
3181 if (text_len > 0) { | 3137 text = g_string_new(""); |
3182 if (!(utf8 = oscar_encoding_to_utf8(text_enc, text, text_len))) { | 3138 g_string_append_printf(text, _("Username: <b>%s</b><br>\n"), userinfo->sn); |
3183 utf8 = g_strdup(_("<i>Unable to display information because it was sent in an unknown encoding.</i>")); | 3139 g_string_append_printf(text, _("Warning Level: <b>%d%%</b><br>\n"), (int)((userinfo->warnlevel/10.0) + 0.5)); |
3184 gaim_debug(GAIM_DEBUG_ERROR, "oscar", | 3140 |
3185 "Encountered an unknown encoding while parsing userinfo\n"); | 3141 if (userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) |
3186 } | 3142 g_string_append_printf(text, _("Online Since: <b>%s</b><br>\n"), |
3187 } | 3143 asctime(localtime((time_t *)&userinfo->onlinesince))); |
3188 | 3144 |
3189 if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE) { | 3145 if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) |
3190 onlinesince = g_strdup_printf(_("Online Since : <b>%s</b><br>\n"), | 3146 g_string_append_printf(text, _("Member Since: <b>%s</b><br>\n"), |
3191 asctime(localtime((time_t *)&info->onlinesince))); | 3147 asctime(localtime((time_t *)&userinfo->membersince))); |
3192 } | 3148 |
3193 | 3149 if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) { |
3194 if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE) { | 3150 gchar *itime = sec_to_text(userinfo->idletime*60); |
3195 membersince = g_strdup_printf(_("Member Since : <b>%s</b><br>\n"), | 3151 g_string_append_printf(text, _("Idle: <b>%s</b>"), itime); |
3196 asctime(localtime((time_t *)&info->membersince))); | |
3197 } | |
3198 | |
3199 if (info->present & AIM_USERINFO_PRESENT_IDLE) { | |
3200 gchar *itime = sec_to_text(info->idletime*60); | |
3201 idle = g_strdup_printf(_("Idle : <b>%s</b>"), itime); | |
3202 g_free(itime); | 3152 g_free(itime); |
3203 } else | 3153 } else |
3204 idle = g_strdup(_("Idle: <b>Active</b>")); | 3154 g_string_append_printf(text, _("Idle: <b>Active</b>")); |
3205 | 3155 |
3206 header = g_strdup_printf(_("Username : <b>%s</b> %s <br>\n" | 3156 if ((userinfo->flags & AIM_FLAG_AWAY) && (userinfo->away_len > 0) && (userinfo->away != NULL) && (userinfo->away_encoding != NULL)) { |
3207 "Warning Level : <b>%d %%</b><br>\n" | 3157 away_utf8 = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len); |
3208 "%s" | 3158 if (away_utf8 != NULL) { |
3209 "%s" | 3159 g_string_append_printf(text, _("<hr>%s"), away_utf8); |
3210 "%s\n" | 3160 g_free(away_utf8); |
3211 "<hr>\n"), | 3161 } |
3212 info->sn, | 3162 } |
3213 /* images(info->flags), */ | 3163 |
3214 "", | 3164 if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) { |
3215 (int)((info->warnlevel/10.0) + 0.5), | 3165 info_utf8 = oscar_encoding_to_utf8(userinfo->info_encoding, userinfo->info, userinfo->info_len); |
3216 onlinesince ? onlinesince : "", | 3166 if (info_utf8 != NULL) { |
3217 membersince ? membersince : "", | 3167 g_string_append_printf(text, _("<hr>%s"), info_utf8); |
3218 idle ? idle : ""); | 3168 g_free(info_utf8); |
3219 | 3169 } |
3220 g_free(onlinesince); | 3170 } |
3221 g_free(membersince); | 3171 |
3222 g_free(idle); | 3172 gaim_notify_formatted(gc, NULL, _("Buddy Information"), NULL, text->str, NULL, NULL); |
3223 | 3173 g_string_free(text, TRUE); |
3224 while (l) { | |
3225 char *x = l->data; | |
3226 if (!strcmp(x, normalize(info->sn))) { | |
3227 evilhack = TRUE; | |
3228 g_free(x); | |
3229 od->evilhack = g_slist_remove(od->evilhack, x); | |
3230 break; | |
3231 } | |
3232 l = l->next; | |
3233 } | |
3234 | |
3235 if (infotype == AIM_GETINFO_AWAYMESSAGE) { | |
3236 if (evilhack) { | |
3237 g_show_info_text(gc, info->sn, 2, | |
3238 header, | |
3239 (utf8 && *utf8) ? away_subs(utf8, username) : | |
3240 _("<i>User has no away message</i>"), NULL); | |
3241 } else { | |
3242 g_show_info_text(gc, info->sn, 0, | |
3243 header, | |
3244 (utf8 && *utf8) ? away_subs(utf8, username) : NULL, | |
3245 (utf8 && *utf8) ? "<hr>" : NULL, | |
3246 NULL); | |
3247 } | |
3248 } else if (infotype == AIM_GETINFO_CAPABILITIES) { | |
3249 g_show_info_text(gc, info->sn, 2, | |
3250 header, | |
3251 "<i>", _("Client Capabilities: "), | |
3252 caps_string(info->capabilities), | |
3253 "</i>", | |
3254 NULL); | |
3255 } else { | |
3256 g_show_info_text(gc, info->sn, 1, | |
3257 (utf8 && *utf8) ? away_subs(utf8, username) : _("<i>No Information Provided</i>"), | |
3258 NULL); | |
3259 } | |
3260 | |
3261 g_free(header); | |
3262 g_free(utf8); | |
3263 | 3174 |
3264 return 1; | 3175 return 1; |
3265 } | 3176 } |
3266 | 3177 |
3267 static int gaim_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...) { | 3178 static int gaim_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...) { |
3549 } | 3460 } |
3550 | 3461 |
3551 static gboolean gaim_icon_timerfunc(gpointer data) { | 3462 static gboolean gaim_icon_timerfunc(gpointer data) { |
3552 GaimConnection *gc = data; | 3463 GaimConnection *gc = data; |
3553 struct oscar_data *od = gc->proto_data; | 3464 struct oscar_data *od = gc->proto_data; |
3554 struct buddyinfo *bi; | 3465 aim_userinfo_t *userinfo; |
3555 aim_conn_t *conn; | 3466 aim_conn_t *conn; |
3556 | 3467 |
3557 conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_ICON); | 3468 conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_ICON); |
3558 if (!conn) { | 3469 if (!conn) { |
3559 if (!od->iconconnecting) { | 3470 if (!od->iconconnecting) { |
3592 gaim_debug(GAIM_DEBUG_MISC, "oscar", | 3503 gaim_debug(GAIM_DEBUG_MISC, "oscar", |
3593 "no more icons to request\n"); | 3504 "no more icons to request\n"); |
3594 return FALSE; | 3505 return FALSE; |
3595 } | 3506 } |
3596 | 3507 |
3597 bi = g_hash_table_lookup(od->buddyinfo, (char *)od->requesticon->data); | 3508 userinfo = aim_locate_finduserinfo((char *)od->requesticon->data); |
3598 if (bi && (bi->iconcsumlen > 0)) { | 3509 if ((userinfo != NULL) && (userinfo->iconcsumlen > 0)) { |
3599 aim_bart_request(od->sess, od->requesticon->data, bi->iconcsum, bi->iconcsumlen); | 3510 aim_bart_request(od->sess, od->requesticon->data, userinfo->iconcsum, userinfo->iconcsumlen); |
3600 return FALSE; | 3511 return FALSE; |
3601 } else { | 3512 } else { |
3602 char *sn = od->requesticon->data; | 3513 char *sn = od->requesticon->data; |
3603 od->requesticon = g_slist_remove(od->requesticon, sn); | 3514 od->requesticon = g_slist_remove(od->requesticon, sn); |
3604 free(sn); | 3515 free(sn); |
3746 gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: requesting ssi list\n"); | 3657 gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: requesting ssi list\n"); |
3747 aim_ssi_reqrights(sess); | 3658 aim_ssi_reqrights(sess); |
3748 aim_ssi_reqdata(sess); | 3659 aim_ssi_reqdata(sess); |
3749 #endif | 3660 #endif |
3750 | 3661 |
3751 aim_bos_reqlocaterights(sess, fr->conn); | 3662 aim_locate_reqrights(sess); |
3752 aim_bos_reqbuddyrights(sess, fr->conn); | 3663 aim_bos_reqbuddyrights(sess, fr->conn); |
3753 aim_im_reqparams(sess); | 3664 aim_im_reqparams(sess); |
3754 aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi? */ | 3665 aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi? */ |
3755 | 3666 |
3756 #ifdef NOSSI | 3667 #ifdef NOSSI |
3850 "locate rights: max sig len = %d\n", maxsiglen); | 3761 "locate rights: max sig len = %d\n", maxsiglen); |
3851 | 3762 |
3852 od->rights.maxsiglen = od->rights.maxawaymsglen = (guint)maxsiglen; | 3763 od->rights.maxsiglen = od->rights.maxawaymsglen = (guint)maxsiglen; |
3853 | 3764 |
3854 if (od->icq) | 3765 if (od->icq) |
3855 aim_bos_setprofile(sess, fr->conn, NULL, NULL, 0, NULL, NULL, 0, caps_icq); | 3766 aim_locate_setprofile(sess, NULL, NULL, 0, NULL, NULL, 0, caps_icq); |
3856 else | 3767 else |
3857 oscar_set_info(gc, gc->account->user_info); | 3768 oscar_set_info(gc, gc->account->user_info); |
3858 | 3769 |
3859 return 1; | 3770 return 1; |
3860 } | 3771 } |
4418 return 1; | 4329 return 1; |
4419 | 4330 |
4420 return ret; | 4331 return ret; |
4421 } | 4332 } |
4422 | 4333 |
4423 static void oscar_get_info(GaimConnection *g, const char *name) { | 4334 static void oscar_get_info(GaimConnection *gc, const char *name) { |
4424 struct oscar_data *od = (struct oscar_data *)g->proto_data; | 4335 struct oscar_data *od = (struct oscar_data *)gc->proto_data; |
4336 | |
4425 if (od->icq) | 4337 if (od->icq) |
4426 aim_icq_getallinfo(od->sess, name); | 4338 aim_icq_getallinfo(od->sess, name); |
4427 else | 4339 else |
4428 /* people want the away message on the top, so we get the away message | 4340 aim_locate_getinfoshort(od->sess, name, 0x00000007); |
4429 * first and then get the regular info, since it's too difficult to | 4341 } |
4430 * insert in the middle. i hate people. */ | 4342 |
4431 aim_getinfo(od->sess, od->conn, name, AIM_GETINFO_AWAYMESSAGE); | 4343 static void oscar_get_away(GaimConnection *gc, const char *who) { |
4432 } | 4344 struct oscar_data *od = (struct oscar_data *)gc->proto_data; |
4433 | |
4434 static void oscar_get_away(GaimConnection *g, const char *who) { | |
4435 struct oscar_data *od = (struct oscar_data *)g->proto_data; | |
4436 if (od->icq) { | 4345 if (od->icq) { |
4437 GaimBuddy *budlight = gaim_find_buddy(g->account, who); | 4346 GaimBuddy *budlight = gaim_find_buddy(gc->account, who); |
4438 if (budlight) | 4347 if (budlight) |
4439 if ((budlight->uc & 0xffff0000) >> 16) | 4348 if ((budlight->uc & 0xffff0000) >> 16) |
4440 aim_im_sendch2_geticqaway(od->sess, who, (budlight->uc & 0xffff0000) >> 16); | 4349 aim_im_sendch2_geticqaway(od->sess, who, (budlight->uc & 0xffff0000) >> 16); |
4441 else | 4350 else |
4442 gaim_debug(GAIM_DEBUG_ERROR, "oscar", | 4351 gaim_debug(GAIM_DEBUG_ERROR, "oscar", |
4443 "Error: The user %s has no status message, therefore not requesting.\n", who); | 4352 "Error: The user %s has no status message, therefore not requesting.\n", who); |
4444 else | 4353 else |
4445 gaim_debug(GAIM_DEBUG_ERROR, "oscar", | 4354 gaim_debug(GAIM_DEBUG_ERROR, "oscar", |
4446 "Error: Could not find %s in local contact list, therefore unable to request status message.\n", who); | 4355 "Error: Could not find %s in local contact list, therefore unable to request status message.\n", who); |
4447 } else | 4356 } else |
4448 aim_getinfo(od->sess, od->conn, who, AIM_GETINFO_GENERALINFO); | 4357 aim_locate_getinfoshort(od->sess, who, 0x00000002); |
4449 } | 4358 } |
4450 | 4359 |
4451 static void oscar_set_dir(GaimConnection *g, const char *first, const char *middle, const char *last, | 4360 static void oscar_set_dir(GaimConnection *gc, const char *first, const char *middle, const char *last, |
4452 const char *maiden, const char *city, const char *state, const char *country, int web) { | 4361 const char *maiden, const char *city, const char *state, const char *country, int web) { |
4453 /* XXX - some of these things are wrong, but i'm lazy */ | 4362 /* XXX - some of these things are wrong, but i'm lazy */ |
4454 struct oscar_data *od = (struct oscar_data *)g->proto_data; | 4363 struct oscar_data *od = (struct oscar_data *)gc->proto_data; |
4455 aim_setdirectoryinfo(od->sess, od->conn, first, middle, last, | 4364 aim_locate_setdirinfo(od->sess, first, middle, last, |
4456 maiden, NULL, NULL, city, state, NULL, 0, web); | 4365 maiden, NULL, NULL, city, state, NULL, 0, web); |
4457 } | 4366 } |
4458 | 4367 |
4459 static void oscar_set_idle(GaimConnection *gc, int time) { | 4368 static void oscar_set_idle(GaimConnection *gc, int time) { |
4460 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | 4369 struct oscar_data *od = (struct oscar_data *)gc->proto_data; |
4474 "profile before the login procedure completed. " | 4383 "profile before the login procedure completed. " |
4475 "Your profile remains unset; try setting it " | 4384 "Your profile remains unset; try setting it " |
4476 "again when you are fully connected.")); | 4385 "again when you are fully connected.")); |
4477 | 4386 |
4478 if (od->icq) | 4387 if (od->icq) |
4479 aim_bos_setprofile(od->sess, od->conn, NULL, NULL, 0, NULL, NULL, 0, caps_icq); | 4388 aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, NULL, 0, caps_icq); |
4480 else { | 4389 else { |
4481 if (!text) { | 4390 if (!text) { |
4482 aim_bos_setprofile(od->sess, od->conn, NULL, NULL, 0, NULL, NULL, 0, caps_aim); | 4391 aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, NULL, 0, caps_aim); |
4483 return; | 4392 return; |
4484 } | 4393 } |
4485 | 4394 |
4486 text_html = strdup_withhtml(text); | 4395 text_html = strdup_withhtml(text); |
4487 flags = oscar_encoding_check(text_html); | 4396 flags = oscar_encoding_check(text_html); |
4488 if (flags & AIM_IMFLAGS_UNICODE) { | 4397 if (flags & AIM_IMFLAGS_UNICODE) { |
4489 msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); | 4398 msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); |
4490 aim_bos_setprofile(od->sess, od->conn, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); | 4399 aim_locate_setprofile(od->sess, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); |
4491 g_free(msg); | 4400 g_free(msg); |
4492 } else if (flags & AIM_IMFLAGS_ISO_8859_1) { | 4401 } else if (flags & AIM_IMFLAGS_ISO_8859_1) { |
4493 msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); | 4402 msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); |
4494 aim_bos_setprofile(od->sess, od->conn, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); | 4403 aim_locate_setprofile(od->sess, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); |
4495 g_free(msg); | 4404 g_free(msg); |
4496 } else { | 4405 } else { |
4497 msglen = strlen(text_html); | 4406 msglen = strlen(text_html); |
4498 aim_bos_setprofile(od->sess, od->conn, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); | 4407 aim_locate_setprofile(od->sess, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); |
4499 } | 4408 } |
4500 | 4409 |
4501 if (msglen > od->rights.maxsiglen) { | 4410 if (msglen > od->rights.maxsiglen) { |
4502 gchar *errstr; | 4411 gchar *errstr; |
4503 errstr = g_strdup_printf(ngettext("The maximum profile length of %d byte " | 4412 errstr = g_strdup_printf(ngettext("The maximum profile length of %d byte " |
4535 g_free(gc->away); | 4444 g_free(gc->away); |
4536 gc->away = NULL; | 4445 gc->away = NULL; |
4537 } | 4446 } |
4538 | 4447 |
4539 if (!text) { | 4448 if (!text) { |
4540 aim_bos_setprofile(od->sess, od->conn, NULL, NULL, 0, NULL, "", 0, caps_aim); | 4449 aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0, caps_aim); |
4541 return; | 4450 return; |
4542 } | 4451 } |
4543 | 4452 |
4544 text_html = strdup_withhtml(text); | 4453 text_html = strdup_withhtml(text); |
4545 flags = oscar_encoding_check(text_html); | 4454 flags = oscar_encoding_check(text_html); |
4546 if (flags & AIM_IMFLAGS_UNICODE) { | 4455 if (flags & AIM_IMFLAGS_UNICODE) { |
4547 msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); | 4456 msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); |
4548 aim_bos_setprofile(od->sess, od->conn, NULL, NULL, 0, "unicode-2-0", msg, | 4457 aim_locate_setprofile(od->sess, NULL, NULL, 0, "unicode-2-0", msg, |
4549 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim); | 4458 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim); |
4550 g_free(msg); | 4459 g_free(msg); |
4551 gc->away = g_strndup(text, od->rights.maxawaymsglen/2); | 4460 gc->away = g_strndup(text, od->rights.maxawaymsglen/2); |
4552 } else if (flags & AIM_IMFLAGS_ISO_8859_1) { | 4461 } else if (flags & AIM_IMFLAGS_ISO_8859_1) { |
4553 msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); | 4462 msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); |
4554 aim_bos_setprofile(od->sess, od->conn, NULL, NULL, 0, "iso-8859-1", msg, | 4463 aim_locate_setprofile(od->sess, NULL, NULL, 0, "iso-8859-1", msg, |
4555 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim); | 4464 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim); |
4556 g_free(msg); | 4465 g_free(msg); |
4557 gc->away = g_strndup(text_html, od->rights.maxawaymsglen); | 4466 gc->away = g_strndup(text_html, od->rights.maxawaymsglen); |
4558 } else { | 4467 } else { |
4559 msglen = strlen(text_html); | 4468 msglen = strlen(text_html); |
4560 aim_bos_setprofile(od->sess, od->conn, NULL, NULL, 0, "us-ascii", text_html, | 4469 aim_locate_setprofile(od->sess, NULL, NULL, 0, "us-ascii", text_html, |
4561 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim); | 4470 (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim); |
4562 gc->away = g_strndup(text_html, od->rights.maxawaymsglen); | 4471 gc->away = g_strndup(text_html, od->rights.maxawaymsglen); |
4563 } | 4472 } |
4564 | 4473 |
4565 if (msglen > od->rights.maxawaymsglen) { | 4474 if (msglen > od->rights.maxawaymsglen) { |
5439 | 5348 |
5440 static char *oscar_tooltip_text(GaimBuddy *b) { | 5349 static char *oscar_tooltip_text(GaimBuddy *b) { |
5441 GaimConnection *gc = b->account->gc; | 5350 GaimConnection *gc = b->account->gc; |
5442 struct oscar_data *od = gc->proto_data; | 5351 struct oscar_data *od = gc->proto_data; |
5443 struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, normalize(b->name)); | 5352 struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, normalize(b->name)); |
5444 gchar *tmp, *yay = g_strdup(""); | 5353 aim_userinfo_t *userinfo = aim_locate_finduserinfo(b->name); |
5354 gchar *tmp = NULL, *ret = g_strdup(""); | |
5445 | 5355 |
5446 if (GAIM_BUDDY_IS_ONLINE(b)) { | 5356 if (GAIM_BUDDY_IS_ONLINE(b)) { |
5447 if (isdigit(b->name[0])) { | 5357 if (isdigit(b->name[0])) { |
5448 char *tmp, *status; | 5358 char *status; |
5449 status = gaim_icq_status((b->uc & 0xffff0000) >> 16); | 5359 status = gaim_icq_status((b->uc & 0xffff0000) >> 16); |
5450 tmp = yay; | 5360 tmp = ret; |
5451 yay = g_strconcat(tmp, _("<b>Status:</b> "), status, "\n", NULL); | 5361 ret = g_strconcat(tmp, _("<b>Status:</b> "), status, "\n", NULL); |
5452 g_free(tmp); | 5362 g_free(tmp); |
5453 g_free(status); | 5363 g_free(status); |
5454 } | 5364 } |
5455 | 5365 |
5456 if (bi) { | 5366 if (userinfo != NULL) { |
5457 char *tstr = sec_to_text(time(NULL) - bi->signon + | 5367 char *tstr = sec_to_text(time(NULL) - userinfo->onlinesince + |
5458 (gc->login_time_official ? gc->login_time_official - gc->login_time : 0)); | 5368 (gc->login_time_official ? gc->login_time_official - gc->login_time : 0)); |
5459 tmp = yay; | 5369 tmp = ret; |
5460 yay = g_strconcat(tmp, _("<b>Logged In:</b> "), tstr, "\n", NULL); | 5370 ret = g_strconcat(tmp, _("<b>Logged In:</b> "), tstr, "\n", NULL); |
5461 free(tmp); | 5371 free(tmp); |
5462 free(tstr); | 5372 free(tstr); |
5463 | 5373 } |
5464 if (bi->ipaddr) { | 5374 |
5465 char *tstr = g_strdup_printf("%hhd.%hhd.%hhd.%hhd", | 5375 if ((bi != NULL) && (bi->ipaddr)) { |
5466 (bi->ipaddr & 0xff000000) >> 24, | 5376 char *tstr = g_strdup_printf("%hhd.%hhd.%hhd.%hhd", |
5467 (bi->ipaddr & 0x00ff0000) >> 16, | 5377 (bi->ipaddr & 0xff000000) >> 24, |
5468 (bi->ipaddr & 0x0000ff00) >> 8, | 5378 (bi->ipaddr & 0x00ff0000) >> 16, |
5469 (bi->ipaddr & 0x000000ff)); | 5379 (bi->ipaddr & 0x0000ff00) >> 8, |
5470 tmp = yay; | 5380 (bi->ipaddr & 0x000000ff)); |
5471 yay = g_strconcat(tmp, _("<b>IP Address:</b> "), tstr, "\n", NULL); | 5381 tmp = ret; |
5382 ret = g_strconcat(tmp, _("<b>IP Address:</b> "), tstr, "\n", NULL); | |
5383 free(tmp); | |
5384 free(tstr); | |
5385 } | |
5386 | |
5387 if ((userinfo != NULL) && (userinfo->capabilities)) { | |
5388 char *caps = caps_string(userinfo->capabilities); | |
5389 tmp = ret; | |
5390 ret = g_strconcat(tmp, _("<b>Capabilities:</b> "), caps, "\n", NULL); | |
5391 free(tmp); | |
5392 } | |
5393 | |
5394 if ((bi != NULL) && (bi->availmsg != NULL) && !(b->uc & UC_UNAVAILABLE)) { | |
5395 gchar *escaped = g_markup_escape_text(bi->availmsg, strlen(bi->availmsg)); | |
5396 tmp = ret; | |
5397 ret = g_strconcat(tmp, _("<b>Available:</b> "), escaped, "\n", NULL); | |
5398 free(tmp); | |
5399 g_free(escaped); | |
5400 } | |
5401 | |
5402 if ((userinfo != NULL) && (userinfo->flags & AIM_FLAG_AWAY) && (userinfo->away_len > 0) && (userinfo->away != NULL) && (userinfo->away_encoding != NULL)) { | |
5403 gchar *away_utf8 = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len); | |
5404 if (away_utf8 != NULL) { | |
5405 gchar *withcr, *nohtml; | |
5406 withcr = gaim_strreplace(away_utf8, "<BR>", "\n"); | |
5407 nohtml = strip_html(withcr); | |
5408 g_free(withcr); | |
5409 tmp = ret; | |
5410 ret = g_strconcat(tmp, _("<b>Away Message:</b> "), nohtml, "\n", NULL); | |
5472 free(tmp); | 5411 free(tmp); |
5473 free(tstr); | 5412 g_free(nohtml); |
5474 } | 5413 g_free(away_utf8); |
5475 | |
5476 if (bi->caps) { | |
5477 char *caps = caps_string(bi->caps); | |
5478 tmp = yay; | |
5479 yay = g_strconcat(tmp, _("<b>Capabilities:</b> "), caps, "\n", NULL); | |
5480 free(tmp); | |
5481 } | |
5482 | |
5483 if (bi->availmsg && !(b->uc & UC_UNAVAILABLE)) { | |
5484 gchar *escaped = g_markup_escape_text(bi->availmsg, strlen(bi->availmsg)); | |
5485 tmp = yay; | |
5486 yay = g_strconcat(tmp, _("<b>Available:</b> "), escaped, "\n", NULL); | |
5487 free(tmp); | |
5488 g_free(escaped); | |
5489 } | 5414 } |
5490 } | 5415 } |
5491 } else { | 5416 } else { |
5492 char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name); | 5417 char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name); |
5493 if (aim_ssi_waitingforauth(od->sess->ssi.local, gname, b->name)) { | 5418 if (aim_ssi_waitingforauth(od->sess->ssi.local, gname, b->name)) { |
5494 tmp = yay; | 5419 tmp = ret; |
5495 yay = g_strconcat(tmp, _("<b>Status:</b> Not Authorized"), "\n", NULL); | 5420 ret = g_strconcat(tmp, _("<b>Status:</b> Not Authorized"), "\n", NULL); |
5496 g_free(tmp); | 5421 g_free(tmp); |
5497 } else { | 5422 } else { |
5498 tmp = yay; | 5423 tmp = ret; |
5499 yay = g_strconcat(tmp, _("<b>Status:</b> Offline"), "\n", NULL); | 5424 ret = g_strconcat(tmp, _("<b>Status:</b> Offline"), "\n", NULL); |
5500 g_free(tmp); | 5425 g_free(tmp); |
5501 } | 5426 } |
5502 } | 5427 } |
5503 | 5428 |
5504 /* remove the trailing newline character */ | 5429 /* remove the trailing newline character */ |
5505 if (yay) | 5430 if (ret) |
5506 yay[strlen(yay)-1] = '\0'; | 5431 ret[strlen(ret)-1] = '\0'; |
5507 return yay; | 5432 return ret; |
5508 } | 5433 } |
5509 | 5434 |
5510 static char *oscar_status_text(GaimBuddy *b) { | 5435 static char *oscar_status_text(GaimBuddy *b) { |
5511 GaimConnection *gc = b->account->gc; | 5436 GaimConnection *gc = b->account->gc; |
5512 struct oscar_data *od = gc->proto_data; | 5437 struct oscar_data *od = gc->proto_data; |
6140 pbm->gc = gc; | 6065 pbm->gc = gc; |
6141 m = g_list_append(m, pbm); | 6066 m = g_list_append(m, pbm); |
6142 #endif | 6067 #endif |
6143 } else { | 6068 } else { |
6144 GaimBuddy *b = gaim_find_buddy(gc->account, who); | 6069 GaimBuddy *b = gaim_find_buddy(gc->account, who); |
6145 struct buddyinfo *bi; | 6070 aim_userinfo_t *userinfo; |
6146 | 6071 |
6147 if (b) | 6072 if (b) |
6148 bi = g_hash_table_lookup(od->buddyinfo, normalize(b->name)); | 6073 userinfo = aim_locate_finduserinfo(b->name); |
6149 | 6074 |
6150 if (b && bi && aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), who) && GAIM_BUDDY_IS_ONLINE(b)) { | 6075 if (b && userinfo && aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), who) && GAIM_BUDDY_IS_ONLINE(b)) { |
6151 if (bi->caps & AIM_CAPS_DIRECTIM) { | 6076 if (userinfo->capabilities & AIM_CAPS_DIRECTIM) { |
6152 pbm = g_new0(struct proto_buddy_menu, 1); | 6077 pbm = g_new0(struct proto_buddy_menu, 1); |
6153 pbm->label = _("Direct IM"); | 6078 pbm->label = _("Direct IM"); |
6154 pbm->callback = oscar_ask_direct_im; | 6079 pbm->callback = oscar_ask_direct_im; |
6155 pbm->gc = gc; | 6080 pbm->gc = gc; |
6156 m = g_list_append(m, pbm); | 6081 m = g_list_append(m, pbm); |
6157 } | 6082 } |
6158 | 6083 |
6159 if (bi->caps & AIM_CAPS_SENDFILE) { | 6084 if (userinfo->capabilities & AIM_CAPS_SENDFILE) { |
6160 pbm = g_new0(struct proto_buddy_menu, 1); | 6085 pbm = g_new0(struct proto_buddy_menu, 1); |
6161 pbm->label = _("Send File"); | 6086 pbm->label = _("Send File"); |
6162 pbm->callback = oscar_ask_sendfile; | 6087 pbm->callback = oscar_ask_sendfile; |
6163 pbm->gc = gc; | 6088 pbm->gc = gc; |
6164 m = g_list_append(m, pbm); | 6089 m = g_list_append(m, pbm); |
6165 } | 6090 } |
6166 #if 0 | 6091 #if 0 |
6167 if (bi->caps & AIM_CAPS_GETFILE) { | 6092 if (userinfo->capabilities & AIM_CAPS_GETFILE) { |
6168 pbm = g_new0(struct proto_buddy_menu, 1); | 6093 pbm = g_new0(struct proto_buddy_menu, 1); |
6169 pbm->label = _("Get File"); | 6094 pbm->label = _("Get File"); |
6170 pbm->callback = oscar_ask_getfile; | 6095 pbm->callback = oscar_ask_getfile; |
6171 pbm->gc = gc; | 6096 pbm->gc = gc; |
6172 m = g_list_append(m, pbm); | 6097 m = g_list_append(m, pbm); |