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