Mercurial > pidgin
comparison src/protocols/yahoo/yahoo.c @ 6729:7b878ee8f064
[gaim-migrate @ 7256]
Tim Ringenbach (marv_sf) writes:
" This adds Chat and Conference support to the Yahoo! prpl.
I think I got all the major bugs out, and it works
pretty good.
You can invite others, and accept inventations for both
chats and conferences, you can join a chat from the
Buddies menu in the buddy list, like you would for irc,
and you can initiate a conference by right clicking on
a buddy, like you would for msn. You can also attempt
to join user in chat, which will fail if they're not
actually in a chat. (Apparently the offical version
can't tell before hand either.)
Oh, and you can chat."
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Wed, 03 Sep 2003 12:45:17 +0000 |
parents | 0c5637b5462e |
children | e7e21e5d1d16 |
comparison
equal
deleted
inserted
replaced
6728:fa7359c3f93c | 6729:7b878ee8f064 |
---|---|
32 #include "server.h" | 32 #include "server.h" |
33 #include "util.h" | 33 #include "util.h" |
34 #include "html.h" | 34 #include "html.h" |
35 | 35 |
36 #include "yahoo.h" | 36 #include "yahoo.h" |
37 #include "yahoochat.h" | |
37 #include "md5.h" | 38 #include "md5.h" |
38 | 39 |
39 /* XXX */ | 40 /* XXX */ |
40 #include "gtkinternal.h" | 41 #include "gtkinternal.h" |
41 #include "gaim.h" | 42 #include "gaim.h" |
51 #define YAHOO_PAGER_PORT 5050 | 52 #define YAHOO_PAGER_PORT 5050 |
52 #define YAHOO_PROFILE_URL "http://profiles.yahoo.com/" | 53 #define YAHOO_PROFILE_URL "http://profiles.yahoo.com/" |
53 | 54 |
54 #define YAHOO_PROTO_VER 0x0900 | 55 #define YAHOO_PROTO_VER 0x0900 |
55 | 56 |
56 enum yahoo_service { /* these are easier to see in hex */ | |
57 YAHOO_SERVICE_LOGON = 1, | |
58 YAHOO_SERVICE_LOGOFF, | |
59 YAHOO_SERVICE_ISAWAY, | |
60 YAHOO_SERVICE_ISBACK, | |
61 YAHOO_SERVICE_IDLE, /* 5 (placemarker) */ | |
62 YAHOO_SERVICE_MESSAGE, | |
63 YAHOO_SERVICE_IDACT, | |
64 YAHOO_SERVICE_IDDEACT, | |
65 YAHOO_SERVICE_MAILSTAT, | |
66 YAHOO_SERVICE_USERSTAT, /* 0xa */ | |
67 YAHOO_SERVICE_NEWMAIL, | |
68 YAHOO_SERVICE_CHATINVITE, | |
69 YAHOO_SERVICE_CALENDAR, | |
70 YAHOO_SERVICE_NEWPERSONALMAIL, | |
71 YAHOO_SERVICE_NEWCONTACT, | |
72 YAHOO_SERVICE_ADDIDENT, /* 0x10 */ | |
73 YAHOO_SERVICE_ADDIGNORE, | |
74 YAHOO_SERVICE_PING, | |
75 YAHOO_SERVICE_GROUPRENAME, | |
76 YAHOO_SERVICE_SYSMESSAGE = 0x14, | |
77 YAHOO_SERVICE_PASSTHROUGH2 = 0x16, | |
78 YAHOO_SERVICE_CONFINVITE = 0x18, | |
79 YAHOO_SERVICE_CONFLOGON, | |
80 YAHOO_SERVICE_CONFDECLINE, | |
81 YAHOO_SERVICE_CONFLOGOFF, | |
82 YAHOO_SERVICE_CONFADDINVITE, | |
83 YAHOO_SERVICE_CONFMSG, | |
84 YAHOO_SERVICE_CHATLOGON, | |
85 YAHOO_SERVICE_CHATLOGOFF, | |
86 YAHOO_SERVICE_CHATMSG = 0x20, | |
87 YAHOO_SERVICE_GAMELOGON = 0x28, | |
88 YAHOO_SERVICE_GAMELOGOFF, | |
89 YAHOO_SERVICE_GAMEMSG = 0x2a, | |
90 YAHOO_SERVICE_FILETRANSFER = 0x46, | |
91 YAHOO_SERVICE_NOTIFY = 0x4B, | |
92 YAHOO_SERVICE_AUTHRESP = 0x54, | |
93 YAHOO_SERVICE_LIST = 0x55, | |
94 YAHOO_SERVICE_AUTH = 0x57, | |
95 YAHOO_SERVICE_ADDBUDDY = 0x83, | |
96 YAHOO_SERVICE_REMBUDDY = 0x84 | |
97 }; | |
98 | |
99 enum yahoo_status { | |
100 YAHOO_STATUS_AVAILABLE = 0, | |
101 YAHOO_STATUS_BRB, | |
102 YAHOO_STATUS_BUSY, | |
103 YAHOO_STATUS_NOTATHOME, | |
104 YAHOO_STATUS_NOTATDESK, | |
105 YAHOO_STATUS_NOTINOFFICE, | |
106 YAHOO_STATUS_ONPHONE, | |
107 YAHOO_STATUS_ONVACATION, | |
108 YAHOO_STATUS_OUTTOLUNCH, | |
109 YAHOO_STATUS_STEPPEDOUT, | |
110 YAHOO_STATUS_INVISIBLE = 12, | |
111 YAHOO_STATUS_CUSTOM = 99, | |
112 YAHOO_STATUS_IDLE = 999, | |
113 YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */ | |
114 YAHOO_STATUS_TYPING = 0x16 | |
115 }; | |
116 #define YAHOO_STATUS_GAME 0x2 /* Games don't fit into the regular status model */ | |
117 | |
118 struct yahoo_data { | |
119 int fd; | |
120 guchar *rxqueue; | |
121 int rxlen; | |
122 GHashTable *hash; | |
123 GHashTable *games; | |
124 int current_status; | |
125 gboolean logged_in; | |
126 }; | |
127 | |
128 struct yahoo_pair { | |
129 int key; | |
130 char *value; | |
131 }; | |
132 | |
133 struct yahoo_packet { | |
134 guint16 service; | |
135 guint32 status; | |
136 guint32 id; | |
137 GSList *hash; | |
138 }; | |
139 | |
140 #define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4) | 57 #define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4) |
141 | 58 |
142 static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id) | 59 struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id) |
143 { | 60 { |
144 struct yahoo_packet *pkt = g_new0(struct yahoo_packet, 1); | 61 struct yahoo_packet *pkt = g_new0(struct yahoo_packet, 1); |
145 | 62 |
146 pkt->service = service; | 63 pkt->service = service; |
147 pkt->status = status; | 64 pkt->status = status; |
148 pkt->id = id; | 65 pkt->id = id; |
149 | 66 |
150 return pkt; | 67 return pkt; |
151 } | 68 } |
152 | 69 |
153 static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value) | 70 void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value) |
154 { | 71 { |
155 struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); | 72 struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); |
156 pair->key = key; | 73 pair->key = key; |
157 pair->value = g_strdup(value); | 74 pair->value = g_strdup(value); |
158 pkt->hash = g_slist_append(pkt->hash, pair); | 75 pkt->hash = g_slist_append(pkt->hash, pair); |
312 | 229 |
313 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); | 230 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); |
314 #endif | 231 #endif |
315 } | 232 } |
316 | 233 |
317 static int yahoo_send_packet(struct yahoo_data *yd, struct yahoo_packet *pkt) | 234 int yahoo_send_packet(struct yahoo_data *yd, struct yahoo_packet *pkt) |
318 { | 235 { |
319 int pktlen = yahoo_packet_length(pkt); | 236 int pktlen = yahoo_packet_length(pkt); |
320 int len = YAHOO_PACKET_HDRLEN + pktlen; | 237 int len = YAHOO_PACKET_HDRLEN + pktlen; |
321 int ret; | 238 int ret; |
322 | 239 |
343 g_free(data); | 260 g_free(data); |
344 | 261 |
345 return ret; | 262 return ret; |
346 } | 263 } |
347 | 264 |
348 static void yahoo_packet_free(struct yahoo_packet *pkt) | 265 void yahoo_packet_free(struct yahoo_packet *pkt) |
349 { | 266 { |
350 while (pkt->hash) { | 267 while (pkt->hash) { |
351 struct yahoo_pair *pair = pkt->hash->data; | 268 struct yahoo_pair *pair = pkt->hash->data; |
352 g_free(pair->value); | 269 g_free(pair->value); |
353 g_free(pair); | 270 g_free(pair); |
915 yahoo_process_list(gc, pkt); | 832 yahoo_process_list(gc, pkt); |
916 break; | 833 break; |
917 case YAHOO_SERVICE_AUTH: | 834 case YAHOO_SERVICE_AUTH: |
918 yahoo_process_auth(gc, pkt); | 835 yahoo_process_auth(gc, pkt); |
919 break; | 836 break; |
837 case YAHOO_SERVICE_CONFINVITE: | |
838 case YAHOO_SERVICE_CONFADDINVITE: | |
839 yahoo_process_conference_invite(gc, pkt); | |
840 break; | |
841 case YAHOO_SERVICE_CONFDECLINE: | |
842 yahoo_process_conference_decline(gc, pkt); | |
843 break; | |
844 case YAHOO_SERVICE_CONFLOGON: | |
845 yahoo_process_conference_logon(gc, pkt); | |
846 break; | |
847 case YAHOO_SERVICE_CONFLOGOFF: | |
848 yahoo_process_conference_logoff(gc, pkt); | |
849 break; | |
850 case YAHOO_SERVICE_CONFMSG: | |
851 yahoo_process_conference_message(gc, pkt); | |
852 break; | |
853 case YAHOO_SERVICE_CHATONLINE: | |
854 yahoo_process_chat_online(gc, pkt); | |
855 break; | |
856 case YAHOO_SERVICE_CHATLOGOUT: | |
857 yahoo_process_chat_logout(gc, pkt); | |
858 break; | |
859 case YAHOO_SERVICE_CHATGOTO: | |
860 yahoo_process_chat_goto(gc, pkt); | |
861 break; | |
862 case YAHOO_SERVICE_CHATJOIN: | |
863 yahoo_process_chat_join(gc, pkt); | |
864 break; | |
865 case YAHOO_SERVICE_CHATLEAVE: /* XXX is this right? */ | |
866 case YAHOO_SERVICE_CHATEXIT: | |
867 yahoo_process_chat_exit(gc, pkt); | |
868 break; | |
869 case YAHOO_SERVICE_CHATINVITE: /* XXX never seen this one, might not do it right */ | |
870 case YAHOO_SERVICE_CHATADDINVITE: | |
871 yahoo_process_chat_addinvite(gc, pkt); | |
872 break; | |
873 case YAHOO_SERVICE_COMMENT: | |
874 yahoo_process_chat_message(gc, pkt); | |
875 break; | |
920 default: | 876 default: |
921 gaim_debug(GAIM_DEBUG_ERROR, "yahoo", | 877 gaim_debug(GAIM_DEBUG_ERROR, "yahoo", |
922 "Unhandled service 0x%02x\n", pkt->service); | 878 "Unhandled service 0x%02x\n", pkt->service); |
923 break; | 879 break; |
924 } | 880 } |
1028 gaim_connection_update_progress(gc, _("Connecting"), 1, 2); | 984 gaim_connection_update_progress(gc, _("Connecting"), 1, 2); |
1029 | 985 |
1030 yd->fd = -1; | 986 yd->fd = -1; |
1031 yd->hash = g_hash_table_new(g_str_hash, g_str_equal); | 987 yd->hash = g_hash_table_new(g_str_hash, g_str_equal); |
1032 yd->games = g_hash_table_new(g_str_hash, g_str_equal); | 988 yd->games = g_hash_table_new(g_str_hash, g_str_equal); |
989 yd->confs = NULL; | |
990 yd->conf_id = 2; | |
1033 | 991 |
1034 if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", YAHOO_PAGER_HOST), | 992 if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", YAHOO_PAGER_HOST), |
1035 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), | 993 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), |
1036 yahoo_got_connected, gc) != 0) { | 994 yahoo_got_connected, gc) != 0) { |
1037 gaim_connection_error(gc, _("Connection problem")); | 995 gaim_connection_error(gc, _("Connection problem")); |
1051 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | 1009 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; |
1052 g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); | 1010 g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); |
1053 g_hash_table_destroy(yd->hash); | 1011 g_hash_table_destroy(yd->hash); |
1054 g_hash_table_foreach_remove(yd->games, yahoo_destroy_hash, NULL); | 1012 g_hash_table_foreach_remove(yd->games, yahoo_destroy_hash, NULL); |
1055 g_hash_table_destroy(yd->games); | 1013 g_hash_table_destroy(yd->games); |
1014 | |
1015 g_slist_free(yd->confs); | |
1016 | |
1056 if (yd->fd >= 0) | 1017 if (yd->fd >= 0) |
1057 close(yd->fd); | 1018 close(yd->fd); |
1058 | 1019 |
1059 if (yd->rxqueue) | 1020 if (yd->rxqueue) |
1060 g_free(yd->rxqueue); | 1021 g_free(yd->rxqueue); |
1116 default: | 1077 default: |
1117 return _("Online"); | 1078 return _("Online"); |
1118 } | 1079 } |
1119 } | 1080 } |
1120 | 1081 |
1082 static void yahoo_initiate_conference(GaimConnection *gc, const char *name) | |
1083 { | |
1084 GHashTable *components; | |
1085 struct yahoo_data *yd; | |
1086 int id; | |
1087 | |
1088 yd = gc->proto_data; | |
1089 id = yd->conf_id; | |
1090 | |
1091 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
1092 g_hash_table_replace(components, g_strdup("room"), | |
1093 g_strdup_printf("%s-%d", gaim_connection_get_display_name(gc), id)); | |
1094 g_hash_table_replace(components, g_strdup("topic"), g_strdup("Join my conference...")); | |
1095 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference")); | |
1096 yahoo_c_join(gc, components); | |
1097 g_hash_table_destroy(components); | |
1098 | |
1099 yahoo_c_invite(gc, id, "Join my conference...", name); | |
1100 } | |
1101 | |
1121 static void yahoo_game(GaimConnection *gc, const char *name) { | 1102 static void yahoo_game(GaimConnection *gc, const char *name) { |
1122 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | 1103 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; |
1123 char *game = g_hash_table_lookup(yd->games, name); | 1104 char *game = g_hash_table_lookup(yd->games, name); |
1124 char *t; | 1105 char *t; |
1125 char url[256]; | 1106 char url[256]; |
1181 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | 1162 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; |
1182 GaimBuddy *b = gaim_find_buddy(gc->account, who); /* this should never be null. if it is, | 1163 GaimBuddy *b = gaim_find_buddy(gc->account, who); /* this should never be null. if it is, |
1183 segfault and get the bug report. */ | 1164 segfault and get the bug report. */ |
1184 static char buf2[1024]; | 1165 static char buf2[1024]; |
1185 | 1166 |
1167 pbm = g_new0(struct proto_buddy_menu, 1); | |
1168 pbm->label = _("Join in Chat"); | |
1169 pbm->callback = yahoo_chat_goto; | |
1170 pbm->gc = gc; | |
1171 m = g_list_append(m, pbm); | |
1172 | |
1173 pbm = g_new0(struct proto_buddy_menu, 1); | |
1174 pbm->label = _("Initiate Conference"); | |
1175 pbm->callback = yahoo_initiate_conference; | |
1176 pbm->gc = gc; | |
1177 m = g_list_append(m, pbm); | |
1178 | |
1186 if (b->uc | YAHOO_STATUS_GAME) { | 1179 if (b->uc | YAHOO_STATUS_GAME) { |
1187 char *game = g_hash_table_lookup(yd->games, b->name); | 1180 char *game = g_hash_table_lookup(yd->games, b->name); |
1188 char *room; | 1181 char *room; |
1189 if (!game) | 1182 if (!game) |
1190 return m; | 1183 return m; |
1191 if (game) { | 1184 if (game) { |
1192 char *t; | 1185 char *t; |
1193 pbm = g_new0(struct proto_buddy_menu, 1); | 1186 pbm = g_new0(struct proto_buddy_menu, 1); |
1194 if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ | 1187 if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ |
1195 return NULL; | 1188 return m; |
1196 while (*room && *room != '\t') /* skip to the tab */ | 1189 while (*room && *room != '\t') /* skip to the tab */ |
1197 room++; | 1190 room++; |
1198 t = room++; /* room as now at the name */ | 1191 t = room++; /* room as now at the name */ |
1199 while (*t != '\n') | 1192 while (*t != '\n') |
1200 t++; /* replace the \n with a space */ | 1193 t++; /* replace the \n with a space */ |
1201 *t = ' '; | 1194 *t = ' '; |
1202 g_snprintf(buf2, sizeof buf2, "%s", room); | 1195 g_snprintf(buf2, sizeof buf2, "%s", room); |
1203 pbm->label = buf2; | 1196 pbm->label = buf2; |
1204 pbm->callback = yahoo_game; | 1197 pbm->callback = yahoo_game; |
1205 pbm->gc = gc; | 1198 pbm->gc = gc; |
1206 m = g_list_append(m, pbm); | 1199 m = g_list_append(m, pbm); |
1207 } | 1200 } |
1208 } | 1201 } |
1209 | 1202 |
1210 return m; | 1203 return m; |
1211 } | 1204 } |
1212 | 1205 |
1213 static void yahoo_act_id(GaimConnection *gc, const char *entry) | 1206 static void yahoo_act_id(GaimConnection *gc, const char *entry) |
1214 { | 1207 { |
1399 { | 1392 { |
1400 struct yahoo_data *yd = gc->proto_data; | 1393 struct yahoo_data *yd = gc->proto_data; |
1401 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); | 1394 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); |
1402 yahoo_send_packet(yd, pkt); | 1395 yahoo_send_packet(yd, pkt); |
1403 yahoo_packet_free(pkt); | 1396 yahoo_packet_free(pkt); |
1397 | |
1398 if (!yd->chat_online) | |
1399 return; | |
1400 | |
1401 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, 0); | |
1402 yahoo_packet_hash(pkt, 109, gaim_connection_get_display_name(gc)); | |
1403 yahoo_send_packet(yd, pkt); | |
1404 yahoo_packet_free(pkt); | |
1404 } | 1405 } |
1405 | 1406 |
1406 static void yahoo_add_buddy(GaimConnection *gc, const char *who) | 1407 static void yahoo_add_buddy(GaimConnection *gc, const char *who) |
1407 { | 1408 { |
1408 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | 1409 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; |
1617 static GaimPlugin *my_protocol = NULL; | 1618 static GaimPlugin *my_protocol = NULL; |
1618 | 1619 |
1619 static GaimPluginProtocolInfo prpl_info = | 1620 static GaimPluginProtocolInfo prpl_info = |
1620 { | 1621 { |
1621 GAIM_PROTO_YAHOO, | 1622 GAIM_PROTO_YAHOO, |
1622 OPT_PROTO_MAIL_CHECK, | 1623 OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC, |
1623 NULL, | 1624 NULL, /* user_splits */ |
1624 NULL, | 1625 NULL, /* protocol_options */ |
1625 yahoo_list_icon, | 1626 yahoo_list_icon, |
1626 yahoo_list_emblems, | 1627 yahoo_list_emblems, |
1627 yahoo_status_text, | 1628 yahoo_status_text, |
1628 yahoo_tooltip_text, | 1629 yahoo_tooltip_text, |
1629 yahoo_away_states, | 1630 yahoo_away_states, |
1630 yahoo_actions, | 1631 yahoo_actions, |
1631 yahoo_buddy_menu, | 1632 yahoo_buddy_menu, |
1632 NULL, | 1633 yahoo_c_info, |
1633 yahoo_login, | 1634 yahoo_login, |
1634 yahoo_close, | 1635 yahoo_close, |
1635 yahoo_send_im, | 1636 yahoo_send_im, |
1636 NULL, | 1637 NULL, /* set info */ |
1637 yahoo_send_typing, | 1638 yahoo_send_typing, |
1638 yahoo_get_info, | 1639 yahoo_get_info, |
1639 yahoo_set_away, | 1640 yahoo_set_away, |
1640 NULL, | 1641 NULL, /* get_away */ |
1641 NULL, | 1642 NULL, /* set_dir */ |
1642 NULL, | 1643 NULL, /* get_dir */ |
1643 NULL, | 1644 NULL, /* dir_search */ |
1644 yahoo_set_idle, | 1645 yahoo_set_idle, |
1645 NULL, | 1646 NULL, /* change_passwd*/ |
1646 yahoo_add_buddy, | 1647 yahoo_add_buddy, |
1647 NULL, | 1648 NULL, /* add_buddies */ |
1648 yahoo_remove_buddy, | 1649 yahoo_remove_buddy, |
1649 NULL, | 1650 NULL, /*remove_buddies */ |
1650 NULL, | 1651 NULL, /* add_permit */ |
1651 NULL, | 1652 NULL, /* add_dey */ |
1652 NULL, | 1653 NULL, /* rem_permit */ |
1653 NULL, | 1654 NULL, /* rem_deny */ |
1654 NULL, | 1655 NULL, /* set_permit_deny */ |
1655 NULL, | 1656 NULL, /* warn */ |
1656 NULL, | 1657 yahoo_c_join, |
1657 NULL, | 1658 yahoo_c_invite, |
1658 NULL, | 1659 yahoo_c_leave, |
1659 NULL, | 1660 NULL, /* chat whisper */ |
1660 NULL, | 1661 yahoo_c_send, |
1661 yahoo_keepalive, | 1662 yahoo_keepalive, |
1662 NULL, | 1663 NULL, /* register_user */ |
1663 NULL, | 1664 NULL, /* get_cb_info */ |
1664 NULL, | 1665 NULL, /* get_cb_away */ |
1665 NULL, | 1666 NULL, /* alias_buddy */ |
1666 NULL, | 1667 NULL, /* change group */ |
1667 NULL, | 1668 NULL, /* rename group */ |
1668 NULL, | 1669 NULL, /* buddy_free */ |
1669 NULL, | 1670 NULL, /* convo_closed */ |
1670 NULL | 1671 NULL, /* normalize */ |
1672 NULL /* set_buddy_icon */ | |
1671 }; | 1673 }; |
1672 | 1674 |
1673 static GaimPluginInfo info = | 1675 static GaimPluginInfo info = |
1674 { | 1676 { |
1675 2, /**< api_version */ | 1677 2, /**< api_version */ |