Mercurial > pidgin.yaz
annotate src/protocols/yahoo/yahoo.c @ 9325:f40233043b5a
[gaim-migrate @ 10133]
This fixes some oddities with fetching a users icon if he had previously
unset it, and then set the same one. We were forgetting to unset some flags
and also the checksum, so we noticed the checksum was the same and didn't
ask for the icon, even though we didn't have an icon. Its still not always
fetching it, which is odd.
committer: Tailor Script <tailor@pidgin.im>
author | Tim Ringenbach <marv@pidgin.im> |
---|---|
date | Sun, 20 Jun 2004 07:38:40 +0000 |
parents | 01c50436203e |
children | d42f3e4fd7ad |
rev | line source |
---|---|
2681 | 1 /* |
2 * gaim | |
3 * | |
8046 | 4 * Gaim is the legal property of its developers, whose names are too numerous |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
2681 | 7 * |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
23 #include "internal.h" |
2681 | 24 |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
25 #include "account.h" |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5590
diff
changeset
|
26 #include "accountopt.h" |
6760 | 27 #include "blist.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
28 #include "debug.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
29 #include "notify.h" |
6760 | 30 #include "privacy.h" |
2681 | 31 #include "prpl.h" |
32 #include "proxy.h" | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
33 #include "request.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
34 #include "server.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
35 #include "util.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
36 |
6986 | 37 #include "sha.h" |
6513 | 38 #include "yahoo.h" |
9278 | 39 #include "yahoo_friend.h" |
6729 | 40 #include "yahoochat.h" |
8349 | 41 #include "yahoo_auth.h" |
7651 | 42 #include "yahoo_filexfer.h" |
9306 | 43 #include "yahoo_picture.h" |
3147 | 44 #include "md5.h" |
2681 | 45 |
5583 | 46 extern char *yahoo_crypt(const char *, const char *); |
2795
536bb833fdeb
[gaim-migrate @ 2808]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2786
diff
changeset
|
47 |
5493
3e8487580024
[gaim-migrate @ 5889]
Christian Hammond <chipx86@chipx86.com>
parents:
5436
diff
changeset
|
48 /* #define YAHOO_DEBUG */ |
2681 | 49 |
9285 | 50 static void yahoo_add_buddy(GaimConnection *gc, GaimBuddy *, GaimGroup *); |
9306 | 51 |
6784 | 52 |
6729 | 53 struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id) |
2681 | 54 { |
55 struct yahoo_packet *pkt = g_new0(struct yahoo_packet, 1); | |
56 | |
57 pkt->service = service; | |
58 pkt->status = status; | |
59 pkt->id = id; | |
60 | |
61 return pkt; | |
62 } | |
63 | |
6729 | 64 void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value) |
2681 | 65 { |
66 struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); | |
67 pair->key = key; | |
68 pair->value = g_strdup(value); | |
69 pkt->hash = g_slist_append(pkt->hash, pair); | |
70 } | |
71 | |
7651 | 72 int yahoo_packet_length(struct yahoo_packet *pkt) |
2681 | 73 { |
74 GSList *l; | |
75 | |
76 int len = 0; | |
77 | |
78 l = pkt->hash; | |
79 while (l) { | |
80 struct yahoo_pair *pair = l->data; | |
81 int tmp = pair->key; | |
82 do { | |
83 tmp /= 10; | |
84 len++; | |
85 } while (tmp); | |
86 len += 2; | |
87 len += strlen(pair->value); | |
88 len += 2; | |
89 l = l->next; | |
90 } | |
91 | |
92 return len; | |
93 } | |
94 | |
95 static void yahoo_packet_read(struct yahoo_packet *pkt, guchar *data, int len) | |
96 { | |
97 int pos = 0; | |
98 | |
99 while (pos + 1 < len) { | |
6629 | 100 char key[64], *value = NULL, *esc; |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
101 int accept; |
2681 | 102 int x; |
103 | |
104 struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); | |
105 | |
106 x = 0; | |
107 while (pos + 1 < len) { | |
108 if (data[pos] == 0xc0 && data[pos + 1] == 0x80) | |
109 break; | |
8118 | 110 if (x >= sizeof(key)-1) { |
111 x++; | |
8357 | 112 pos++; |
8118 | 113 continue; |
114 } | |
2681 | 115 key[x++] = data[pos++]; |
116 } | |
8118 | 117 if (x >= sizeof(key)-1) { |
118 x = 0; | |
119 } | |
2681 | 120 key[x] = 0; |
121 pos += 2; | |
122 pair->key = strtol(key, NULL, 10); | |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
123 accept = x; /* if x is 0 there was no key, so don't accept it */ |
2681 | 124 |
3996
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
125 if (len - pos + 1 <= 0) { |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
126 /* Truncated. Garbage or something. */ |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
127 accept = 0; |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
128 } |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
129 |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
130 if (accept) { |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
131 value = g_malloc(len - pos + 1); |
3996
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
132 x = 0; |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
133 while (pos + 1 < len) { |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
134 if (data[pos] == 0xc0 && data[pos + 1] == 0x80) |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
135 break; |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
136 value[x++] = data[pos++]; |
3996
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
137 } |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
138 value[x] = 0; |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
139 pair->value = g_strdup(value); |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
140 g_free(value); |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
141 pkt->hash = g_slist_append(pkt->hash, pair); |
6629 | 142 esc = g_strescape(pair->value, NULL); |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
143 gaim_debug(GAIM_DEBUG_MISC, "yahoo", |
6629 | 144 "Key: %d \tValue: %s\n", pair->key, esc); |
145 g_free(esc); | |
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
146 } else { |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
147 g_free(pair); |
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
148 } |
3996
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
149 pos += 2; |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
150 |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
151 /* Skip over garbage we've noticed in the mail notifications */ |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
152 if (data[0] == '9' && data[pos] == 0x01) |
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
153 pos++; |
2681 | 154 } |
155 } | |
156 | |
7651 | 157 void yahoo_packet_write(struct yahoo_packet *pkt, guchar *data) |
2681 | 158 { |
159 GSList *l = pkt->hash; | |
160 int pos = 0; | |
161 | |
162 while (l) { | |
163 struct yahoo_pair *pair = l->data; | |
164 guchar buf[100]; | |
165 | |
166 g_snprintf(buf, sizeof(buf), "%d", pair->key); | |
167 strcpy(data + pos, buf); | |
168 pos += strlen(buf); | |
169 data[pos++] = 0xc0; | |
170 data[pos++] = 0x80; | |
171 | |
172 strcpy(data + pos, pair->value); | |
173 pos += strlen(pair->value); | |
174 data[pos++] = 0xc0; | |
175 data[pos++] = 0x80; | |
176 | |
177 l = l->next; | |
178 } | |
179 } | |
180 | |
181 static void yahoo_packet_dump(guchar *data, int len) | |
182 { | |
183 #ifdef YAHOO_DEBUG | |
184 int i; | |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
185 |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
186 gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
187 |
2681 | 188 for (i = 0; i + 1 < len; i += 2) { |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
189 if ((i % 16 == 0) && i) { |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
190 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
191 gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
192 } |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
193 |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
194 gaim_debug(GAIM_DEBUG_MISC, NULL, "%02x%02x ", data[i], data[i + 1]); |
2681 | 195 } |
196 if (i < len) | |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
197 gaim_debug(GAIM_DEBUG_MISC, NULL, "%02x", data[i]); |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
198 |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
199 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
200 gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
201 |
2681 | 202 for (i = 0; i < len; i++) { |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
203 if ((i % 16 == 0) && i) { |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
204 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
205 gaim_debug(GAIM_DEBUG_MISC, "yahoo", ""); |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
206 } |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
207 |
6686 | 208 if (g_ascii_isprint(data[i])) |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
209 gaim_debug(GAIM_DEBUG_MISC, NULL, "%c ", data[i]); |
2681 | 210 else |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
211 gaim_debug(GAIM_DEBUG_MISC, NULL, ". "); |
2681 | 212 } |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
213 |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
214 gaim_debug(GAIM_DEBUG_MISC, NULL, "\n"); |
2681 | 215 #endif |
216 } | |
217 | |
6729 | 218 int yahoo_send_packet(struct yahoo_data *yd, struct yahoo_packet *pkt) |
2681 | 219 { |
220 int pktlen = yahoo_packet_length(pkt); | |
221 int len = YAHOO_PACKET_HDRLEN + pktlen; | |
222 int ret; | |
223 | |
224 guchar *data; | |
225 int pos = 0; | |
226 | |
227 if (yd->fd < 0) | |
228 return -1; | |
229 | |
230 data = g_malloc0(len + 1); | |
231 | |
232 memcpy(data + pos, "YMSG", 4); pos += 4; | |
3467 | 233 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); |
2681 | 234 pos += yahoo_put16(data + pos, 0x0000); |
235 pos += yahoo_put16(data + pos, pktlen); | |
236 pos += yahoo_put16(data + pos, pkt->service); | |
237 pos += yahoo_put32(data + pos, pkt->status); | |
238 pos += yahoo_put32(data + pos, pkt->id); | |
239 | |
240 yahoo_packet_write(pkt, data + pos); | |
241 | |
242 yahoo_packet_dump(data, len); | |
243 ret = write(yd->fd, data, len); | |
244 g_free(data); | |
245 | |
246 return ret; | |
247 } | |
248 | |
9306 | 249 int yahoo_send_packet_special(int fd, struct yahoo_packet *pkt, int pad) |
250 { | |
251 int pktlen = yahoo_packet_length(pkt); | |
252 int len = YAHOO_PACKET_HDRLEN + pktlen; | |
253 int ret; | |
254 | |
255 guchar *data; | |
256 int pos = 0; | |
257 | |
258 if (fd < 0) | |
259 return -1; | |
260 | |
261 data = g_malloc0(len + 1); | |
262 | |
263 memcpy(data + pos, "YMSG", 4); pos += 4; | |
264 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); | |
265 pos += yahoo_put16(data + pos, 0x0000); | |
266 pos += yahoo_put16(data + pos, pktlen + pad); | |
267 pos += yahoo_put16(data + pos, pkt->service); | |
268 pos += yahoo_put32(data + pos, pkt->status); | |
269 pos += yahoo_put32(data + pos, pkt->id); | |
270 | |
271 yahoo_packet_write(pkt, data + pos); | |
272 | |
273 ret = write(fd, data, len); | |
274 g_free(data); | |
275 | |
276 return ret; | |
277 } | |
278 | |
6729 | 279 void yahoo_packet_free(struct yahoo_packet *pkt) |
2681 | 280 { |
281 while (pkt->hash) { | |
282 struct yahoo_pair *pair = pkt->hash->data; | |
283 g_free(pair->value); | |
284 g_free(pair); | |
285 pkt->hash = g_slist_remove(pkt->hash, pair); | |
286 } | |
287 g_free(pkt); | |
288 } | |
289 | |
9278 | 290 static void yahoo_update_status(GaimConnection *gc, const char *name, YahooFriend *f) |
6784 | 291 { |
6840 | 292 int online = 1; |
293 | |
6784 | 294 if (!gc || !name || !f || !gaim_find_buddy(gaim_connection_get_account(gc), name)) |
295 return; | |
296 | |
6840 | 297 if (f->status == YAHOO_STATUS_OFFLINE) |
298 online = 0; | |
299 | |
300 serv_got_update(gc, name, online, 0, 0, f->idle, f->away ? UC_UNAVAILABLE : 0); | |
6784 | 301 } |
302 | |
5583 | 303 static void yahoo_process_status(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 304 { |
305 struct yahoo_data *yd = gc->proto_data; | |
306 GSList *l = pkt->hash; | |
9278 | 307 YahooFriend *f = NULL; |
2681 | 308 char *name = NULL; |
6784 | 309 |
7892 | 310 if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) { |
8383 | 311 gc->wants_to_die = TRUE; |
7892 | 312 gaim_connection_error(gc, _("You have been logged off as you have logged in on a different machine or device.")); |
313 return; | |
314 } | |
6686 | 315 |
2681 | 316 while (l) { |
317 struct yahoo_pair *pair = l->data; | |
318 | |
319 switch (pair->key) { | |
320 case 0: /* we won't actually do anything with this */ | |
321 break; | |
322 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
|
323 if (!yd->logged_in) { |
7664 | 324 gaim_connection_set_display_name(gc, pair->value); |
5583 | 325 gaim_connection_set_state(gc, GAIM_CONNECTED); |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
326 serv_finish_login(gc); |
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
327 yd->logged_in = TRUE; |
9306 | 328 if (yd->picture_upload_todo) { |
329 yahoo_buddy_icon_upload(gc, yd->picture_upload_todo); | |
330 yd->picture_upload_todo = NULL; | |
331 } | |
2681 | 332 |
3147 | 333 /* this requests the list. i have a feeling that this is very evil |
334 * | |
6686 | 335 * scs.yahoo.com sends you the list before this packet without it being |
3147 | 336 * requested |
337 * | |
338 * do_import(gc, NULL); | |
339 * newpkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_OFFLINE, 0); | |
340 * yahoo_send_packet(yd, newpkt); | |
341 * yahoo_packet_free(newpkt); | |
342 */ | |
343 | |
344 } | |
2681 | 345 break; |
346 case 8: /* how many online buddies we have */ | |
347 break; | |
348 case 7: /* the current buddy */ | |
349 name = pair->value; | |
9279 | 350 f = yahoo_friend_find_or_new(gc, name); |
2681 | 351 break; |
352 case 10: /* state */ | |
6784 | 353 if (!f) |
354 break; | |
355 | |
356 f->status = strtol(pair->value, NULL, 10); | |
357 if ((f->status >= YAHOO_STATUS_BRB) && (f->status <= YAHOO_STATUS_STEPPEDOUT)) | |
358 f->away = 1; | |
359 else | |
360 f->away = 0; | |
361 if (f->status == YAHOO_STATUS_IDLE) | |
362 f->idle = time(NULL); | |
6804 | 363 else |
364 f->idle = 0; | |
9283 | 365 if (f->status != YAHOO_STATUS_CUSTOM) |
366 yahoo_friend_set_status_message(f, NULL); | |
6847 | 367 |
368 f->sms = 0; | |
2681 | 369 break; |
370 case 19: /* custom message */ | |
9283 | 371 if (f) |
372 yahoo_friend_set_status_message(f, yahoo_string_decode(gc, pair->value, FALSE)); | |
2681 | 373 break; |
6686 | 374 case 11: /* this is the buddy's session id */ |
2681 | 375 break; |
376 case 17: /* in chat? */ | |
377 break; | |
6784 | 378 case 47: /* is custom status away or not? 2=idle*/ |
379 if (!f) | |
380 break; | |
8441 | 381 |
382 /* I have no idea what it means when this is | |
383 * set when someone's available, but it doesn't | |
384 * mean idle. */ | |
385 if (f->status == YAHOO_STATUS_AVAILABLE) | |
386 break; | |
6784 | 387 f->away = strtol(pair->value, NULL, 10); |
388 if (f->away == 2) | |
389 f->idle = time(NULL); | |
6686 | 390 break; |
6784 | 391 case 138: /* either we're not idle, or we are but won't say how long */ |
392 if (!f) | |
393 break; | |
394 | |
395 if (f->idle) | |
396 f->idle = -1; | |
397 break; | |
398 case 137: /* usually idle time in seconds, sometimes login time */ | |
399 if (!f) | |
400 break; | |
401 | |
402 if (f->status != YAHOO_STATUS_AVAILABLE) | |
403 f->idle = time(NULL) - strtol(pair->value, NULL, 10); | |
6686 | 404 break; |
405 case 13: /* bitmask, bit 0 = pager, bit 1 = chat, bit 2 = game */ | |
6784 | 406 if (strtol(pair->value, NULL, 10) == 0) { |
407 if (f) | |
408 f->status = YAHOO_STATUS_OFFLINE; | |
4732 | 409 serv_got_update(gc, name, 0, 0, 0, 0, 0); |
2807
f01e6a425136
[gaim-migrate @ 2820]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2805
diff
changeset
|
410 break; |
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
411 } |
6784 | 412 |
413 if (f) | |
414 yahoo_update_status(gc, name, f); | |
415 break; | |
416 case 60: /* SMS */ | |
417 if (f) { | |
418 f->sms = strtol(pair->value, NULL, 10); | |
419 yahoo_update_status(gc, name, f); | |
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
420 } |
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
421 break; |
9292 | 422 case 197: /* Avatars */ |
9277 | 423 { |
424 char *decoded, *tmp; | |
425 guint len; | |
426 | |
427 if (pair->value) { | |
428 gaim_base64_decode(pair->value, &decoded, &len); | |
429 if (len) { | |
430 tmp = gaim_str_binary_to_ascii(decoded, len); | |
431 gaim_debug_info("yahoo", "Got key 197, value = %s\n", tmp); | |
432 g_free(tmp); | |
433 } | |
434 g_free(decoded); | |
435 } | |
436 break; | |
437 } | |
9292 | 438 case 192: /* Pictures, aka Buddy Icons, checksum */ |
439 { | |
440 int cksum = strtol(pair->value, NULL, 10); | |
441 GaimBuddy *b; | |
442 | |
443 if (!name) | |
444 break; | |
445 | |
9325 | 446 b = gaim_find_buddy(gc->account, name); |
447 | |
9292 | 448 if (!cksum || (cksum == -1)) { |
9325 | 449 if (f) |
450 yahoo_friend_set_buddy_icon_need_request(f, TRUE); | |
9292 | 451 gaim_buddy_icons_set_for_user(gc->account, name, NULL, 0); |
9325 | 452 if (b) |
453 gaim_blist_node_remove_setting((GaimBlistNode *)b, YAHOO_ICON_CHECKSUM_KEY); | |
9292 | 454 break; |
455 } | |
456 | |
457 if (!f) | |
458 break; | |
9325 | 459 |
9292 | 460 yahoo_friend_set_buddy_icon_need_request(f, FALSE); |
461 if (cksum != gaim_blist_node_get_int((GaimBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY)) | |
9310 | 462 yahoo_send_picture_request(gc, name); |
9292 | 463 |
464 break; | |
465 } | |
2979 | 466 case 16: /* Custom error message */ |
7827 | 467 { |
468 char *tmp = yahoo_string_decode(gc, pair->value, TRUE); | |
469 gaim_notify_error(gc, NULL, tmp, NULL); | |
470 g_free(tmp); | |
471 } | |
2951 | 472 break; |
2681 | 473 default: |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
474 gaim_debug(GAIM_DEBUG_ERROR, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
475 "Unknown status key %d\n", pair->key); |
2681 | 476 break; |
477 } | |
478 | |
479 l = l->next; | |
480 } | |
481 } | |
482 | |
9285 | 483 static void yahoo_do_group_check(GaimAccount *account, GHashTable *ht, const char *name, const char *group) |
6820 | 484 { |
485 GaimBuddy *b; | |
486 GaimGroup *g; | |
487 GSList *list, *i; | |
488 gboolean onlist = 0; | |
489 char *oname = NULL; | |
490 | |
9015 | 491 char **oname_p = &oname; |
492 GSList **list_p = &list; | |
493 | |
494 if (!g_hash_table_lookup_extended(ht, gaim_normalize(account, name), (gpointer *) oname_p, (gpointer *) list_p)) | |
6820 | 495 list = gaim_find_buddies(account, name); |
496 else | |
497 g_hash_table_steal(ht, name); | |
498 | |
499 for (i = list; i; i = i->next) { | |
500 b = i->data; | |
501 g = gaim_find_buddys_group(b); | |
502 if (!gaim_utf8_strcasecmp(group, g->name)) { | |
503 gaim_debug(GAIM_DEBUG_MISC, "yahoo", | |
504 "Oh good, %s is in the right group (%s).\n", name, group); | |
505 list = g_slist_delete_link(list, i); | |
506 onlist = 1; | |
507 break; | |
508 } | |
509 } | |
510 | |
511 if (!onlist) { | |
512 gaim_debug(GAIM_DEBUG_MISC, "yahoo", | |
513 "Uhoh, %s isn't on the list (or not in this group), adding him to group %s.\n", name, group); | |
514 if (!(g = gaim_find_group(group))) { | |
515 g = gaim_group_new(group); | |
516 gaim_blist_add_group(g, NULL); | |
517 } | |
518 b = gaim_buddy_new(account, name, NULL); | |
519 gaim_blist_add_buddy(b, NULL, g, NULL); | |
520 } | |
521 | |
522 if (list) { | |
523 if (!oname) | |
7823 | 524 oname = g_strdup(gaim_normalize(account, name)); |
6820 | 525 g_hash_table_insert(ht, oname, list); |
526 } else if (oname) | |
527 g_free(oname); | |
528 } | |
529 | |
530 static void yahoo_do_group_cleanup(gpointer key, gpointer value, gpointer user_data) | |
531 { | |
532 char *name = key; | |
533 GSList *list = value, *i; | |
534 GaimBuddy *b; | |
535 GaimGroup *g; | |
536 | |
537 for (i = list; i; i = i->next) { | |
538 b = i->data; | |
539 g = gaim_find_buddys_group(b); | |
540 gaim_debug(GAIM_DEBUG_MISC, "yahoo", "Deleting Buddy %s from group %s.\n", name, g->name); | |
541 gaim_blist_remove_buddy(b); | |
542 } | |
543 } | |
544 | |
7651 | 545 static char *_getcookie(char *rawcookie) |
546 { | |
547 char *cookie = NULL; | |
548 char *tmpcookie; | |
549 char *cookieend; | |
550 | |
551 if (strlen(rawcookie) < 2) | |
552 return NULL; | |
553 tmpcookie = g_strdup(rawcookie+2); | |
554 cookieend = strchr(tmpcookie, ';'); | |
555 | |
556 if (cookieend) | |
557 *cookieend = '\0'; | |
558 | |
559 cookie = g_strdup(tmpcookie); | |
560 g_free(tmpcookie); | |
561 | |
562 return cookie; | |
563 } | |
564 | |
565 static void yahoo_process_cookie(struct yahoo_data *yd, char *c) | |
566 { | |
567 if (c[0] == 'Y') { | |
568 if (yd->cookie_y) | |
569 g_free(yd->cookie_y); | |
570 yd->cookie_y = _getcookie(c); | |
571 } else if (c[0] == 'T') { | |
572 if (yd->cookie_t) | |
573 g_free(yd->cookie_t); | |
574 yd->cookie_t = _getcookie(c); | |
575 } | |
576 } | |
577 | |
5583 | 578 static void yahoo_process_list(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 579 { |
580 GSList *l = pkt->hash; | |
581 gboolean export = FALSE; | |
6760 | 582 gboolean got_serv_list = FALSE; |
6695 | 583 GaimBuddy *b; |
584 GaimGroup *g; | |
9278 | 585 YahooFriend *f = NULL; |
6820 | 586 GaimAccount *account = gaim_connection_get_account(gc); |
6784 | 587 struct yahoo_data *yd = gc->proto_data; |
6820 | 588 GHashTable *ht; |
6784 | 589 |
590 char **lines; | |
591 char **split; | |
592 char **buddies; | |
7823 | 593 char **tmp, **bud, *norm_bud; |
7827 | 594 char *grp = NULL; |
2681 | 595 |
7651 | 596 if (pkt->id) |
597 yd->session_id = pkt->id; | |
598 | |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
599 while (l) { |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
600 struct yahoo_pair *pair = l->data; |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
601 l = l->next; |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
602 |
6760 | 603 switch (pair->key) { |
604 case 87: | |
6784 | 605 if (!yd->tmp_serv_blist) |
606 yd->tmp_serv_blist = g_string_new(pair->value); | |
607 else | |
608 g_string_append(yd->tmp_serv_blist, pair->value); | |
6760 | 609 break; |
610 case 88: | |
6784 | 611 if (!yd->tmp_serv_ilist) |
612 yd->tmp_serv_ilist = g_string_new(pair->value); | |
613 else | |
614 g_string_append(yd->tmp_serv_ilist, pair->value); | |
6760 | 615 break; |
7651 | 616 case 59: /* cookies, yum */ |
617 yahoo_process_cookie(yd, pair->value); | |
618 break; | |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
619 } |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
620 } |
2681 | 621 |
6784 | 622 if (pkt->status != 0) |
623 return; | |
624 | |
625 if (yd->tmp_serv_blist) { | |
6820 | 626 ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_slist_free); |
627 | |
6784 | 628 lines = g_strsplit(yd->tmp_serv_blist->str, "\n", -1); |
629 for (tmp = lines; *tmp; tmp++) { | |
630 split = g_strsplit(*tmp, ":", 2); | |
631 if (!split) | |
632 continue; | |
633 if (!split[0] || !split[1]) { | |
634 g_strfreev(split); | |
635 continue; | |
636 } | |
7827 | 637 grp = yahoo_string_decode(gc, split[0], FALSE); |
6784 | 638 buddies = g_strsplit(split[1], ",", -1); |
639 for (bud = buddies; bud && *bud; bud++) { | |
7823 | 640 norm_bud = g_strdup(gaim_normalize(account, *bud)); |
9279 | 641 f = yahoo_friend_find_or_new(gc, norm_bud); |
642 | |
7827 | 643 if (!(b = gaim_find_buddy(account, norm_bud))) { |
644 if (!(g = gaim_find_group(grp))) { | |
645 g = gaim_group_new(grp); | |
6784 | 646 gaim_blist_add_group(g, NULL); |
647 } | |
7823 | 648 b = gaim_buddy_new(account, norm_bud, NULL); |
6784 | 649 gaim_blist_add_buddy(b, NULL, g, NULL); |
650 export = TRUE; | |
6820 | 651 } |
6784 | 652 |
9285 | 653 yahoo_do_group_check(account, ht, norm_bud, grp); |
7823 | 654 g_free(norm_bud); |
6784 | 655 } |
656 g_strfreev(buddies); | |
657 g_strfreev(split); | |
7827 | 658 g_free(grp); |
6784 | 659 } |
660 g_strfreev(lines); | |
661 | |
662 g_string_free(yd->tmp_serv_blist, TRUE); | |
663 yd->tmp_serv_blist = NULL; | |
9285 | 664 g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL); |
6820 | 665 g_hash_table_destroy(ht); |
6784 | 666 } |
667 | |
668 | |
669 if (yd->tmp_serv_ilist) { | |
670 buddies = g_strsplit(yd->tmp_serv_ilist->str, ",", -1); | |
671 for (bud = buddies; bud && *bud; bud++) { | |
672 /* The server is already ignoring the user */ | |
673 got_serv_list = TRUE; | |
674 gaim_privacy_deny_add(gc->account, *bud, 1); | |
675 } | |
676 g_strfreev(buddies); | |
677 | |
678 g_string_free(yd->tmp_serv_ilist, TRUE); | |
679 yd->tmp_serv_ilist = NULL; | |
680 } | |
681 | |
682 if (got_serv_list) { | |
683 gc->account->perm_deny = 4; | |
684 serv_set_permit_deny(gc); | |
685 } | |
2681 | 686 } |
687 | |
5583 | 688 static void yahoo_process_notify(GaimConnection *gc, struct yahoo_packet *pkt) |
2993 | 689 { |
690 char *msg = NULL; | |
691 char *from = NULL; | |
3019 | 692 char *stat = NULL; |
693 char *game = NULL; | |
9278 | 694 YahooFriend *f = NULL; |
2993 | 695 GSList *l = pkt->hash; |
6784 | 696 |
2993 | 697 while (l) { |
698 struct yahoo_pair *pair = l->data; | |
699 if (pair->key == 4) | |
700 from = pair->value; | |
701 if (pair->key == 49) | |
702 msg = pair->value; | |
3001 | 703 if (pair->key == 13) |
3019 | 704 stat = pair->value; |
705 if (pair->key == 14) | |
706 game = pair->value; | |
2993 | 707 l = l->next; |
708 } | |
3640 | 709 |
6784 | 710 if (!from || !msg) |
3640 | 711 return; |
6686 | 712 |
4793 | 713 if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING"))) { |
3019 | 714 if (*stat == '1') |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
715 serv_got_typing(gc, from, 0, GAIM_TYPING); |
3019 | 716 else |
717 serv_got_typing_stopped(gc, from); | |
4793 | 718 } else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) { |
6695 | 719 GaimBuddy *bud = gaim_find_buddy(gc->account, from); |
6784 | 720 |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
721 if (!bud) { |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
722 gaim_debug(GAIM_DEBUG_WARNING, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
723 "%s is playing a game, and doesn't want " |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
724 "you to know.\n", from); |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
725 } |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
726 |
9279 | 727 f = yahoo_friend_find(gc, from); |
6784 | 728 if (!f) |
729 return; /* if they're not on the list, don't bother */ | |
730 | |
9283 | 731 yahoo_friend_set_game(f, NULL); |
6784 | 732 |
3019 | 733 if (*stat == '1') { |
9283 | 734 yahoo_friend_set_game(f, game); |
3020 | 735 if (bud) |
6784 | 736 yahoo_update_status(gc, from, f); |
3019 | 737 } |
738 } | |
2993 | 739 } |
740 | |
7827 | 741 |
742 struct _yahoo_im { | |
743 char *from; | |
744 int time; | |
745 int utf8; | |
9284 | 746 int buddy_icon; |
7827 | 747 char *msg; |
748 }; | |
749 | |
5583 | 750 static void yahoo_process_message(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 751 { |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
752 GSList *l = pkt->hash; |
7827 | 753 GSList *list = NULL; |
754 struct _yahoo_im *im = NULL; | |
6069 | 755 |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
756 if (pkt->status <= 1 || pkt->status == 5) { |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
757 while (l) { |
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
758 struct yahoo_pair *pair = l->data; |
7827 | 759 if (pair->key == 4) { |
760 im = g_new0(struct _yahoo_im, 1); | |
761 list = g_slist_append(list, im); | |
762 im->from = pair->value; | |
763 im->time = time(NULL); | |
764 } | |
765 if (pair->key == 97) | |
766 if (im) | |
767 im->utf8 = strtol(pair->value, NULL, 10); | |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
768 if (pair->key == 15) |
7827 | 769 if (im) |
770 im->time = strtol(pair->value, NULL, 10); | |
9284 | 771 if (pair->key == 206) |
772 if (im) | |
773 im->buddy_icon = strtol(pair->value, NULL, 10); | |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
774 if (pair->key == 14) { |
7827 | 775 if (im) |
776 im->msg = pair->value; | |
6687 | 777 } |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
778 l = l->next; |
6687 | 779 } |
2681 | 780 } else if (pkt->status == 2) { |
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5367
diff
changeset
|
781 gaim_notify_error(gc, NULL, |
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5367
diff
changeset
|
782 _("Your Yahoo! message did not get sent."), NULL); |
2681 | 783 } |
7827 | 784 |
785 for (l = list; l; l = l->next) { | |
9306 | 786 YahooFriend *f; |
7827 | 787 char *m, *m2; |
788 im = l->data; | |
789 | |
790 if (!im->from || !im->msg) { | |
791 g_free(im); | |
792 continue; | |
793 } | |
794 | |
795 m = yahoo_string_decode(gc, im->msg, im->utf8); | |
796 gaim_str_strip_cr(m); | |
8375 | 797 |
798 if (!strcmp(m, "<ding>")) { | |
799 GaimConversation *c = gaim_conversation_new(GAIM_CONV_IM, | |
800 gaim_connection_get_account(gc), im->from); | |
801 gaim_conv_im_write(GAIM_CONV_IM(c), "", _("Buzz!!"), GAIM_MESSAGE_NICK|GAIM_MESSAGE_RECV, | |
802 im->time); | |
803 g_free(m); | |
804 g_free(im); | |
805 continue; | |
806 } | |
807 | |
7827 | 808 m2 = yahoo_codes_to_html(m); |
809 g_free(m); | |
810 serv_got_im(gc, im->from, m2, 0, im->time); | |
811 g_free(m2); | |
9284 | 812 |
813 if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) { | |
814 if (yahoo_friend_get_buddy_icon_need_request(f)) { | |
9310 | 815 yahoo_send_picture_request(gc, im->from); |
9284 | 816 yahoo_friend_set_buddy_icon_need_request(f, FALSE); |
817 } | |
818 } | |
819 | |
7827 | 820 g_free(im); |
821 } | |
822 g_slist_free(list); | |
2681 | 823 } |
824 | |
7865 | 825 static void yahoo_process_sysmessage(GaimConnection *gc, struct yahoo_packet *pkt) |
826 { | |
827 GSList *l = pkt->hash; | |
828 char *prim, *me = NULL, *msg = NULL; | |
829 | |
830 while (l) { | |
831 struct yahoo_pair *pair = l->data; | |
832 | |
833 if (pair->key == 5) | |
834 me = pair->value; | |
835 if (pair->key == 14) | |
836 msg = pair->value; | |
837 | |
838 l = l->next; | |
839 } | |
840 | |
841 if (!msg) | |
842 return; | |
843 | |
844 prim = g_strdup_printf(_("Yahoo! system message for %s:"), | |
845 me?me:gaim_connection_get_display_name(gc)); | |
846 gaim_notify_info(NULL, NULL, prim, msg); | |
847 g_free(prim); | |
848 } | |
849 | |
6686 | 850 static void yahoo_buddy_added_us(GaimConnection *gc, struct yahoo_packet *pkt) { |
2681 | 851 char *id = NULL; |
852 char *who = NULL; | |
7827 | 853 char *msg = NULL, *tmpmsg = NULL; |
2681 | 854 GSList *l = pkt->hash; |
855 | |
856 while (l) { | |
857 struct yahoo_pair *pair = l->data; | |
6686 | 858 |
859 switch (pair->key) { | |
860 case 1: | |
2681 | 861 id = pair->value; |
6686 | 862 break; |
863 case 3: | |
2681 | 864 who = pair->value; |
6686 | 865 break; |
866 case 15: /* time, for when they add us and we're offline */ | |
867 break; | |
868 case 14: | |
2681 | 869 msg = pair->value; |
6686 | 870 break; |
871 } | |
2681 | 872 l = l->next; |
873 } | |
874 | |
7827 | 875 if (id) { |
876 if (msg) | |
877 tmpmsg = yahoo_string_decode(gc, msg, FALSE); | |
878 gaim_account_notify_added(gc->account, id, who, NULL, tmpmsg); | |
879 if (tmpmsg) | |
880 g_free(tmpmsg); | |
881 } | |
6686 | 882 } |
883 | |
884 static void yahoo_buddy_denied_our_add(GaimConnection *gc, struct yahoo_packet *pkt) | |
885 { | |
886 char *who = NULL; | |
887 char *msg = NULL; | |
888 GSList *l = pkt->hash; | |
889 GString *buf = NULL; | |
6784 | 890 struct yahoo_data *yd = gc->proto_data; |
6686 | 891 |
892 while (l) { | |
893 struct yahoo_pair *pair = l->data; | |
894 | |
895 switch (pair->key) { | |
896 case 3: | |
897 who = pair->value; | |
898 break; | |
899 case 14: | |
900 msg = pair->value; | |
901 break; | |
902 } | |
903 l = l->next; | |
904 } | |
905 | |
906 if (who) { | |
7827 | 907 char *msg2; |
6686 | 908 buf = g_string_sized_new(0); |
7827 | 909 if (!msg) { |
6686 | 910 g_string_printf(buf, _("%s has (retroactively) denied your request to add them to your list."), who); |
7827 | 911 } else { |
912 msg2 = yahoo_string_decode(gc, msg, FALSE); | |
913 g_string_printf(buf, _("%s has (retroactively) denied your request to add them to your list for the following reason: %s."), who, msg2); | |
914 g_free(msg2); | |
915 } | |
6840 | 916 gaim_notify_info(gc, NULL, _("Add buddy rejected"), buf->str); |
6686 | 917 g_string_free(buf, TRUE); |
6784 | 918 g_hash_table_remove(yd->friends, who); |
919 serv_got_update(gc, who, 0, 0, 0, 0, 0); | |
6686 | 920 } |
921 } | |
922 | |
923 static void yahoo_process_contact(GaimConnection *gc, struct yahoo_packet *pkt) | |
924 { | |
925 | |
926 | |
927 switch (pkt->status) { | |
928 case 1: | |
929 yahoo_process_status(gc, pkt); | |
930 return; | |
931 case 3: | |
932 yahoo_buddy_added_us(gc, pkt); | |
933 break; | |
934 case 7: | |
935 yahoo_buddy_denied_our_add(gc, pkt); | |
936 break; | |
937 default: | |
938 break; | |
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
939 } |
2681 | 940 } |
941 | |
7747 | 942 #define OUT_CHARSET "utf-8" |
943 | |
944 static char *yahoo_decode(const char *text) | |
945 { | |
9221 | 946 char *converted = NULL; |
8125 | 947 char *n, *new; |
948 const char *end, *p; | |
8616 | 949 int i, k; |
8125 | 950 |
7771 | 951 n = new = g_malloc(strlen (text) + 1); |
8118 | 952 end = text + strlen(text); |
953 | |
8125 | 954 for (p = text; p < end; p++, n++) { |
7747 | 955 if (*p == '\\') { |
9064 | 956 if (p[1] >= '0' && p[1] <= '7') { |
957 p += 1; | |
958 for (i = 0, k = 0; k < 3; k += 1) { | |
959 char c = p[k]; | |
9065 | 960 if (c < '0' || c > '7') break; |
9064 | 961 i *= 8; |
962 i += c - '0'; | |
963 } | |
964 *n = i; | |
965 p += k - 1; | |
966 } else { /* bug 959248 */ | |
967 /* If we see a \ not followed by an octal number, | |
968 * it means that it is actually a \\ with one \ | |
969 * already eaten by some unknown function. | |
970 * This is arguably broken. | |
971 * | |
972 * I think wing is wrong here, there is no function | |
973 * called that I see that could have done it. I guess | |
974 * it is just really sending single \'s. That's yahoo | |
975 * for you. | |
976 */ | |
977 *n = *p; | |
978 } | |
7747 | 979 } |
980 else | |
981 *n = *p; | |
982 } | |
983 | |
984 *n = '\0'; | |
8125 | 985 |
9221 | 986 if (strstr(text, "\033$B")) |
987 converted = g_convert(new, n - new, OUT_CHARSET, "iso-2022-jp", NULL, NULL, NULL); | |
988 if (!converted) | |
989 converted = g_convert(new, n - new, OUT_CHARSET, "iso-8859-1", NULL, NULL, NULL); | |
7747 | 990 g_free(new); |
991 | |
992 return converted; | |
993 } | |
994 | |
5583 | 995 static void yahoo_process_mail(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 996 { |
5583 | 997 GaimAccount *account = gaim_connection_get_account(gc); |
9221 | 998 struct yahoo_data *yd = gc->proto_data; |
2681 | 999 char *who = NULL; |
1000 char *email = NULL; | |
1001 char *subj = NULL; | |
9221 | 1002 char *yahoo_mail_url = (yd->jp? YAHOOJP_MAIL_URL: YAHOO_MAIL_URL); |
2681 | 1003 int count = 0; |
1004 GSList *l = pkt->hash; | |
1005 | |
5583 | 1006 if (!gaim_account_get_check_mail(account)) |
5521
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
1007 return; |
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
1008 |
2681 | 1009 while (l) { |
1010 struct yahoo_pair *pair = l->data; | |
1011 if (pair->key == 9) | |
1012 count = strtol(pair->value, NULL, 10); | |
1013 else if (pair->key == 43) | |
1014 who = pair->value; | |
1015 else if (pair->key == 42) | |
1016 email = pair->value; | |
1017 else if (pair->key == 18) | |
1018 subj = pair->value; | |
1019 l = l->next; | |
1020 } | |
1021 | |
4001 | 1022 if (who && subj && email && *email) { |
7747 | 1023 char *dec_who = yahoo_decode(who); |
1024 char *dec_subj = yahoo_decode(subj); | |
1025 char *from = g_strdup_printf("%s (%s)", dec_who, email); | |
1026 | |
1027 gaim_notify_email(gc, dec_subj, from, gaim_account_get_username(account), | |
9221 | 1028 yahoo_mail_url, NULL, NULL); |
5521
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
1029 |
7747 | 1030 g_free(dec_who); |
1031 g_free(dec_subj); | |
2850
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
1032 g_free(from); |
5521
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
1033 } else if (count > 0) { |
5583 | 1034 const char *to = gaim_account_get_username(account); |
9221 | 1035 const char *url = yahoo_mail_url; |
5521
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
1036 |
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
1037 gaim_notify_emails(gc, count, FALSE, NULL, NULL, &to, &url, |
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
1038 NULL, NULL); |
76ec14ba51d7
[gaim-migrate @ 5921]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
1039 } |
2681 | 1040 } |
3147 | 1041 /* This is the y64 alphabet... it's like base64, but has a . and a _ */ |
1042 char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._"; | |
1043 | |
1044 /* This is taken from Sylpheed by Hiroyuki Yamamoto. We have our own tobase64 function | |
1045 * in util.c, but it has a bug I don't feel like finding right now ;) */ | |
1046 void to_y64(unsigned char *out, const unsigned char *in, int inlen) | |
1047 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ | |
1048 { | |
1049 for (; inlen >= 3; inlen -= 3) | |
1050 { | |
1051 *out++ = base64digits[in[0] >> 2]; | |
1052 *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; | |
1053 *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; | |
1054 *out++ = base64digits[in[2] & 0x3f]; | |
1055 in += 3; | |
1056 } | |
1057 if (inlen > 0) | |
1058 { | |
1059 unsigned char fragment; | |
1060 | |
1061 *out++ = base64digits[in[0] >> 2]; | |
1062 fragment = (in[0] << 4) & 0x30; | |
1063 if (inlen > 1) | |
1064 fragment |= in[1] >> 4; | |
1065 *out++ = base64digits[fragment]; | |
1066 *out++ = (inlen < 2) ? '-' : base64digits[(in[1] << 2) & 0x3c]; | |
1067 *out++ = '-'; | |
1068 } | |
1069 *out = '\0'; | |
1070 } | |
1071 | |
6986 | 1072 static void yahoo_process_auth_old(GaimConnection *gc, const char *seed) |
1073 { | |
1074 struct yahoo_packet *pack; | |
1075 GaimAccount *account = gaim_connection_get_account(gc); | |
7261 | 1076 const char *name = gaim_normalize(account, gaim_account_get_username(account)); |
6986 | 1077 const char *pass = gaim_account_get_password(account); |
1078 struct yahoo_data *yd = gc->proto_data; | |
1079 | |
1080 /* So, Yahoo has stopped supporting its older clients in India, and undoubtedly | |
1081 * will soon do so in the rest of the world. | |
1082 * | |
1083 * The new clients use this authentication method. I warn you in advance, it's | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8713
diff
changeset
|
1084 * bizarre, convoluted, inordinately complicated. It's also no more secure than |
6986 | 1085 * crypt() was. The only purpose this scheme could serve is to prevent third |
1086 * part clients from connecting to their servers. | |
1087 * | |
1088 * Sorry, Yahoo. | |
1089 */ | |
9277 | 1090 |
6986 | 1091 md5_byte_t result[16]; |
1092 md5_state_t ctx; | |
9277 | 1093 |
6986 | 1094 char *crypt_result; |
1095 char password_hash[25]; | |
1096 char crypt_hash[25]; | |
1097 char *hash_string_p = g_malloc(50 + strlen(name)); | |
1098 char *hash_string_c = g_malloc(50 + strlen(name)); | |
9277 | 1099 |
6986 | 1100 char checksum; |
9277 | 1101 |
6986 | 1102 int sv; |
9277 | 1103 |
6986 | 1104 char result6[25]; |
1105 char result96[25]; | |
1106 | |
1107 sv = seed[15]; | |
1108 sv = sv % 8; | |
1109 | |
1110 md5_init(&ctx); | |
1111 md5_append(&ctx, pass, strlen(pass)); | |
1112 md5_finish(&ctx, result); | |
1113 to_y64(password_hash, result, 16); | |
9277 | 1114 |
6986 | 1115 md5_init(&ctx); |
9277 | 1116 crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$"); |
6986 | 1117 md5_append(&ctx, crypt_result, strlen(crypt_result)); |
1118 md5_finish(&ctx, result); | |
1119 to_y64(crypt_hash, result, 16); | |
1120 | |
1121 switch (sv) { | |
1122 case 1: | |
1123 case 6: | |
1124 checksum = seed[seed[9] % 16]; | |
1125 g_snprintf(hash_string_p, strlen(name) + 50, | |
1126 "%c%s%s%s", checksum, name, seed, password_hash); | |
1127 g_snprintf(hash_string_c, strlen(name) + 50, | |
1128 "%c%s%s%s", checksum, name, seed, crypt_hash); | |
1129 break; | |
1130 case 2: | |
1131 case 7: | |
1132 checksum = seed[seed[15] % 16]; | |
1133 g_snprintf(hash_string_p, strlen(name) + 50, | |
1134 "%c%s%s%s", checksum, seed, password_hash, name); | |
1135 g_snprintf(hash_string_c, strlen(name) + 50, | |
1136 "%c%s%s%s", checksum, seed, crypt_hash, name); | |
1137 break; | |
1138 case 3: | |
1139 checksum = seed[seed[1] % 16]; | |
1140 g_snprintf(hash_string_p, strlen(name) + 50, | |
1141 "%c%s%s%s", checksum, name, password_hash, seed); | |
1142 g_snprintf(hash_string_c, strlen(name) + 50, | |
1143 "%c%s%s%s", checksum, name, crypt_hash, seed); | |
1144 break; | |
1145 case 4: | |
1146 checksum = seed[seed[3] % 16]; | |
1147 g_snprintf(hash_string_p, strlen(name) + 50, | |
1148 "%c%s%s%s", checksum, password_hash, seed, name); | |
1149 g_snprintf(hash_string_c, strlen(name) + 50, | |
1150 "%c%s%s%s", checksum, crypt_hash, seed, name); | |
1151 break; | |
1152 case 0: | |
1153 case 5: | |
1154 checksum = seed[seed[7] % 16]; | |
1155 g_snprintf(hash_string_p, strlen(name) + 50, | |
1156 "%c%s%s%s", checksum, password_hash, name, seed); | |
1157 g_snprintf(hash_string_c, strlen(name) + 50, | |
1158 "%c%s%s%s", checksum, crypt_hash, name, seed); | |
1159 break; | |
1160 } | |
9277 | 1161 |
1162 md5_init(&ctx); | |
6986 | 1163 md5_append(&ctx, hash_string_p, strlen(hash_string_p)); |
1164 md5_finish(&ctx, result); | |
1165 to_y64(result6, result, 16); | |
9277 | 1166 |
1167 md5_init(&ctx); | |
6986 | 1168 md5_append(&ctx, hash_string_c, strlen(hash_string_c)); |
1169 md5_finish(&ctx, result); | |
1170 to_y64(result96, result, 16); | |
1171 | |
1172 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); | |
1173 yahoo_packet_hash(pack, 0, name); | |
1174 yahoo_packet_hash(pack, 6, result6); | |
1175 yahoo_packet_hash(pack, 96, result96); | |
1176 yahoo_packet_hash(pack, 1, name); | |
9277 | 1177 |
6986 | 1178 yahoo_send_packet(yd, pack); |
9277 | 1179 |
6986 | 1180 g_free(hash_string_p); |
1181 g_free(hash_string_c); | |
9277 | 1182 |
6986 | 1183 yahoo_packet_free(pack); |
9277 | 1184 |
6986 | 1185 } |
1186 | |
6998 | 1187 /* I'm dishing out some uber-mad props to Cerulean Studios for cracking this |
1188 * and sending the fix! Thanks guys. */ | |
1189 | |
6986 | 1190 static void yahoo_process_auth_new(GaimConnection *gc, const char *seed) |
1191 { | |
1192 struct yahoo_packet *pack = NULL; | |
1193 GaimAccount *account = gaim_connection_get_account(gc); | |
7261 | 1194 const char *name = gaim_normalize(account, gaim_account_get_username(account)); |
6986 | 1195 const char *pass = gaim_account_get_password(account); |
1196 struct yahoo_data *yd = gc->proto_data; | |
9277 | 1197 |
8349 | 1198 md5_byte_t result[16]; |
1199 md5_state_t ctx; | |
9277 | 1200 |
8349 | 1201 SHA_CTX ctx1; |
1202 SHA_CTX ctx2; | |
9277 | 1203 |
8349 | 1204 char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ"; |
1205 char *alphabet2 = "F0E1D2C3B4A59687abcdefghijklmnop"; | |
1206 | |
1207 char *challenge_lookup = "qzec2tb3um1olpar8whx4dfgijknsvy5"; | |
1208 char *operand_lookup = "+|&%/*^-"; | |
1209 char *delimit_lookup = ",;"; | |
1210 | |
1211 char *password_hash = (char *)g_malloc(25); | |
1212 char *crypt_hash = (char *)g_malloc(25); | |
1213 char *crypt_result = NULL; | |
1214 | |
1215 char pass_hash_xor1[64]; | |
1216 char pass_hash_xor2[64]; | |
1217 char crypt_hash_xor1[64]; | |
1218 char crypt_hash_xor2[64]; | |
1219 char resp_6[100]; | |
1220 char resp_96[100]; | |
1221 | |
1222 unsigned char digest1[20]; | |
1223 unsigned char digest2[20]; | |
1224 unsigned char comparison_src[20]; | |
1225 unsigned char magic_key_char[4]; | |
8375 | 1226 const unsigned char *magic_ptr; |
8349 | 1227 |
1228 unsigned int magic[64]; | |
1229 unsigned int magic_work = 0; | |
1230 unsigned int magic_4 = 0; | |
1231 | |
1232 int x; | |
1233 int y; | |
1234 int cnt = 0; | |
1235 int magic_cnt = 0; | |
1236 int magic_len; | |
1237 | |
1238 memset(password_hash, 0, 25); | |
1239 memset(crypt_hash, 0, 25); | |
6986 | 1240 memset(&pass_hash_xor1, 0, 64); |
1241 memset(&pass_hash_xor2, 0, 64); | |
1242 memset(&crypt_hash_xor1, 0, 64); | |
1243 memset(&crypt_hash_xor2, 0, 64); | |
1244 memset(&digest1, 0, 20); | |
1245 memset(&digest2, 0, 20); | |
1246 memset(&magic, 0, 64); | |
1247 memset(&resp_6, 0, 100); | |
1248 memset(&resp_96, 0, 100); | |
1249 memset(&magic_key_char, 0, 4); | |
8349 | 1250 memset(&comparison_src, 0, 20); |
6986 | 1251 |
1252 /* | |
8349 | 1253 * Magic: Phase 1. Generate what seems to be a 30 byte value (could change if base64 |
1254 * ends up differently? I don't remember and I'm tired, so use a 64 byte buffer. | |
6986 | 1255 */ |
9277 | 1256 |
6986 | 1257 magic_ptr = seed; |
8375 | 1258 |
6986 | 1259 while (*magic_ptr != (int)NULL) { |
8349 | 1260 char *loc; |
6986 | 1261 |
8349 | 1262 /* Ignore parentheses. |
1263 */ | |
6986 | 1264 |
1265 if (*magic_ptr == '(' || *magic_ptr == ')') { | |
1266 magic_ptr++; | |
1267 continue; | |
1268 } | |
1269 | |
8349 | 1270 /* Characters and digits verify against the challenge lookup. |
1271 */ | |
6986 | 1272 |
1273 if (isalpha(*magic_ptr) || isdigit(*magic_ptr)) { | |
1274 loc = strchr(challenge_lookup, *magic_ptr); | |
1275 if (!loc) { | |
8349 | 1276 /* SME XXX Error - disconnect here */ |
6986 | 1277 } |
1278 | |
8349 | 1279 /* Get offset into lookup table and shl 3. |
1280 */ | |
6986 | 1281 |
1282 magic_work = loc - challenge_lookup; | |
1283 magic_work <<= 3; | |
1284 | |
1285 magic_ptr++; | |
1286 continue; | |
1287 } else { | |
8349 | 1288 unsigned int local_store; |
6986 | 1289 |
1290 loc = strchr(operand_lookup, *magic_ptr); | |
1291 if (!loc) { | |
8349 | 1292 /* SME XXX Disconnect */ |
6986 | 1293 } |
1294 | |
1295 local_store = loc - operand_lookup; | |
8349 | 1296 |
1297 /* Oops; how did this happen? | |
1298 */ | |
1299 | |
6986 | 1300 if (magic_cnt >= 64) |
1301 break; | |
8349 | 1302 |
6986 | 1303 magic[magic_cnt++] = magic_work | local_store; |
1304 magic_ptr++; | |
1305 continue; | |
1306 } | |
8349 | 1307 } |
6986 | 1308 |
1309 magic_len = magic_cnt; | |
1310 magic_cnt = 0; | |
1311 | |
8349 | 1312 /* Magic: Phase 2. Take generated magic value and sprinkle fairy dust on the values. |
1313 */ | |
1314 | |
6986 | 1315 for (magic_cnt = magic_len-2; magic_cnt >= 0; magic_cnt--) { |
8349 | 1316 unsigned char byte1; |
1317 unsigned char byte2; | |
6986 | 1318 |
1319 /* Bad. Abort. | |
1320 */ | |
8349 | 1321 |
1322 if ((magic_cnt + 1 > magic_len) || (magic_cnt > magic_len)) | |
6986 | 1323 break; |
1324 | |
1325 byte1 = magic[magic_cnt]; | |
1326 byte2 = magic[magic_cnt+1]; | |
8349 | 1327 |
6986 | 1328 byte1 *= 0xcd; |
1329 byte1 ^= byte2; | |
1330 | |
1331 magic[magic_cnt+1] = byte1; | |
8349 | 1332 } |
1333 | |
1334 /* | |
1335 * Magic: Phase 3. This computes 20 bytes. The first 4 bytes are used as our magic | |
1336 * key (and may be changed later); the next 16 bytes are an MD5 sum of the magic key | |
1337 * plus 3 bytes. The 3 bytes are found by looping, and they represent the offsets | |
1338 * into particular functions we'll later call to potentially alter the magic key. | |
1339 * | |
1340 * %-) | |
1341 */ | |
1342 | |
1343 magic_cnt = 1; | |
1344 x = 0; | |
1345 | |
1346 do { | |
1347 unsigned int bl = 0; | |
1348 unsigned int cl = magic[magic_cnt++]; | |
1349 | |
1350 if (magic_cnt >= magic_len) | |
1351 break; | |
1352 | |
1353 if (cl > 0x7F) { | |
1354 if (cl < 0xe0) | |
1355 bl = cl = (cl & 0x1f) << 6; | |
1356 else { | |
1357 bl = magic[magic_cnt++]; | |
1358 cl = (cl & 0x0f) << 6; | |
1359 bl = ((bl & 0x3f) + cl) << 6; | |
1360 } | |
9277 | 1361 |
8349 | 1362 cl = magic[magic_cnt++]; |
1363 bl = (cl & 0x3f) + bl; | |
1364 } else | |
1365 bl = cl; | |
1366 | |
1367 comparison_src[x++] = (bl & 0xff00) >> 8; | |
1368 comparison_src[x++] = bl & 0xff; | |
1369 } while (x < 20); | |
1370 | |
1371 /* First four bytes are magic key. | |
1372 */ | |
1373 | |
1374 memcpy(&magic_key_char[0], comparison_src, 4); | |
8482 | 1375 magic_4 = magic_key_char[0] | (magic_key_char[1]<<8) | (magic_key_char[2]<<16) | (magic_key_char[3]<<24); |
8349 | 1376 |
1377 /* | |
1378 * Magic: Phase 4. Determine what function to use later by getting outside/inside | |
1379 * loop values until we match our previous buffer. | |
1380 */ | |
1381 | |
1382 for (x = 0; x < 65535; x++) { | |
1383 int leave = 0; | |
1384 | |
1385 for (y = 0; y < 5; y++) { | |
1386 md5_byte_t result[16]; | |
1387 md5_state_t ctx; | |
1388 | |
1389 unsigned char test[3]; | |
1390 | |
1391 memset(&result, 0, 16); | |
1392 memset(&test, 0, 3); | |
1393 | |
1394 /* Calculate buffer. | |
1395 */ | |
1396 | |
1397 test[0] = x; | |
1398 test[1] = x >> 8; | |
1399 test[2] = y; | |
1400 | |
1401 md5_init(&ctx); | |
1402 md5_append(&ctx, magic_key_char, 4); | |
1403 md5_append(&ctx, test, 3); | |
1404 md5_finish(&ctx, result); | |
1405 | |
1406 if (!memcmp(result, comparison_src+4, 16)) { | |
1407 leave = 1; | |
1408 break; | |
1409 } | |
1410 } | |
1411 | |
1412 if (leave == 1) | |
1413 break; | |
6986 | 1414 } |
1415 | |
8349 | 1416 /* If y != 0, we need some help. |
1417 */ | |
6986 | 1418 |
8349 | 1419 if (y != 0) { |
1420 unsigned int updated_key; | |
6986 | 1421 |
8349 | 1422 /* Update magic stuff. Call it twice because Yahoo's encryption is super bad ass. |
1423 */ | |
7127 | 1424 |
8349 | 1425 updated_key = yahoo_auth_finalCountdown(magic_4, 0x60, y, x); |
1426 updated_key = yahoo_auth_finalCountdown(updated_key, 0x60, y, x); | |
6986 | 1427 |
8482 | 1428 magic_key_char[0] = updated_key & 0xff; |
1429 magic_key_char[1] = (updated_key >> 8) & 0xff; | |
1430 magic_key_char[2] = (updated_key >> 16) & 0xff; | |
1431 magic_key_char[3] = (updated_key >> 24) & 0xff; | |
8349 | 1432 } |
7127 | 1433 |
8349 | 1434 /* Get password and crypt hashes as per usual. |
1435 */ | |
1436 | |
6986 | 1437 md5_init(&ctx); |
8349 | 1438 md5_append(&ctx, pass, strlen(pass)); |
6986 | 1439 md5_finish(&ctx, result); |
1440 to_y64(password_hash, result, 16); | |
1441 | |
1442 md5_init(&ctx); | |
1443 crypt_result = yahoo_crypt(pass, "$1$_2S43d5f$"); | |
1444 md5_append(&ctx, crypt_result, strlen(crypt_result)); | |
1445 md5_finish(&ctx, result); | |
1446 to_y64(crypt_hash, result, 16); | |
8349 | 1447 |
1448 /* Our first authentication response is based off of the password hash. | |
1449 */ | |
6986 | 1450 |
1451 for (x = 0; x < (int)strlen(password_hash); x++) | |
1452 pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36; | |
1453 | |
1454 if (cnt < 64) | |
1455 memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt); | |
8349 | 1456 |
6986 | 1457 cnt = 0; |
1458 | |
1459 for (x = 0; x < (int)strlen(password_hash); x++) | |
1460 pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c; | |
1461 | |
1462 if (cnt < 64) | |
1463 memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt); | |
1464 | |
1465 shaInit(&ctx1); | |
1466 shaInit(&ctx2); | |
1467 | |
8349 | 1468 /* |
1469 * The first context gets the password hash XORed with 0x36 plus a magic value | |
1470 * which we previously extrapolated from our challenge. | |
1471 */ | |
6986 | 1472 |
1473 shaUpdate(&ctx1, pass_hash_xor1, 64); | |
1474 shaUpdate(&ctx1, magic_key_char, 4); | |
1475 shaFinal(&ctx1, digest1); | |
1476 | |
8349 | 1477 /* |
1478 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest | |
1479 * of the first context. | |
1480 */ | |
6986 | 1481 |
1482 shaUpdate(&ctx2, pass_hash_xor2, 64); | |
1483 shaUpdate(&ctx2, digest1, 20); | |
1484 shaFinal(&ctx2, digest2); | |
1485 | |
8349 | 1486 /* |
1487 * Now that we have digest2, use it to fetch characters from an alphabet to construct | |
1488 * our first authentication response. | |
1489 */ | |
1490 | |
6986 | 1491 for (x = 0; x < 20; x += 2) { |
8349 | 1492 unsigned int val = 0; |
1493 unsigned int lookup = 0; | |
6986 | 1494 |
8349 | 1495 char byte[6]; |
1496 | |
6986 | 1497 memset(&byte, 0, 6); |
8349 | 1498 |
1499 /* First two bytes of digest stuffed together. | |
6986 | 1500 */ |
9277 | 1501 |
6986 | 1502 val = digest2[x]; |
1503 val <<= 8; | |
1504 val += digest2[x+1]; | |
1505 | |
1506 lookup = (val >> 0x0b); | |
1507 lookup &= 0x1f; | |
1508 if (lookup >= strlen(alphabet1)) | |
1509 break; | |
1510 sprintf(byte, "%c", alphabet1[lookup]); | |
1511 strcat(resp_6, byte); | |
1512 strcat(resp_6, "="); | |
8349 | 1513 |
6986 | 1514 lookup = (val >> 0x06); |
1515 lookup &= 0x1f; | |
1516 if (lookup >= strlen(alphabet2)) | |
1517 break; | |
1518 sprintf(byte, "%c", alphabet2[lookup]); | |
1519 strcat(resp_6, byte); | |
1520 | |
1521 lookup = (val >> 0x01); | |
1522 lookup &= 0x1f; | |
1523 if (lookup >= strlen(alphabet2)) | |
1524 break; | |
1525 sprintf(byte, "%c", alphabet2[lookup]); | |
1526 strcat(resp_6, byte); | |
8349 | 1527 |
6986 | 1528 lookup = (val & 0x01); |
1529 if (lookup >= strlen(delimit_lookup)) | |
1530 break; | |
1531 sprintf(byte, "%c", delimit_lookup[lookup]); | |
1532 strcat(resp_6, byte); | |
1533 } | |
1534 | |
8349 | 1535 /* Our second authentication response is based off of the crypto hash. |
1536 */ | |
6986 | 1537 |
1538 cnt = 0; | |
1539 memset(&digest1, 0, 20); | |
1540 memset(&digest2, 0, 20); | |
1541 | |
1542 for (x = 0; x < (int)strlen(crypt_hash); x++) | |
1543 crypt_hash_xor1[cnt++] = crypt_hash[x] ^ 0x36; | |
1544 | |
1545 if (cnt < 64) | |
1546 memset(&(crypt_hash_xor1[cnt]), 0x36, 64-cnt); | |
8349 | 1547 |
6986 | 1548 cnt = 0; |
1549 | |
1550 for (x = 0; x < (int)strlen(crypt_hash); x++) | |
1551 crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c; | |
1552 | |
1553 if (cnt < 64) | |
1554 memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt); | |
1555 | |
1556 shaInit(&ctx1); | |
1557 shaInit(&ctx2); | |
1558 | |
8349 | 1559 /* |
1560 * The first context gets the password hash XORed with 0x36 plus a magic value | |
1561 * which we previously extrapolated from our challenge. | |
1562 */ | |
6986 | 1563 |
1564 shaUpdate(&ctx1, crypt_hash_xor1, 64); | |
1565 shaUpdate(&ctx1, magic_key_char, 4); | |
1566 shaFinal(&ctx1, digest1); | |
1567 | |
8349 | 1568 /* |
1569 * The second context gets the password hash XORed with 0x5c plus the SHA-1 digest | |
1570 * of the first context. | |
1571 */ | |
6986 | 1572 |
1573 shaUpdate(&ctx2, crypt_hash_xor2, 64); | |
1574 shaUpdate(&ctx2, digest1, 20); | |
1575 shaFinal(&ctx2, digest2); | |
1576 | |
8349 | 1577 /* |
1578 * Now that we have digest2, use it to fetch characters from an alphabet to construct | |
1579 * our first authentication response. | |
1580 */ | |
6986 | 1581 |
1582 for (x = 0; x < 20; x += 2) { | |
8349 | 1583 unsigned int val = 0; |
1584 unsigned int lookup = 0; | |
6986 | 1585 |
8349 | 1586 char byte[6]; |
6986 | 1587 |
1588 memset(&byte, 0, 6); | |
1589 | |
8349 | 1590 /* First two bytes of digest stuffed together. |
1591 */ | |
6986 | 1592 |
1593 val = digest2[x]; | |
1594 val <<= 8; | |
1595 val += digest2[x+1]; | |
8349 | 1596 |
6986 | 1597 lookup = (val >> 0x0b); |
1598 lookup &= 0x1f; | |
1599 if (lookup >= strlen(alphabet1)) | |
1600 break; | |
1601 sprintf(byte, "%c", alphabet1[lookup]); | |
1602 strcat(resp_96, byte); | |
1603 strcat(resp_96, "="); | |
1604 | |
1605 lookup = (val >> 0x06); | |
1606 lookup &= 0x1f; | |
1607 if (lookup >= strlen(alphabet2)) | |
1608 break; | |
1609 sprintf(byte, "%c", alphabet2[lookup]); | |
1610 strcat(resp_96, byte); | |
1611 | |
1612 lookup = (val >> 0x01); | |
1613 lookup &= 0x1f; | |
1614 if (lookup >= strlen(alphabet2)) | |
1615 break; | |
1616 sprintf(byte, "%c", alphabet2[lookup]); | |
1617 strcat(resp_96, byte); | |
1618 | |
1619 lookup = (val & 0x01); | |
1620 if (lookup >= strlen(delimit_lookup)) | |
1621 break; | |
1622 sprintf(byte, "%c", delimit_lookup[lookup]); | |
1623 strcat(resp_96, byte); | |
1624 } | |
1625 | |
1626 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); | |
1627 yahoo_packet_hash(pack, 0, name); | |
1628 yahoo_packet_hash(pack, 6, resp_6); | |
1629 yahoo_packet_hash(pack, 96, resp_96); | |
1630 yahoo_packet_hash(pack, 1, name); | |
9306 | 1631 if (yd->picture_checksum) { |
1632 char *cksum = g_strdup_printf("%d", yd->picture_checksum); | |
1633 yahoo_packet_hash(pack, 192, cksum); | |
1634 g_free(cksum); | |
1635 } | |
6986 | 1636 yahoo_send_packet(yd, pack); |
1637 yahoo_packet_free(pack); | |
1638 | |
7424 | 1639 g_free(password_hash); |
1640 g_free(crypt_hash); | |
6986 | 1641 } |
1642 | |
5583 | 1643 static void yahoo_process_auth(GaimConnection *gc, struct yahoo_packet *pkt) |
3147 | 1644 { |
1645 char *seed = NULL; | |
1646 char *sn = NULL; | |
1647 GSList *l = pkt->hash; | |
7010 | 1648 int m = 0; |
9277 | 1649 gchar *buf; |
1650 | |
1651 | |
3147 | 1652 while (l) { |
1653 struct yahoo_pair *pair = l->data; | |
1654 if (pair->key == 94) | |
1655 seed = pair->value; | |
1656 if (pair->key == 1) | |
1657 sn = pair->value; | |
6986 | 1658 if (pair->key == 13) |
1659 m = atoi(pair->value); | |
3147 | 1660 l = l->next; |
1661 } | |
9277 | 1662 |
3147 | 1663 if (seed) { |
6986 | 1664 switch (m) { |
1665 case 0: | |
1666 yahoo_process_auth_old(gc, seed); | |
1667 break; | |
3147 | 1668 case 1: |
6986 | 1669 yahoo_process_auth_new(gc, seed); |
3147 | 1670 break; |
6986 | 1671 default: |
7043 | 1672 buf = g_strdup_printf(_("The Yahoo server has requested the use of an unrecognized " |
7129 | 1673 "authentication method. This version of Gaim will likely not be able " |
7043 | 1674 "to successfully sign on to Yahoo. Check %s for updates."), GAIM_WEBSITE); |
6986 | 1675 gaim_notify_error(gc, "", _("Failed Yahoo! Authentication"), |
7043 | 1676 buf); |
1677 g_free(buf); | |
6986 | 1678 yahoo_process_auth_new(gc, seed); /* Can't hurt to try it anyway. */ |
3147 | 1679 } |
1680 } | |
1681 } | |
2681 | 1682 |
9285 | 1683 static void ignore_buddy(GaimBuddy *buddy) { |
1684 GaimGroup *group; | |
1685 GaimConversation *conv; | |
6760 | 1686 GaimAccount *account; |
1687 gchar *name; | |
1688 | |
9285 | 1689 if (!buddy) |
6792 | 1690 return; |
6760 | 1691 |
9285 | 1692 group = gaim_find_buddys_group(buddy); |
1693 name = g_strdup(buddy->name); | |
1694 account = buddy->account; | |
6760 | 1695 |
6792 | 1696 gaim_debug(GAIM_DEBUG_INFO, "blist", |
9285 | 1697 "Removing '%s' from buddy list.\n", buddy->name); |
1698 serv_remove_buddy(account->gc, buddy, group); | |
1699 gaim_blist_remove_buddy(buddy); | |
6760 | 1700 |
6792 | 1701 serv_add_deny(account->gc, name); |
9285 | 1702 |
1703 conv = gaim_find_conversation_with_account(name, account); | |
1704 | |
1705 if (conv != NULL) | |
1706 gaim_conversation_update(conv, GAIM_CONV_UPDATE_REMOVE); | |
6760 | 1707 |
1708 g_free(name); | |
1709 } | |
1710 | |
1711 static void keep_buddy(GaimBuddy *b) { | |
1712 gaim_privacy_deny_remove(b->account, b->name, 1); | |
1713 } | |
1714 | |
1715 static void yahoo_process_ignore(GaimConnection *gc, struct yahoo_packet *pkt) { | |
1716 GaimBuddy *b; | |
1717 GSList *l; | |
1718 gchar *who = NULL; | |
1719 gchar *sn = NULL; | |
1720 gchar buf[BUF_LONG]; | |
1721 gint ignore = 0; | |
1722 gint status = 0; | |
1723 | |
1724 for (l = pkt->hash; l; l = l->next) { | |
1725 struct yahoo_pair *pair = l->data; | |
1726 switch (pair->key) { | |
1727 case 0: | |
1728 who = pair->value; | |
1729 break; | |
1730 case 1: | |
1731 sn = pair->value; | |
1732 break; | |
1733 case 13: | |
1734 ignore = strtol(pair->value, NULL, 10); | |
1735 break; | |
1736 case 66: | |
1737 status = strtol(pair->value, NULL, 10); | |
1738 break; | |
1739 default: | |
1740 break; | |
1741 } | |
1742 } | |
1743 | |
1744 switch (status) { | |
1745 case 12: | |
1746 b = gaim_find_buddy(gc->account, who); | |
1747 g_snprintf(buf, sizeof(buf), _("You have tried to ignore %s, but the " | |
1748 "user is on your buddy list. Clicking \"Yes\" " | |
1749 "will remove and ignore the buddy."), who); | |
1750 gaim_request_yes_no(gc, NULL, _("Ignore buddy?"), buf, 0, b, | |
1751 G_CALLBACK(ignore_buddy), | |
1752 G_CALLBACK(keep_buddy)); | |
1753 break; | |
1754 case 2: | |
1755 case 3: | |
1756 case 0: | |
1757 default: | |
1758 break; | |
1759 } | |
1760 } | |
1761 | |
6761 | 1762 static void yahoo_process_authresp(GaimConnection *gc, struct yahoo_packet *pkt) |
1763 { | |
1764 GSList *l = pkt->hash; | |
1765 int err = 0; | |
1766 char *msg; | |
7865 | 1767 char *url = NULL; |
1768 char *fullmsg; | |
6761 | 1769 |
1770 while (l) { | |
1771 struct yahoo_pair *pair = l->data; | |
1772 | |
1773 if (pair->key == 66) | |
1774 err = strtol(pair->value, NULL, 10); | |
7865 | 1775 if (pair->key == 20) |
1776 url = pair->value; | |
6761 | 1777 |
1778 l = l->next; | |
1779 } | |
1780 | |
1781 switch (err) { | |
1782 case 3: | |
7865 | 1783 msg = g_strdup(_("Invalid username.")); |
6761 | 1784 break; |
1785 case 13: | |
7865 | 1786 msg = g_strdup(_("Incorrect password.")); |
1787 break; | |
1788 case 14: | |
9280 | 1789 msg = g_strdup(_("Your account is locked, please log in to the Yahoo! website.")); |
6761 | 1790 break; |
1791 default: | |
9280 | 1792 msg = g_strdup_printf(_("Unknown error number %d. Logging into the Yahoo! website may fix this."), err); |
6761 | 1793 } |
7865 | 1794 |
1795 if (url) | |
1796 fullmsg = g_strdup_printf("%s\n%s", msg, url); | |
1797 else | |
1798 fullmsg = g_strdup(msg); | |
1799 | |
9280 | 1800 gc->wants_to_die = TRUE; |
7865 | 1801 gaim_connection_error(gc, fullmsg); |
1802 g_free(msg); | |
1803 g_free(fullmsg); | |
6761 | 1804 } |
1805 | |
6840 | 1806 static void yahoo_process_addbuddy(GaimConnection *gc, struct yahoo_packet *pkt) |
1807 { | |
1808 int err = 0; | |
1809 char *who = NULL; | |
1810 char *group = NULL; | |
7827 | 1811 char *decoded_group; |
6840 | 1812 char *buf; |
9278 | 1813 YahooFriend *f; |
6840 | 1814 GSList *l = pkt->hash; |
1815 | |
1816 while (l) { | |
1817 struct yahoo_pair *pair = l->data; | |
1818 | |
1819 switch (pair->key) { | |
1820 case 66: | |
1821 err = strtol(pair->value, NULL, 10); | |
1822 break; | |
1823 case 7: | |
1824 who = pair->value; | |
1825 break; | |
1826 case 65: | |
1827 group = pair->value; | |
1828 break; | |
1829 } | |
1830 | |
1831 l = l->next; | |
1832 } | |
1833 | |
1834 if (!who) | |
1835 return; | |
1836 if (!group) | |
1837 group = ""; | |
1838 | |
1839 if (!err || (err == 2)) { /* 0 = ok, 2 = already on serv list */ | |
9279 | 1840 f = yahoo_friend_find_or_new(gc, who); |
1841 yahoo_update_status(gc, who, f); | |
6840 | 1842 return; |
1843 } | |
1844 | |
7827 | 1845 decoded_group = yahoo_string_decode(gc, group, FALSE); |
6840 | 1846 buf = g_strdup_printf(_("Could not add buddy %s to group %s to the server list on account %s."), |
7827 | 1847 who, decoded_group, gaim_connection_get_display_name(gc)); |
6840 | 1848 gaim_notify_error(gc, NULL, _("Could not add buddy to server list"), buf); |
1849 g_free(buf); | |
7827 | 1850 g_free(decoded_group); |
6840 | 1851 } |
1852 | |
9062 | 1853 static void yahoo_process_p2p(GaimConnection *gc, struct yahoo_packet *pkt) |
1854 { | |
1855 GSList *l = pkt->hash; | |
1856 char *who = NULL; | |
1857 char *base64 = NULL; | |
9277 | 1858 char *decoded; |
9062 | 1859 int len; |
1860 | |
1861 while (l) { | |
1862 struct yahoo_pair *pair = l->data; | |
1863 | |
1864 switch (pair->key) { | |
1865 case 5: | |
1866 /* our identity */ | |
1867 break; | |
1868 case 4: | |
1869 who = pair->value; | |
1870 break; | |
1871 case 1: | |
1872 /* who again, the master identity this time? */ | |
1873 break; | |
1874 case 12: | |
1875 base64 = pair->value; | |
1876 /* so, this is an ip address. in base64. decoded it's in ascii. | |
1877 after strtol, it's in reversed byte order. Who thought this up?*/ | |
1878 break; | |
1879 /* | |
1880 TODO: figure these out | |
1881 yahoo: Key: 61 Value: 0 | |
1882 yahoo: Key: 2 Value: | |
1883 yahoo: Key: 13 Value: 0 | |
1884 yahoo: Key: 49 Value: PEERTOPEER | |
1885 yahoo: Key: 140 Value: 1 | |
1886 yahoo: Key: 11 Value: -1786225828 | |
1887 */ | |
1888 | |
1889 } | |
1890 | |
1891 l = l->next; | |
1892 } | |
1893 | |
9277 | 1894 if (base64) { |
9281 | 1895 guint32 ip; |
1896 char *tmp2; | |
1897 YahooFriend *f; | |
1898 | |
9062 | 1899 gaim_base64_decode(base64, &decoded, &len); |
9277 | 1900 if (len) { |
1901 char *tmp = gaim_str_binary_to_ascii(decoded, len); | |
1902 gaim_debug_info("yahoo", "Got P2P service packet (from server): who = %s, ip = %s\n", who, tmp); | |
1903 g_free(tmp); | |
1904 } | |
9281 | 1905 |
1906 tmp2 = g_strndup(decoded, len); /* so its \0 terminated...*/ | |
1907 ip = strtol(tmp2, NULL, 10); | |
1908 g_free(tmp2); | |
9062 | 1909 g_free(decoded); |
9281 | 1910 tmp2 = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, |
1911 (ip >> 24) & 0xff); | |
1912 f = yahoo_friend_find(gc, who); | |
1913 if (f) | |
1914 yahoo_friend_set_ip(f, tmp2); | |
1915 g_free(tmp2); | |
9062 | 1916 } |
1917 } | |
1918 | |
5583 | 1919 static void yahoo_packet_process(GaimConnection *gc, struct yahoo_packet *pkt) |
2681 | 1920 { |
6760 | 1921 switch (pkt->service) { |
2681 | 1922 case YAHOO_SERVICE_LOGON: |
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
1923 case YAHOO_SERVICE_LOGOFF: |
2681 | 1924 case YAHOO_SERVICE_ISAWAY: |
2737
f61c1f3a6afa
[gaim-migrate @ 2750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2724
diff
changeset
|
1925 case YAHOO_SERVICE_ISBACK: |
3019 | 1926 case YAHOO_SERVICE_GAMELOGON: |
1927 case YAHOO_SERVICE_GAMELOGOFF: | |
6686 | 1928 case YAHOO_SERVICE_CHATLOGON: |
1929 case YAHOO_SERVICE_CHATLOGOFF: | |
2681 | 1930 yahoo_process_status(gc, pkt); |
1931 break; | |
3019 | 1932 case YAHOO_SERVICE_NOTIFY: |
1933 yahoo_process_notify(gc, pkt); | |
2993 | 1934 break; |
2681 | 1935 case YAHOO_SERVICE_MESSAGE: |
2786
318f846120e2
[gaim-migrate @ 2799]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2772
diff
changeset
|
1936 case YAHOO_SERVICE_GAMEMSG: |
5939 | 1937 case YAHOO_SERVICE_CHATMSG: |
2681 | 1938 yahoo_process_message(gc, pkt); |
1939 break; | |
7865 | 1940 case YAHOO_SERVICE_SYSMESSAGE: |
1941 yahoo_process_sysmessage(gc, pkt); | |
1942 break; | |
2681 | 1943 case YAHOO_SERVICE_NEWMAIL: |
1944 yahoo_process_mail(gc, pkt); | |
1945 break; | |
1946 case YAHOO_SERVICE_NEWCONTACT: | |
1947 yahoo_process_contact(gc, pkt); | |
1948 break; | |
6784 | 1949 case YAHOO_SERVICE_AUTHRESP: |
1950 yahoo_process_authresp(gc, pkt); | |
1951 break; | |
2681 | 1952 case YAHOO_SERVICE_LIST: |
1953 yahoo_process_list(gc, pkt); | |
1954 break; | |
3147 | 1955 case YAHOO_SERVICE_AUTH: |
1956 yahoo_process_auth(gc, pkt); | |
1957 break; | |
6840 | 1958 case YAHOO_SERVICE_ADDBUDDY: |
1959 yahoo_process_addbuddy(gc, pkt); | |
1960 break; | |
6760 | 1961 case YAHOO_SERVICE_IGNORECONTACT: |
1962 yahoo_process_ignore(gc, pkt); | |
1963 break; | |
6729 | 1964 case YAHOO_SERVICE_CONFINVITE: |
1965 case YAHOO_SERVICE_CONFADDINVITE: | |
1966 yahoo_process_conference_invite(gc, pkt); | |
1967 break; | |
1968 case YAHOO_SERVICE_CONFDECLINE: | |
1969 yahoo_process_conference_decline(gc, pkt); | |
1970 break; | |
1971 case YAHOO_SERVICE_CONFLOGON: | |
1972 yahoo_process_conference_logon(gc, pkt); | |
1973 break; | |
1974 case YAHOO_SERVICE_CONFLOGOFF: | |
1975 yahoo_process_conference_logoff(gc, pkt); | |
1976 break; | |
1977 case YAHOO_SERVICE_CONFMSG: | |
1978 yahoo_process_conference_message(gc, pkt); | |
1979 break; | |
1980 case YAHOO_SERVICE_CHATONLINE: | |
1981 yahoo_process_chat_online(gc, pkt); | |
1982 break; | |
1983 case YAHOO_SERVICE_CHATLOGOUT: | |
1984 yahoo_process_chat_logout(gc, pkt); | |
1985 break; | |
1986 case YAHOO_SERVICE_CHATGOTO: | |
1987 yahoo_process_chat_goto(gc, pkt); | |
1988 break; | |
1989 case YAHOO_SERVICE_CHATJOIN: | |
1990 yahoo_process_chat_join(gc, pkt); | |
1991 break; | |
1992 case YAHOO_SERVICE_CHATLEAVE: /* XXX is this right? */ | |
1993 case YAHOO_SERVICE_CHATEXIT: | |
1994 yahoo_process_chat_exit(gc, pkt); | |
1995 break; | |
1996 case YAHOO_SERVICE_CHATINVITE: /* XXX never seen this one, might not do it right */ | |
1997 case YAHOO_SERVICE_CHATADDINVITE: | |
1998 yahoo_process_chat_addinvite(gc, pkt); | |
1999 break; | |
2000 case YAHOO_SERVICE_COMMENT: | |
2001 yahoo_process_chat_message(gc, pkt); | |
2002 break; | |
7651 | 2003 case YAHOO_SERVICE_P2PFILEXFER: |
2004 case YAHOO_SERVICE_FILETRANSFER: | |
2005 yahoo_process_filetransfer(gc, pkt); | |
2006 break; | |
9062 | 2007 case YAHOO_SERVICE_PEEPTOPEER: |
2008 yahoo_process_p2p(gc, pkt); | |
2009 break; | |
9284 | 2010 case YAHOO_SERVICE_PICTURE: |
2011 yahoo_process_picture(gc, pkt); | |
2012 break; | |
9292 | 2013 case YAHOO_SERVICE_PICTURE_UPDATE: |
2014 yahoo_process_picture_update(gc, pkt); | |
2015 break; | |
2016 case YAHOO_SERVICE_PICTURE_CHECKSUM: | |
2017 yahoo_process_picture_checksum(gc, pkt); | |
2018 break; | |
9306 | 2019 case YAHOO_SERVICE_PICTURE_UPLOAD: |
2020 yahoo_process_picture_upload(gc, pkt); | |
2021 break; | |
2681 | 2022 default: |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
2023 gaim_debug(GAIM_DEBUG_ERROR, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
2024 "Unhandled service 0x%02x\n", pkt->service); |
2681 | 2025 break; |
2026 } | |
2027 } | |
2028 | |
2029 static void yahoo_pending(gpointer data, gint source, GaimInputCondition cond) | |
2030 { | |
5583 | 2031 GaimConnection *gc = data; |
2681 | 2032 struct yahoo_data *yd = gc->proto_data; |
2033 char buf[1024]; | |
2034 int len; | |
2035 | |
2036 len = read(yd->fd, buf, sizeof(buf)); | |
2037 | |
2038 if (len <= 0) { | |
6321 | 2039 gaim_connection_error(gc, _("Unable to read")); |
2681 | 2040 return; |
2041 } | |
2042 | |
2043 yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen); | |
2044 memcpy(yd->rxqueue + yd->rxlen, buf, len); | |
2045 yd->rxlen += len; | |
2046 | |
2047 while (1) { | |
2048 struct yahoo_packet *pkt; | |
2049 int pos = 0; | |
2050 int pktlen; | |
2051 | |
2052 if (yd->rxlen < YAHOO_PACKET_HDRLEN) | |
2053 return; | |
2054 | |
2055 pos += 4; /* YMSG */ | |
2056 pos += 2; | |
2057 pos += 2; | |
2058 | |
2059 pktlen = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
2060 gaim_debug(GAIM_DEBUG_MISC, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
2061 "%d bytes to read, rxlen is %d\n", pktlen, yd->rxlen); |
2681 | 2062 |
2063 if (yd->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) | |
2064 return; | |
2065 | |
2066 yahoo_packet_dump(yd->rxqueue, YAHOO_PACKET_HDRLEN + pktlen); | |
2067 | |
2068 pkt = yahoo_packet_new(0, 0, 0); | |
2069 | |
2070 pkt->service = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
3021 | 2071 pkt->status = yahoo_get32(yd->rxqueue + pos); pos += 4; |
5220
7b9d78fa051e
[gaim-migrate @ 5590]
Christian Hammond <chipx86@chipx86.com>
parents:
5216
diff
changeset
|
2072 gaim_debug(GAIM_DEBUG_MISC, "yahoo", |
5216
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
2073 "Yahoo Service: 0x%02x Status: %d\n", |
00bd3019749e
[gaim-migrate @ 5586]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
2074 pkt->service, pkt->status); |
2681 | 2075 pkt->id = yahoo_get32(yd->rxqueue + pos); pos += 4; |
2076 | |
2077 yahoo_packet_read(pkt, yd->rxqueue + pos, pktlen); | |
2078 | |
2079 yd->rxlen -= YAHOO_PACKET_HDRLEN + pktlen; | |
2080 if (yd->rxlen) { | |
2081 char *tmp = g_memdup(yd->rxqueue + YAHOO_PACKET_HDRLEN + pktlen, yd->rxlen); | |
2082 g_free(yd->rxqueue); | |
2083 yd->rxqueue = tmp; | |
2084 } else { | |
2085 g_free(yd->rxqueue); | |
2086 yd->rxqueue = NULL; | |
2087 } | |
2088 | |
2089 yahoo_packet_process(gc, pkt); | |
2090 | |
2091 yahoo_packet_free(pkt); | |
2092 } | |
2093 } | |
2094 | |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2095 #ifndef YAHOO_WEBMESSENGER |
2681 | 2096 static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) |
2097 { | |
5583 | 2098 GaimConnection *gc = data; |
2681 | 2099 struct yahoo_data *yd; |
2100 struct yahoo_packet *pkt; | |
2101 | |
5590
011a0a975060
[gaim-migrate @ 5994]
Christian Hammond <chipx86@chipx86.com>
parents:
5583
diff
changeset
|
2102 if (!g_list_find(gaim_connections_get_all(), gc)) { |
2681 | 2103 close(source); |
2104 return; | |
2105 } | |
2106 | |
2107 if (source < 0) { | |
8057 | 2108 gaim_connection_error(gc, _("Unable to connect.")); |
2681 | 2109 return; |
2110 } | |
2111 | |
2112 yd = gc->proto_data; | |
2113 yd->fd = source; | |
2114 | |
3147 | 2115 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0); |
2681 | 2116 |
7261 | 2117 yahoo_packet_hash(pkt, 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc)))); |
2681 | 2118 yahoo_send_packet(yd, pkt); |
2119 | |
2120 yahoo_packet_free(pkt); | |
2121 | |
2122 gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); | |
2123 } | |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2124 #endif |
2681 | 2125 |
7134 | 2126 #ifdef YAHOO_WEBMESSENGER |
2127 static void yahoo_got_web_connected(gpointer data, gint source, GaimInputCondition cond) | |
2128 { | |
2129 GaimConnection *gc = data; | |
2130 struct yahoo_data *yd; | |
2131 struct yahoo_packet *pkt; | |
2132 | |
2133 if (!g_list_find(gaim_connections_get_all(), gc)) { | |
2134 close(source); | |
2135 return; | |
2136 } | |
2137 | |
2138 if (source < 0) { | |
8057 | 2139 gaim_connection_error(gc, _("Unable to connect.")); |
7134 | 2140 return; |
2141 } | |
2142 | |
2143 yd = gc->proto_data; | |
2144 yd->fd = source; | |
2145 | |
2146 pkt = yahoo_packet_new(YAHOO_SERVICE_WEBLOGIN, YAHOO_STATUS_WEBLOGIN, 0); | |
2147 | |
7261 | 2148 yahoo_packet_hash(pkt, 0, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc)))); |
2149 yahoo_packet_hash(pkt, 1, gaim_normalize(gc->account, gaim_account_get_username(gaim_connection_get_account(gc)))); | |
7134 | 2150 yahoo_packet_hash(pkt, 6, yd->auth); |
2151 yahoo_send_packet(yd, pkt); | |
2152 | |
2153 yahoo_packet_free(pkt); | |
2154 g_free(yd->auth); | |
2155 gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); | |
2156 } | |
2157 | |
2158 static void yahoo_web_pending(gpointer data, gint source, GaimInputCondition cond) | |
2159 { | |
2160 GaimConnection *gc = data; | |
2161 GaimAccount *account = gaim_connection_get_account(gc); | |
2162 struct yahoo_data *yd = gc->proto_data; | |
8243 | 2163 char buf[2048], *i = buf; |
8161 | 2164 int len; |
2165 GString *s; | |
7134 | 2166 |
8118 | 2167 len = read(source, buf, sizeof(buf)-1); |
8216
dcace041cfb8
[gaim-migrate @ 8939]
Christian Hammond <chipx86@chipx86.com>
parents:
8212
diff
changeset
|
2168 if (len <= 0 || (strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302")) && |
dcace041cfb8
[gaim-migrate @ 8939]
Christian Hammond <chipx86@chipx86.com>
parents:
8212
diff
changeset
|
2169 strncmp(buf, "HTTP/1.1 302", strlen("HTTP/1.1 302")))) { |
7134 | 2170 gaim_connection_error(gc, _("Unable to read")); |
2171 return; | |
2172 } | |
8161 | 2173 |
2174 s = g_string_sized_new(len); | |
8118 | 2175 buf[sizeof(buf)-1] = '\0'; |
8161 | 2176 |
2177 while ((i = strstr(i, "Set-Cookie: "))) { | |
2178 i += strlen("Set-Cookie: "); | |
8243 | 2179 for (;*i != ';' && *i != '\0'; i++) |
8161 | 2180 g_string_append_c(s, *i); |
2181 | |
2182 g_string_append(s, "; "); | |
7134 | 2183 } |
8161 | 2184 |
2185 yd->auth = g_string_free(s, FALSE); | |
7134 | 2186 gaim_input_remove(gc->inpa); |
2187 close(source); | |
2188 /* Now we have our cookies to login with. I'll go get the milk. */ | |
8045 | 2189 if (gaim_proxy_connect(account, "wcs2.msg.dcn.yahoo.com", |
7134 | 2190 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), |
2191 yahoo_got_web_connected, gc) != 0) { | |
2192 gaim_connection_error(gc, _("Connection problem")); | |
2193 return; | |
2194 } | |
2195 } | |
2196 | |
2197 static void yahoo_got_cookies(gpointer data, gint source, GaimInputCondition cond) | |
2198 { | |
2199 GaimConnection *gc = data; | |
2200 struct yahoo_data *yd = gc->proto_data; | |
2201 if (source < 0) { | |
8057 | 2202 gaim_connection_error(gc, _("Unable to connect.")); |
7134 | 2203 return; |
2204 } | |
2205 write(source, yd->auth, strlen(yd->auth)); | |
2206 g_free(yd->auth); | |
2207 gc->inpa = gaim_input_add(source, GAIM_INPUT_READ, yahoo_web_pending, gc); | |
2208 } | |
2209 | |
2210 static void yahoo_login_page_hash_iter(const char *key, const char *val, GString *url) | |
2211 { | |
2212 if (!strcmp(key, "passwd")) | |
2213 return; | |
2214 url = g_string_append_c(url, '&'); | |
2215 url = g_string_append(url, key); | |
2216 url = g_string_append_c(url, '='); | |
2217 if (!strcmp(key, ".save") || !strcmp(key, ".js")) | |
2218 url = g_string_append_c(url, '1'); | |
2219 else if (!strcmp(key, ".challenge")) | |
2220 url = g_string_append(url, val); | |
2221 else | |
2222 url = g_string_append(url, gaim_url_encode(val)); | |
2223 } | |
2224 | |
2225 static GHashTable *yahoo_login_page_hash(const char *buf, size_t len) | |
2226 { | |
2227 GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2228 const char *c = buf; |
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2229 char *d; |
7134 | 2230 char name[64], value[64]; |
8118 | 2231 int count = sizeof(name)-1; |
7134 | 2232 while ((c < (buf + len)) && (c = strstr(c, "<input "))) { |
2233 c = strstr(c, "name=\"") + strlen("name=\""); | |
8118 | 2234 for (d = name; *c!='"' && count; c++, d++, count--) |
7134 | 2235 *d = *c; |
2236 *d = '\0'; | |
8118 | 2237 count = sizeof(value)-1; |
7134 | 2238 d = strstr(c, "value=\"") + strlen("value=\""); |
2239 if (strchr(c, '>') < d) | |
2240 break; | |
8118 | 2241 for (c = d, d = value; *c!='"' && count; c++, d++, count--) |
7134 | 2242 *d = *c; |
2243 *d = '\0'; | |
2244 g_hash_table_insert(hash, g_strdup(name), g_strdup(value)); | |
2245 } | |
2246 return hash; | |
2247 } | |
2248 | |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2249 static void yahoo_login_page_cb(void *user_data, const char *buf, size_t len) |
7134 | 2250 { |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2251 GaimConnection *gc = (GaimConnection *)user_data; |
7134 | 2252 GaimAccount *account = gaim_connection_get_account(gc); |
2253 struct yahoo_data *yd = gc->proto_data; | |
2254 const char *sn = gaim_account_get_username(account); | |
2255 const char *pass = gaim_account_get_password(account); | |
2256 GHashTable *hash = yahoo_login_page_hash(buf, len); | |
2257 GString *url = g_string_new("GET /config/login?login="); | |
2258 char md5[33], *hashp = md5, *chal; | |
2259 int i; | |
2260 md5_byte_t result[16]; | |
2261 md5_state_t ctx; | |
7191
4bd3892cded3
[gaim-migrate @ 7760]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7161
diff
changeset
|
2262 |
4bd3892cded3
[gaim-migrate @ 7760]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7161
diff
changeset
|
2263 url = g_string_append(url, sn); |
4bd3892cded3
[gaim-migrate @ 7760]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7161
diff
changeset
|
2264 url = g_string_append(url, "&passwd="); |
4bd3892cded3
[gaim-migrate @ 7760]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7161
diff
changeset
|
2265 |
7134 | 2266 md5_init(&ctx); |
2267 md5_append(&ctx, pass, strlen(pass)); | |
2268 md5_finish(&ctx, result); | |
2269 for (i = 0; i < 16; ++i) { | |
2270 g_snprintf(hashp, 3, "%02x", result[i]); | |
2271 hashp += 2; | |
2272 } | |
2273 chal = g_strconcat(md5, g_hash_table_lookup(hash, ".challenge"), NULL); | |
2274 md5_init(&ctx); | |
2275 md5_append(&ctx, chal, strlen(chal)); | |
2276 md5_finish(&ctx, result); | |
2277 hashp = md5; | |
2278 for (i = 0; i < 16; ++i) { | |
2279 g_snprintf(hashp, 3, "%02x", result[i]); | |
2280 hashp += 2; | |
2281 } | |
2282 /* | |
2283 md5_init(&ctx); | |
2284 md5_append(&ctx, md5, strlen(md5)); | |
2285 md5_finish(&ctx, result); | |
2286 hashp = md5; | |
2287 for (i = 0; i < 16; ++i) { | |
2288 g_snprintf(hashp, 3, "%02x", result[i]); | |
2289 hashp += 2; | |
2290 } | |
2291 */ | |
2292 g_free(chal); | |
2293 | |
2294 url = g_string_append(url, md5); | |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2295 g_hash_table_foreach(hash, (GHFunc)yahoo_login_page_hash_iter, url); |
7134 | 2296 |
2297 url = g_string_append(url, "&.hash=1&.md5=1 HTTP/1.1\r\n" | |
2298 "Host: login.yahoo.com\r\n\r\n"); | |
2299 g_hash_table_destroy(hash); | |
2300 yd->auth = g_string_free(url, FALSE); | |
2301 if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, gc) != 0) { | |
2302 gaim_connection_error(gc, _("Connection problem")); | |
2303 return; | |
2304 } | |
2305 } | |
2306 | |
2307 #endif /* YAHOO_WEBMESSENGER */ | |
2308 | |
7883 | 2309 #ifndef YAHOO_WEBMESSENGER |
2310 static void yahoo_server_check(GaimAccount *account) | |
2311 { | |
2312 const char *server; | |
2313 | |
2314 server = gaim_account_get_string(account, "server", YAHOO_PAGER_HOST); | |
2315 | |
2316 if (strcmp(server, "scs.yahoo.com") == 0) | |
2317 gaim_account_set_string(account, "server", YAHOO_PAGER_HOST); | |
2318 } | |
9306 | 2319 |
2320 static void yahoo_picture_check(GaimAccount *account) | |
2321 { | |
2322 GaimConnection *gc = gaim_account_get_connection(account); | |
2323 const char *buddyicon; | |
2324 | |
2325 buddyicon = gaim_account_get_buddy_icon(account); | |
2326 yahoo_set_buddy_icon(gc, buddyicon); | |
2327 } | |
2328 | |
7883 | 2329 #endif |
2330 | |
5583 | 2331 static void yahoo_login(GaimAccount *account) { |
2332 GaimConnection *gc = gaim_account_get_connection(account); | |
2681 | 2333 struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); |
2334 | |
9041 | 2335 gc->flags |= GAIM_CONNECTION_HTML | GAIM_CONNECTION_NO_BGCOLOR | GAIM_CONNECTION_NO_URLDESC; |
6629 | 2336 |
5583 | 2337 gaim_connection_update_progress(gc, _("Connecting"), 1, 2); |
2681 | 2338 |
8235 | 2339 gaim_connection_set_display_name(gc, gaim_account_get_username(account)); |
2340 | |
2681 | 2341 yd->fd = -1; |
6784 | 2342 yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free); |
6729 | 2343 yd->confs = NULL; |
2344 yd->conf_id = 2; | |
2681 | 2345 |
7134 | 2346 #ifndef YAHOO_WEBMESSENGER |
7827 | 2347 |
7883 | 2348 yahoo_server_check(account); |
9306 | 2349 yahoo_picture_check(account); |
7883 | 2350 |
9164 | 2351 if (gaim_account_get_bool(account, "yahoojp", FALSE)) { |
2352 yd->jp = TRUE; | |
2353 if (gaim_proxy_connect(account, | |
2354 gaim_account_get_string(account, "serverjp", YAHOOJP_PAGER_HOST), | |
2355 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), | |
2356 yahoo_got_connected, gc) != 0) | |
2357 { | |
2358 gaim_connection_error(gc, _("Connection problem")); | |
2359 return; | |
2360 } | |
2361 } else { | |
2362 yd->jp = FALSE; | |
2363 if (gaim_proxy_connect(account, | |
2364 gaim_account_get_string(account, "server", YAHOO_PAGER_HOST), | |
2365 gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), | |
2366 yahoo_got_connected, gc) != 0) | |
2367 { | |
2368 gaim_connection_error(gc, _("Connection problem")); | |
2369 return; | |
2370 } | |
2681 | 2371 } |
7134 | 2372 #else |
7138
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2373 gaim_url_fetch(WEBMESSENGER_URL, TRUE, "Gaim/" VERSION, FALSE, |
f189f8ccaa98
[gaim-migrate @ 7705]
Christian Hammond <chipx86@chipx86.com>
parents:
7134
diff
changeset
|
2374 yahoo_login_page_cb, gc); |
7134 | 2375 #endif |
2681 | 2376 |
2377 } | |
2378 | |
5583 | 2379 static void yahoo_close(GaimConnection *gc) { |
2681 | 2380 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; |
6729 | 2381 |
6784 | 2382 g_hash_table_destroy(yd->friends); |
6729 | 2383 g_slist_free(yd->confs); |
6784 | 2384 if (yd->chat_name) |
2385 g_free(yd->chat_name); | |
6729 | 2386 |
7651 | 2387 if (yd->cookie_y) |
2388 g_free(yd->cookie_y); | |
2389 if (yd->cookie_t) | |
2390 g_free(yd->cookie_t); | |
2391 | |
2681 | 2392 if (yd->fd >= 0) |
2393 close(yd->fd); | |
3720
34c95669952f
[gaim-migrate @ 3853]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3642
diff
changeset
|
2394 |
2681 | 2395 if (yd->rxqueue) |
2396 g_free(yd->rxqueue); | |
2687
2d544f48146d
[gaim-migrate @ 2700]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2686
diff
changeset
|
2397 yd->rxlen = 0; |
9306 | 2398 if (yd->picture_url) |
2399 g_free(yd->picture_url); | |
2400 if (yd->picture_upload_todo) | |
2401 yahoo_buddy_icon_upload_data_free(yd->picture_upload_todo); | |
2681 | 2402 if (gc->inpa) |
2403 gaim_input_remove(gc->inpa); | |
2404 g_free(yd); | |
2405 } | |
2406 | |
6695 | 2407 static const char *yahoo_list_icon(GaimAccount *a, GaimBuddy *b) |
2681 | 2408 { |
4687 | 2409 return "yahoo"; |
2681 | 2410 } |
4916 | 2411 |
6695 | 2412 static void yahoo_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne) |
4916 | 2413 { |
2414 int i = 0; | |
2415 char *emblems[4] = {NULL,NULL,NULL,NULL}; | |
6784 | 2416 GaimAccount *account; |
2417 GaimConnection *gc; | |
2418 struct yahoo_data *yd; | |
9278 | 2419 YahooFriend *f; |
6784 | 2420 |
2421 if (!b || !(account = b->account) || !(gc = gaim_account_get_connection(account)) || | |
2422 !(yd = gc->proto_data)) | |
2423 return; | |
2424 | |
9279 | 2425 f = yahoo_friend_find(gc, b->name); |
6784 | 2426 if (!f) { |
2427 *se = "notauthorized"; | |
2428 return; | |
2429 } | |
2430 | |
5068 | 2431 if (b->present == GAIM_BUDDY_OFFLINE) { |
4916 | 2432 *se = "offline"; |
2433 return; | |
2434 } else { | |
6784 | 2435 if (f->away) |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
2436 emblems[i++] = "away"; |
6784 | 2437 if (f->sms) |
2438 emblems[i++] = "wireless"; | |
9283 | 2439 if (yahoo_friend_get_game(f)) |
4916 | 2440 emblems[i++] = "game"; |
2441 } | |
2442 *se = emblems[0]; | |
2443 *sw = emblems[1]; | |
2444 *nw = emblems[2]; | |
2445 *ne = emblems[3]; | |
2446 } | |
2681 | 2447 |
2448 static char *yahoo_get_status_string(enum yahoo_status a) | |
2449 { | |
2450 switch (a) { | |
2451 case YAHOO_STATUS_BRB: | |
4596 | 2452 return _("Be Right Back"); |
2681 | 2453 case YAHOO_STATUS_BUSY: |
4596 | 2454 return _("Busy"); |
2681 | 2455 case YAHOO_STATUS_NOTATHOME: |
4596 | 2456 return _("Not At Home"); |
2681 | 2457 case YAHOO_STATUS_NOTATDESK: |
4596 | 2458 return _("Not At Desk"); |
2681 | 2459 case YAHOO_STATUS_NOTINOFFICE: |
4596 | 2460 return _("Not In Office"); |
2681 | 2461 case YAHOO_STATUS_ONPHONE: |
4606 | 2462 return _("On The Phone"); |
2681 | 2463 case YAHOO_STATUS_ONVACATION: |
4596 | 2464 return _("On Vacation"); |
2681 | 2465 case YAHOO_STATUS_OUTTOLUNCH: |
4596 | 2466 return _("Out To Lunch"); |
2681 | 2467 case YAHOO_STATUS_STEPPEDOUT: |
4596 | 2468 return _("Stepped Out"); |
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
2469 case YAHOO_STATUS_INVISIBLE: |
4596 | 2470 return _("Invisible"); |
4730 | 2471 case YAHOO_STATUS_IDLE: |
2472 return _("Idle"); | |
6784 | 2473 case YAHOO_STATUS_OFFLINE: |
2474 return _("Offline"); | |
2879
5fc5123b7098
[gaim-migrate @ 2892]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2878
diff
changeset
|
2475 default: |
4596 | 2476 return _("Online"); |
2681 | 2477 } |
2478 } | |
2479 | |
9030 | 2480 static void yahoo_initiate_conference(GaimBlistNode *node, gpointer data) { |
2481 | |
2482 GaimBuddy *buddy; | |
2483 GaimConnection *gc; | |
2484 | |
6729 | 2485 GHashTable *components; |
2486 struct yahoo_data *yd; | |
2487 int id; | |
2488 | |
9030 | 2489 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
2490 | |
2491 buddy = (GaimBuddy *) node; | |
2492 gc = gaim_account_get_connection(buddy->account); | |
6729 | 2493 yd = gc->proto_data; |
2494 id = yd->conf_id; | |
2495 | |
2496 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
2497 g_hash_table_replace(components, g_strdup("room"), | |
2498 g_strdup_printf("%s-%d", gaim_connection_get_display_name(gc), id)); | |
2499 g_hash_table_replace(components, g_strdup("topic"), g_strdup("Join my conference...")); | |
2500 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference")); | |
2501 yahoo_c_join(gc, components); | |
2502 g_hash_table_destroy(components); | |
2503 | |
9030 | 2504 yahoo_c_invite(gc, id, "Join my conference...", buddy->name); |
6729 | 2505 } |
2506 | |
9030 | 2507 static void yahoo_game(GaimBlistNode *node, gpointer data) { |
2508 | |
2509 GaimBuddy *buddy; | |
2510 GaimConnection *gc; | |
2511 | |
2512 struct yahoo_data *yd; | |
9283 | 2513 const char *game; |
2514 char *game2; | |
3019 | 2515 char *t; |
2516 char url[256]; | |
9278 | 2517 YahooFriend *f; |
3019 | 2518 |
9030 | 2519 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
2520 | |
2521 buddy = (GaimBuddy *) node; | |
2522 gc = gaim_account_get_connection(buddy->account); | |
2523 yd = (struct yahoo_data *) gc->proto_data; | |
2524 | |
9279 | 2525 f = yahoo_friend_find(gc, buddy->name); |
6784 | 2526 if (!f) |
2527 return; | |
2528 | |
9283 | 2529 game = yahoo_friend_get_game(f); |
3019 | 2530 if (!game) |
2531 return; | |
6784 | 2532 |
9283 | 2533 t = game2 = g_strdup(strstr(game, "ante?room=")); |
2534 while (*t && *t != '\t') | |
3019 | 2535 t++; |
2536 *t = 0; | |
9283 | 2537 g_snprintf(url, sizeof url, "http://games.yahoo.com/games/%s", game2); |
6465
fb64cc87bc96
[gaim-migrate @ 6974]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
2538 gaim_notify_uri(gc, url); |
9283 | 2539 g_free(game2); |
3019 | 2540 } |
4722 | 2541 |
6695 | 2542 static char *yahoo_status_text(GaimBuddy *b) |
4722 | 2543 { |
9278 | 2544 YahooFriend *f = NULL; |
9283 | 2545 const char *msg; |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
2546 |
9279 | 2547 f = yahoo_friend_find(b->account->gc, b->name); |
6784 | 2548 if (!f) |
2549 return g_strdup(_("Not on server list")); | |
2550 | |
2551 switch (f->status) { | |
2552 case YAHOO_STATUS_AVAILABLE: | |
2553 return NULL; | |
2554 case YAHOO_STATUS_IDLE: | |
2555 if (f->idle == -1) | |
2556 return g_strdup(yahoo_get_status_string(f->status)); | |
2557 return NULL; | |
2558 case YAHOO_STATUS_CUSTOM: | |
9283 | 2559 if (!(msg = yahoo_friend_get_status_message(f))) |
6784 | 2560 return NULL; |
9283 | 2561 return g_markup_escape_text(msg, strlen(msg)); |
9224 | 2562 |
6784 | 2563 default: |
2564 return g_strdup(yahoo_get_status_string(f->status)); | |
2565 } | |
4722 | 2566 } |
2567 | |
9220 | 2568 char *yahoo_tooltip_text(GaimBuddy *b) |
4724 | 2569 { |
9278 | 2570 YahooFriend *f; |
6784 | 2571 char *escaped, *status, *ret; |
2572 | |
9279 | 2573 f = yahoo_friend_find(b->account->gc, b->name); |
6784 | 2574 if (!f) |
8591 | 2575 status = g_strdup_printf("\n%s", _("Not on server list")); |
6784 | 2576 else |
2577 switch (f->status) { | |
2578 case YAHOO_STATUS_IDLE: | |
2579 if (f->idle == -1) { | |
2580 status = g_strdup(yahoo_get_status_string(f->status)); | |
2581 break; | |
2582 } | |
2583 return NULL; | |
2584 case YAHOO_STATUS_CUSTOM: | |
9283 | 2585 if (!yahoo_friend_get_status_message(f)) |
6784 | 2586 return NULL; |
9283 | 2587 status = g_strdup(yahoo_friend_get_status_message(f)); |
6784 | 2588 break; |
2589 default: | |
2590 status = g_strdup(yahoo_get_status_string(f->status)); | |
2591 break; | |
4745 | 2592 } |
6784 | 2593 |
2594 escaped = g_markup_escape_text(status, strlen(status)); | |
8591 | 2595 ret = g_strdup_printf(_("\n<b>%s:</b> %s"), _("Status"), escaped); |
6784 | 2596 g_free(status); |
2597 g_free(escaped); | |
2598 | |
2599 return ret; | |
4729 | 2600 } |
2601 | |
9030 | 2602 static void yahoo_addbuddyfrommenu_cb(GaimBlistNode *node, gpointer data) |
2603 { | |
2604 GaimBuddy *buddy; | |
2605 GaimConnection *gc; | |
2606 | |
2607 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
2608 | |
2609 buddy = (GaimBuddy *) node; | |
2610 gc = gaim_account_get_connection(buddy->account); | |
2611 | |
9285 | 2612 yahoo_add_buddy(gc, buddy, NULL); |
9030 | 2613 } |
2614 | |
2615 | |
2616 static void yahoo_chat_goto_menu(GaimBlistNode *node, gpointer data) | |
6796 | 2617 { |
9030 | 2618 GaimBuddy *buddy; |
2619 GaimConnection *gc; | |
2620 | |
2621 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
2622 | |
2623 buddy = (GaimBuddy *) node; | |
2624 gc = gaim_account_get_connection(buddy->account); | |
2625 | |
2626 yahoo_chat_goto(gc, buddy->name); | |
6796 | 2627 } |
2628 | |
9030 | 2629 |
2630 static void yahoo_ask_send_file_menu(GaimBlistNode *node, gpointer data) | |
2631 { | |
2632 GaimBuddy *buddy; | |
2633 GaimConnection *gc; | |
2634 | |
2635 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
2636 | |
2637 buddy = (GaimBuddy *) node; | |
2638 gc = gaim_account_get_connection(buddy->account); | |
2639 | |
2640 yahoo_ask_send_file(gc, buddy->name); | |
2641 } | |
2642 | |
2643 | |
2644 static GList *yahoo_buddy_menu(GaimBuddy *buddy) | |
2681 | 2645 { |
2646 GList *m = NULL; | |
9030 | 2647 GaimBlistNodeAction *act; |
2648 | |
2649 GaimConnection *gc = gaim_account_get_connection(buddy->account); | |
3019 | 2650 static char buf2[1024]; |
9278 | 2651 YahooFriend *f; |
6784 | 2652 |
9279 | 2653 f = yahoo_friend_find(gc, buddy->name); |
6784 | 2654 |
2655 if (!f) { | |
9030 | 2656 act = gaim_blist_node_action_new(_("Add Buddy"), |
2657 yahoo_addbuddyfrommenu_cb, NULL); | |
2658 m = g_list_append(m, act); | |
6784 | 2659 |
2660 return m; | |
9030 | 2661 |
2662 } else if (f->status == YAHOO_STATUS_OFFLINE) { | |
6784 | 2663 return NULL; |
9030 | 2664 } |
2665 | |
2666 act = gaim_blist_node_action_new(_("Join in Chat"), | |
2667 yahoo_chat_goto_menu, NULL); | |
2668 m = g_list_append(m, act); | |
2669 | |
2670 act = gaim_blist_node_action_new(_("Initiate Conference"), | |
2671 yahoo_initiate_conference, NULL); | |
2672 m = g_list_append(m, act); | |
6729 | 2673 |
7651 | 2674 /* FIXME: remove this when the ui does it for us. */ |
9030 | 2675 act = gaim_blist_node_action_new(_("Send File"), |
2676 yahoo_ask_send_file_menu, NULL); | |
2677 m = g_list_append(m, act); | |
7651 | 2678 |
9283 | 2679 if (yahoo_friend_get_game(f)) { |
2680 const char *game = yahoo_friend_get_game(f); | |
3019 | 2681 char *room; |
6784 | 2682 char *t; |
2683 | |
2684 if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ | |
2685 return m; | |
2686 while (*room && *room != '\t') /* skip to the tab */ | |
2687 room++; | |
2688 t = room++; /* room as now at the name */ | |
2689 while (*t != '\n') | |
2690 t++; /* replace the \n with a space */ | |
2691 *t = ' '; | |
2692 g_snprintf(buf2, sizeof buf2, "%s", room); | |
9030 | 2693 |
2694 act = gaim_blist_node_action_new(buf2, yahoo_game, NULL); | |
2695 m = g_list_append(m, act); | |
3019 | 2696 } |
6729 | 2697 |
2681 | 2698 return m; |
2699 } | |
2700 | |
9030 | 2701 |
2702 static GList *yahoo_blist_node_menu(GaimBlistNode *node) | |
2703 { | |
2704 if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
2705 return yahoo_buddy_menu((GaimBuddy *) node); | |
2706 } else { | |
2707 return NULL; | |
2708 } | |
2709 } | |
2710 | |
2711 | |
5583 | 2712 static void yahoo_act_id(GaimConnection *gc, const char *entry) |
2681 | 2713 { |
2714 struct yahoo_data *yd = gc->proto_data; | |
2715 | |
2716 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0); | |
2717 yahoo_packet_hash(pkt, 3, entry); | |
2718 yahoo_send_packet(yd, pkt); | |
2719 yahoo_packet_free(pkt); | |
2720 | |
5583 | 2721 gaim_connection_set_display_name(gc, entry); |
2681 | 2722 } |
2723 | |
9015 | 2724 static void yahoo_show_act_id(GaimPluginAction *action) |
2681 | 2725 { |
9015 | 2726 GaimConnection *gc = (GaimConnection *) action->context; |
5493
3e8487580024
[gaim-migrate @ 5889]
Christian Hammond <chipx86@chipx86.com>
parents:
5436
diff
changeset
|
2727 gaim_request_input(gc, NULL, _("Active which ID?"), NULL, |
8697 | 2728 gaim_connection_get_display_name(gc), FALSE, FALSE, NULL, |
5493
3e8487580024
[gaim-migrate @ 5889]
Christian Hammond <chipx86@chipx86.com>
parents:
5436
diff
changeset
|
2729 _("OK"), G_CALLBACK(yahoo_act_id), |
3e8487580024
[gaim-migrate @ 5889]
Christian Hammond <chipx86@chipx86.com>
parents:
5436
diff
changeset
|
2730 _("Cancel"), NULL, gc); |
2681 | 2731 } |
2732 | |
9015 | 2733 static void yahoo_show_chat_goto(GaimPluginAction *action) |
7878 | 2734 { |
9015 | 2735 GaimConnection *gc = (GaimConnection *) action->context; |
7878 | 2736 gaim_request_input(gc, NULL, _("Join who in chat?"), NULL, |
8697 | 2737 "", FALSE, FALSE, NULL, |
7878 | 2738 _("OK"), G_CALLBACK(yahoo_chat_goto), |
2739 _("Cancel"), NULL, gc); | |
2740 } | |
2741 | |
9015 | 2742 static GList *yahoo_actions(GaimPlugin *plugin, gpointer context) { |
2681 | 2743 GList *m = NULL; |
9015 | 2744 GaimPluginAction *act; |
2745 | |
2746 act = gaim_plugin_action_new(_("Activate ID..."), | |
2747 yahoo_show_act_id); | |
2748 m = g_list_append(m, act); | |
2749 | |
2750 act = gaim_plugin_action_new(_("Join user in chat..."), | |
2751 yahoo_show_chat_goto); | |
2752 m = g_list_append(m, act); | |
7878 | 2753 |
2681 | 2754 return m; |
2755 } | |
2756 | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7112
diff
changeset
|
2757 static int yahoo_send_im(GaimConnection *gc, const char *who, const char *what, GaimConvImFlags flags) |
2681 | 2758 { |
2759 struct yahoo_data *yd = gc->proto_data; | |
2760 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); | |
6629 | 2761 char *msg = yahoo_html_to_codes(what); |
7827 | 2762 char *msg2; |
2763 gboolean utf8 = TRUE; | |
2764 | |
2765 msg2 = yahoo_string_encode(gc, msg, &utf8); | |
2681 | 2766 |
5583 | 2767 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); |
2681 | 2768 yahoo_packet_hash(pkt, 5, who); |
7827 | 2769 if (utf8) |
2770 yahoo_packet_hash(pkt, 97, "1"); | |
2771 yahoo_packet_hash(pkt, 14, msg2); | |
2772 | |
9280 | 2773 yahoo_packet_hash(pkt, 63, ";0"); /* IMvironment */ |
2774 yahoo_packet_hash(pkt, 64, "0"); /* no idea */ | |
9062 | 2775 yahoo_packet_hash(pkt, 1002, "1"); /* no idea, Yahoo 6 or later only it seems */ |
9306 | 2776 if (!yd->picture_url) |
2777 yahoo_packet_hash(pkt, 206, "0"); /* 0 = no picture, 2 = picture, maybe 1 = avatar? */ | |
2778 else | |
2779 yahoo_packet_hash(pkt, 206, "2"); | |
2681 | 2780 |
2781 yahoo_send_packet(yd, pkt); | |
2782 | |
2783 yahoo_packet_free(pkt); | |
6629 | 2784 |
2785 g_free(msg); | |
7827 | 2786 g_free(msg2); |
6629 | 2787 |
2681 | 2788 return 1; |
2789 } | |
2790 | |
6059 | 2791 int yahoo_send_typing(GaimConnection *gc, const char *who, int typ) |
2993 | 2792 { |
2793 struct yahoo_data *yd = gc->proto_data; | |
3019 | 2794 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); |
2993 | 2795 yahoo_packet_hash(pkt, 49, "TYPING"); |
5583 | 2796 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); |
2993 | 2797 yahoo_packet_hash(pkt, 14, " "); |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
2798 yahoo_packet_hash(pkt, 13, typ == GAIM_TYPING ? "1" : "0"); |
2993 | 2799 yahoo_packet_hash(pkt, 5, who); |
2800 yahoo_packet_hash(pkt, 1002, "1"); | |
2801 | |
2802 yahoo_send_packet(yd, pkt); | |
2803 | |
2804 yahoo_packet_free(pkt); | |
2805 | |
3001 | 2806 return 0; |
2993 | 2807 } |
2808 | |
6059 | 2809 static void yahoo_set_away(GaimConnection *gc, const char *state, const char *msg) |
2681 | 2810 { |
2811 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
2812 struct yahoo_packet *pkt; | |
2772
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
2813 int service; |
2681 | 2814 char s[4]; |
7827 | 2815 char *conv_msg = NULL; |
8503 | 2816 char *conv_msg2 = NULL; |
6691
306790891ce7
[gaim-migrate @ 7217]
Christian Hammond <chipx86@chipx86.com>
parents:
6687
diff
changeset
|
2817 |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
2818 if (gc->away) { |
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
2819 g_free(gc->away); |
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
2820 gc->away = NULL; |
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
2821 } |
2681 | 2822 |
2823 if (msg) { | |
2824 yd->current_status = YAHOO_STATUS_CUSTOM; | |
6847 | 2825 gc->away = g_strndup(msg, YAHOO_MAX_STATUS_MESSAGE_LENGTH); |
2681 | 2826 } else if (state) { |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
2827 gc->away = g_strdup(""); |
4596 | 2828 if (!strcmp(state, _("Available"))) { |
2681 | 2829 yd->current_status = YAHOO_STATUS_AVAILABLE; |
4596 | 2830 } else if (!strcmp(state, _("Be Right Back"))) { |
2681 | 2831 yd->current_status = YAHOO_STATUS_BRB; |
4596 | 2832 } else if (!strcmp(state, _("Busy"))) { |
2681 | 2833 yd->current_status = YAHOO_STATUS_BUSY; |
4596 | 2834 } else if (!strcmp(state, _("Not At Home"))) { |
2681 | 2835 yd->current_status = YAHOO_STATUS_NOTATHOME; |
4596 | 2836 } else if (!strcmp(state, _("Not At Desk"))) { |
2681 | 2837 yd->current_status = YAHOO_STATUS_NOTATDESK; |
4596 | 2838 } else if (!strcmp(state, _("Not In Office"))) { |
2681 | 2839 yd->current_status = YAHOO_STATUS_NOTINOFFICE; |
4606 | 2840 } else if (!strcmp(state, _("On The Phone"))) { |
2681 | 2841 yd->current_status = YAHOO_STATUS_ONPHONE; |
4596 | 2842 } else if (!strcmp(state, _("On Vacation"))) { |
2681 | 2843 yd->current_status = YAHOO_STATUS_ONVACATION; |
4596 | 2844 } else if (!strcmp(state, _("Out To Lunch"))) { |
2681 | 2845 yd->current_status = YAHOO_STATUS_OUTTOLUNCH; |
4596 | 2846 } else if (!strcmp(state, _("Stepped Out"))) { |
2681 | 2847 yd->current_status = YAHOO_STATUS_STEPPEDOUT; |
4596 | 2848 } else if (!strcmp(state, _("Invisible"))) { |
2681 | 2849 yd->current_status = YAHOO_STATUS_INVISIBLE; |
6847 | 2850 } else if (!strcmp(state, GAIM_AWAY_CUSTOM)) { /* this should never happen? */ |
2681 | 2851 if (gc->is_idle) { |
2852 yd->current_status = YAHOO_STATUS_IDLE; | |
2853 } else { | |
2854 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
2855 } | |
2856 } | |
2857 } else if (gc->is_idle) { | |
2858 yd->current_status = YAHOO_STATUS_IDLE; | |
2859 } else { | |
2860 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
2861 } | |
2862 | |
2772
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
2863 if (yd->current_status == YAHOO_STATUS_AVAILABLE) |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
2864 service = YAHOO_SERVICE_ISBACK; |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
2865 else |
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
2866 service = YAHOO_SERVICE_ISAWAY; |
6847 | 2867 |
2868 pkt = yahoo_packet_new(service, YAHOO_STATUS_AVAILABLE, 0); | |
2681 | 2869 g_snprintf(s, sizeof(s), "%d", yd->current_status); |
2870 yahoo_packet_hash(pkt, 10, s); | |
6847 | 2871 |
7827 | 2872 if ((yd->current_status == YAHOO_STATUS_CUSTOM) && gc->away) { |
2873 conv_msg = yahoo_string_encode(gc, gc->away, NULL); | |
8503 | 2874 conv_msg2 = gaim_unescape_html(conv_msg); |
2875 yahoo_packet_hash(pkt, 19, conv_msg2); | |
7827 | 2876 } |
6847 | 2877 |
2878 if ((yd->current_status != YAHOO_STATUS_AVAILABLE) && | |
2879 (yd->current_status != YAHOO_STATUS_IDLE)) { | |
6784 | 2880 if (gc->is_idle) |
2881 yahoo_packet_hash(pkt, 47, "2"); | |
2882 else | |
2883 yahoo_packet_hash(pkt, 47, "1"); | |
6686 | 2884 } |
2681 | 2885 |
2886 yahoo_send_packet(yd, pkt); | |
2887 yahoo_packet_free(pkt); | |
7827 | 2888 if (conv_msg) |
2889 g_free(conv_msg); | |
8503 | 2890 if (conv_msg2) |
2891 g_free(conv_msg2); | |
2681 | 2892 } |
2893 | |
5583 | 2894 static void yahoo_set_idle(GaimConnection *gc, int idle) |
2681 | 2895 { |
2896 struct yahoo_data *yd = gc->proto_data; | |
2897 struct yahoo_packet *pkt = NULL; | |
8503 | 2898 char *msg = NULL, *msg2 = NULL; |
2681 | 2899 |
2900 if (idle && yd->current_status == YAHOO_STATUS_AVAILABLE) { | |
6847 | 2901 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_AVAILABLE, 0); |
2681 | 2902 yd->current_status = YAHOO_STATUS_IDLE; |
2903 } else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) { | |
2904 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_AVAILABLE, 0); | |
2905 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
6847 | 2906 } else { |
6784 | 2907 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_AVAILABLE, 0); |
2681 | 2908 } |
2909 | |
2910 if (pkt) { | |
2911 char buf[4]; | |
2912 g_snprintf(buf, sizeof(buf), "%d", yd->current_status); | |
2913 yahoo_packet_hash(pkt, 10, buf); | |
6784 | 2914 if (gc->away && yd->current_status == YAHOO_STATUS_CUSTOM) { |
7827 | 2915 msg = yahoo_string_encode(gc, gc->away, NULL); |
8503 | 2916 msg2 = gaim_unescape_html(msg); |
2917 yahoo_packet_hash(pkt, 19, msg2); | |
6784 | 2918 if (idle) |
2919 yahoo_packet_hash(pkt, 47, "2"); | |
2920 else | |
2921 yahoo_packet_hash(pkt, 47, "1"); /* fixme when available messages are possible */ | |
6847 | 2922 } else if (idle && (yd->current_status != YAHOO_STATUS_AVAILABLE) && |
2923 (yd->current_status != YAHOO_STATUS_IDLE)) { | |
2924 yahoo_packet_hash(pkt, 47, "2"); | |
2925 } else if (!idle && (yd->current_status != YAHOO_STATUS_AVAILABLE) && | |
2926 (yd->current_status != YAHOO_STATUS_IDLE)) { | |
2927 yahoo_packet_hash(pkt, 47, "1"); | |
6784 | 2928 } |
6847 | 2929 |
2681 | 2930 yahoo_send_packet(yd, pkt); |
2931 yahoo_packet_free(pkt); | |
2932 } | |
7827 | 2933 if (msg) |
2934 g_free(msg); | |
8503 | 2935 if (msg2) |
2936 g_free(msg2); | |
2681 | 2937 } |
2938 | |
5583 | 2939 static GList *yahoo_away_states(GaimConnection *gc) |
2681 | 2940 { |
2941 GList *m = NULL; | |
2942 | |
4596 | 2943 m = g_list_append(m, _("Available")); |
2944 m = g_list_append(m, _("Be Right Back")); | |
2945 m = g_list_append(m, _("Busy")); | |
2946 m = g_list_append(m, _("Not At Home")); | |
2947 m = g_list_append(m, _("Not At Desk")); | |
2948 m = g_list_append(m, _("Not In Office")); | |
4606 | 2949 m = g_list_append(m, _("On The Phone")); |
4596 | 2950 m = g_list_append(m, _("On Vacation")); |
2951 m = g_list_append(m, _("Out To Lunch")); | |
2952 m = g_list_append(m, _("Stepped Out")); | |
2953 m = g_list_append(m, _("Invisible")); | |
2681 | 2954 m = g_list_append(m, GAIM_AWAY_CUSTOM); |
2955 | |
2956 return m; | |
2957 } | |
2958 | |
5583 | 2959 static void yahoo_keepalive(GaimConnection *gc) |
2681 | 2960 { |
2961 struct yahoo_data *yd = gc->proto_data; | |
2962 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); | |
2963 yahoo_send_packet(yd, pkt); | |
2964 yahoo_packet_free(pkt); | |
6729 | 2965 |
2966 if (!yd->chat_online) | |
2967 return; | |
2968 | |
2969 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, 0); | |
2970 yahoo_packet_hash(pkt, 109, gaim_connection_get_display_name(gc)); | |
2971 yahoo_send_packet(yd, pkt); | |
2972 yahoo_packet_free(pkt); | |
2681 | 2973 } |
2974 | |
9285 | 2975 /* XXX - What's the deal with GaimGroup *foo? */ |
2976 static void yahoo_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *foo) | |
2681 | 2977 { |
2978 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
2979 struct yahoo_packet *pkt; | |
6695 | 2980 GaimGroup *g; |
2681 | 2981 char *group = NULL; |
7829 | 2982 char *group2 = NULL; |
2681 | 2983 |
2984 if (!yd->logged_in) | |
2985 return; | |
2986 | |
6840 | 2987 if (foo) |
2988 group = foo->name; | |
2989 if (!group) { | |
9285 | 2990 g = gaim_find_buddys_group(gaim_find_buddy(gc->account, buddy->name)); |
6840 | 2991 if (g) |
2992 group = g->name; | |
2993 else | |
2994 group = "Buddies"; | |
2995 } | |
2681 | 2996 |
7829 | 2997 group2 = yahoo_string_encode(gc, group, NULL); |
2681 | 2998 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); |
5583 | 2999 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); |
9285 | 3000 yahoo_packet_hash(pkt, 7, buddy->name); |
7829 | 3001 yahoo_packet_hash(pkt, 65, group2); |
6820 | 3002 yahoo_packet_hash(pkt, 14, ""); |
2681 | 3003 yahoo_send_packet(yd, pkt); |
3004 yahoo_packet_free(pkt); | |
7829 | 3005 g_free(group2); |
2681 | 3006 } |
3007 | |
9285 | 3008 static void yahoo_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
2681 | 3009 { |
3010 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
9278 | 3011 YahooFriend *f; |
6795
40ba19133882
[gaim-migrate @ 7334]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
6793
diff
changeset
|
3012 struct yahoo_packet *pkt; |
6840 | 3013 GSList *buddies, *l; |
3014 GaimGroup *g; | |
3015 gboolean remove = TRUE; | |
7827 | 3016 char *cg; |
6784 | 3017 |
9285 | 3018 if (!(f = yahoo_friend_find(gc, buddy->name))) |
6784 | 3019 return; |
3020 | |
9285 | 3021 buddies = gaim_find_buddies(gaim_connection_get_account(gc), buddy->name); |
6840 | 3022 for (l = buddies; l; l = l->next) { |
3023 g = gaim_find_buddys_group(l->data); | |
9285 | 3024 if (gaim_utf8_strcasecmp(group->name, g->name)) { |
6840 | 3025 remove = FALSE; |
3026 break; | |
3027 } | |
3028 } | |
3029 | |
3030 g_slist_free(buddies); | |
3031 | |
3032 if (remove) | |
9285 | 3033 g_hash_table_remove(yd->friends, buddy->name); |
3034 | |
3035 cg = yahoo_string_encode(gc, group->name, NULL); | |
6795
40ba19133882
[gaim-migrate @ 7334]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
6793
diff
changeset
|
3036 pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); |
5583 | 3037 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); |
9285 | 3038 yahoo_packet_hash(pkt, 7, buddy->name); |
7827 | 3039 yahoo_packet_hash(pkt, 65, cg); |
2681 | 3040 yahoo_send_packet(yd, pkt); |
3041 yahoo_packet_free(pkt); | |
7827 | 3042 g_free(cg); |
2681 | 3043 } |
3044 | |
6760 | 3045 static void yahoo_add_deny(GaimConnection *gc, const char *who) { |
3046 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
3047 struct yahoo_packet *pkt; | |
3048 | |
3049 if (!yd->logged_in) | |
3050 return; | |
8057 | 3051 /* It seems to work better without this */ |
3052 | |
8113 | 3053 /* if (gc->account->perm_deny != 4) |
3054 return; */ | |
3055 | |
3056 if (!who || who[0] == '\0') | |
3057 return; | |
3058 | |
6760 | 3059 pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, 0); |
3060 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); | |
3061 yahoo_packet_hash(pkt, 7, who); | |
3062 yahoo_packet_hash(pkt, 13, "1"); | |
3063 yahoo_send_packet(yd, pkt); | |
3064 yahoo_packet_free(pkt); | |
3065 } | |
3066 | |
3067 static void yahoo_rem_deny(GaimConnection *gc, const char *who) { | |
3068 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
3069 struct yahoo_packet *pkt; | |
3070 | |
3071 if (!yd->logged_in) | |
3072 return; | |
3073 | |
3074 if (!who || who[0] == '\0') | |
3075 return; | |
3076 | |
3077 pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, 0); | |
3078 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); | |
3079 yahoo_packet_hash(pkt, 7, who); | |
3080 yahoo_packet_hash(pkt, 13, "2"); | |
3081 yahoo_send_packet(yd, pkt); | |
3082 yahoo_packet_free(pkt); | |
3083 } | |
3084 | |
3085 static void yahoo_set_permit_deny(GaimConnection *gc) { | |
3086 GaimAccount *acct; | |
3087 GSList *deny; | |
3088 | |
3089 acct = gc->account; | |
3090 | |
3091 switch (acct->perm_deny) { | |
3092 case 1: | |
3093 case 3: | |
3094 case 5: | |
3095 for (deny = acct->deny;deny;deny = deny->next) | |
3096 yahoo_rem_deny(gc, deny->data); | |
3097 break; | |
3098 case 4: | |
3099 for (deny = acct->deny;deny;deny = deny->next) | |
3100 yahoo_add_deny(gc, deny->data); | |
3101 break; | |
3102 case 2: | |
3103 default: | |
3104 break; | |
3105 } | |
3106 } | |
3107 | |
6513 | 3108 static gboolean yahoo_unload_plugin(GaimPlugin *plugin) |
3109 { | |
3110 yahoo_dest_colorht(); | |
3111 return TRUE; | |
3112 } | |
3113 | |
6793 | 3114 static void yahoo_change_buddys_group(GaimConnection *gc, const char *who, |
3115 const char *old_group, const char *new_group) | |
3116 { | |
3117 struct yahoo_data *yd = gc->proto_data; | |
3118 struct yahoo_packet *pkt; | |
7827 | 3119 char *gpn, *gpo; |
6793 | 3120 |
3121 /* Step 0: If they aren't on the server list anyway, | |
3122 * don't bother letting the server know. | |
3123 */ | |
9279 | 3124 if (!yahoo_friend_find(gc, who)) |
6793 | 3125 return; |
3126 | |
7827 | 3127 /* If old and new are the same, we would probably |
3128 * end up deleting the buddy, which would be bad. | |
3129 * This might happen because of the charset conversation. | |
3130 */ | |
3131 gpn = yahoo_string_encode(gc, new_group, NULL); | |
3132 gpo = yahoo_string_encode(gc, old_group, NULL); | |
3133 if (!strcmp(gpn, gpo)) { | |
3134 g_free(gpn); | |
3135 g_free(gpo); | |
3136 return; | |
3137 } | |
3138 | |
6793 | 3139 /* Step 1: Add buddy to new group. */ |
3140 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
3141 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); | |
3142 yahoo_packet_hash(pkt, 7, who); | |
7827 | 3143 yahoo_packet_hash(pkt, 65, gpn); |
6793 | 3144 yahoo_packet_hash(pkt, 14, ""); |
3145 yahoo_send_packet(yd, pkt); | |
3146 yahoo_packet_free(pkt); | |
3147 | |
3148 /* Step 2: Remove buddy from old group */ | |
3149 pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
3150 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); | |
3151 yahoo_packet_hash(pkt, 7, who); | |
7827 | 3152 yahoo_packet_hash(pkt, 65, gpo); |
6793 | 3153 yahoo_send_packet(yd, pkt); |
3154 yahoo_packet_free(pkt); | |
7827 | 3155 g_free(gpn); |
3156 g_free(gpo); | |
6793 | 3157 } |
3158 | |
9285 | 3159 static void yahoo_rename_group(GaimConnection *gc, const char *old_name, |
3160 GaimGroup *group, GList *moved_buddies) | |
6793 | 3161 { |
3162 struct yahoo_data *yd = gc->proto_data; | |
3163 struct yahoo_packet *pkt; | |
7827 | 3164 char *gpn, *gpo; |
3165 | |
9285 | 3166 gpn = yahoo_string_encode(gc, group->name, NULL); |
3167 gpo = yahoo_string_encode(gc, old_name, NULL); | |
7827 | 3168 if (!strcmp(gpn, gpo)) { |
3169 g_free(gpn); | |
3170 g_free(gpo); | |
3171 return; | |
3172 } | |
6793 | 3173 |
3174 pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, YAHOO_STATUS_AVAILABLE, 0); | |
3175 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); | |
7827 | 3176 yahoo_packet_hash(pkt, 65, gpo); |
3177 yahoo_packet_hash(pkt, 67, gpn); | |
6793 | 3178 yahoo_send_packet(yd, pkt); |
3179 yahoo_packet_free(pkt); | |
7827 | 3180 g_free(gpn); |
3181 g_free(gpo); | |
6793 | 3182 } |
3183 | |
7696 | 3184 #if 0 |
7651 | 3185 static gboolean yahoo_has_send_file(GaimConnection *gc, const char *who) |
3186 { | |
3187 return TRUE; | |
3188 } | |
7696 | 3189 #endif |
7651 | 3190 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3191 static GaimPlugin *my_protocol = NULL; |
2681 | 3192 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3193 static GaimPluginProtocolInfo prpl_info = |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3194 { |
8749
d7b8eb1f0a18
[gaim-migrate @ 9504]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
3195 GAIM_PRPL_API_VERSION, |
9308 | 3196 OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC, |
6729 | 3197 NULL, /* user_splits */ |
3198 NULL, /* protocol_options */ | |
9318 | 3199 {"png", 96, 96, 96, 96, GAIM_ICON_SCALE_SEND}, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3200 yahoo_list_icon, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3201 yahoo_list_emblems, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3202 yahoo_status_text, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3203 yahoo_tooltip_text, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3204 yahoo_away_states, |
9030 | 3205 yahoo_blist_node_menu, |
6729 | 3206 yahoo_c_info, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3207 yahoo_login, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3208 yahoo_close, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3209 yahoo_send_im, |
6729 | 3210 NULL, /* set info */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3211 yahoo_send_typing, |
6514 | 3212 yahoo_get_info, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3213 yahoo_set_away, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3214 yahoo_set_idle, |
6729 | 3215 NULL, /* change_passwd*/ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3216 yahoo_add_buddy, |
6729 | 3217 NULL, /* add_buddies */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3218 yahoo_remove_buddy, |
6729 | 3219 NULL, /*remove_buddies */ |
3220 NULL, /* add_permit */ | |
6760 | 3221 yahoo_add_deny, |
6729 | 3222 NULL, /* rem_permit */ |
6760 | 3223 yahoo_rem_deny, |
3224 yahoo_set_permit_deny, | |
6729 | 3225 NULL, /* warn */ |
3226 yahoo_c_join, | |
8562 | 3227 NULL, /* reject chat invite */ |
6729 | 3228 yahoo_c_invite, |
3229 yahoo_c_leave, | |
3230 NULL, /* chat whisper */ | |
3231 yahoo_c_send, | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3232 yahoo_keepalive, |
6729 | 3233 NULL, /* register_user */ |
3234 NULL, /* get_cb_info */ | |
3235 NULL, /* get_cb_away */ | |
3236 NULL, /* alias_buddy */ | |
6793 | 3237 yahoo_change_buddys_group, |
3238 yahoo_rename_group, | |
6729 | 3239 NULL, /* buddy_free */ |
3240 NULL, /* convo_closed */ | |
3241 NULL, /* normalize */ | |
9306 | 3242 yahoo_set_buddy_icon, |
7651 | 3243 NULL, /* void (*remove_group)(GaimConnection *gc, const char *group);*/ |
3244 NULL, /* char *(*get_cb_real_name)(GaimConnection *gc, int id, const char *who); */ | |
3245 #if 0 | |
3246 yahoo_ask_send_file, | |
3247 yahoo_send_file, | |
8113 | 3248 yahoo_has_send_file, |
7651 | 3249 #endif |
8113 | 3250 NULL, |
3251 NULL, | |
3252 yahoo_roomlist_get_list, | |
3253 yahoo_roomlist_cancel, | |
9030 | 3254 yahoo_roomlist_expand_category |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3255 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3256 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3257 static GaimPluginInfo info = |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3258 { |
8749
d7b8eb1f0a18
[gaim-migrate @ 9504]
Christian Hammond <chipx86@chipx86.com>
parents:
8735
diff
changeset
|
3259 GAIM_PLUGIN_API_VERSION, /**< api_version */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3260 GAIM_PLUGIN_PROTOCOL, /**< type */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3261 NULL, /**< ui_requirement */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3262 0, /**< flags */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3263 NULL, /**< dependencies */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3264 GAIM_PRIORITY_DEFAULT, /**< priority */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3265 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3266 "prpl-yahoo", /**< id */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3267 "Yahoo", /**< name */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3268 VERSION, /**< version */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3269 /** summary */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3270 N_("Yahoo Protocol Plugin"), |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3271 /** description */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3272 N_("Yahoo Protocol Plugin"), |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3273 NULL, /**< author */ |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6321
diff
changeset
|
3274 GAIM_WEBSITE, /**< homepage */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3275 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3276 NULL, /**< load */ |
6513 | 3277 yahoo_unload_plugin, /**< unload */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3278 NULL, /**< destroy */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3279 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3280 NULL, /**< ui_info */ |
8993 | 3281 &prpl_info, /**< extra_info */ |
3282 NULL, | |
9015 | 3283 yahoo_actions |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3284 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3285 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3286 static void |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
3287 init_plugin(GaimPlugin *plugin) |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3288 { |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5590
diff
changeset
|
3289 GaimAccountOption *option; |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3290 |
9164 | 3291 option = gaim_account_option_bool_new(_("Yahoo Japan"), "yahoojp", FALSE); |
3292 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3293 | |
7827 | 3294 option = gaim_account_option_string_new(_("Pager host"), "server", YAHOO_PAGER_HOST); |
3295 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3296 | |
9164 | 3297 option = gaim_account_option_string_new(_("Japan Pager host"), "serverjp", YAHOOJP_PAGER_HOST); |
3298 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3299 | |
7827 | 3300 option = gaim_account_option_int_new(_("Pager port"), "port", YAHOO_PAGER_PORT); |
3301 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
7651 | 3302 |
3303 option = gaim_account_option_string_new(_("File transfer host"), "xfer_host", YAHOO_XFER_HOST); | |
3304 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3305 | |
9164 | 3306 option = gaim_account_option_string_new(_("Japan File transfer host"), "xferjp_host", YAHOOJP_XFER_HOST); |
3307 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3308 | |
7651 | 3309 option = gaim_account_option_int_new(_("File transfer port"), "xfer_port", YAHOO_XFER_PORT); |
3310 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3311 | |
8113 | 3312 option = gaim_account_option_string_new(_("Chat Room List Url"), "room_list", YAHOO_ROOMLIST_URL); |
3313 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
3314 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3315 my_protocol = plugin; |
6513 | 3316 |
3317 yahoo_init_colorht(); | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3318 } |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5136
diff
changeset
|
3319 |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
3320 GAIM_INIT_PLUGIN(yahoo, init_plugin, info); |