Mercurial > pidgin.yaz
annotate src/protocols/yahoo/yahoo.c @ 4634:d19872836812
[gaim-migrate @ 4941]
This will let you set up different proxy settings for different accounts.
Mainly useful to the corporate users that need to connect to an internal
jabber server, and still want to connect to "external" stuff through a
proxy, or something along those lines. I'm sure someone will come up with
another use for it.
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Sun, 02 Mar 2003 18:48:02 +0000 |
parents | 5fcb44d771d2 |
children | 283fb289c510 |
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> | |
4608 | 44 #include "gaim.h" |
2681 | 45 #include "multi.h" |
46 #include "prpl.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 | |
467 lines = g_strsplit(pair->value, "\n", -1); | |
468 for (tmp = lines; *tmp; tmp++) { | |
469 split = g_strsplit(*tmp, ":", 2); | |
2697
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
470 if (!split) |
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
471 continue; |
2702
94b4271b9567
[gaim-migrate @ 2715]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2697
diff
changeset
|
472 if (!split[0] || !split[1]) { |
2697
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
473 g_strfreev(split); |
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
474 continue; |
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
475 } |
2681 | 476 buddies = g_strsplit(split[1], ",", -1); |
2697
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
477 for (bud = buddies; bud && *bud; bud++) |
4491 | 478 if (!find_buddy(gc->account, *bud)) { |
479 add_buddy(gc->account, split[0], *bud, *bud); | |
2681 | 480 export = TRUE; |
481 } | |
482 g_strfreev(buddies); | |
483 g_strfreev(split); | |
484 } | |
485 g_strfreev(lines); | |
486 } | |
487 | |
488 if (export) | |
4349 | 489 gaim_blist_save(); |
2681 | 490 } |
491 | |
3019 | 492 static void yahoo_process_notify(struct gaim_connection *gc, struct yahoo_packet *pkt) |
2993 | 493 { |
494 char *msg = NULL; | |
495 char *from = NULL; | |
3019 | 496 char *stat = NULL; |
497 char *game = NULL; | |
2993 | 498 GSList *l = pkt->hash; |
3019 | 499 struct yahoo_data *yd = (struct yahoo_data*) gc->proto_data; |
2993 | 500 while (l) { |
501 struct yahoo_pair *pair = l->data; | |
502 if (pair->key == 4) | |
503 from = pair->value; | |
504 if (pair->key == 49) | |
505 msg = pair->value; | |
3001 | 506 if (pair->key == 13) |
3019 | 507 stat = pair->value; |
508 if (pair->key == 14) | |
509 game = pair->value; | |
2993 | 510 l = l->next; |
511 } | |
3640 | 512 |
513 if (!msg) | |
514 return; | |
3019 | 515 |
516 if (!g_strncasecmp(msg, "TYPING", strlen("TYPING"))) { | |
517 if (*stat == '1') | |
3768 | 518 serv_got_typing(gc, from, 0, TYPING); |
3019 | 519 else |
520 serv_got_typing_stopped(gc, from); | |
521 } else if (!g_strncasecmp(msg, "GAME", strlen("GAME"))) { | |
4491 | 522 struct buddy *bud = find_buddy(gc->account, from); |
3019 | 523 void *free1=NULL, *free2=NULL; |
4201
511c2b63caa4
[gaim-migrate @ 4432]
Christian Hammond <chipx86@chipx86.com>
parents:
4115
diff
changeset
|
524 if (!bud) |
511c2b63caa4
[gaim-migrate @ 4432]
Christian Hammond <chipx86@chipx86.com>
parents:
4115
diff
changeset
|
525 debug_printf("%s is playing a game, and doesn't want you to know.\n", from); |
3019 | 526 if (*stat == '1') { |
527 if (g_hash_table_lookup_extended (yd->games, from, free1, free2)) { | |
528 g_free(free1); | |
529 g_free(free2); | |
530 } | |
531 g_hash_table_insert (yd->games, g_strdup(from), g_strdup(game)); | |
3020 | 532 if (bud) |
533 serv_got_update(gc, from, 1, 0, 0, 0, bud->uc | YAHOO_STATUS_GAME, 0); | |
3019 | 534 } else { |
535 if (g_hash_table_lookup_extended (yd->games, from, free1, free2)) { | |
536 g_free(free1); | |
537 g_free(free2); | |
538 g_hash_table_remove (yd->games, from); | |
539 } | |
3020 | 540 if (bud) |
541 serv_got_update(gc, from, 1, 0, 0, 0, bud->uc & ~YAHOO_STATUS_GAME, 0); | |
3019 | 542 } |
543 } | |
2993 | 544 } |
545 | |
2681 | 546 static void yahoo_process_message(struct gaim_connection *gc, struct yahoo_packet *pkt) |
547 { | |
548 char *msg = NULL; | |
549 char *from = NULL; | |
550 time_t tm = time(NULL); | |
551 GSList *l = pkt->hash; | |
3021 | 552 |
2681 | 553 while (l) { |
554 struct yahoo_pair *pair = l->data; | |
555 if (pair->key == 4) | |
556 from = pair->value; | |
557 if (pair->key == 14) | |
558 msg = pair->value; | |
559 if (pair->key == 15) | |
560 tm = strtol(pair->value, NULL, 10); | |
561 l = l->next; | |
562 } | |
563 | |
3021 | 564 if (pkt->status <= 1 || pkt->status == 5) { |
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
565 char *m; |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
566 int i, j; |
2681 | 567 strip_linefeed(msg); |
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
568 m = msg; |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
569 for (i = 0, j = 0; m[i]; i++) { |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
570 if (m[i] == 033) { |
2813
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
571 while (m[i] && (m[i] != 'm')) |
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
572 i++; |
2813
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
573 if (!m[i]) |
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
574 i--; |
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
575 continue; |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
576 } |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
577 msg[j++] = m[i]; |
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
578 } |
2813
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
579 msg[j] = 0; |
3642 | 580 serv_got_im(gc, from, g_strdup(msg), 0, tm, -1); |
2681 | 581 } else if (pkt->status == 2) { |
3427 | 582 do_error_dialog(_("Your Yahoo! message did not get sent."), NULL, GAIM_ERROR); |
2681 | 583 } |
584 } | |
585 | |
586 | |
587 static void yahoo_process_contact(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
588 { | |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
589 struct yahoo_data *yd = gc->proto_data; |
2681 | 590 char *id = NULL; |
591 char *who = NULL; | |
592 char *msg = NULL; | |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
593 char *name = NULL; |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
594 int state = YAHOO_STATUS_AVAILABLE; |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
595 int online = FALSE; |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
596 |
2681 | 597 GSList *l = pkt->hash; |
598 | |
599 while (l) { | |
600 struct yahoo_pair *pair = l->data; | |
601 if (pair->key == 1) | |
602 id = pair->value; | |
603 else if (pair->key == 3) | |
604 who = pair->value; | |
605 else if (pair->key == 14) | |
606 msg = pair->value; | |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
607 else if (pair->key == 7) |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
608 name = pair->value; |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
609 else if (pair->key == 10) |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
610 state = strtol(pair->value, NULL, 10); |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
611 else if (pair->key == 13) |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
612 online = strtol(pair->value, NULL, 10); |
2681 | 613 l = l->next; |
614 } | |
615 | |
2682
db2b0b733732
[gaim-migrate @ 2695]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2681
diff
changeset
|
616 if (id) |
db2b0b733732
[gaim-migrate @ 2695]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2681
diff
changeset
|
617 show_got_added(gc, id, who, NULL, msg); |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
618 if (name) { |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
619 if (state == YAHOO_STATUS_AVAILABLE) |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
620 serv_got_update(gc, name, 1, 0, 0, 0, 0, 0); |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
621 else if (state == YAHOO_STATUS_IDLE) |
3019 | 622 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
|
623 else |
3019 | 624 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
|
625 if (state == YAHOO_STATUS_CUSTOM) { |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
626 gpointer val = g_hash_table_lookup(yd->hash, name); |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
627 if (val) { |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
628 g_free(val); |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
629 g_hash_table_insert(yd->hash, name, |
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
630 msg ? g_strdup(msg) : g_malloc0(1)); |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
631 } else |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
632 g_hash_table_insert(yd->hash, g_strdup(name), |
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
633 msg ? g_strdup(msg) : g_malloc0(1)); |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
634 } |
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
635 } |
2681 | 636 } |
637 | |
638 static void yahoo_process_mail(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
639 { | |
640 char *who = NULL; | |
641 char *email = NULL; | |
642 char *subj = NULL; | |
643 int count = 0; | |
644 GSList *l = pkt->hash; | |
645 | |
646 while (l) { | |
647 struct yahoo_pair *pair = l->data; | |
648 if (pair->key == 9) | |
649 count = strtol(pair->value, NULL, 10); | |
650 else if (pair->key == 43) | |
651 who = pair->value; | |
652 else if (pair->key == 42) | |
653 email = pair->value; | |
654 else if (pair->key == 18) | |
655 subj = pair->value; | |
656 l = l->next; | |
657 } | |
658 | |
4001 | 659 if (who && subj && email && *email) { |
2850
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
660 char *from = g_strdup_printf("%s (%s)", who, email); |
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
661 connection_has_mail(gc, -1, from, subj, "http://mail.yahoo.com/"); |
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
662 g_free(from); |
4001 | 663 } else if (count > 0) |
2850
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
664 connection_has_mail(gc, count, NULL, NULL, "http://mail.yahoo.com/"); |
2681 | 665 } |
3147 | 666 /* This is the y64 alphabet... it's like base64, but has a . and a _ */ |
667 char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._"; | |
668 | |
669 /* This is taken from Sylpheed by Hiroyuki Yamamoto. We have our own tobase64 function | |
670 * in util.c, but it has a bug I don't feel like finding right now ;) */ | |
671 void to_y64(unsigned char *out, const unsigned char *in, int inlen) | |
672 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ | |
673 { | |
674 for (; inlen >= 3; inlen -= 3) | |
675 { | |
676 *out++ = base64digits[in[0] >> 2]; | |
677 *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; | |
678 *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; | |
679 *out++ = base64digits[in[2] & 0x3f]; | |
680 in += 3; | |
681 } | |
682 if (inlen > 0) | |
683 { | |
684 unsigned char fragment; | |
685 | |
686 *out++ = base64digits[in[0] >> 2]; | |
687 fragment = (in[0] << 4) & 0x30; | |
688 if (inlen > 1) | |
689 fragment |= in[1] >> 4; | |
690 *out++ = base64digits[fragment]; | |
691 *out++ = (inlen < 2) ? '-' : base64digits[(in[1] << 2) & 0x3c]; | |
692 *out++ = '-'; | |
693 } | |
694 *out = '\0'; | |
695 } | |
696 | |
697 static void yahoo_process_auth(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
698 { | |
699 char *seed = NULL; | |
700 char *sn = NULL; | |
701 GSList *l = pkt->hash; | |
702 struct yahoo_data *yd = gc->proto_data; | |
703 | |
704 while (l) { | |
705 struct yahoo_pair *pair = l->data; | |
706 if (pair->key == 94) | |
707 seed = pair->value; | |
708 if (pair->key == 1) | |
709 sn = pair->value; | |
710 l = l->next; | |
711 } | |
712 | |
713 if (seed) { | |
714 struct yahoo_packet *pack; | |
715 | |
716 /* So, Yahoo has stopped supporting its older clients in India, and undoubtedly | |
717 * will soon do so in the rest of the world. | |
718 * | |
719 * The new clients use this authentication method. I warn you in advance, it's | |
720 * bizzare, convoluted, inordinately complicated. It's also no more secure than | |
721 * crypt() was. The only purpose this scheme could serve is to prevent third | |
722 * part clients from connecting to their servers. | |
723 * | |
724 * Sorry, Yahoo. | |
725 */ | |
726 | |
727 md5_byte_t result[16]; | |
728 md5_state_t ctx; | |
729 char *crypt_result; | |
730 char *password_hash = g_malloc(25); | |
731 char *crypt_hash = g_malloc(25); | |
732 char *hash_string_p = g_malloc(50 + strlen(sn)); | |
733 char *hash_string_c = g_malloc(50 + strlen(sn)); | |
734 | |
735 char checksum; | |
736 | |
3157 | 737 int sv; |
3147 | 738 |
739 char *result6 = g_malloc(25); | |
740 char *result96 = g_malloc(25); | |
741 | |
742 sv = seed[15]; | |
3157 | 743 sv = sv % 8; |
3147 | 744 |
745 md5_init(&ctx); | |
746 md5_append(&ctx, gc->password, strlen(gc->password)); | |
747 md5_finish(&ctx, result); | |
748 to_y64(password_hash, result, 16); | |
749 | |
750 md5_init(&ctx); | |
751 crypt_result = yahoo_crypt(gc->password, "$1$_2S43d5f$"); | |
752 md5_append(&ctx, crypt_result, strlen(crypt_result)); | |
753 md5_finish(&ctx, result); | |
754 to_y64(crypt_hash, result, 16); | |
3157 | 755 |
756 switch (sv) { | |
3147 | 757 case 1: |
758 case 6: | |
3157 | 759 checksum = seed[seed[9] % 16]; |
3147 | 760 g_snprintf(hash_string_p, strlen(sn) + 50, |
3157 | 761 "%c%s%s%s", checksum, gc->username, seed, password_hash); |
762 g_snprintf(hash_string_c, strlen(sn) + 50, | |
3147 | 763 "%c%s%s%s", checksum, gc->username, seed, crypt_hash); |
764 break; | |
765 case 2: | |
766 case 7: | |
3157 | 767 checksum = seed[seed[15] % 16]; |
3147 | 768 g_snprintf(hash_string_p, strlen(sn) + 50, |
3157 | 769 "%c%s%s%s", checksum, seed, password_hash, gc->username); |
770 g_snprintf(hash_string_c, strlen(sn) + 50, | |
771 "%c%s%s%s", checksum, seed, crypt_hash, gc->username); | |
772 break; | |
3147 | 773 case 3: |
3157 | 774 checksum = seed[seed[1] % 16]; |
3147 | 775 g_snprintf(hash_string_p, strlen(sn) + 50, |
3157 | 776 "%c%s%s%s", checksum, gc->username, password_hash, seed); |
777 g_snprintf(hash_string_c, strlen(sn) + 50, | |
778 "%c%s%s%s", checksum, gc->username, crypt_hash, seed); | |
779 break; | |
780 case 4: | |
781 checksum = seed[seed[3] % 16]; | |
782 g_snprintf(hash_string_p, strlen(sn) + 50, | |
783 "%c%s%s%s", checksum, password_hash, seed, gc->username); | |
3147 | 784 g_snprintf(hash_string_c, strlen(sn) + 50, |
3157 | 785 "%c%s%s%s", checksum, crypt_hash, seed, gc->username); |
786 break; | |
3147 | 787 case 0: |
788 case 5: | |
3157 | 789 checksum = seed[seed[7] % 16]; |
3147 | 790 g_snprintf(hash_string_p, strlen(sn) + 50, |
3157 | 791 "%c%s%s%s", checksum, password_hash, gc->username, seed); |
792 g_snprintf(hash_string_c, strlen(sn) + 50, | |
3147 | 793 "%c%s%s%s", checksum, crypt_hash, gc->username, seed); |
3157 | 794 break; |
3147 | 795 } |
3157 | 796 |
3147 | 797 md5_init(&ctx); |
3157 | 798 md5_append(&ctx, hash_string_p, strlen(hash_string_p)); |
3147 | 799 md5_finish(&ctx, result); |
800 to_y64(result6, result, 16); | |
801 | |
802 md5_init(&ctx); | |
803 md5_append(&ctx, hash_string_c, strlen(hash_string_c)); | |
804 md5_finish(&ctx, result); | |
805 to_y64(result96, result, 16); | |
806 | |
807 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); | |
808 yahoo_packet_hash(pack, 0, gc->username); | |
809 yahoo_packet_hash(pack, 6, result6); | |
810 yahoo_packet_hash(pack, 96, result96); | |
811 yahoo_packet_hash(pack, 1, gc->username); | |
812 | |
813 yahoo_send_packet(yd, pack); | |
814 | |
3523 | 815 g_free(result6); |
816 g_free(result96); | |
3147 | 817 g_free(password_hash); |
818 g_free(crypt_hash); | |
819 g_free(hash_string_p); | |
820 g_free(hash_string_c); | |
821 | |
822 yahoo_packet_free(pack); | |
823 } | |
824 } | |
2681 | 825 |
826 static void yahoo_packet_process(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
827 { | |
828 switch (pkt->service) | |
829 { | |
830 case YAHOO_SERVICE_LOGON: | |
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
831 case YAHOO_SERVICE_LOGOFF: |
2681 | 832 case YAHOO_SERVICE_ISAWAY: |
2737
f61c1f3a6afa
[gaim-migrate @ 2750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2724
diff
changeset
|
833 case YAHOO_SERVICE_ISBACK: |
3019 | 834 case YAHOO_SERVICE_GAMELOGON: |
835 case YAHOO_SERVICE_GAMELOGOFF: | |
2681 | 836 yahoo_process_status(gc, pkt); |
837 break; | |
3019 | 838 case YAHOO_SERVICE_NOTIFY: |
839 yahoo_process_notify(gc, pkt); | |
2993 | 840 break; |
2681 | 841 case YAHOO_SERVICE_MESSAGE: |
2786
318f846120e2
[gaim-migrate @ 2799]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2772
diff
changeset
|
842 case YAHOO_SERVICE_GAMEMSG: |
2681 | 843 yahoo_process_message(gc, pkt); |
844 break; | |
845 case YAHOO_SERVICE_NEWMAIL: | |
846 yahoo_process_mail(gc, pkt); | |
847 break; | |
848 case YAHOO_SERVICE_NEWCONTACT: | |
849 yahoo_process_contact(gc, pkt); | |
850 break; | |
851 case YAHOO_SERVICE_LIST: | |
852 yahoo_process_list(gc, pkt); | |
853 break; | |
3147 | 854 case YAHOO_SERVICE_AUTH: |
855 yahoo_process_auth(gc, pkt); | |
856 break; | |
2681 | 857 default: |
2741
38cb5fa48bec
[gaim-migrate @ 2754]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2737
diff
changeset
|
858 debug_printf("unhandled service 0x%02x\n", pkt->service); |
2681 | 859 break; |
860 } | |
861 } | |
862 | |
863 static void yahoo_pending(gpointer data, gint source, GaimInputCondition cond) | |
864 { | |
865 struct gaim_connection *gc = data; | |
866 struct yahoo_data *yd = gc->proto_data; | |
867 char buf[1024]; | |
868 int len; | |
869 | |
870 len = read(yd->fd, buf, sizeof(buf)); | |
871 | |
872 if (len <= 0) { | |
3074 | 873 hide_login_progress_error(gc, "Unable to read"); |
2681 | 874 signoff(gc); |
875 return; | |
876 } | |
877 | |
878 yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen); | |
879 memcpy(yd->rxqueue + yd->rxlen, buf, len); | |
880 yd->rxlen += len; | |
881 | |
882 while (1) { | |
883 struct yahoo_packet *pkt; | |
884 int pos = 0; | |
885 int pktlen; | |
886 | |
887 if (yd->rxlen < YAHOO_PACKET_HDRLEN) | |
888 return; | |
889 | |
890 pos += 4; /* YMSG */ | |
891 pos += 2; | |
892 pos += 2; | |
893 | |
894 pktlen = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
895 debug_printf("%d bytes to read, rxlen is %d\n", pktlen, yd->rxlen); | |
896 | |
897 if (yd->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) | |
898 return; | |
899 | |
900 yahoo_packet_dump(yd->rxqueue, YAHOO_PACKET_HDRLEN + pktlen); | |
901 | |
902 pkt = yahoo_packet_new(0, 0, 0); | |
903 | |
904 pkt->service = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
3021 | 905 pkt->status = yahoo_get32(yd->rxqueue + pos); pos += 4; |
2741
38cb5fa48bec
[gaim-migrate @ 2754]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2737
diff
changeset
|
906 debug_printf("Yahoo Service: 0x%02x Status: %d\n", pkt->service, pkt->status); |
2681 | 907 pkt->id = yahoo_get32(yd->rxqueue + pos); pos += 4; |
908 | |
909 yahoo_packet_read(pkt, yd->rxqueue + pos, pktlen); | |
910 | |
911 yd->rxlen -= YAHOO_PACKET_HDRLEN + pktlen; | |
912 if (yd->rxlen) { | |
913 char *tmp = g_memdup(yd->rxqueue + YAHOO_PACKET_HDRLEN + pktlen, yd->rxlen); | |
914 g_free(yd->rxqueue); | |
915 yd->rxqueue = tmp; | |
916 } else { | |
917 g_free(yd->rxqueue); | |
918 yd->rxqueue = NULL; | |
919 } | |
920 | |
921 yahoo_packet_process(gc, pkt); | |
922 | |
923 yahoo_packet_free(pkt); | |
924 } | |
925 } | |
926 | |
927 static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) | |
928 { | |
929 struct gaim_connection *gc = data; | |
930 struct yahoo_data *yd; | |
931 struct yahoo_packet *pkt; | |
932 | |
933 if (!g_slist_find(connections, gc)) { | |
934 close(source); | |
935 return; | |
936 } | |
937 | |
938 if (source < 0) { | |
939 hide_login_progress(gc, "Unable to connect"); | |
940 signoff(gc); | |
941 return; | |
942 } | |
943 | |
944 yd = gc->proto_data; | |
945 yd->fd = source; | |
946 | |
3147 | 947 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0); |
2681 | 948 |
949 yahoo_packet_hash(pkt, 1, gc->username); | |
950 yahoo_send_packet(yd, pkt); | |
951 | |
952 yahoo_packet_free(pkt); | |
953 | |
954 gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); | |
955 } | |
956 | |
4491 | 957 static void yahoo_login(struct gaim_account *account) { |
958 struct gaim_connection *gc = new_gaim_conn(account); | |
2681 | 959 struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); |
960 | |
961 set_login_progress(gc, 1, "Connecting"); | |
962 | |
963 yd->fd = -1; | |
964 yd->hash = g_hash_table_new(g_str_hash, g_str_equal); | |
3019 | 965 yd->games = g_hash_table_new(g_str_hash, g_str_equal); |
2681 | 966 |
3193 | 967 |
4491 | 968 if (!g_strncasecmp(account->proto_opt[USEROPT_PAGERHOST], "cs.yahoo.com", strlen("cs.yahoo.com"))) { |
3193 | 969 /* Figured out the new auth method -- cs.yahoo.com likes to disconnect on buddy remove and add now */ |
2951 | 970 debug_printf("Setting new Yahoo! server.\n"); |
4491 | 971 g_snprintf(account->proto_opt[USEROPT_PAGERHOST], strlen("scs.yahoo.com") + 1, "scs.yahoo.com"); |
2951 | 972 save_prefs(); |
973 } | |
4491 | 974 |
975 | |
4634 | 976 if (proxy_connect(account, account->proto_opt[USEROPT_PAGERHOST][0] ? |
4491 | 977 account->proto_opt[USEROPT_PAGERHOST] : YAHOO_PAGER_HOST, |
978 account->proto_opt[USEROPT_PAGERPORT][0] ? | |
979 atoi(account->proto_opt[USEROPT_PAGERPORT]) : YAHOO_PAGER_PORT, | |
980 yahoo_got_connected, gc) != 0) { | |
2681 | 981 hide_login_progress(gc, "Connection problem"); |
982 signoff(gc); | |
983 return; | |
984 } | |
985 | |
986 } | |
987 | |
988 static gboolean yahoo_destroy_hash(gpointer key, gpointer val, gpointer data) | |
989 { | |
990 g_free(key); | |
991 g_free(val); | |
992 return TRUE; | |
993 } | |
994 | |
995 static void yahoo_close(struct gaim_connection *gc) { | |
996 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
997 g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); | |
998 g_hash_table_destroy(yd->hash); | |
3019 | 999 g_hash_table_foreach_remove(yd->games, yahoo_destroy_hash, NULL); |
1000 g_hash_table_destroy(yd->games); | |
2681 | 1001 if (yd->fd >= 0) |
1002 close(yd->fd); | |
3720
34c95669952f
[gaim-migrate @ 3853]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3642
diff
changeset
|
1003 |
2681 | 1004 if (yd->rxqueue) |
1005 g_free(yd->rxqueue); | |
2687
2d544f48146d
[gaim-migrate @ 2700]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2686
diff
changeset
|
1006 yd->rxlen = 0; |
2681 | 1007 if (gc->inpa) |
1008 gaim_input_remove(gc->inpa); | |
1009 g_free(yd); | |
1010 } | |
1011 | |
1012 static char **yahoo_list_icon(int uc) | |
1013 { | |
3019 | 1014 if ((uc >> 2) == YAHOO_STATUS_IDLE) |
2681 | 1015 return status_idle_xpm; |
3019 | 1016 else if (uc & UC_UNAVAILABLE) |
1017 return status_away_xpm; | |
1018 else if (uc & YAHOO_STATUS_GAME) | |
1019 return status_game_xpm; | |
1020 return status_here_xpm; | |
2681 | 1021 } |
1022 | |
1023 static char *yahoo_get_status_string(enum yahoo_status a) | |
1024 { | |
1025 switch (a) { | |
1026 case YAHOO_STATUS_BRB: | |
4596 | 1027 return _("Be Right Back"); |
2681 | 1028 case YAHOO_STATUS_BUSY: |
4596 | 1029 return _("Busy"); |
2681 | 1030 case YAHOO_STATUS_NOTATHOME: |
4596 | 1031 return _("Not At Home"); |
2681 | 1032 case YAHOO_STATUS_NOTATDESK: |
4596 | 1033 return _("Not At Desk"); |
2681 | 1034 case YAHOO_STATUS_NOTINOFFICE: |
4596 | 1035 return _("Not In Office"); |
2681 | 1036 case YAHOO_STATUS_ONPHONE: |
4606 | 1037 return _("On The Phone"); |
2681 | 1038 case YAHOO_STATUS_ONVACATION: |
4596 | 1039 return _("On Vacation"); |
2681 | 1040 case YAHOO_STATUS_OUTTOLUNCH: |
4596 | 1041 return _("Out To Lunch"); |
2681 | 1042 case YAHOO_STATUS_STEPPEDOUT: |
4596 | 1043 return _("Stepped Out"); |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
1044 case YAHOO_STATUS_INVISIBLE: |
4596 | 1045 return _("Invisible"); |
2879
5fc5123b7098
[gaim-migrate @ 2892]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2878
diff
changeset
|
1046 default: |
4596 | 1047 return _("Online"); |
2681 | 1048 } |
1049 } | |
1050 | |
3019 | 1051 static void yahoo_game(struct gaim_connection *gc, char *name) { |
1052 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1053 char *game = g_hash_table_lookup(yd->games, name); | |
1054 char *t; | |
1055 char url[256]; | |
1056 | |
1057 if (!game) | |
1058 return; | |
1059 t = game = g_strdup(strstr(game, "ante?room=")); | |
1060 while (*t != '\t') | |
1061 t++; | |
1062 *t = 0; | |
1063 g_snprintf(url, sizeof url, "http://games.yahoo.com/games/%s", game); | |
1064 open_url(NULL, url); | |
1065 g_free(game); | |
1066 } | |
2681 | 1067 static GList *yahoo_buddy_menu(struct gaim_connection *gc, char *who) |
1068 { | |
1069 GList *m = NULL; | |
1070 struct proto_buddy_menu *pbm; | |
1071 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
4491 | 1072 struct buddy *b = find_buddy(gc->account, who); /* this should never be null. if it is, |
2681 | 1073 segfault and get the bug report. */ |
1074 static char buf[1024]; | |
3019 | 1075 static char buf2[1024]; |
1076 | |
1077 if (b->uc & UC_UNAVAILABLE && b->uc >> 2 != YAHOO_STATUS_IDLE) { | |
1078 pbm = g_new0(struct proto_buddy_menu, 1); | |
1079 if ((b->uc >> 2) != YAHOO_STATUS_CUSTOM) | |
1080 g_snprintf(buf, sizeof buf, | |
1081 "Status: %s", yahoo_get_status_string(b->uc >> 2)); | |
1082 else | |
1083 g_snprintf(buf, sizeof buf, "Custom Status: %s", | |
1084 (char *)g_hash_table_lookup(yd->hash, b->name)); | |
1085 pbm->label = buf; | |
1086 pbm->callback = NULL; | |
1087 pbm->gc = gc; | |
1088 m = g_list_append(m, pbm); | |
1089 } | |
1090 | |
1091 if (b->uc | YAHOO_STATUS_GAME) { | |
1092 char *game = g_hash_table_lookup(yd->games, b->name); | |
1093 char *room; | |
1094 if (!game) | |
1095 return m; | |
1096 if (game) { | |
1097 char *t; | |
1098 pbm = g_new0(struct proto_buddy_menu, 1); | |
1099 if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ | |
1100 return NULL; | |
1101 while (*room && *room != '\t') /* skip to the tab */ | |
1102 room++; | |
1103 t = room++; /* room as now at the name */ | |
1104 while (*t != '\n') | |
1105 t++; /* replace the \n with a space */ | |
1106 *t = ' '; | |
1107 g_snprintf(buf2, sizeof buf2, "%s", room); | |
1108 pbm->label = buf2; | |
1109 pbm->callback = yahoo_game; | |
1110 pbm->gc = gc; | |
1111 m = g_list_append(m, pbm); | |
1112 } | |
1113 } | |
2681 | 1114 |
1115 return m; | |
1116 } | |
1117 | |
1118 static void yahoo_act_id(gpointer data, char *entry) | |
1119 { | |
1120 struct gaim_connection *gc = data; | |
1121 struct yahoo_data *yd = gc->proto_data; | |
1122 | |
1123 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0); | |
1124 yahoo_packet_hash(pkt, 3, entry); | |
1125 yahoo_send_packet(yd, pkt); | |
1126 yahoo_packet_free(pkt); | |
1127 | |
1128 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", entry); | |
1129 } | |
1130 | |
4333 | 1131 static void yahoo_show_act_id(struct gaim_connection *gc) |
2681 | 1132 { |
4333 | 1133 do_prompt_dialog("Activate which ID:", gc->displayname, gc, yahoo_act_id, NULL); |
2681 | 1134 } |
1135 | |
4333 | 1136 static GList *yahoo_actions(struct gaim_connection *gc) { |
2681 | 1137 GList *m = NULL; |
4333 | 1138 struct proto_actions_menu *pam; |
2681 | 1139 |
4333 | 1140 pam = g_new0(struct proto_actions_menu, 1); |
1141 pam->label = _("Activate ID"); | |
1142 pam->callback = yahoo_show_act_id; | |
1143 pam->gc = gc; | |
1144 m = g_list_append(m, pam); | |
2681 | 1145 |
1146 return m; | |
1147 } | |
1148 | |
3033 | 1149 static int yahoo_send_im(struct gaim_connection *gc, char *who, char *what, int len, int flags) |
2681 | 1150 { |
1151 struct yahoo_data *yd = gc->proto_data; | |
1152 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); | |
3642 | 1153 char *msg = g_strdup(what); |
2681 | 1154 |
1155 yahoo_packet_hash(pkt, 1, gc->displayname); | |
1156 yahoo_packet_hash(pkt, 5, who); | |
3493 | 1157 yahoo_packet_hash(pkt, 14, msg); |
2681 | 1158 |
1159 yahoo_send_packet(yd, pkt); | |
1160 | |
1161 yahoo_packet_free(pkt); | |
3493 | 1162 |
2681 | 1163 return 1; |
1164 } | |
1165 | |
3001 | 1166 int yahoo_send_typing(struct gaim_connection *gc, char *who, int typ) |
2993 | 1167 { |
1168 struct yahoo_data *yd = gc->proto_data; | |
3019 | 1169 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); |
2993 | 1170 yahoo_packet_hash(pkt, 49, "TYPING"); |
1171 yahoo_packet_hash(pkt, 1, gc->displayname); | |
1172 yahoo_packet_hash(pkt, 14, " "); | |
3596 | 1173 yahoo_packet_hash(pkt, 13, typ == TYPING ? "1" : "0"); |
2993 | 1174 yahoo_packet_hash(pkt, 5, who); |
1175 yahoo_packet_hash(pkt, 1002, "1"); | |
1176 | |
1177 yahoo_send_packet(yd, pkt); | |
1178 | |
1179 yahoo_packet_free(pkt); | |
1180 | |
3001 | 1181 return 0; |
2993 | 1182 } |
1183 | |
2681 | 1184 static void yahoo_set_away(struct gaim_connection *gc, char *state, char *msg) |
1185 { | |
1186 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1187 struct yahoo_packet *pkt; | |
2772
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1188 int service; |
2681 | 1189 char s[4]; |
1190 | |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1191 if (gc->away) { |
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1192 g_free(gc->away); |
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1193 gc->away = NULL; |
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1194 } |
2681 | 1195 |
1196 if (msg) { | |
1197 yd->current_status = YAHOO_STATUS_CUSTOM; | |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1198 gc->away = g_strdup(msg); |
2681 | 1199 } else if (state) { |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1200 gc->away = g_strdup(""); |
4596 | 1201 if (!strcmp(state, _("Available"))) { |
2681 | 1202 yd->current_status = YAHOO_STATUS_AVAILABLE; |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1203 g_free(gc->away); |
2681 | 1204 gc->away = NULL; |
4596 | 1205 } else if (!strcmp(state, _("Be Right Back"))) { |
2681 | 1206 yd->current_status = YAHOO_STATUS_BRB; |
4596 | 1207 } else if (!strcmp(state, _("Busy"))) { |
2681 | 1208 yd->current_status = YAHOO_STATUS_BUSY; |
4596 | 1209 } else if (!strcmp(state, _("Not At Home"))) { |
2681 | 1210 yd->current_status = YAHOO_STATUS_NOTATHOME; |
4596 | 1211 } else if (!strcmp(state, _("Not At Desk"))) { |
2681 | 1212 yd->current_status = YAHOO_STATUS_NOTATDESK; |
4596 | 1213 } else if (!strcmp(state, _("Not In Office"))) { |
2681 | 1214 yd->current_status = YAHOO_STATUS_NOTINOFFICE; |
4606 | 1215 } else if (!strcmp(state, _("On The Phone"))) { |
2681 | 1216 yd->current_status = YAHOO_STATUS_ONPHONE; |
4596 | 1217 } else if (!strcmp(state, _("On Vacation"))) { |
2681 | 1218 yd->current_status = YAHOO_STATUS_ONVACATION; |
4596 | 1219 } else if (!strcmp(state, _("Out To Lunch"))) { |
2681 | 1220 yd->current_status = YAHOO_STATUS_OUTTOLUNCH; |
4596 | 1221 } else if (!strcmp(state, _("Stepped Out"))) { |
2681 | 1222 yd->current_status = YAHOO_STATUS_STEPPEDOUT; |
4596 | 1223 } else if (!strcmp(state, _("Invisible"))) { |
2681 | 1224 yd->current_status = YAHOO_STATUS_INVISIBLE; |
1225 } else if (!strcmp(state, GAIM_AWAY_CUSTOM)) { | |
1226 if (gc->is_idle) { | |
1227 yd->current_status = YAHOO_STATUS_IDLE; | |
1228 } else { | |
1229 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
1230 } | |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1231 g_free(gc->away); |
2681 | 1232 gc->away = NULL; |
1233 } | |
1234 } else if (gc->is_idle) { | |
1235 yd->current_status = YAHOO_STATUS_IDLE; | |
1236 } else { | |
1237 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
1238 } | |
1239 | |
2772
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1240 if (yd->current_status == YAHOO_STATUS_AVAILABLE) |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1241 service = YAHOO_SERVICE_ISBACK; |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1242 else |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1243 service = YAHOO_SERVICE_ISAWAY; |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1244 pkt = yahoo_packet_new(service, yd->current_status, 0); |
2681 | 1245 g_snprintf(s, sizeof(s), "%d", yd->current_status); |
1246 yahoo_packet_hash(pkt, 10, s); | |
1247 if (yd->current_status == YAHOO_STATUS_CUSTOM) | |
1248 yahoo_packet_hash(pkt, 19, msg); | |
1249 | |
1250 yahoo_send_packet(yd, pkt); | |
1251 yahoo_packet_free(pkt); | |
1252 } | |
1253 | |
1254 static void yahoo_set_idle(struct gaim_connection *gc, int idle) | |
1255 { | |
1256 struct yahoo_data *yd = gc->proto_data; | |
1257 struct yahoo_packet *pkt = NULL; | |
1258 | |
1259 if (idle && yd->current_status == YAHOO_STATUS_AVAILABLE) { | |
1260 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_IDLE, 0); | |
1261 yd->current_status = YAHOO_STATUS_IDLE; | |
1262 } else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) { | |
1263 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_AVAILABLE, 0); | |
1264 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
1265 } | |
1266 | |
1267 if (pkt) { | |
1268 char buf[4]; | |
1269 g_snprintf(buf, sizeof(buf), "%d", yd->current_status); | |
1270 yahoo_packet_hash(pkt, 10, buf); | |
1271 yahoo_send_packet(yd, pkt); | |
1272 yahoo_packet_free(pkt); | |
1273 } | |
1274 } | |
1275 | |
1276 static GList *yahoo_away_states(struct gaim_connection *gc) | |
1277 { | |
1278 GList *m = NULL; | |
1279 | |
4596 | 1280 m = g_list_append(m, _("Available")); |
1281 m = g_list_append(m, _("Be Right Back")); | |
1282 m = g_list_append(m, _("Busy")); | |
1283 m = g_list_append(m, _("Not At Home")); | |
1284 m = g_list_append(m, _("Not At Desk")); | |
1285 m = g_list_append(m, _("Not In Office")); | |
4606 | 1286 m = g_list_append(m, _("On The Phone")); |
4596 | 1287 m = g_list_append(m, _("On Vacation")); |
1288 m = g_list_append(m, _("Out To Lunch")); | |
1289 m = g_list_append(m, _("Stepped Out")); | |
1290 m = g_list_append(m, _("Invisible")); | |
2681 | 1291 m = g_list_append(m, GAIM_AWAY_CUSTOM); |
1292 | |
1293 return m; | |
1294 } | |
1295 | |
1296 static void yahoo_keepalive(struct gaim_connection *gc) | |
1297 { | |
1298 struct yahoo_data *yd = gc->proto_data; | |
1299 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); | |
1300 yahoo_send_packet(yd, pkt); | |
1301 yahoo_packet_free(pkt); | |
1302 } | |
1303 | |
3466 | 1304 static void yahoo_add_buddy(struct gaim_connection *gc, const char *who) |
2681 | 1305 { |
1306 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1307 struct yahoo_packet *pkt; | |
1308 struct group *g; | |
1309 char *group = NULL; | |
1310 | |
1311 if (!yd->logged_in) | |
1312 return; | |
1313 | |
4491 | 1314 g = find_group_by_buddy(find_buddy(gc->account, who)); |
2681 | 1315 if (g) |
1316 group = g->name; | |
1317 else | |
1318 group = "Buddies"; | |
1319 | |
1320 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
1321 yahoo_packet_hash(pkt, 1, gc->displayname); | |
1322 yahoo_packet_hash(pkt, 7, who); | |
1323 yahoo_packet_hash(pkt, 65, group); | |
1324 yahoo_send_packet(yd, pkt); | |
1325 yahoo_packet_free(pkt); | |
1326 } | |
1327 | |
1328 static void yahoo_remove_buddy(struct gaim_connection *gc, char *who, char *group) | |
1329 { | |
1330 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
1331 | |
1332 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
1333 yahoo_packet_hash(pkt, 1, gc->displayname); | |
1334 yahoo_packet_hash(pkt, 7, who); | |
1335 yahoo_packet_hash(pkt, 65, group); | |
1336 yahoo_send_packet(yd, pkt); | |
1337 yahoo_packet_free(pkt); | |
1338 } | |
1339 | |
1340 static struct prpl *my_protocol = NULL; | |
1341 | |
3630 | 1342 G_MODULE_EXPORT void yahoo_init(struct prpl *ret) { |
3572 | 1343 struct proto_user_opt *puo; |
2681 | 1344 ret->protocol = PROTO_YAHOO; |
1345 ret->options = OPT_PROTO_MAIL_CHECK; | |
3572 | 1346 ret->name = g_strdup("Yahoo"); |
2681 | 1347 ret->login = yahoo_login; |
1348 ret->close = yahoo_close; | |
1349 ret->buddy_menu = yahoo_buddy_menu; | |
1350 ret->list_icon = yahoo_list_icon; | |
1351 ret->actions = yahoo_actions; | |
1352 ret->send_im = yahoo_send_im; | |
1353 ret->away_states = yahoo_away_states; | |
1354 ret->set_away = yahoo_set_away; | |
1355 ret->set_idle = yahoo_set_idle; | |
1356 ret->keepalive = yahoo_keepalive; | |
1357 ret->add_buddy = yahoo_add_buddy; | |
1358 ret->remove_buddy = yahoo_remove_buddy; | |
2993 | 1359 ret->send_typing = yahoo_send_typing; |
2681 | 1360 |
3572 | 1361 puo = g_new0(struct proto_user_opt, 1); |
4115 | 1362 puo->label = g_strdup(_("Pager Host:")); |
3572 | 1363 puo->def = g_strdup(YAHOO_PAGER_HOST); |
1364 puo->pos = USEROPT_PAGERHOST; | |
1365 ret->user_opts = g_list_append(ret->user_opts, puo); | |
1366 | |
1367 puo = g_new0(struct proto_user_opt, 1); | |
4115 | 1368 puo->label = g_strdup(_("Pager Port:")); |
3572 | 1369 puo->def = g_strdup("5050"); |
1370 puo->pos = USEROPT_PAGERPORT; | |
1371 ret->user_opts = g_list_append(ret->user_opts, puo); | |
1372 | |
2681 | 1373 my_protocol = ret; |
1374 } | |
1375 | |
1376 #ifndef STATIC | |
1377 | |
3630 | 1378 G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) |
2681 | 1379 { |
3572 | 1380 yahoo_init(prpl); |
1381 prpl->plug->desc.api_version = PLUGIN_API_VERSION; | |
2681 | 1382 } |
1383 | |
1384 #endif |