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