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