Mercurial > pidgin
annotate src/protocols/yahoo/yahoo_filexfer.c @ 14084:b7e4180af1db
[gaim-migrate @ 16705]
Don't use the same callback for both gaim_proxy_connect() and
gaim_input_add(). Aside from being a little confusing, it's
hindering some changes I want to make to gaim_proxy_connect().
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Fri, 11 Aug 2006 08:08:19 +0000 |
parents | 8d1c55309e3c |
children | 10e8eb6a4910 |
rev | line source |
---|---|
7651 | 1 /* |
2 * @file yahoo_filexfer.c Yahoo Filetransfer | |
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. | |
7651 | 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 | |
23 #include "prpl.h" | |
24 #include "internal.h" | |
25 #include "util.h" | |
26 #include "debug.h" | |
27 #include "notify.h" | |
28 #include "proxy.h" | |
29 #include "ft.h" | |
30 #include "yahoo.h" | |
10392 | 31 #include "yahoo_packet.h" |
7651 | 32 #include "yahoo_filexfer.h" |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
33 #include "yahoo_doodle.h" |
7651 | 34 |
35 struct yahoo_xfer_data { | |
36 gchar *host; | |
37 gchar *path; | |
38 int port; | |
39 GaimConnection *gc; | |
40 long expires; | |
41 gboolean started; | |
13271
aaeb6ea63c56
[gaim-migrate @ 15637]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13200
diff
changeset
|
42 gchar *txbuf; |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
43 gsize txbuflen; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
44 gsize txbuf_written; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
45 guint tx_handler; |
7651 | 46 gchar *rxqueue; |
47 guint rxlen; | |
48 }; | |
49 | |
50 static void yahoo_xfer_data_free(struct yahoo_xfer_data *xd) | |
51 { | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
52 g_free(xd->host); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
53 g_free(xd->path); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
54 g_free(xd->txbuf); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
55 if (xd->tx_handler) |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
56 gaim_input_remove(xd->tx_handler); |
7651 | 57 g_free(xd); |
58 } | |
59 | |
14084 | 60 static void yahoo_receivefile_send_cb(gpointer data, gint source, GaimInputCondition condition) |
61 { | |
62 GaimXfer *xfer; | |
63 struct yahoo_xfer_data *xd; | |
64 int remaining, written; | |
65 | |
66 xfer = data; | |
67 xd = xfer->data; | |
68 | |
69 remaining = xd->txbuflen - xd->txbuf_written; | |
70 written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining); | |
71 | |
72 if (written < 0 && errno == EAGAIN) | |
73 written = 0; | |
74 else if (written <= 0) { | |
75 gaim_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno); | |
76 gaim_xfer_cancel_remote(xfer); | |
77 return; | |
78 } | |
79 | |
80 if (written < remaining) { | |
81 xd->txbuf_written += written; | |
82 return; | |
83 } | |
84 | |
85 gaim_input_remove(xd->tx_handler); | |
86 xd->tx_handler = 0; | |
87 g_free(xd->txbuf); | |
88 xd->txbuf = NULL; | |
89 xd->txbuflen = 0; | |
90 | |
91 gaim_xfer_start(xfer, source, NULL, 0); | |
92 | |
93 } | |
94 | |
7651 | 95 static void yahoo_receivefile_connected(gpointer data, gint source, GaimInputCondition condition) |
96 { | |
97 GaimXfer *xfer; | |
98 struct yahoo_xfer_data *xd; | |
99 | |
100 gaim_debug(GAIM_DEBUG_INFO, "yahoo", | |
101 "AAA - in yahoo_receivefile_connected\n"); | |
102 if (!(xfer = data)) | |
103 return; | |
104 if (!(xd = xfer->data)) | |
105 return; | |
13143
a1d5f154585b
[gaim-migrate @ 15506]
Richard Laager <rlaager@wiktel.com>
parents:
12412
diff
changeset
|
106 if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) { |
10654 | 107 gaim_xfer_error(GAIM_XFER_RECEIVE, gaim_xfer_get_account(xfer), |
108 xfer->who, _("Unable to connect.")); | |
7805 | 109 gaim_xfer_cancel_remote(xfer); |
7651 | 110 return; |
111 } | |
112 | |
14084 | 113 xfer->fd = source; |
114 | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
115 /* The first time we get here, assemble the tx buffer */ |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
116 if (xd->txbuflen == 0) { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
117 xd->txbuf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
118 xd->path, xd->host); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
119 xd->txbuflen = strlen(xd->txbuf); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
120 xd->txbuf_written = 0; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
121 } |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
122 |
14084 | 123 if (!xd->tx_handler) |
124 { | |
125 xd->tx_handler = gaim_input_add(source, GAIM_INPUT_WRITE, | |
126 yahoo_receivefile_send_cb, xfer); | |
127 yahoo_receivefile_send_cb(xfer, source, GAIM_INPUT_WRITE); | |
128 } | |
129 } | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
130 |
14084 | 131 static void yahoo_sendfile_send_cb(gpointer data, gint source, GaimInputCondition condition) |
132 { | |
133 GaimXfer *xfer; | |
134 struct yahoo_xfer_data *xd; | |
135 int written, remaining; | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
136 |
14084 | 137 xfer = data; |
138 xd = xfer->data; | |
139 | |
140 remaining = xd->txbuflen - xd->txbuf_written; | |
141 written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining); | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
142 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
143 if (written < 0 && errno == EAGAIN) |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
144 written = 0; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
145 else if (written <= 0) { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
146 gaim_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
147 gaim_xfer_cancel_remote(xfer); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
148 return; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
149 } |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
150 |
14084 | 151 if (written < remaining) { |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
152 xd->txbuf_written += written; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
153 return; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
154 } |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
155 |
14084 | 156 gaim_input_remove(xd->tx_handler); |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
157 xd->tx_handler = 0; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
158 g_free(xd->txbuf); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
159 xd->txbuf = NULL; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
160 xd->txbuflen = 0; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
161 |
7651 | 162 gaim_xfer_start(xfer, source, NULL, 0); |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
163 } |
7651 | 164 |
165 static void yahoo_sendfile_connected(gpointer data, gint source, GaimInputCondition condition) | |
166 { | |
167 GaimXfer *xfer; | |
168 struct yahoo_xfer_data *xd; | |
14084 | 169 struct yahoo_packet *pkt; |
170 gchar *size, *filename, *encoded_filename, *header; | |
171 guchar *pkt_buf; | |
172 const char *host; | |
173 int port; | |
174 size_t content_length, header_len, pkt_buf_len; | |
175 GaimConnection *gc; | |
176 GaimAccount *account; | |
177 struct yahoo_data *yd; | |
7651 | 178 |
179 gaim_debug(GAIM_DEBUG_INFO, "yahoo", | |
180 "AAA - in yahoo_sendfile_connected\n"); | |
181 if (!(xfer = data)) | |
182 return; | |
183 if (!(xd = xfer->data)) | |
184 return; | |
185 | |
186 if (source < 0) { | |
10654 | 187 gaim_xfer_error(GAIM_XFER_RECEIVE, gaim_xfer_get_account(xfer), |
188 xfer->who, _("Unable to connect.")); | |
7805 | 189 gaim_xfer_cancel_remote(xfer); |
7651 | 190 return; |
191 } | |
192 | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
193 xfer->fd = source; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
194 |
14084 | 195 /* Assemble the tx buffer */ |
196 gc = xd->gc; | |
197 account = gaim_connection_get_account(gc); | |
198 yd = gc->proto_data; | |
199 | |
200 pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER, | |
201 YAHOO_STATUS_AVAILABLE, yd->session_id); | |
7651 | 202 |
14084 | 203 size = g_strdup_printf("%" G_GSIZE_FORMAT, gaim_xfer_get_size(xfer)); |
204 filename = g_path_get_basename(gaim_xfer_get_local_filename(xfer)); | |
205 encoded_filename = yahoo_string_encode(gc, filename, NULL); | |
206 | |
207 yahoo_packet_hash(pkt, "sssss", 0, gaim_connection_get_display_name(gc), | |
208 5, xfer->who, 14, "", 27, encoded_filename, 28, size); | |
209 g_free(size); | |
210 g_free(encoded_filename); | |
211 g_free(filename); | |
212 | |
213 content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); | |
214 | |
215 pkt_buf_len = yahoo_packet_build(pkt, 8, FALSE, &pkt_buf); | |
216 yahoo_packet_free(pkt); | |
7651 | 217 |
14084 | 218 host = gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST); |
219 port = gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT); | |
220 header = g_strdup_printf( | |
221 "POST http://%s:%d/notifyft HTTP/1.0\r\n" | |
222 "Content-length: %" G_GSIZE_FORMAT "\r\n" | |
223 "Host: %s:%d\r\n" | |
224 "Cookie: Y=%s; T=%s\r\n" | |
225 "\r\n", | |
226 host, port, content_length + 4 + gaim_xfer_get_size(xfer), | |
227 host, port, yd->cookie_y, yd->cookie_t); | |
228 | |
229 header_len = strlen(header); | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
230 |
14084 | 231 xd->txbuflen = header_len + pkt_buf_len + 4; |
232 xd->txbuf = g_malloc(xd->txbuflen); | |
233 | |
234 memcpy(xd->txbuf, header, header_len); | |
235 g_free(header); | |
236 memcpy(xd->txbuf + header_len, pkt_buf, pkt_buf_len); | |
237 g_free(pkt_buf); | |
238 memcpy(xd->txbuf + header_len + pkt_buf_len, "29\xc0\x80", 4); | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13143
diff
changeset
|
239 |
14084 | 240 xd->txbuf_written = 0; |
241 | |
242 if (xd->tx_handler == 0) | |
243 { | |
244 xd->tx_handler = gaim_input_add(source, GAIM_INPUT_WRITE, | |
245 yahoo_sendfile_send_cb, xfer); | |
246 yahoo_sendfile_send_cb(xfer, source, GAIM_INPUT_WRITE); | |
247 } | |
7651 | 248 } |
249 | |
250 static void yahoo_xfer_init(GaimXfer *xfer) | |
251 { | |
252 struct yahoo_xfer_data *xfer_data; | |
253 GaimConnection *gc; | |
254 GaimAccount *account; | |
7827 | 255 struct yahoo_data *yd; |
7651 | 256 |
257 xfer_data = xfer->data; | |
258 gc = xfer_data->gc; | |
7827 | 259 yd = gc->proto_data; |
7651 | 260 account = gaim_connection_get_account(gc); |
261 | |
262 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) { | |
10937 | 263 if (yd->jp) { |
264 if (gaim_proxy_connect(account, gaim_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST), | |
265 gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), | |
266 yahoo_sendfile_connected, xfer) == -1) | |
267 { | |
268 gaim_notify_error(gc, NULL, _("File Transfer Failed"), | |
269 _("Unable to establish file descriptor.")); | |
270 gaim_xfer_cancel_remote(xfer); | |
271 } | |
8282 | 272 } else { |
10937 | 273 if (gaim_proxy_connect(account, gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST), |
274 gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), | |
275 yahoo_sendfile_connected, xfer) == -1) | |
276 { | |
277 gaim_notify_error(gc, NULL, _("File Transfer Failed"), | |
278 _("Unable to establish file descriptor.")); | |
279 gaim_xfer_cancel_remote(xfer); | |
8282 | 280 } |
7651 | 281 } |
282 } else { | |
283 xfer->fd = gaim_proxy_connect(account, xfer_data->host, xfer_data->port, | |
284 yahoo_receivefile_connected, xfer); | |
285 if (xfer->fd == -1) { | |
10654 | 286 gaim_notify_error(gc, NULL, _("File Transfer Failed"), |
7651 | 287 _("Unable to establish file descriptor.")); |
288 gaim_xfer_cancel_remote(xfer); | |
289 } | |
290 } | |
291 } | |
292 | |
293 static void yahoo_xfer_start(GaimXfer *xfer) | |
294 { | |
295 /* We don't need to do anything here, do we? */ | |
296 } | |
297 | |
298 static void yahoo_xfer_end(GaimXfer *xfer) | |
299 { | |
300 struct yahoo_xfer_data *xfer_data; | |
301 | |
302 xfer_data = xfer->data; | |
303 | |
304 if (xfer_data) | |
305 yahoo_xfer_data_free(xfer_data); | |
306 xfer->data = NULL; | |
307 | |
308 } | |
309 | |
11897 | 310 static guint calculate_length(const gchar *l, size_t len) |
7651 | 311 { |
312 int i; | |
313 | |
314 for (i = 0; i < len; i++) { | |
315 if (!g_ascii_isdigit(l[i])) | |
316 continue; | |
317 return strtol(l + i, NULL, 10); | |
318 } | |
319 return 0; | |
320 } | |
321 | |
12412
a88ca6da0b38
[gaim-migrate @ 14719]
Richard Laager <rlaager@wiktel.com>
parents:
12151
diff
changeset
|
322 static gssize yahoo_xfer_read(guchar **buffer, GaimXfer *xfer) |
7651 | 323 { |
7710 | 324 gchar buf[4096]; |
12151
de798f2f4bf1
[gaim-migrate @ 14452]
Richard Laager <rlaager@wiktel.com>
parents:
12143
diff
changeset
|
325 gssize len; |
7651 | 326 gchar *start = NULL; |
327 gchar *length; | |
328 gchar *end; | |
7710 | 329 int filelen; |
7651 | 330 struct yahoo_xfer_data *xd = xfer->data; |
331 | |
332 if (gaim_xfer_get_type(xfer) != GAIM_XFER_RECEIVE) { | |
333 return 0; | |
334 } | |
335 | |
336 len = read(xfer->fd, buf, sizeof(buf)); | |
337 | |
7682 | 338 if (len <= 0) { |
7710 | 339 if ((gaim_xfer_get_size(xfer) > 0) && |
9798 | 340 (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer))) { |
7682 | 341 gaim_xfer_set_completed(xfer, TRUE); |
9798 | 342 return 0; |
343 } else | |
344 return -1; | |
7651 | 345 } |
346 | |
347 if (!xd->started) { | |
348 xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen); | |
349 memcpy(xd->rxqueue + xd->rxlen, buf, len); | |
350 xd->rxlen += len; | |
351 | |
352 length = g_strstr_len(xd->rxqueue, len, "Content-length:"); | |
10579 | 353 /* some proxies re-write this header, changing the capitalization :( |
354 * technically that's allowed since headers are case-insensitive | |
355 * [RFC 2616, section 4.2] */ | |
356 if (length == NULL) | |
357 length = g_strstr_len(xd->rxqueue, len, "Content-Length:"); | |
7651 | 358 if (length) { |
359 end = g_strstr_len(length, length - xd->rxqueue, "\r\n"); | |
360 if (!end) | |
361 return 0; | |
7710 | 362 if ((filelen = calculate_length(length, len - (length - xd->rxqueue)))) |
363 gaim_xfer_set_size(xfer, filelen); | |
7651 | 364 } |
365 start = g_strstr_len(xd->rxqueue, len, "\r\n\r\n"); | |
366 if (start) | |
367 start += 4; | |
368 if (!start || start > (xd->rxqueue + len)) | |
369 return 0; | |
370 xd->started = TRUE; | |
371 | |
372 len -= (start - xd->rxqueue); | |
373 | |
374 *buffer = g_malloc(len); | |
375 memcpy(*buffer, start, len); | |
376 g_free(xd->rxqueue); | |
377 xd->rxqueue = NULL; | |
378 xd->rxlen = 0; | |
379 } else { | |
380 *buffer = g_malloc(len); | |
381 memcpy(*buffer, buf, len); | |
382 } | |
383 | |
384 return len; | |
385 } | |
386 | |
12412
a88ca6da0b38
[gaim-migrate @ 14719]
Richard Laager <rlaager@wiktel.com>
parents:
12151
diff
changeset
|
387 static gssize yahoo_xfer_write(const guchar *buffer, size_t size, GaimXfer *xfer) |
7651 | 388 { |
12151
de798f2f4bf1
[gaim-migrate @ 14452]
Richard Laager <rlaager@wiktel.com>
parents:
12143
diff
changeset
|
389 gssize len; |
7651 | 390 struct yahoo_xfer_data *xd = xfer->data; |
391 | |
392 if (!xd) | |
9798 | 393 return -1; |
7651 | 394 |
395 if (gaim_xfer_get_type(xfer) != GAIM_XFER_SEND) { | |
9798 | 396 return -1; |
7651 | 397 } |
398 | |
399 len = write(xfer->fd, buffer, size); | |
400 | |
7710 | 401 if (len == -1) { |
402 if (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer)) | |
403 gaim_xfer_set_completed(xfer, TRUE); | |
404 if ((errno != EAGAIN) && (errno != EINTR)) | |
9798 | 405 return -1; |
7710 | 406 return 0; |
407 } | |
408 | |
409 if ((gaim_xfer_get_bytes_sent(xfer) + len) >= gaim_xfer_get_size(xfer)) | |
7651 | 410 gaim_xfer_set_completed(xfer, TRUE); |
411 | |
412 return len; | |
413 } | |
414 | |
415 static void yahoo_xfer_cancel_send(GaimXfer *xfer) | |
416 { | |
417 struct yahoo_xfer_data *xfer_data; | |
418 | |
419 xfer_data = xfer->data; | |
420 | |
421 if (xfer_data) | |
422 yahoo_xfer_data_free(xfer_data); | |
423 xfer->data = NULL; | |
424 } | |
425 | |
426 static void yahoo_xfer_cancel_recv(GaimXfer *xfer) | |
427 { | |
428 struct yahoo_xfer_data *xfer_data; | |
429 | |
430 xfer_data = xfer->data; | |
431 | |
432 if (xfer_data) | |
433 yahoo_xfer_data_free(xfer_data); | |
434 xfer->data = NULL; | |
435 } | |
436 | |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
437 void yahoo_process_p2pfilexfer(GaimConnection *gc, struct yahoo_packet *pkt) |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
438 { |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
439 GSList *l = pkt->hash; |
11644 | 440 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
441 char *me = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
442 char *from = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
443 char *service = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
444 char *message = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
445 char *command = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
446 char *imv = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
447 char *unknown = NULL; |
11644 | 448 |
11801
81806e9241be
[gaim-migrate @ 14092]
Gary Kramlich <grim@reaperworld.com>
parents:
11644
diff
changeset
|
449 /* Get all the necessary values from this new packet */ |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
450 while(l != NULL) |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
451 { |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
452 struct yahoo_pair *pair = l->data; |
11644 | 453 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
454 if(pair->key == 5) /* Get who the packet is for */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
455 me = pair->value; |
11644 | 456 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
457 if(pair->key == 4) /* Get who the packet is from */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
458 from = pair->value; |
11644 | 459 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
460 if(pair->key == 49) /* Get the type of service */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
461 service = pair->value; |
11644 | 462 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
463 if(pair->key == 14) /* Get the 'message' of the packet */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
464 message = pair->value; |
11644 | 465 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
466 if(pair->key == 13) /* Get the command associated with this packet */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
467 command = pair->value; |
11644 | 468 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
469 if(pair->key == 63) /* IMVironment name and version */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
470 imv = pair->value; |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
471 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
472 if(pair->key == 64) /* Not sure, but it does vary with initialization of Doodle */ |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
473 unknown = pair->value; /* So, I'll keep it (for a little while atleast) */ |
11644 | 474 |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
475 l = l->next; |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
476 } |
11644 | 477 |
11801
81806e9241be
[gaim-migrate @ 14092]
Gary Kramlich <grim@reaperworld.com>
parents:
11644
diff
changeset
|
478 /* If this packet is an IMVIRONMENT, handle it accordingly */ |
13458
6e50059617d3
[gaim-migrate @ 15833]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13276
diff
changeset
|
479 if(service != NULL && imv != NULL && !strcmp(service, "IMVIRONMENT")) |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
480 { |
11801
81806e9241be
[gaim-migrate @ 14092]
Gary Kramlich <grim@reaperworld.com>
parents:
11644
diff
changeset
|
481 /* Check for a Doodle packet and handle it accordingly */ |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
482 if(!strcmp(imv, "doodle;11")) |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
483 yahoo_doodle_process(gc, me, from, command, message); |
11644 | 484 |
11801
81806e9241be
[gaim-migrate @ 14092]
Gary Kramlich <grim@reaperworld.com>
parents:
11644
diff
changeset
|
485 /* If an IMVIRONMENT packet comes without a specific imviroment name */ |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
486 if(!strcmp(imv, ";0")) |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
487 { |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
488 /* It is unfortunately time to close all IMVironments with the remote client */ |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
489 yahoo_doodle_command_got_shutdown(gc, from); |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
490 } |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
491 } |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
492 } |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
493 |
7651 | 494 void yahoo_process_filetransfer(GaimConnection *gc, struct yahoo_packet *pkt) |
495 { | |
496 char *from = NULL; | |
497 char *to = NULL; | |
498 char *msg = NULL; | |
499 char *url = NULL; | |
13849 | 500 char *imv = NULL; |
7651 | 501 long expires = 0; |
502 GaimXfer *xfer; | |
13849 | 503 struct yahoo_data *yd; |
7651 | 504 struct yahoo_xfer_data *xfer_data; |
505 char *service = NULL; | |
506 char *filename = NULL; | |
507 unsigned long filesize = 0L; | |
508 GSList *l; | |
509 | |
13849 | 510 yd = gc->proto_data; |
511 | |
7651 | 512 for (l = pkt->hash; l; l = l->next) { |
513 struct yahoo_pair *pair = l->data; | |
514 | |
515 if (pair->key == 4) | |
516 from = pair->value; | |
517 if (pair->key == 5) | |
518 to = pair->value; | |
519 if (pair->key == 14) | |
520 msg = pair->value; | |
521 if (pair->key == 20) | |
522 url = pair->value; | |
523 if (pair->key == 38) | |
524 expires = strtol(pair->value, NULL, 10); | |
525 if (pair->key == 27) | |
526 filename = pair->value; | |
527 if (pair->key == 28) | |
528 filesize = atol(pair->value); | |
529 if (pair->key == 49) | |
530 service = pair->value; | |
13849 | 531 if (pair->key == 63) |
532 imv = pair->value; | |
533 } | |
534 | |
535 /* | |
536 * The remote user has changed their IMVironment. We | |
537 * record it for later use. | |
538 */ | |
539 if (from && imv && service && (strcmp("IMVIRONMENT", service) == 0)) { | |
540 g_hash_table_replace(yd->imvironments, g_strdup(from), g_strdup(imv)); | |
541 return; | |
7651 | 542 } |
543 | |
544 if (pkt->service == YAHOO_SERVICE_P2PFILEXFER) { | |
10261 | 545 if (service && (strcmp("FILEXFER", service) != 0)) { |
13466
d7b01bcfb031
[gaim-migrate @ 15841]
Richard Laager <rlaager@wiktel.com>
parents:
13458
diff
changeset
|
546 gaim_debug_misc("yahoo", "unhandled service 0x%02x\n", pkt->service); |
7651 | 547 return; |
548 } | |
549 } | |
550 | |
551 if (msg) { | |
552 char *tmp; | |
553 tmp = strchr(msg, '\006'); | |
554 if (tmp) | |
555 *tmp = '\0'; | |
556 } | |
557 | |
558 if (!url || !from) | |
559 return; | |
560 | |
561 /* Setup the Yahoo-specific file transfer data */ | |
562 xfer_data = g_new0(struct yahoo_xfer_data, 1); | |
563 xfer_data->gc = gc; | |
9227
9171e528d7e5
[gaim-migrate @ 10023]
Christian Hammond <chipx86@chipx86.com>
parents:
9164
diff
changeset
|
564 if (!gaim_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL)) { |
7651 | 565 g_free(xfer_data); |
566 return; | |
567 } | |
568 | |
569 gaim_debug_misc("yahoo_filexfer", "Host is %s, port is %d, path is %s, and the full url was %s.\n", | |
570 xfer_data->host, xfer_data->port, xfer_data->path, url); | |
571 | |
572 /* Build the file transfer handle. */ | |
573 xfer = gaim_xfer_new(gc->account, GAIM_XFER_RECEIVE, from); | |
574 xfer->data = xfer_data; | |
575 | |
576 /* Set the info about the incoming file. */ | |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
577 if (filename) { |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
578 char *utf8_filename = yahoo_string_decode(gc, filename, TRUE); |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
579 gaim_xfer_set_filename(xfer, utf8_filename); |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
580 g_free(utf8_filename); |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
581 } else { |
7651 | 582 gchar *start, *end; |
583 start = g_strrstr(xfer_data->path, "/"); | |
584 if (start) | |
585 start++; | |
586 end = g_strrstr(xfer_data->path, "?"); | |
587 if (start && *start && end) { | |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
588 char *utf8_filename; |
7651 | 589 filename = g_strndup(start, end - start); |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
590 utf8_filename = yahoo_string_decode(gc, filename, TRUE); |
7651 | 591 g_free(filename); |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
592 gaim_xfer_set_filename(xfer, utf8_filename); |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
593 g_free(utf8_filename); |
7651 | 594 filename = NULL; |
595 } | |
596 } | |
597 | |
598 gaim_xfer_set_size(xfer, filesize); | |
599 | |
600 /* Setup our I/O op functions */ | |
601 gaim_xfer_set_init_fnc(xfer, yahoo_xfer_init); | |
602 gaim_xfer_set_start_fnc(xfer, yahoo_xfer_start); | |
603 gaim_xfer_set_end_fnc(xfer, yahoo_xfer_end); | |
604 gaim_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send); | |
605 gaim_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv); | |
606 gaim_xfer_set_read_fnc(xfer, yahoo_xfer_read); | |
607 gaim_xfer_set_write_fnc(xfer, yahoo_xfer_write); | |
608 | |
609 /* Now perform the request */ | |
610 gaim_xfer_request(xfer); | |
611 } | |
612 | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
613 GaimXfer *yahoo_new_xfer(GaimConnection *gc, const char *who) |
7651 | 614 { |
615 GaimXfer *xfer; | |
616 struct yahoo_xfer_data *xfer_data; | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
617 |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
618 g_return_val_if_fail(who != NULL, NULL); |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
619 |
7651 | 620 xfer_data = g_new0(struct yahoo_xfer_data, 1); |
621 xfer_data->gc = gc; | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
622 |
7651 | 623 /* Build the file transfer handle. */ |
624 xfer = gaim_xfer_new(gc->account, GAIM_XFER_SEND, who); | |
625 xfer->data = xfer_data; | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
626 |
7651 | 627 /* Setup our I/O op functions */ |
628 gaim_xfer_set_init_fnc(xfer, yahoo_xfer_init); | |
629 gaim_xfer_set_start_fnc(xfer, yahoo_xfer_start); | |
630 gaim_xfer_set_end_fnc(xfer, yahoo_xfer_end); | |
631 gaim_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send); | |
632 gaim_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv); | |
633 gaim_xfer_set_read_fnc(xfer, yahoo_xfer_read); | |
634 gaim_xfer_set_write_fnc(xfer, yahoo_xfer_write); | |
635 | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
636 return xfer; |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
637 } |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
638 |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
639 void yahoo_send_file(GaimConnection *gc, const char *who, const char *file) |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
640 { |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
641 GaimXfer *xfer = yahoo_new_xfer(gc, who); |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
642 |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
643 g_return_if_fail(xfer != NULL); |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
644 |
7651 | 645 /* Now perform the request */ |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
646 if (file) |
9466 | 647 gaim_xfer_request_accepted(xfer, file); |
648 else | |
649 gaim_xfer_request(xfer); | |
7651 | 650 } |