Mercurial > pidgin
annotate src/protocols/yahoo/yahoo_filexfer.c @ 13143:a1d5f154585b
[gaim-migrate @ 15506]
SF Patch #1415729 from Evan
"I've received a few crash reports in which yahoo_receivefile_connected()
crashes in g_strdup_printf() as a result of being passed a NULL string.
There are only two arguments to that call... xd->path and xd->host. If
either were null for some reason, we couldn't receive a file, anyways, since
we need both to do the HTTP GET request.
This patch checks against NULL for both and cancels the transfer in the
same manner it would be canceled if fed a negative (invalid) source."
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Tue, 07 Feb 2006 01:43:27 +0000 |
parents | a88ca6da0b38 |
children | 33bef17125c2 |
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; | |
42 gchar *rxqueue; | |
43 guint rxlen; | |
44 }; | |
45 | |
46 static void yahoo_xfer_data_free(struct yahoo_xfer_data *xd) | |
47 { | |
48 if (xd->host) | |
49 g_free(xd->host); | |
50 if (xd->path) | |
51 g_free(xd->path); | |
52 g_free(xd); | |
53 } | |
54 | |
55 static void yahoo_receivefile_connected(gpointer data, gint source, GaimInputCondition condition) | |
56 { | |
57 GaimXfer *xfer; | |
58 struct yahoo_xfer_data *xd; | |
59 gchar *buf; | |
60 | |
61 gaim_debug(GAIM_DEBUG_INFO, "yahoo", | |
62 "AAA - in yahoo_receivefile_connected\n"); | |
63 if (!(xfer = data)) | |
64 return; | |
65 if (!(xd = xfer->data)) | |
66 return; | |
13143
a1d5f154585b
[gaim-migrate @ 15506]
Richard Laager <rlaager@wiktel.com>
parents:
12412
diff
changeset
|
67 if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) { |
10654 | 68 gaim_xfer_error(GAIM_XFER_RECEIVE, gaim_xfer_get_account(xfer), |
69 xfer->who, _("Unable to connect.")); | |
7805 | 70 gaim_xfer_cancel_remote(xfer); |
7651 | 71 return; |
72 } | |
73 | |
74 xfer->fd = source; | |
75 gaim_xfer_start(xfer, source, NULL, 0); | |
76 | |
10651 | 77 buf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", |
78 xd->path, xd->host); | |
7651 | 79 write(xfer->fd, buf, strlen(buf)); |
80 g_free(buf); | |
81 | |
82 return; | |
83 } | |
84 | |
85 static void yahoo_sendfile_connected(gpointer data, gint source, GaimInputCondition condition) | |
86 { | |
87 GaimXfer *xfer; | |
88 struct yahoo_xfer_data *xd; | |
89 struct yahoo_packet *pkt; | |
90 gchar *size, *post, *buf; | |
10576 | 91 const char *host; |
10575 | 92 int content_length, port; |
7651 | 93 GaimConnection *gc; |
94 GaimAccount *account; | |
95 struct yahoo_data *yd; | |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
96 char *filename, *encoded_filename; |
7651 | 97 |
98 gaim_debug(GAIM_DEBUG_INFO, "yahoo", | |
99 "AAA - in yahoo_sendfile_connected\n"); | |
100 if (!(xfer = data)) | |
101 return; | |
102 if (!(xd = xfer->data)) | |
103 return; | |
104 | |
105 gc = xd->gc; | |
106 account = gaim_connection_get_account(gc); | |
107 yd = gc->proto_data; | |
108 | |
109 if (source < 0) { | |
10654 | 110 gaim_xfer_error(GAIM_XFER_RECEIVE, gaim_xfer_get_account(xfer), |
111 xfer->who, _("Unable to connect.")); | |
7805 | 112 gaim_xfer_cancel_remote(xfer); |
7651 | 113 return; |
114 } | |
115 | |
116 xfer->fd = source; | |
117 gaim_xfer_start(xfer, source, NULL, 0); | |
118 | |
119 pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER, YAHOO_STATUS_AVAILABLE, yd->session_id); | |
120 | |
10111 | 121 size = g_strdup_printf("%" G_GSIZE_FORMAT, gaim_xfer_get_size(xfer)); |
7805 | 122 filename = g_path_get_basename(gaim_xfer_get_local_filename(xfer)); |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
123 encoded_filename = yahoo_string_encode(gc, filename, NULL); |
11644 | 124 |
10394 | 125 yahoo_packet_hash(pkt, "sssss", 0, gaim_connection_get_display_name(gc), |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
126 5, xfer->who, 14, "", 27, encoded_filename, 28, size); |
7651 | 127 |
128 content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); | |
129 | |
130 buf = g_strdup_printf("Y=%s; T=%s", yd->cookie_y, yd->cookie_t); | |
131 | |
10576 | 132 host = gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST); |
10575 | 133 port = gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT); |
134 post = g_strdup_printf("POST http://%s:%d/notifyft HTTP/1.0\r\n" | |
10111 | 135 "Content-length: %" G_GSIZE_FORMAT "\r\n" |
7651 | 136 "Host: %s:%d\r\n" |
137 "Cookie: %s\r\n" | |
138 "\r\n", | |
11644 | 139 host, port, content_length + 4 + gaim_xfer_get_size(xfer), |
140 host, port, buf); | |
7651 | 141 write(xfer->fd, post, strlen(post)); |
142 | |
10392 | 143 yahoo_packet_send_special(pkt, xfer->fd, 8); |
7651 | 144 yahoo_packet_free(pkt); |
145 | |
146 write(xfer->fd, "29\xc0\x80", 4); | |
147 | |
148 g_free(size); | |
149 g_free(post); | |
150 g_free(buf); | |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
151 g_free(encoded_filename); |
7805 | 152 g_free(filename); |
7651 | 153 } |
154 | |
155 static void yahoo_xfer_init(GaimXfer *xfer) | |
156 { | |
157 struct yahoo_xfer_data *xfer_data; | |
158 GaimConnection *gc; | |
159 GaimAccount *account; | |
7827 | 160 struct yahoo_data *yd; |
7651 | 161 |
162 xfer_data = xfer->data; | |
163 gc = xfer_data->gc; | |
7827 | 164 yd = gc->proto_data; |
7651 | 165 account = gaim_connection_get_account(gc); |
166 | |
167 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) { | |
10937 | 168 if (yd->jp) { |
169 if (gaim_proxy_connect(account, gaim_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST), | |
170 gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), | |
171 yahoo_sendfile_connected, xfer) == -1) | |
172 { | |
173 gaim_notify_error(gc, NULL, _("File Transfer Failed"), | |
174 _("Unable to establish file descriptor.")); | |
175 gaim_xfer_cancel_remote(xfer); | |
176 } | |
8282 | 177 } else { |
10937 | 178 if (gaim_proxy_connect(account, gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST), |
179 gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), | |
180 yahoo_sendfile_connected, xfer) == -1) | |
181 { | |
182 gaim_notify_error(gc, NULL, _("File Transfer Failed"), | |
183 _("Unable to establish file descriptor.")); | |
184 gaim_xfer_cancel_remote(xfer); | |
8282 | 185 } |
7651 | 186 } |
187 } else { | |
188 xfer->fd = gaim_proxy_connect(account, xfer_data->host, xfer_data->port, | |
189 yahoo_receivefile_connected, xfer); | |
190 if (xfer->fd == -1) { | |
10654 | 191 gaim_notify_error(gc, NULL, _("File Transfer Failed"), |
7651 | 192 _("Unable to establish file descriptor.")); |
193 gaim_xfer_cancel_remote(xfer); | |
194 } | |
195 } | |
196 } | |
197 | |
198 static void yahoo_xfer_start(GaimXfer *xfer) | |
199 { | |
200 /* We don't need to do anything here, do we? */ | |
201 } | |
202 | |
203 static void yahoo_xfer_end(GaimXfer *xfer) | |
204 { | |
205 GaimAccount *account; | |
206 struct yahoo_xfer_data *xfer_data; | |
207 | |
208 account = gaim_xfer_get_account(xfer); | |
209 xfer_data = xfer->data; | |
210 | |
211 if (xfer_data) | |
212 yahoo_xfer_data_free(xfer_data); | |
213 xfer->data = NULL; | |
214 | |
215 } | |
216 | |
11897 | 217 static guint calculate_length(const gchar *l, size_t len) |
7651 | 218 { |
219 int i; | |
220 | |
221 for (i = 0; i < len; i++) { | |
222 if (!g_ascii_isdigit(l[i])) | |
223 continue; | |
224 return strtol(l + i, NULL, 10); | |
225 } | |
226 return 0; | |
227 } | |
228 | |
12412
a88ca6da0b38
[gaim-migrate @ 14719]
Richard Laager <rlaager@wiktel.com>
parents:
12151
diff
changeset
|
229 static gssize yahoo_xfer_read(guchar **buffer, GaimXfer *xfer) |
7651 | 230 { |
7710 | 231 gchar buf[4096]; |
12151
de798f2f4bf1
[gaim-migrate @ 14452]
Richard Laager <rlaager@wiktel.com>
parents:
12143
diff
changeset
|
232 gssize len; |
7651 | 233 gchar *start = NULL; |
234 gchar *length; | |
235 gchar *end; | |
7710 | 236 int filelen; |
7651 | 237 struct yahoo_xfer_data *xd = xfer->data; |
238 | |
239 if (gaim_xfer_get_type(xfer) != GAIM_XFER_RECEIVE) { | |
240 return 0; | |
241 } | |
242 | |
243 len = read(xfer->fd, buf, sizeof(buf)); | |
244 | |
7682 | 245 if (len <= 0) { |
7710 | 246 if ((gaim_xfer_get_size(xfer) > 0) && |
9798 | 247 (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer))) { |
7682 | 248 gaim_xfer_set_completed(xfer, TRUE); |
9798 | 249 return 0; |
250 } else | |
251 return -1; | |
7651 | 252 } |
253 | |
254 if (!xd->started) { | |
255 xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen); | |
256 memcpy(xd->rxqueue + xd->rxlen, buf, len); | |
257 xd->rxlen += len; | |
258 | |
259 length = g_strstr_len(xd->rxqueue, len, "Content-length:"); | |
10579 | 260 /* some proxies re-write this header, changing the capitalization :( |
261 * technically that's allowed since headers are case-insensitive | |
262 * [RFC 2616, section 4.2] */ | |
263 if (length == NULL) | |
264 length = g_strstr_len(xd->rxqueue, len, "Content-Length:"); | |
7651 | 265 if (length) { |
266 end = g_strstr_len(length, length - xd->rxqueue, "\r\n"); | |
267 if (!end) | |
268 return 0; | |
7710 | 269 if ((filelen = calculate_length(length, len - (length - xd->rxqueue)))) |
270 gaim_xfer_set_size(xfer, filelen); | |
7651 | 271 } |
272 start = g_strstr_len(xd->rxqueue, len, "\r\n\r\n"); | |
273 if (start) | |
274 start += 4; | |
275 if (!start || start > (xd->rxqueue + len)) | |
276 return 0; | |
277 xd->started = TRUE; | |
278 | |
279 len -= (start - xd->rxqueue); | |
280 | |
281 *buffer = g_malloc(len); | |
282 memcpy(*buffer, start, len); | |
283 g_free(xd->rxqueue); | |
284 xd->rxqueue = NULL; | |
285 xd->rxlen = 0; | |
286 } else { | |
287 *buffer = g_malloc(len); | |
288 memcpy(*buffer, buf, len); | |
289 } | |
290 | |
291 return len; | |
292 } | |
293 | |
12412
a88ca6da0b38
[gaim-migrate @ 14719]
Richard Laager <rlaager@wiktel.com>
parents:
12151
diff
changeset
|
294 static gssize yahoo_xfer_write(const guchar *buffer, size_t size, GaimXfer *xfer) |
7651 | 295 { |
12151
de798f2f4bf1
[gaim-migrate @ 14452]
Richard Laager <rlaager@wiktel.com>
parents:
12143
diff
changeset
|
296 gssize len; |
7651 | 297 struct yahoo_xfer_data *xd = xfer->data; |
298 | |
299 if (!xd) | |
9798 | 300 return -1; |
7651 | 301 |
302 if (gaim_xfer_get_type(xfer) != GAIM_XFER_SEND) { | |
9798 | 303 return -1; |
7651 | 304 } |
305 | |
306 len = write(xfer->fd, buffer, size); | |
307 | |
7710 | 308 if (len == -1) { |
309 if (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer)) | |
310 gaim_xfer_set_completed(xfer, TRUE); | |
311 if ((errno != EAGAIN) && (errno != EINTR)) | |
9798 | 312 return -1; |
7710 | 313 return 0; |
314 } | |
315 | |
316 if ((gaim_xfer_get_bytes_sent(xfer) + len) >= gaim_xfer_get_size(xfer)) | |
7651 | 317 gaim_xfer_set_completed(xfer, TRUE); |
318 | |
319 return len; | |
320 } | |
321 | |
322 static void yahoo_xfer_cancel_send(GaimXfer *xfer) | |
323 { | |
324 GaimAccount *account; | |
325 struct yahoo_xfer_data *xfer_data; | |
326 | |
327 xfer_data = xfer->data; | |
328 account = gaim_xfer_get_account(xfer); | |
329 | |
330 if (xfer_data) | |
331 yahoo_xfer_data_free(xfer_data); | |
332 xfer->data = NULL; | |
333 } | |
334 | |
335 static void yahoo_xfer_cancel_recv(GaimXfer *xfer) | |
336 { | |
337 GaimAccount *account; | |
338 struct yahoo_xfer_data *xfer_data; | |
339 | |
340 account = gaim_xfer_get_account(xfer); | |
341 xfer_data = xfer->data; | |
342 | |
343 if (xfer_data) | |
344 yahoo_xfer_data_free(xfer_data); | |
345 xfer->data = NULL; | |
346 } | |
347 | |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
348 void yahoo_process_p2pfilexfer(GaimConnection *gc, struct yahoo_packet *pkt) |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
349 { |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
350 GSList *l = pkt->hash; |
11644 | 351 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
352 char *me = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
353 char *from = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
354 char *service = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
355 char *message = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
356 char *command = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
357 char *imv = NULL; |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
358 char *unknown = NULL; |
11644 | 359 |
11801
81806e9241be
[gaim-migrate @ 14092]
Gary Kramlich <grim@reaperworld.com>
parents:
11644
diff
changeset
|
360 /* Get all the necessary values from this new packet */ |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
361 while(l != NULL) |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
362 { |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
363 struct yahoo_pair *pair = l->data; |
11644 | 364 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
365 if(pair->key == 5) /* Get who the packet is for */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
366 me = pair->value; |
11644 | 367 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
368 if(pair->key == 4) /* Get who the packet is from */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
369 from = pair->value; |
11644 | 370 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
371 if(pair->key == 49) /* Get the type of service */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
372 service = pair->value; |
11644 | 373 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
374 if(pair->key == 14) /* Get the 'message' of the packet */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
375 message = pair->value; |
11644 | 376 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
377 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
|
378 command = pair->value; |
11644 | 379 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
380 if(pair->key == 63) /* IMVironment name and version */ |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
381 imv = pair->value; |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
382 |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
383 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
|
384 unknown = pair->value; /* So, I'll keep it (for a little while atleast) */ |
11644 | 385 |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
386 l = l->next; |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
387 } |
11644 | 388 |
11801
81806e9241be
[gaim-migrate @ 14092]
Gary Kramlich <grim@reaperworld.com>
parents:
11644
diff
changeset
|
389 /* If this packet is an IMVIRONMENT, handle it accordingly */ |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
390 if(!strcmp(service, "IMVIRONMENT")) |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
391 { |
11801
81806e9241be
[gaim-migrate @ 14092]
Gary Kramlich <grim@reaperworld.com>
parents:
11644
diff
changeset
|
392 /* Check for a Doodle packet and handle it accordingly */ |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
393 if(!strcmp(imv, "doodle;11")) |
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
394 yahoo_doodle_process(gc, me, from, command, message); |
11644 | 395 |
11801
81806e9241be
[gaim-migrate @ 14092]
Gary Kramlich <grim@reaperworld.com>
parents:
11644
diff
changeset
|
396 /* If an IMVIRONMENT packet comes without a specific imviroment name */ |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
397 if(!strcmp(imv, ";0")) |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
398 { |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
399 /* 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
|
400 yahoo_doodle_command_got_shutdown(gc, from); |
11475
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
401 } |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
402 } |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
403 } |
7fab28c991f3
[gaim-migrate @ 13717]
Gary Kramlich <grim@reaperworld.com>
parents:
11159
diff
changeset
|
404 |
7651 | 405 void yahoo_process_filetransfer(GaimConnection *gc, struct yahoo_packet *pkt) |
406 { | |
407 char *from = NULL; | |
408 char *to = NULL; | |
409 char *msg = NULL; | |
410 char *url = NULL; | |
411 long expires = 0; | |
412 GaimXfer *xfer; | |
413 struct yahoo_xfer_data *xfer_data; | |
414 char *service = NULL; | |
415 char *filename = NULL; | |
416 unsigned long filesize = 0L; | |
417 GSList *l; | |
418 | |
419 for (l = pkt->hash; l; l = l->next) { | |
420 struct yahoo_pair *pair = l->data; | |
421 | |
422 if (pair->key == 4) | |
423 from = pair->value; | |
424 if (pair->key == 5) | |
425 to = pair->value; | |
426 if (pair->key == 14) | |
427 msg = pair->value; | |
428 if (pair->key == 20) | |
429 url = pair->value; | |
430 if (pair->key == 38) | |
431 expires = strtol(pair->value, NULL, 10); | |
432 if (pair->key == 27) | |
433 filename = pair->value; | |
434 if (pair->key == 28) | |
435 filesize = atol(pair->value); | |
436 if (pair->key == 49) | |
437 service = pair->value; | |
438 } | |
439 | |
440 if (pkt->service == YAHOO_SERVICE_P2PFILEXFER) { | |
10261 | 441 if (service && (strcmp("FILEXFER", service) != 0)) { |
7651 | 442 gaim_debug_misc("yahoo", "unhandled service 0x%02x", pkt->service); |
443 return; | |
444 } | |
445 } | |
446 | |
447 if (msg) { | |
448 char *tmp; | |
449 tmp = strchr(msg, '\006'); | |
450 if (tmp) | |
451 *tmp = '\0'; | |
452 } | |
453 | |
454 if (!url || !from) | |
455 return; | |
456 | |
457 /* Setup the Yahoo-specific file transfer data */ | |
458 xfer_data = g_new0(struct yahoo_xfer_data, 1); | |
459 xfer_data->gc = gc; | |
9227
9171e528d7e5
[gaim-migrate @ 10023]
Christian Hammond <chipx86@chipx86.com>
parents:
9164
diff
changeset
|
460 if (!gaim_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL)) { |
7651 | 461 g_free(xfer_data); |
462 return; | |
463 } | |
464 | |
465 gaim_debug_misc("yahoo_filexfer", "Host is %s, port is %d, path is %s, and the full url was %s.\n", | |
466 xfer_data->host, xfer_data->port, xfer_data->path, url); | |
467 | |
468 /* Build the file transfer handle. */ | |
469 xfer = gaim_xfer_new(gc->account, GAIM_XFER_RECEIVE, from); | |
470 xfer->data = xfer_data; | |
471 | |
472 /* Set the info about the incoming file. */ | |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
473 if (filename) { |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
474 char *utf8_filename = yahoo_string_decode(gc, filename, TRUE); |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
475 gaim_xfer_set_filename(xfer, utf8_filename); |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
476 g_free(utf8_filename); |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
477 } else { |
7651 | 478 gchar *start, *end; |
479 start = g_strrstr(xfer_data->path, "/"); | |
480 if (start) | |
481 start++; | |
482 end = g_strrstr(xfer_data->path, "?"); | |
483 if (start && *start && end) { | |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
484 char *utf8_filename; |
7651 | 485 filename = g_strndup(start, end - start); |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
486 utf8_filename = yahoo_string_decode(gc, filename, TRUE); |
7651 | 487 g_free(filename); |
10976
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
488 gaim_xfer_set_filename(xfer, utf8_filename); |
be22eb8fa671
[gaim-migrate @ 12802]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10937
diff
changeset
|
489 g_free(utf8_filename); |
7651 | 490 filename = NULL; |
491 } | |
492 } | |
493 | |
494 gaim_xfer_set_size(xfer, filesize); | |
495 | |
496 /* Setup our I/O op functions */ | |
497 gaim_xfer_set_init_fnc(xfer, yahoo_xfer_init); | |
498 gaim_xfer_set_start_fnc(xfer, yahoo_xfer_start); | |
499 gaim_xfer_set_end_fnc(xfer, yahoo_xfer_end); | |
500 gaim_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send); | |
501 gaim_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv); | |
502 gaim_xfer_set_read_fnc(xfer, yahoo_xfer_read); | |
503 gaim_xfer_set_write_fnc(xfer, yahoo_xfer_write); | |
504 | |
505 /* Now perform the request */ | |
506 gaim_xfer_request(xfer); | |
507 } | |
508 | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
509 GaimXfer *yahoo_new_xfer(GaimConnection *gc, const char *who) |
7651 | 510 { |
511 GaimXfer *xfer; | |
512 struct yahoo_xfer_data *xfer_data; | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
513 |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
514 g_return_val_if_fail(who != NULL, NULL); |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
515 |
7651 | 516 xfer_data = g_new0(struct yahoo_xfer_data, 1); |
517 xfer_data->gc = gc; | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
518 |
7651 | 519 /* Build the file transfer handle. */ |
520 xfer = gaim_xfer_new(gc->account, GAIM_XFER_SEND, who); | |
521 xfer->data = xfer_data; | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
522 |
7651 | 523 /* Setup our I/O op functions */ |
524 gaim_xfer_set_init_fnc(xfer, yahoo_xfer_init); | |
525 gaim_xfer_set_start_fnc(xfer, yahoo_xfer_start); | |
526 gaim_xfer_set_end_fnc(xfer, yahoo_xfer_end); | |
527 gaim_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send); | |
528 gaim_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv); | |
529 gaim_xfer_set_read_fnc(xfer, yahoo_xfer_read); | |
530 gaim_xfer_set_write_fnc(xfer, yahoo_xfer_write); | |
531 | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
532 return xfer; |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
533 } |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
534 |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
535 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
|
536 { |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
537 GaimXfer *xfer = yahoo_new_xfer(gc, who); |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
538 |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
539 g_return_if_fail(xfer != NULL); |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11914
diff
changeset
|
540 |
7651 | 541 /* Now perform the request */ |
11914
2219f4bf4a57
[gaim-migrate @ 14205]
Richard Laager <rlaager@wiktel.com>
parents:
11897
diff
changeset
|
542 if (file) |
9466 | 543 gaim_xfer_request_accepted(xfer, file); |
544 else | |
545 gaim_xfer_request(xfer); | |
7651 | 546 } |