Mercurial > pidgin
annotate src/protocols/yahoo/yahoo.c @ 3572:bdd0bebd2d04
[gaim-migrate @ 3670]
Phase II. No longer do you have to worry about protocol plugins. When
Gaim probes plugins on load, it will detect protocol plugins and add them
to the list of available protocols. When you try to log an account on with
one of them, Gaim will automatically load the plugin--when no more accounts
need the protocol--Gaim will automatically unload it. Protocol plugins are
no longer available in the plugins ui, and no protocols are compiled statically
by default.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Mon, 30 Sep 2002 01:05:18 +0000 |
parents | 82180bb28f1f |
children | bb966d68f9e3 |
rev | line source |
---|---|
2681 | 1 /* |
2 * gaim | |
3 * | |
4 * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
5 * libfaim code copyright 1998, 1999 Adam Fritzler <afritz@auk.cx> | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 * | |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include "config.h" | |
25 #endif | |
26 | |
27 | |
28 #include <netdb.h> | |
29 #include <unistd.h> | |
30 #include <errno.h> | |
31 #include <netinet/in.h> | |
32 #include <arpa/inet.h> | |
33 #include <string.h> | |
34 #include <stdlib.h> | |
35 #include <stdio.h> | |
36 #include <time.h> | |
37 #include <sys/socket.h> | |
38 #include <sys/stat.h> | |
39 #include <ctype.h> | |
40 #include "multi.h" | |
41 #include "prpl.h" | |
42 #include "gaim.h" | |
43 #include "proxy.h" | |
3147 | 44 #include "md5.h" |
2681 | 45 |
2795
536bb833fdeb
[gaim-migrate @ 2808]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2786
diff
changeset
|
46 extern char *yahoo_crypt(char *, char *); |
536bb833fdeb
[gaim-migrate @ 2808]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2786
diff
changeset
|
47 |
2681 | 48 #include "pixmaps/status-away.xpm" |
49 #include "pixmaps/status-here.xpm" | |
50 #include "pixmaps/status-idle.xpm" | |
3019 | 51 #include "pixmaps/status-game.xpm" |
2681 | 52 |
3035 | 53 /* Yahoo Smilies go here */ |
54 #include "pixmaps/protocols/yahoo/yahoo_alien.xpm" | |
55 #include "pixmaps/protocols/yahoo/yahoo_angel.xpm" | |
56 #include "pixmaps/protocols/yahoo/yahoo_angry.xpm" | |
57 #include "pixmaps/protocols/yahoo/yahoo_bigsmile.xpm" | |
58 #include "pixmaps/protocols/yahoo/yahoo_blush.xpm" | |
59 #include "pixmaps/protocols/yahoo/yahoo_bye.xpm" | |
60 #include "pixmaps/protocols/yahoo/yahoo_clown.xpm" | |
61 #include "pixmaps/protocols/yahoo/yahoo_cow.xpm" | |
62 #include "pixmaps/protocols/yahoo/yahoo_cowboy.xpm" | |
63 #include "pixmaps/protocols/yahoo/yahoo_cry.xpm" | |
64 #include "pixmaps/protocols/yahoo/yahoo_devil.xpm" | |
65 #include "pixmaps/protocols/yahoo/yahoo_flower.xpm" | |
66 #include "pixmaps/protocols/yahoo/yahoo_ghost.xpm" | |
67 #include "pixmaps/protocols/yahoo/yahoo_glasses.xpm" | |
68 #include "pixmaps/protocols/yahoo/yahoo_laughloud.xpm" | |
69 #include "pixmaps/protocols/yahoo/yahoo_love.xpm" | |
70 #include "pixmaps/protocols/yahoo/yahoo_mean.xpm" | |
71 #include "pixmaps/protocols/yahoo/yahoo_neutral.xpm" | |
72 #include "pixmaps/protocols/yahoo/yahoo_ooooh.xpm" | |
73 #include "pixmaps/protocols/yahoo/yahoo_question.xpm" | |
74 #include "pixmaps/protocols/yahoo/yahoo_sad.xpm" | |
75 #include "pixmaps/protocols/yahoo/yahoo_sleep.xpm" | |
76 #include "pixmaps/protocols/yahoo/yahoo_smiley.xpm" | |
77 #include "pixmaps/protocols/yahoo/yahoo_sunglas.xpm" | |
78 #include "pixmaps/protocols/yahoo/yahoo_tongue.xpm" | |
79 #include "pixmaps/protocols/yahoo/yahoo_wink.xpm" | |
80 | |
2993 | 81 #define YAHOO_DEBUG |
2681 | 82 |
83 #define USEROPT_MAIL 0 | |
84 | |
85 #define USEROPT_PAGERHOST 3 | |
3147 | 86 #define YAHOO_PAGER_HOST "scs.yahoo.com" |
2681 | 87 #define USEROPT_PAGERPORT 4 |
88 #define YAHOO_PAGER_PORT 5050 | |
89 | |
3467 | 90 #define YAHOO_PROTO_VER 0x0900 |
91 | |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
92 enum yahoo_service { /* these are easier to see in hex */ |
2681 | 93 YAHOO_SERVICE_LOGON = 1, |
94 YAHOO_SERVICE_LOGOFF, | |
95 YAHOO_SERVICE_ISAWAY, | |
96 YAHOO_SERVICE_ISBACK, | |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
97 YAHOO_SERVICE_IDLE, /* 5 (placemarker) */ |
2681 | 98 YAHOO_SERVICE_MESSAGE, |
99 YAHOO_SERVICE_IDACT, | |
100 YAHOO_SERVICE_IDDEACT, | |
101 YAHOO_SERVICE_MAILSTAT, | |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
102 YAHOO_SERVICE_USERSTAT, /* 0xa */ |
2681 | 103 YAHOO_SERVICE_NEWMAIL, |
104 YAHOO_SERVICE_CHATINVITE, | |
105 YAHOO_SERVICE_CALENDAR, | |
106 YAHOO_SERVICE_NEWPERSONALMAIL, | |
107 YAHOO_SERVICE_NEWCONTACT, | |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
108 YAHOO_SERVICE_ADDIDENT, /* 0x10 */ |
2681 | 109 YAHOO_SERVICE_ADDIGNORE, |
110 YAHOO_SERVICE_PING, | |
111 YAHOO_SERVICE_GROUPRENAME, | |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
112 YAHOO_SERVICE_SYSMESSAGE = 0x14, |
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
113 YAHOO_SERVICE_PASSTHROUGH2 = 0x16, |
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
114 YAHOO_SERVICE_CONFINVITE = 0x18, |
2681 | 115 YAHOO_SERVICE_CONFLOGON, |
116 YAHOO_SERVICE_CONFDECLINE, | |
117 YAHOO_SERVICE_CONFLOGOFF, | |
118 YAHOO_SERVICE_CONFADDINVITE, | |
119 YAHOO_SERVICE_CONFMSG, | |
120 YAHOO_SERVICE_CHATLOGON, | |
121 YAHOO_SERVICE_CHATLOGOFF, | |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
122 YAHOO_SERVICE_CHATMSG = 0x20, |
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
123 YAHOO_SERVICE_GAMELOGON = 0x28, |
2786
318f846120e2
[gaim-migrate @ 2799]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2772
diff
changeset
|
124 YAHOO_SERVICE_GAMELOGOFF, |
318f846120e2
[gaim-migrate @ 2799]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2772
diff
changeset
|
125 YAHOO_SERVICE_GAMEMSG = 0x2a, |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
126 YAHOO_SERVICE_FILETRANSFER = 0x46, |
3019 | 127 YAHOO_SERVICE_NOTIFY = 0x4B, |
3147 | 128 YAHOO_SERVICE_AUTHRESP = 0x54, |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
129 YAHOO_SERVICE_LIST = 0x55, |
3147 | 130 YAHOO_SERVICE_AUTH = 0x57, |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
131 YAHOO_SERVICE_ADDBUDDY = 0x83, |
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
132 YAHOO_SERVICE_REMBUDDY = 0x84 |
2681 | 133 }; |
134 | |
135 enum yahoo_status { | |
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
136 YAHOO_STATUS_AVAILABLE = 0, |
2681 | 137 YAHOO_STATUS_BRB, |
138 YAHOO_STATUS_BUSY, | |
139 YAHOO_STATUS_NOTATHOME, | |
140 YAHOO_STATUS_NOTATDESK, | |
141 YAHOO_STATUS_NOTINOFFICE, | |
142 YAHOO_STATUS_ONPHONE, | |
143 YAHOO_STATUS_ONVACATION, | |
144 YAHOO_STATUS_OUTTOLUNCH, | |
145 YAHOO_STATUS_STEPPEDOUT, | |
146 YAHOO_STATUS_INVISIBLE = 12, | |
147 YAHOO_STATUS_CUSTOM = 99, | |
148 YAHOO_STATUS_IDLE = 999, | |
2993 | 149 YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */ |
150 YAHOO_STATUS_TYPING = 0x16 | |
2681 | 151 }; |
3019 | 152 #define YAHOO_STATUS_GAME 0x2 /* Games don't fit into the regular status model */ |
2681 | 153 |
154 struct yahoo_data { | |
155 int fd; | |
156 guchar *rxqueue; | |
157 int rxlen; | |
158 GHashTable *hash; | |
3019 | 159 GHashTable *games; |
2681 | 160 int current_status; |
161 gboolean logged_in; | |
162 }; | |
163 | |
164 struct yahoo_pair { | |
165 int key; | |
166 char *value; | |
167 }; | |
168 | |
169 struct yahoo_packet { | |
170 guint16 service; | |
171 guint32 status; | |
172 guint32 id; | |
173 GSList *hash; | |
174 }; | |
175 | |
176 #define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4) | |
177 | |
178 static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id) | |
179 { | |
180 struct yahoo_packet *pkt = g_new0(struct yahoo_packet, 1); | |
181 | |
182 pkt->service = service; | |
183 pkt->status = status; | |
184 pkt->id = id; | |
185 | |
186 return pkt; | |
187 } | |
188 | |
3466 | 189 static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value) |
2681 | 190 { |
191 struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); | |
192 pair->key = key; | |
193 pair->value = g_strdup(value); | |
194 pkt->hash = g_slist_append(pkt->hash, pair); | |
195 } | |
196 | |
197 static int yahoo_packet_length(struct yahoo_packet *pkt) | |
198 { | |
199 GSList *l; | |
200 | |
201 int len = 0; | |
202 | |
203 l = pkt->hash; | |
204 while (l) { | |
205 struct yahoo_pair *pair = l->data; | |
206 int tmp = pair->key; | |
207 do { | |
208 tmp /= 10; | |
209 len++; | |
210 } while (tmp); | |
211 len += 2; | |
212 len += strlen(pair->value); | |
213 len += 2; | |
214 l = l->next; | |
215 } | |
216 | |
217 return len; | |
218 } | |
219 | |
220 /* sometimes i wish prpls could #include things from other prpls. then i could just | |
221 * use the routines from libfaim and not have to admit to knowing how they work. */ | |
222 #define yahoo_put16(buf, data) ( \ | |
223 (*(buf) = (u_char)((data)>>8)&0xff), \ | |
224 (*((buf)+1) = (u_char)(data)&0xff), \ | |
225 2) | |
226 #define yahoo_get16(buf) ((((*(buf))<<8)&0xff00) + ((*((buf)+1)) & 0xff)) | |
227 #define yahoo_put32(buf, data) ( \ | |
228 (*((buf)) = (u_char)((data)>>24)&0xff), \ | |
229 (*((buf)+1) = (u_char)((data)>>16)&0xff), \ | |
230 (*((buf)+2) = (u_char)((data)>>8)&0xff), \ | |
231 (*((buf)+3) = (u_char)(data)&0xff), \ | |
232 4) | |
233 #define yahoo_get32(buf) ((((*(buf))<<24)&0xff000000) + \ | |
234 (((*((buf)+1))<<16)&0x00ff0000) + \ | |
235 (((*((buf)+2))<< 8)&0x0000ff00) + \ | |
236 (((*((buf)+3) )&0x000000ff))) | |
237 | |
238 static void yahoo_packet_read(struct yahoo_packet *pkt, guchar *data, int len) | |
239 { | |
240 int pos = 0; | |
241 | |
242 while (pos + 1 < len) { | |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
243 char key[64], *value = NULL; |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
244 int accept; |
2681 | 245 int x; |
246 | |
247 struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); | |
248 | |
249 x = 0; | |
250 while (pos + 1 < len) { | |
251 if (data[pos] == 0xc0 && data[pos + 1] == 0x80) | |
252 break; | |
253 key[x++] = data[pos++]; | |
254 } | |
255 key[x] = 0; | |
256 pos += 2; | |
257 pair->key = strtol(key, NULL, 10); | |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
258 accept = x; /* if x is 0 there was no key, so don't accept it */ |
2681 | 259 |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
260 if (accept) |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
261 value = g_malloc(len - pos + 1); |
2681 | 262 x = 0; |
263 while (pos + 1 < len) { | |
264 if (data[pos] == 0xc0 && data[pos + 1] == 0x80) | |
265 break; | |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
266 if (accept) |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
267 value[x++] = data[pos++]; |
2681 | 268 } |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
269 if (accept) |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
270 value[x] = 0; |
2681 | 271 pos += 2; |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
272 if (accept) { |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
273 pair->value = g_strdup(value); |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
274 g_free(value); |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
275 pkt->hash = g_slist_append(pkt->hash, pair); |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
276 debug_printf("Key: %d \tValue: %s\n", pair->key, pair->value); |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
277 } else { |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
278 g_free(pair); |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
279 } |
2681 | 280 } |
281 } | |
282 | |
283 static void yahoo_packet_write(struct yahoo_packet *pkt, guchar *data) | |
284 { | |
285 GSList *l = pkt->hash; | |
286 int pos = 0; | |
287 | |
288 while (l) { | |
289 struct yahoo_pair *pair = l->data; | |
290 guchar buf[100]; | |
291 | |
292 g_snprintf(buf, sizeof(buf), "%d", pair->key); | |
293 strcpy(data + pos, buf); | |
294 pos += strlen(buf); | |
295 data[pos++] = 0xc0; | |
296 data[pos++] = 0x80; | |
297 | |
298 strcpy(data + pos, pair->value); | |
299 pos += strlen(pair->value); | |
300 data[pos++] = 0xc0; | |
301 data[pos++] = 0x80; | |
302 | |
303 l = l->next; | |
304 } | |
305 } | |
306 | |
307 static void yahoo_packet_dump(guchar *data, int len) | |
308 { | |
309 #ifdef YAHOO_DEBUG | |
310 int i; | |
311 for (i = 0; i + 1 < len; i += 2) { | |
312 if ((i % 16 == 0) && i) | |
313 debug_printf("\n"); | |
314 debug_printf("%02x", data[i]); | |
315 debug_printf("%02x ", data[i+1]); | |
316 } | |
317 if (i < len) | |
318 debug_printf("%02x", data[i]); | |
319 debug_printf("\n"); | |
320 for (i = 0; i < len; i++) { | |
321 if ((i % 16 == 0) && i) | |
322 debug_printf("\n"); | |
323 if (isprint(data[i])) | |
324 debug_printf("%c ", data[i]); | |
325 else | |
326 debug_printf(". "); | |
327 } | |
328 debug_printf("\n"); | |
329 #endif | |
330 } | |
331 | |
332 static int yahoo_send_packet(struct yahoo_data *yd, struct yahoo_packet *pkt) | |
333 { | |
334 int pktlen = yahoo_packet_length(pkt); | |
335 int len = YAHOO_PACKET_HDRLEN + pktlen; | |
336 int ret; | |
337 | |
338 guchar *data; | |
339 int pos = 0; | |
340 | |
341 if (yd->fd < 0) | |
342 return -1; | |
343 | |
344 data = g_malloc0(len + 1); | |
345 | |
346 memcpy(data + pos, "YMSG", 4); pos += 4; | |
3467 | 347 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); |
2681 | 348 pos += yahoo_put16(data + pos, 0x0000); |
349 pos += yahoo_put16(data + pos, pktlen); | |
350 pos += yahoo_put16(data + pos, pkt->service); | |
351 pos += yahoo_put32(data + pos, pkt->status); | |
352 pos += yahoo_put32(data + pos, pkt->id); | |
353 | |
354 yahoo_packet_write(pkt, data + pos); | |
355 | |
356 yahoo_packet_dump(data, len); | |
357 ret = write(yd->fd, data, len); | |
358 | |
359 g_free(data); | |
360 | |
361 return ret; | |
362 } | |
363 | |
364 static void yahoo_packet_free(struct yahoo_packet *pkt) | |
365 { | |
366 while (pkt->hash) { | |
367 struct yahoo_pair *pair = pkt->hash->data; | |
368 g_free(pair->value); | |
369 g_free(pair); | |
370 pkt->hash = g_slist_remove(pkt->hash, pair); | |
371 } | |
372 g_free(pkt); | |
373 } | |
374 | |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
375 static void yahoo_process_status(struct gaim_connection *gc, struct yahoo_packet *pkt) |
2681 | 376 { |
377 struct yahoo_data *yd = gc->proto_data; | |
378 GSList *l = pkt->hash; | |
379 char *name = NULL; | |
380 int state = 0; | |
3019 | 381 int gamestate = 0; |
2681 | 382 char *msg = NULL; |
3019 | 383 |
2681 | 384 while (l) { |
385 struct yahoo_pair *pair = l->data; | |
386 | |
387 switch (pair->key) { | |
388 case 0: /* we won't actually do anything with this */ | |
389 break; | |
390 case 1: /* we don't get the full buddy list here. */ | |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
391 if (!yd->logged_in) { |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
392 account_online(gc); |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
393 serv_finish_login(gc); |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
394 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", pair->value); |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
395 yd->logged_in = TRUE; |
2681 | 396 |
3147 | 397 /* this requests the list. i have a feeling that this is very evil |
398 * | |
399 * scs.yahoo.com sends you the list before this packet without it being | |
400 * requested | |
401 * | |
402 * do_import(gc, NULL); | |
403 * newpkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_OFFLINE, 0); | |
404 * yahoo_send_packet(yd, newpkt); | |
405 * yahoo_packet_free(newpkt); | |
406 */ | |
407 | |
408 } | |
2681 | 409 break; |
410 case 8: /* how many online buddies we have */ | |
411 break; | |
412 case 7: /* the current buddy */ | |
413 name = pair->value; | |
414 break; | |
415 case 10: /* state */ | |
416 state = strtol(pair->value, NULL, 10); | |
417 break; | |
418 case 19: /* custom message */ | |
419 msg = pair->value; | |
420 break; | |
421 case 11: /* i didn't know what this was in the old protocol either */ | |
422 break; | |
423 case 17: /* in chat? */ | |
424 break; | |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
425 case 13: /* in pager? */ |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
426 if (pkt->service == YAHOO_SERVICE_LOGOFF || |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
427 strtol(pair->value, NULL, 10) == 0) { |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
428 serv_got_update(gc, name, 0, 0, 0, 0, 0, 0); |
2807
f01e6a425136
[gaim-migrate @ 2820]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2805
diff
changeset
|
429 break; |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
430 } |
3019 | 431 if (g_hash_table_lookup(yd->games, name)) |
432 gamestate = YAHOO_STATUS_GAME; | |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
433 if (state == YAHOO_STATUS_AVAILABLE) |
3019 | 434 serv_got_update(gc, name, 1, 0, 0, 0, gamestate, 0); |
3147 | 435 else |
3019 | 436 serv_got_update(gc, name, 1, 0, 0, 0, (state << 2) | UC_UNAVAILABLE | gamestate, 0); |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
437 if (state == YAHOO_STATUS_CUSTOM) { |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
438 gpointer val = g_hash_table_lookup(yd->hash, name); |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
439 if (val) { |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
440 g_free(val); |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
441 g_hash_table_insert(yd->hash, name, |
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
442 msg ? g_strdup(msg) : g_malloc0(1)); |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
443 } else |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
444 g_hash_table_insert(yd->hash, g_strdup(name), |
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
445 msg ? g_strdup(msg) : g_malloc0(1)); |
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
446 } |
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
447 break; |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
448 case 60: /* no clue */ |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
449 break; |
2979 | 450 case 16: /* Custom error message */ |
3427 | 451 do_error_dialog(pair->value, NULL, GAIM_ERROR); |
2951 | 452 break; |
2681 | 453 default: |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
454 debug_printf("unknown status key %d\n", pair->key); |
2681 | 455 break; |
456 } | |
457 | |
458 l = l->next; | |
459 } | |
460 } | |
461 | |
462 static void yahoo_process_list(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
463 { | |
464 GSList *l = pkt->hash; | |
465 gboolean export = FALSE; | |
466 | |
467 while (l) { | |
468 char **lines; | |
469 char **split; | |
470 char **buddies; | |
471 char **tmp, **bud; | |
472 | |
473 struct yahoo_pair *pair = l->data; | |
474 l = l->next; | |
475 | |
476 if (pair->key != 87) | |
477 continue; | |
478 | |
3147 | 479 do_import(gc, NULL); |
2681 | 480 lines = g_strsplit(pair->value, "\n", -1); |
481 for (tmp = lines; *tmp; tmp++) { | |
482 split = g_strsplit(*tmp, ":", 2); | |
2697
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
483 if (!split) |
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
484 continue; |
2702
94b4271b9567
[gaim-migrate @ 2715]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2697
diff
changeset
|
485 if (!split[0] || !split[1]) { |
2697
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
486 g_strfreev(split); |
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
487 continue; |
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
488 } |
2681 | 489 buddies = g_strsplit(split[1], ",", -1); |
2697
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
490 for (bud = buddies; bud && *bud; bud++) |
2681 | 491 if (!find_buddy(gc, *bud)) { |
492 add_buddy(gc, split[0], *bud, *bud); | |
493 export = TRUE; | |
494 } | |
495 g_strfreev(buddies); | |
496 g_strfreev(split); | |
497 } | |
498 g_strfreev(lines); | |
499 } | |
500 | |
501 if (export) | |
502 do_export(gc); | |
503 } | |
504 | |
3019 | 505 static void yahoo_process_notify(struct gaim_connection *gc, struct yahoo_packet *pkt) |
2993 | 506 { |
507 char *msg = NULL; | |
508 char *from = NULL; | |
3019 | 509 char *stat = NULL; |
510 char *game = NULL; | |
2993 | 511 GSList *l = pkt->hash; |
3019 | 512 struct yahoo_data *yd = (struct yahoo_data*) gc->proto_data; |
2993 | 513 while (l) { |
514 struct yahoo_pair *pair = l->data; | |
515 if (pair->key == 4) | |
516 from = pair->value; | |
517 if (pair->key == 49) | |
518 msg = pair->value; | |
3001 | 519 if (pair->key == 13) |
3019 | 520 stat = pair->value; |
521 if (pair->key == 14) | |
522 game = pair->value; | |
2993 | 523 l = l->next; |
524 } | |
3019 | 525 |
526 if (!g_strncasecmp(msg, "TYPING", strlen("TYPING"))) { | |
527 if (*stat == '1') | |
528 serv_got_typing(gc, from, 0); | |
529 else | |
530 serv_got_typing_stopped(gc, from); | |
531 } else if (!g_strncasecmp(msg, "GAME", strlen("GAME"))) { | |
532 struct buddy *bud = find_buddy(gc, from); | |
533 void *free1=NULL, *free2=NULL; | |
3020 | 534 if (!bud) |
3019 | 535 debug_printf("%s is playing a game, and doesn't want you to know.\n"); |
536 if (*stat == '1') { | |
537 if (g_hash_table_lookup_extended (yd->games, from, free1, free2)) { | |
538 g_free(free1); | |
539 g_free(free2); | |
540 } | |
541 g_hash_table_insert (yd->games, g_strdup(from), g_strdup(game)); | |
3020 | 542 if (bud) |
543 serv_got_update(gc, from, 1, 0, 0, 0, bud->uc | YAHOO_STATUS_GAME, 0); | |
3019 | 544 } else { |
545 if (g_hash_table_lookup_extended (yd->games, from, free1, free2)) { | |
546 g_free(free1); | |
547 g_free(free2); | |
548 g_hash_table_remove (yd->games, from); | |
549 } | |
3020 | 550 if (bud) |
551 serv_got_update(gc, from, 1, 0, 0, 0, bud->uc & ~YAHOO_STATUS_GAME, 0); | |
3019 | 552 } |
553 } | |
2993 | 554 } |
555 | |
2681 | 556 static void yahoo_process_message(struct gaim_connection *gc, struct yahoo_packet *pkt) |
557 { | |
558 char *msg = NULL; | |
559 char *from = NULL; | |
560 time_t tm = time(NULL); | |
561 GSList *l = pkt->hash; | |
3021 | 562 |
2681 | 563 while (l) { |
564 struct yahoo_pair *pair = l->data; | |
565 if (pair->key == 4) | |
566 from = pair->value; | |
567 if (pair->key == 14) | |
568 msg = pair->value; | |
569 if (pair->key == 15) | |
570 tm = strtol(pair->value, NULL, 10); | |
571 l = l->next; | |
572 } | |
573 | |
3021 | 574 if (pkt->status <= 1 || pkt->status == 5) { |
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
575 char *m; |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
576 int i, j; |
2681 | 577 strip_linefeed(msg); |
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
578 m = msg; |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
579 for (i = 0, j = 0; m[i]; i++) { |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
580 if (m[i] == 033) { |
2813
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
581 while (m[i] && (m[i] != 'm')) |
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
582 i++; |
2813
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
583 if (!m[i]) |
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
584 i--; |
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
585 continue; |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
586 } |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
587 msg[j++] = m[i]; |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
588 } |
2813
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
589 msg[j] = 0; |
3493 | 590 serv_got_im(gc, from, utf8_to_str(msg), 0, tm, -1); |
2681 | 591 } else if (pkt->status == 2) { |
3427 | 592 do_error_dialog(_("Your Yahoo! message did not get sent."), NULL, GAIM_ERROR); |
2681 | 593 } |
594 } | |
595 | |
596 | |
597 static void yahoo_process_contact(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
598 { | |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
599 struct yahoo_data *yd = gc->proto_data; |
2681 | 600 char *id = NULL; |
601 char *who = NULL; | |
602 char *msg = NULL; | |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
603 char *name = NULL; |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
604 int state = YAHOO_STATUS_AVAILABLE; |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
605 int online = FALSE; |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
606 |
2681 | 607 GSList *l = pkt->hash; |
608 | |
609 while (l) { | |
610 struct yahoo_pair *pair = l->data; | |
611 if (pair->key == 1) | |
612 id = pair->value; | |
613 else if (pair->key == 3) | |
614 who = pair->value; | |
615 else if (pair->key == 14) | |
616 msg = pair->value; | |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
617 else if (pair->key == 7) |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
618 name = pair->value; |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
619 else if (pair->key == 10) |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
620 state = strtol(pair->value, NULL, 10); |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
621 else if (pair->key == 13) |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
622 online = strtol(pair->value, NULL, 10); |
2681 | 623 l = l->next; |
624 } | |
625 | |
2682
db2b0b733732
[gaim-migrate @ 2695]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2681
diff
changeset
|
626 if (id) |
db2b0b733732
[gaim-migrate @ 2695]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2681
diff
changeset
|
627 show_got_added(gc, id, who, NULL, msg); |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
628 if (name) { |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
629 if (state == YAHOO_STATUS_AVAILABLE) |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
630 serv_got_update(gc, name, 1, 0, 0, 0, 0, 0); |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
631 else if (state == YAHOO_STATUS_IDLE) |
3019 | 632 serv_got_update(gc, name, 1, 0, 0, time(NULL) - 600, (state << 2), 0); |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
633 else |
3019 | 634 serv_got_update(gc, name, 1, 0, 0, 0, (state << 2) | UC_UNAVAILABLE, 0); |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
635 if (state == YAHOO_STATUS_CUSTOM) { |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
636 gpointer val = g_hash_table_lookup(yd->hash, name); |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
637 if (val) { |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
638 g_free(val); |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
639 g_hash_table_insert(yd->hash, name, |
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
640 msg ? g_strdup(msg) : g_malloc0(1)); |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
641 } else |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
642 g_hash_table_insert(yd->hash, g_strdup(name), |
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
643 msg ? g_strdup(msg) : g_malloc0(1)); |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
644 } |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
645 } |
2681 | 646 } |
647 | |
648 static void yahoo_process_mail(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
649 { | |
650 char *who = NULL; | |
651 char *email = NULL; | |
652 char *subj = NULL; | |
653 int count = 0; | |
654 GSList *l = pkt->hash; | |
655 | |
656 while (l) { | |
657 struct yahoo_pair *pair = l->data; | |
658 if (pair->key == 9) | |
659 count = strtol(pair->value, NULL, 10); | |
660 else if (pair->key == 43) | |
661 who = pair->value; | |
662 else if (pair->key == 42) | |
663 email = pair->value; | |
664 else if (pair->key == 18) | |
665 subj = pair->value; | |
666 l = l->next; | |
667 } | |
668 | |
2850
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
669 if (who && email && subj) { |
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
670 char *from = g_strdup_printf("%s (%s)", who, email); |
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
671 connection_has_mail(gc, -1, from, subj, "http://mail.yahoo.com/"); |
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
672 g_free(from); |
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
673 } else |
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
674 connection_has_mail(gc, count, NULL, NULL, "http://mail.yahoo.com/"); |
2681 | 675 } |
3147 | 676 /* This is the y64 alphabet... it's like base64, but has a . and a _ */ |
677 char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._"; | |
678 | |
679 /* This is taken from Sylpheed by Hiroyuki Yamamoto. We have our own tobase64 function | |
680 * in util.c, but it has a bug I don't feel like finding right now ;) */ | |
681 void to_y64(unsigned char *out, const unsigned char *in, int inlen) | |
682 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ | |
683 { | |
684 for (; inlen >= 3; inlen -= 3) | |
685 { | |
686 *out++ = base64digits[in[0] >> 2]; | |
687 *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; | |
688 *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; | |
689 *out++ = base64digits[in[2] & 0x3f]; | |
690 in += 3; | |
691 } | |
692 if (inlen > 0) | |
693 { | |
694 unsigned char fragment; | |
695 | |
696 *out++ = base64digits[in[0] >> 2]; | |
697 fragment = (in[0] << 4) & 0x30; | |
698 if (inlen > 1) | |
699 fragment |= in[1] >> 4; | |
700 *out++ = base64digits[fragment]; | |
701 *out++ = (inlen < 2) ? '-' : base64digits[(in[1] << 2) & 0x3c]; | |
702 *out++ = '-'; | |
703 } | |
704 *out = '\0'; | |
705 } | |
706 | |
707 static void yahoo_process_auth(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
708 { | |
709 char *seed = NULL; | |
710 char *sn = NULL; | |
711 GSList *l = pkt->hash; | |
712 struct yahoo_data *yd = gc->proto_data; | |
713 | |
714 while (l) { | |
715 struct yahoo_pair *pair = l->data; | |
716 if (pair->key == 94) | |
717 seed = pair->value; | |
718 if (pair->key == 1) | |
719 sn = pair->value; | |
720 l = l->next; | |
721 } | |
722 | |
723 if (seed) { | |
724 struct yahoo_packet *pack; | |
725 | |
726 /* So, Yahoo has stopped supporting its older clients in India, and undoubtedly | |
727 * will soon do so in the rest of the world. | |
728 * | |
729 * The new clients use this authentication method. I warn you in advance, it's | |
730 * bizzare, convoluted, inordinately complicated. It's also no more secure than | |
731 * crypt() was. The only purpose this scheme could serve is to prevent third | |
732 * part clients from connecting to their servers. | |
733 * | |
734 * Sorry, Yahoo. | |
735 */ | |
736 | |
737 md5_byte_t result[16]; | |
738 md5_state_t ctx; | |
739 char *crypt_result; | |
740 char *password_hash = g_malloc(25); | |
741 char *crypt_hash = g_malloc(25); | |
742 char *hash_string_p = g_malloc(50 + strlen(sn)); | |
743 char *hash_string_c = g_malloc(50 + strlen(sn)); | |
744 | |
745 char checksum; | |
746 | |
3157 | 747 int sv; |
3147 | 748 |
749 char *result6 = g_malloc(25); | |
750 char *result96 = g_malloc(25); | |
751 | |
752 sv = seed[15]; | |
3157 | 753 sv = sv % 8; |
3147 | 754 |
755 md5_init(&ctx); | |
756 md5_append(&ctx, gc->password, strlen(gc->password)); | |
757 md5_finish(&ctx, result); | |
758 to_y64(password_hash, result, 16); | |
759 | |
760 md5_init(&ctx); | |
761 crypt_result = yahoo_crypt(gc->password, "$1$_2S43d5f$"); | |
762 md5_append(&ctx, crypt_result, strlen(crypt_result)); | |
763 md5_finish(&ctx, result); | |
764 to_y64(crypt_hash, result, 16); | |
3157 | 765 |
766 switch (sv) { | |
3147 | 767 case 1: |
768 case 6: | |
3157 | 769 checksum = seed[seed[9] % 16]; |
3147 | 770 g_snprintf(hash_string_p, strlen(sn) + 50, |
3157 | 771 "%c%s%s%s", checksum, gc->username, seed, password_hash); |
772 g_snprintf(hash_string_c, strlen(sn) + 50, | |
3147 | 773 "%c%s%s%s", checksum, gc->username, seed, crypt_hash); |
774 break; | |
775 case 2: | |
776 case 7: | |
3157 | 777 checksum = seed[seed[15] % 16]; |
3147 | 778 g_snprintf(hash_string_p, strlen(sn) + 50, |
3157 | 779 "%c%s%s%s", checksum, seed, password_hash, gc->username); |
780 g_snprintf(hash_string_c, strlen(sn) + 50, | |
781 "%c%s%s%s", checksum, seed, crypt_hash, gc->username); | |
782 break; | |
3147 | 783 case 3: |
3157 | 784 checksum = seed[seed[1] % 16]; |
3147 | 785 g_snprintf(hash_string_p, strlen(sn) + 50, |
3157 | 786 "%c%s%s%s", checksum, gc->username, password_hash, seed); |
787 g_snprintf(hash_string_c, strlen(sn) + 50, | |
788 "%c%s%s%s", checksum, gc->username, crypt_hash, seed); | |
789 break; | |
790 case 4: | |
791 checksum = seed[seed[3] % 16]; | |
792 g_snprintf(hash_string_p, strlen(sn) + 50, | |
793 "%c%s%s%s", checksum, password_hash, seed, gc->username); | |
3147 | 794 g_snprintf(hash_string_c, strlen(sn) + 50, |
3157 | 795 "%c%s%s%s", checksum, crypt_hash, seed, gc->username); |
796 break; | |
3147 | 797 case 0: |
798 case 5: | |
3157 | 799 checksum = seed[seed[7] % 16]; |
3147 | 800 g_snprintf(hash_string_p, strlen(sn) + 50, |
3157 | 801 "%c%s%s%s", checksum, password_hash, gc->username, seed); |
802 g_snprintf(hash_string_c, strlen(sn) + 50, | |
3147 | 803 "%c%s%s%s", checksum, crypt_hash, gc->username, seed); |
3157 | 804 break; |
3147 | 805 } |
3157 | 806 |
3147 | 807 md5_init(&ctx); |
3157 | 808 md5_append(&ctx, hash_string_p, strlen(hash_string_p)); |
3147 | 809 md5_finish(&ctx, result); |
810 to_y64(result6, result, 16); | |
811 | |
812 md5_init(&ctx); | |
813 md5_append(&ctx, hash_string_c, strlen(hash_string_c)); | |
814 md5_finish(&ctx, result); | |
815 to_y64(result96, result, 16); | |
816 | |
817 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); | |
818 yahoo_packet_hash(pack, 0, gc->username); | |
819 yahoo_packet_hash(pack, 6, result6); | |
820 yahoo_packet_hash(pack, 96, result96); | |
821 yahoo_packet_hash(pack, 1, gc->username); | |
822 | |
823 yahoo_send_packet(yd, pack); | |
824 | |
3523 | 825 g_free(result6); |
826 g_free(result96); | |
3147 | 827 g_free(password_hash); |
828 g_free(crypt_hash); | |
829 g_free(hash_string_p); | |
830 g_free(hash_string_c); | |
831 | |
832 yahoo_packet_free(pack); | |
833 } | |
834 } | |
2681 | 835 |
836 static void yahoo_packet_process(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
837 { | |
838 switch (pkt->service) | |
839 { | |
840 case YAHOO_SERVICE_LOGON: | |
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
841 case YAHOO_SERVICE_LOGOFF: |
2681 | 842 case YAHOO_SERVICE_ISAWAY: |
2737
f61c1f3a6afa
[gaim-migrate @ 2750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2724
diff
changeset
|
843 case YAHOO_SERVICE_ISBACK: |
3019 | 844 case YAHOO_SERVICE_GAMELOGON: |
845 case YAHOO_SERVICE_GAMELOGOFF: | |
2681 | 846 yahoo_process_status(gc, pkt); |
847 break; | |
3019 | 848 case YAHOO_SERVICE_NOTIFY: |
849 yahoo_process_notify(gc, pkt); | |
2993 | 850 break; |
2681 | 851 case YAHOO_SERVICE_MESSAGE: |
2786
318f846120e2
[gaim-migrate @ 2799]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2772
diff
changeset
|
852 case YAHOO_SERVICE_GAMEMSG: |
2681 | 853 yahoo_process_message(gc, pkt); |
854 break; | |
855 case YAHOO_SERVICE_NEWMAIL: | |
856 yahoo_process_mail(gc, pkt); | |
857 break; | |
858 case YAHOO_SERVICE_NEWCONTACT: | |
859 yahoo_process_contact(gc, pkt); | |
860 break; | |
861 case YAHOO_SERVICE_LIST: | |
862 yahoo_process_list(gc, pkt); | |
863 break; | |
3147 | 864 case YAHOO_SERVICE_AUTH: |
865 yahoo_process_auth(gc, pkt); | |
866 break; | |
2681 | 867 default: |
2741
38cb5fa48bec
[gaim-migrate @ 2754]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2737
diff
changeset
|
868 debug_printf("unhandled service 0x%02x\n", pkt->service); |
2681 | 869 break; |
870 } | |
871 } | |
872 | |
873 static void yahoo_pending(gpointer data, gint source, GaimInputCondition cond) | |
874 { | |
875 struct gaim_connection *gc = data; | |
876 struct yahoo_data *yd = gc->proto_data; | |
877 char buf[1024]; | |
878 int len; | |
879 | |
880 len = read(yd->fd, buf, sizeof(buf)); | |
881 | |
882 if (len <= 0) { | |
3074 | 883 hide_login_progress_error(gc, "Unable to read"); |
2681 | 884 signoff(gc); |
885 return; | |
886 } | |
887 | |
888 yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen); | |
889 memcpy(yd->rxqueue + yd->rxlen, buf, len); | |
890 yd->rxlen += len; | |
891 | |
892 while (1) { | |
893 struct yahoo_packet *pkt; | |
894 int pos = 0; | |
895 int pktlen; | |
896 | |
897 if (yd->rxlen < YAHOO_PACKET_HDRLEN) | |
898 return; | |
899 | |
900 pos += 4; /* YMSG */ | |
901 pos += 2; | |
902 pos += 2; | |
903 | |
904 pktlen = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
905 debug_printf("%d bytes to read, rxlen is %d\n", pktlen, yd->rxlen); | |
906 | |
907 if (yd->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) | |
908 return; | |
909 | |
910 yahoo_packet_dump(yd->rxqueue, YAHOO_PACKET_HDRLEN + pktlen); | |
911 | |
912 pkt = yahoo_packet_new(0, 0, 0); | |
913 | |
914 pkt->service = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
3021 | 915 pkt->status = yahoo_get32(yd->rxqueue + pos); pos += 4; |
2741
38cb5fa48bec
[gaim-migrate @ 2754]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2737
diff
changeset
|
916 debug_printf("Yahoo Service: 0x%02x Status: %d\n", pkt->service, pkt->status); |
2681 | 917 pkt->id = yahoo_get32(yd->rxqueue + pos); pos += 4; |
918 | |
919 yahoo_packet_read(pkt, yd->rxqueue + pos, pktlen); | |
920 | |
921 yd->rxlen -= YAHOO_PACKET_HDRLEN + pktlen; | |
922 if (yd->rxlen) { | |
923 char *tmp = g_memdup(yd->rxqueue + YAHOO_PACKET_HDRLEN + pktlen, yd->rxlen); | |
924 g_free(yd->rxqueue); | |
925 yd->rxqueue = tmp; | |
926 } else { | |
927 g_free(yd->rxqueue); | |
928 yd->rxqueue = NULL; | |
929 } | |
930 | |
931 yahoo_packet_process(gc, pkt); | |
932 | |
933 yahoo_packet_free(pkt); | |
934 } | |
935 } | |
936 | |
937 static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) | |
938 { | |
939 struct gaim_connection *gc = data; | |
940 struct yahoo_data *yd; | |
941 struct yahoo_packet *pkt; | |
942 | |
943 if (!g_slist_find(connections, gc)) { | |
944 close(source); | |
945 return; | |
946 } | |
947 | |
948 if (source < 0) { | |
949 hide_login_progress(gc, "Unable to connect"); | |
950 signoff(gc); | |
951 return; | |
952 } | |
953 | |
954 yd = gc->proto_data; | |
955 yd->fd = source; | |
956 | |
3147 | 957 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0); |
2681 | 958 |
959 yahoo_packet_hash(pkt, 1, gc->username); | |
960 yahoo_send_packet(yd, pkt); | |
961 | |
962 yahoo_packet_free(pkt); | |
963 | |
964 gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); | |
965 } | |
966 | |
967 static void yahoo_login(struct aim_user *user) { | |
968 struct gaim_connection *gc = new_gaim_conn(user); | |
969 struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); | |
970 | |
971 set_login_progress(gc, 1, "Connecting"); | |
972 | |
973 yd->fd = -1; | |
974 yd->hash = g_hash_table_new(g_str_hash, g_str_equal); | |
3019 | 975 yd->games = g_hash_table_new(g_str_hash, g_str_equal); |
2681 | 976 |
3193 | 977 |
978 if (!g_strncasecmp(user->proto_opt[USEROPT_PAGERHOST], "cs.yahoo.com", strlen("cs.yahoo.com"))) { | |
979 /* Figured out the new auth method -- cs.yahoo.com likes to disconnect on buddy remove and add now */ | |
2951 | 980 debug_printf("Setting new Yahoo! server.\n"); |
3193 | 981 g_snprintf(user->proto_opt[USEROPT_PAGERHOST], strlen("scs.yahoo.com") + 1, "scs.yahoo.com"); |
2951 | 982 save_prefs(); |
983 } | |
3147 | 984 |
985 | |
2951 | 986 if (proxy_connect(user->proto_opt[USEROPT_PAGERHOST][0] ? |
2681 | 987 user->proto_opt[USEROPT_PAGERHOST] : YAHOO_PAGER_HOST, |
988 user->proto_opt[USEROPT_PAGERPORT][0] ? | |
989 atoi(user->proto_opt[USEROPT_PAGERPORT]) : YAHOO_PAGER_PORT, | |
2688
98b1ac8ddea3
[gaim-migrate @ 2701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2687
diff
changeset
|
990 yahoo_got_connected, gc) < 0) { |
2681 | 991 hide_login_progress(gc, "Connection problem"); |
992 signoff(gc); | |
993 return; | |
994 } | |
995 | |
996 } | |
997 | |
998 static gboolean yahoo_destroy_hash(gpointer key, gpointer val, gpointer data) | |
999 { | |
1000 g_free(key); | |
1001 g_free(val); | |
1002 return TRUE; | |
1003 } | |
1004 | |
1005 static void yahoo_close(struct gaim_connection *gc) { | |
1006 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1007 g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); | |
1008 g_hash_table_destroy(yd->hash); | |
3019 | 1009 g_hash_table_foreach_remove(yd->games, yahoo_destroy_hash, NULL); |
1010 g_hash_table_destroy(yd->games); | |
2681 | 1011 if (yd->fd >= 0) |
1012 close(yd->fd); | |
1013 if (yd->rxqueue) | |
1014 g_free(yd->rxqueue); | |
2687
2d544f48146d
[gaim-migrate @ 2700]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2686
diff
changeset
|
1015 yd->rxlen = 0; |
2681 | 1016 if (gc->inpa) |
1017 gaim_input_remove(gc->inpa); | |
1018 g_free(yd); | |
1019 } | |
1020 | |
1021 static char **yahoo_list_icon(int uc) | |
1022 { | |
3019 | 1023 if ((uc >> 2) == YAHOO_STATUS_IDLE) |
2681 | 1024 return status_idle_xpm; |
3019 | 1025 else if (uc & UC_UNAVAILABLE) |
1026 return status_away_xpm; | |
1027 else if (uc & YAHOO_STATUS_GAME) | |
1028 return status_game_xpm; | |
1029 return status_here_xpm; | |
2681 | 1030 } |
1031 | |
1032 static char *yahoo_get_status_string(enum yahoo_status a) | |
1033 { | |
1034 switch (a) { | |
1035 case YAHOO_STATUS_BRB: | |
1036 return "Be Right Back"; | |
1037 case YAHOO_STATUS_BUSY: | |
1038 return "Busy"; | |
1039 case YAHOO_STATUS_NOTATHOME: | |
1040 return "Not At Home"; | |
1041 case YAHOO_STATUS_NOTATDESK: | |
1042 return "Not At Desk"; | |
1043 case YAHOO_STATUS_NOTINOFFICE: | |
1044 return "Not In Office"; | |
1045 case YAHOO_STATUS_ONPHONE: | |
1046 return "On Phone"; | |
1047 case YAHOO_STATUS_ONVACATION: | |
1048 return "On Vacation"; | |
1049 case YAHOO_STATUS_OUTTOLUNCH: | |
1050 return "Out To Lunch"; | |
1051 case YAHOO_STATUS_STEPPEDOUT: | |
1052 return "Stepped Out"; | |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
1053 case YAHOO_STATUS_INVISIBLE: |
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
1054 return "Invisible"; |
2879
5fc5123b7098
[gaim-migrate @ 2892]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2878
diff
changeset
|
1055 default: |
5fc5123b7098
[gaim-migrate @ 2892]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2878
diff
changeset
|
1056 return "Online"; |
2681 | 1057 } |
1058 } | |
1059 | |
3019 | 1060 static void yahoo_game(struct gaim_connection *gc, char *name) { |
1061 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1062 char *game = g_hash_table_lookup(yd->games, name); | |
1063 char *t; | |
1064 char url[256]; | |
1065 | |
1066 if (!game) | |
1067 return; | |
1068 t = game = g_strdup(strstr(game, "ante?room=")); | |
1069 while (*t != '\t') | |
1070 t++; | |
1071 *t = 0; | |
1072 g_snprintf(url, sizeof url, "http://games.yahoo.com/games/%s", game); | |
1073 open_url(NULL, url); | |
1074 g_free(game); | |
1075 } | |
2681 | 1076 static GList *yahoo_buddy_menu(struct gaim_connection *gc, char *who) |
1077 { | |
1078 GList *m = NULL; | |
1079 struct proto_buddy_menu *pbm; | |
1080 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1081 struct buddy *b = find_buddy(gc, who); /* this should never be null. if it is, | |
1082 segfault and get the bug report. */ | |
1083 static char buf[1024]; | |
3019 | 1084 static char buf2[1024]; |
1085 | |
1086 if (b->uc & UC_UNAVAILABLE && b->uc >> 2 != YAHOO_STATUS_IDLE) { | |
1087 pbm = g_new0(struct proto_buddy_menu, 1); | |
1088 if ((b->uc >> 2) != YAHOO_STATUS_CUSTOM) | |
1089 g_snprintf(buf, sizeof buf, | |
1090 "Status: %s", yahoo_get_status_string(b->uc >> 2)); | |
1091 else | |
1092 g_snprintf(buf, sizeof buf, "Custom Status: %s", | |
1093 (char *)g_hash_table_lookup(yd->hash, b->name)); | |
1094 pbm->label = buf; | |
1095 pbm->callback = NULL; | |
1096 pbm->gc = gc; | |
1097 m = g_list_append(m, pbm); | |
1098 } | |
1099 | |
1100 if (b->uc | YAHOO_STATUS_GAME) { | |
1101 char *game = g_hash_table_lookup(yd->games, b->name); | |
1102 char *room; | |
1103 if (!game) | |
1104 return m; | |
1105 if (game) { | |
1106 char *t; | |
1107 pbm = g_new0(struct proto_buddy_menu, 1); | |
1108 if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ | |
1109 return NULL; | |
1110 while (*room && *room != '\t') /* skip to the tab */ | |
1111 room++; | |
1112 t = room++; /* room as now at the name */ | |
1113 while (*t != '\n') | |
1114 t++; /* replace the \n with a space */ | |
1115 *t = ' '; | |
1116 g_snprintf(buf2, sizeof buf2, "%s", room); | |
1117 pbm->label = buf2; | |
1118 pbm->callback = yahoo_game; | |
1119 pbm->gc = gc; | |
1120 m = g_list_append(m, pbm); | |
1121 } | |
1122 } | |
2681 | 1123 |
1124 return m; | |
1125 } | |
1126 | |
1127 static void yahoo_act_id(gpointer data, char *entry) | |
1128 { | |
1129 struct gaim_connection *gc = data; | |
1130 struct yahoo_data *yd = gc->proto_data; | |
1131 | |
1132 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0); | |
1133 yahoo_packet_hash(pkt, 3, entry); | |
1134 yahoo_send_packet(yd, pkt); | |
1135 yahoo_packet_free(pkt); | |
1136 | |
1137 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", entry); | |
1138 } | |
1139 | |
1140 static void yahoo_do_action(struct gaim_connection *gc, char *act) | |
1141 { | |
1142 if (!strcmp(act, "Activate ID")) { | |
1143 do_prompt_dialog("Activate which ID:", gc->displayname, gc, yahoo_act_id, NULL); | |
1144 } | |
1145 } | |
1146 | |
1147 static GList *yahoo_actions() { | |
1148 GList *m = NULL; | |
1149 | |
1150 m = g_list_append(m, "Activate ID"); | |
1151 | |
1152 return m; | |
1153 } | |
1154 | |
3033 | 1155 static int yahoo_send_im(struct gaim_connection *gc, char *who, char *what, int len, int flags) |
2681 | 1156 { |
1157 struct yahoo_data *yd = gc->proto_data; | |
1158 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); | |
3493 | 1159 char *msg = str_to_utf8(what); |
2681 | 1160 |
1161 yahoo_packet_hash(pkt, 1, gc->displayname); | |
1162 yahoo_packet_hash(pkt, 5, who); | |
3493 | 1163 yahoo_packet_hash(pkt, 14, msg); |
2681 | 1164 |
1165 yahoo_send_packet(yd, pkt); | |
1166 | |
1167 yahoo_packet_free(pkt); | |
3493 | 1168 |
2681 | 1169 return 1; |
1170 } | |
1171 | |
3001 | 1172 int yahoo_send_typing(struct gaim_connection *gc, char *who, int typ) |
2993 | 1173 { |
1174 struct yahoo_data *yd = gc->proto_data; | |
3019 | 1175 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); |
2993 | 1176 yahoo_packet_hash(pkt, 49, "TYPING"); |
1177 yahoo_packet_hash(pkt, 1, gc->displayname); | |
1178 yahoo_packet_hash(pkt, 14, " "); | |
3001 | 1179 yahoo_packet_hash(pkt, 13, typ ? "1" : "0"); |
2993 | 1180 yahoo_packet_hash(pkt, 5, who); |
1181 yahoo_packet_hash(pkt, 1002, "1"); | |
1182 | |
1183 yahoo_send_packet(yd, pkt); | |
1184 | |
1185 yahoo_packet_free(pkt); | |
1186 | |
3001 | 1187 return 0; |
2993 | 1188 } |
1189 | |
2681 | 1190 static void yahoo_set_away(struct gaim_connection *gc, char *state, char *msg) |
1191 { | |
1192 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1193 struct yahoo_packet *pkt; | |
2772
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1194 int service; |
2681 | 1195 char s[4]; |
1196 | |
1197 gc->away = NULL; | |
1198 | |
1199 if (msg) { | |
1200 yd->current_status = YAHOO_STATUS_CUSTOM; | |
1201 gc->away = ""; | |
1202 } else if (state) { | |
1203 gc->away = ""; | |
1204 if (!strcmp(state, "Available")) { | |
1205 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
1206 gc->away = NULL; | |
1207 } else if (!strcmp(state, "Be Right Back")) { | |
1208 yd->current_status = YAHOO_STATUS_BRB; | |
1209 } else if (!strcmp(state, "Busy")) { | |
1210 yd->current_status = YAHOO_STATUS_BUSY; | |
1211 } else if (!strcmp(state, "Not At Home")) { | |
1212 yd->current_status = YAHOO_STATUS_NOTATHOME; | |
1213 } else if (!strcmp(state, "Not At Desk")) { | |
1214 yd->current_status = YAHOO_STATUS_NOTATDESK; | |
1215 } else if (!strcmp(state, "Not In Office")) { | |
1216 yd->current_status = YAHOO_STATUS_NOTINOFFICE; | |
1217 } else if (!strcmp(state, "On Phone")) { | |
1218 yd->current_status = YAHOO_STATUS_ONPHONE; | |
1219 } else if (!strcmp(state, "On Vacation")) { | |
1220 yd->current_status = YAHOO_STATUS_ONVACATION; | |
1221 } else if (!strcmp(state, "Out To Lunch")) { | |
1222 yd->current_status = YAHOO_STATUS_OUTTOLUNCH; | |
1223 } else if (!strcmp(state, "Stepped Out")) { | |
1224 yd->current_status = YAHOO_STATUS_STEPPEDOUT; | |
1225 } else if (!strcmp(state, "Invisible")) { | |
1226 yd->current_status = YAHOO_STATUS_INVISIBLE; | |
1227 } else if (!strcmp(state, GAIM_AWAY_CUSTOM)) { | |
1228 if (gc->is_idle) { | |
1229 yd->current_status = YAHOO_STATUS_IDLE; | |
1230 } else { | |
1231 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
1232 } | |
1233 gc->away = NULL; | |
1234 } | |
1235 } else if (gc->is_idle) { | |
1236 yd->current_status = YAHOO_STATUS_IDLE; | |
1237 } else { | |
1238 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
1239 } | |
1240 | |
2772
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1241 if (yd->current_status == YAHOO_STATUS_AVAILABLE) |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1242 service = YAHOO_SERVICE_ISBACK; |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1243 else |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1244 service = YAHOO_SERVICE_ISAWAY; |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1245 pkt = yahoo_packet_new(service, yd->current_status, 0); |
2681 | 1246 g_snprintf(s, sizeof(s), "%d", yd->current_status); |
1247 yahoo_packet_hash(pkt, 10, s); | |
1248 if (yd->current_status == YAHOO_STATUS_CUSTOM) | |
1249 yahoo_packet_hash(pkt, 19, msg); | |
1250 | |
1251 yahoo_send_packet(yd, pkt); | |
1252 yahoo_packet_free(pkt); | |
1253 } | |
1254 | |
1255 static void yahoo_set_idle(struct gaim_connection *gc, int idle) | |
1256 { | |
1257 struct yahoo_data *yd = gc->proto_data; | |
1258 struct yahoo_packet *pkt = NULL; | |
1259 | |
1260 if (idle && yd->current_status == YAHOO_STATUS_AVAILABLE) { | |
1261 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_IDLE, 0); | |
1262 yd->current_status = YAHOO_STATUS_IDLE; | |
1263 } else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) { | |
1264 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_AVAILABLE, 0); | |
1265 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
1266 } | |
1267 | |
1268 if (pkt) { | |
1269 char buf[4]; | |
1270 g_snprintf(buf, sizeof(buf), "%d", yd->current_status); | |
1271 yahoo_packet_hash(pkt, 10, buf); | |
1272 yahoo_send_packet(yd, pkt); | |
1273 yahoo_packet_free(pkt); | |
1274 } | |
1275 } | |
1276 | |
1277 static GList *yahoo_away_states(struct gaim_connection *gc) | |
1278 { | |
1279 GList *m = NULL; | |
1280 | |
1281 m = g_list_append(m, "Available"); | |
1282 m = g_list_append(m, "Be Right Back"); | |
1283 m = g_list_append(m, "Busy"); | |
1284 m = g_list_append(m, "Not At Home"); | |
1285 m = g_list_append(m, "Not At Desk"); | |
1286 m = g_list_append(m, "Not In Office"); | |
1287 m = g_list_append(m, "On Phone"); | |
1288 m = g_list_append(m, "On Vacation"); | |
1289 m = g_list_append(m, "Out To Lunch"); | |
1290 m = g_list_append(m, "Stepped Out"); | |
1291 m = g_list_append(m, "Invisible"); | |
1292 m = g_list_append(m, GAIM_AWAY_CUSTOM); | |
1293 | |
1294 return m; | |
1295 } | |
1296 | |
1297 static void yahoo_keepalive(struct gaim_connection *gc) | |
1298 { | |
1299 struct yahoo_data *yd = gc->proto_data; | |
1300 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); | |
1301 yahoo_send_packet(yd, pkt); | |
1302 yahoo_packet_free(pkt); | |
1303 } | |
1304 | |
3466 | 1305 static void yahoo_add_buddy(struct gaim_connection *gc, const char *who) |
2681 | 1306 { |
1307 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1308 struct yahoo_packet *pkt; | |
1309 struct group *g; | |
1310 char *group = NULL; | |
1311 | |
1312 if (!yd->logged_in) | |
1313 return; | |
1314 | |
1315 g = find_group_by_buddy(gc, who); | |
1316 if (g) | |
1317 group = g->name; | |
1318 else | |
1319 group = "Buddies"; | |
1320 | |
1321 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
1322 yahoo_packet_hash(pkt, 1, gc->displayname); | |
1323 yahoo_packet_hash(pkt, 7, who); | |
1324 yahoo_packet_hash(pkt, 65, group); | |
1325 yahoo_send_packet(yd, pkt); | |
1326 yahoo_packet_free(pkt); | |
1327 } | |
1328 | |
1329 static void yahoo_remove_buddy(struct gaim_connection *gc, char *who, char *group) | |
1330 { | |
1331 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1332 | |
1333 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
1334 yahoo_packet_hash(pkt, 1, gc->displayname); | |
1335 yahoo_packet_hash(pkt, 7, who); | |
1336 yahoo_packet_hash(pkt, 65, group); | |
1337 yahoo_send_packet(yd, pkt); | |
1338 yahoo_packet_free(pkt); | |
1339 } | |
1340 | |
3035 | 1341 |
1342 GSList *yahoo_smiley_list() | |
1343 { | |
1344 GSList *smilies = NULL; | |
1345 | |
1346 smilies = add_smiley(smilies, "=:)", yahoo_alien, 1); | |
1347 smilies = add_smiley(smilies, "=:-)", yahoo_alien, 0); | |
1348 smilies = add_smiley(smilies, "o:)", yahoo_angel, 0); | |
1349 smilies = add_smiley(smilies, "o:-)", yahoo_angel, 0); | |
1350 smilies = add_smiley(smilies, "0:)", yahoo_angel, 0); | |
1351 smilies = add_smiley(smilies, "0:-)", yahoo_angel, 0); | |
1352 smilies = add_smiley(smilies, "X-(", yahoo_angry, 1); | |
1353 smilies = add_smiley(smilies, "X(", yahoo_angry, 0); | |
1354 smilies = add_smiley(smilies, "x-(", yahoo_angry, 0); | |
1355 smilies = add_smiley(smilies, "x(", yahoo_angry, 0); | |
1356 smilies = add_smiley(smilies, ":D", yahoo_bigsmile, 1); | |
1357 smilies = add_smiley(smilies, ":-D", yahoo_bigsmile, 0); | |
1358 smilies = add_smiley(smilies, ":\">", yahoo_blush, 1); | |
1359 smilies = add_smiley(smilies, "=;", yahoo_bye, 1); | |
1360 smilies = add_smiley(smilies, ":o)", yahoo_clown, 1); | |
1361 smilies = add_smiley(smilies, ":0)", yahoo_clown, 0); | |
1362 smilies = add_smiley(smilies, ":O)", yahoo_clown, 0); | |
1363 smilies = add_smiley(smilies, "<@:)", yahoo_clown, 0); | |
1364 smilies = add_smiley(smilies, "3:-0", yahoo_cow, 1); | |
1365 smilies = add_smiley(smilies, "3:-o", yahoo_cow, 0); | |
1366 smilies = add_smiley(smilies, "3:-O", yahoo_cow, 0); | |
1367 smilies = add_smiley(smilies, "3:O", yahoo_cow, 0); | |
1368 smilies = add_smiley(smilies, "<):)", yahoo_cowboy, 1); | |
1369 smilies = add_smiley(smilies, ":((", yahoo_cry, 1); | |
1370 smilies = add_smiley(smilies, ":-((", yahoo_cry, 0); | |
1371 smilies = add_smiley(smilies, ">:)", yahoo_devil, 1); | |
1372 smilies = add_smiley(smilies, "@};-", yahoo_flower, 1); | |
1373 smilies = add_smiley(smilies, "8-X", yahoo_ghost, 1); | |
1374 smilies = add_smiley(smilies, ":B", yahoo_glasses, 1); | |
1375 smilies = add_smiley(smilies, ":-B", yahoo_glasses, 0); | |
1376 smilies = add_smiley(smilies, ":))", yahoo_laughloud, 1); | |
1377 smilies = add_smiley(smilies, ":-))", yahoo_laughloud, 0); | |
1378 smilies = add_smiley(smilies, ":x", yahoo_love, 1); | |
1379 smilies = add_smiley(smilies, ":-x", yahoo_love, 0); | |
1380 smilies = add_smiley(smilies, ":X", yahoo_love, 0); | |
1381 smilies = add_smiley(smilies, ":-X", yahoo_love, 0); | |
1382 smilies = add_smiley(smilies, ":>", yahoo_mean, 1); | |
1383 smilies = add_smiley(smilies, ":->", yahoo_mean, 0); | |
1384 smilies = add_smiley(smilies, ":|", yahoo_neutral, 1); | |
1385 smilies = add_smiley(smilies, ":-|", yahoo_neutral, 0); | |
1386 smilies = add_smiley(smilies, ":O", yahoo_ooooh, 1); | |
1387 smilies = add_smiley(smilies, ":-O", yahoo_ooooh, 0); | |
1388 smilies = add_smiley(smilies, ":-\\", yahoo_question, 1); | |
1389 smilies = add_smiley(smilies, ":-/", yahoo_question, 0); | |
1390 smilies = add_smiley(smilies, ":(", yahoo_sad, 1); | |
1391 smilies = add_smiley(smilies, ":-(", yahoo_sad, 0); | |
1392 smilies = add_smiley(smilies, "I-)", yahoo_sleep, 1); | |
1393 smilies = add_smiley(smilies, "|-)", yahoo_sleep, 0); | |
1394 smilies = add_smiley(smilies, "I-|", yahoo_sleep, 0); | |
1395 smilies = add_smiley(smilies, ":)", yahoo_smiley, 1); | |
1396 smilies = add_smiley(smilies, ":-)", yahoo_smiley, 0); | |
1397 smilies = add_smiley(smilies, "(:", yahoo_smiley, 0); | |
1398 smilies = add_smiley(smilies, "(-:", yahoo_smiley, 0); | |
1399 smilies = add_smiley(smilies, "B-)", yahoo_sunglas, 1); | |
1400 smilies = add_smiley(smilies, ":-p", yahoo_tongue, 1); | |
1401 smilies = add_smiley(smilies, ":p", yahoo_tongue, 0); | |
1402 smilies = add_smiley(smilies, ":P", yahoo_tongue, 0); | |
1403 smilies = add_smiley(smilies, ":-P", yahoo_tongue, 0); | |
1404 smilies = add_smiley(smilies, ";)", yahoo_wink, 1); | |
1405 smilies = add_smiley(smilies, ";-)", yahoo_wink, 0); | |
1406 | |
1407 | |
1408 return smilies; | |
1409 } | |
1410 | |
2681 | 1411 static struct prpl *my_protocol = NULL; |
1412 | |
1413 void yahoo_init(struct prpl *ret) { | |
3572 | 1414 struct proto_user_opt *puo; |
2681 | 1415 ret->protocol = PROTO_YAHOO; |
1416 ret->options = OPT_PROTO_MAIL_CHECK; | |
3572 | 1417 ret->name = g_strdup("Yahoo"); |
2681 | 1418 ret->login = yahoo_login; |
1419 ret->close = yahoo_close; | |
1420 ret->buddy_menu = yahoo_buddy_menu; | |
1421 ret->list_icon = yahoo_list_icon; | |
1422 ret->actions = yahoo_actions; | |
1423 ret->do_action = yahoo_do_action; | |
1424 ret->send_im = yahoo_send_im; | |
1425 ret->away_states = yahoo_away_states; | |
1426 ret->set_away = yahoo_set_away; | |
1427 ret->set_idle = yahoo_set_idle; | |
1428 ret->keepalive = yahoo_keepalive; | |
1429 ret->add_buddy = yahoo_add_buddy; | |
1430 ret->remove_buddy = yahoo_remove_buddy; | |
2993 | 1431 ret->send_typing = yahoo_send_typing; |
3035 | 1432 ret->smiley_list = yahoo_smiley_list; |
2681 | 1433 |
3572 | 1434 puo = g_new0(struct proto_user_opt, 1); |
1435 puo->label = g_strdup("Pager Host:"); | |
1436 puo->def = g_strdup(YAHOO_PAGER_HOST); | |
1437 puo->pos = USEROPT_PAGERHOST; | |
1438 ret->user_opts = g_list_append(ret->user_opts, puo); | |
1439 | |
1440 puo = g_new0(struct proto_user_opt, 1); | |
1441 puo->label = g_strdup("Pager Port:"); | |
1442 puo->def = g_strdup("5050"); | |
1443 puo->pos = USEROPT_PAGERPORT; | |
1444 ret->user_opts = g_list_append(ret->user_opts, puo); | |
1445 | |
2681 | 1446 my_protocol = ret; |
1447 } | |
1448 | |
1449 #ifndef STATIC | |
1450 | |
3572 | 1451 void *gaim_prpl_init(struct prpl *prpl) |
2681 | 1452 { |
3572 | 1453 yahoo_init(prpl); |
1454 prpl->plug->desc.api_version = PLUGIN_API_VERSION; | |
2681 | 1455 } |
1456 | |
1457 #endif |