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