Mercurial > gftp.yaz
annotate lib/rfc959.c @ 209:d79e2782eb1b
2003-7-5 Brian Masney <masneyb@gftp.org>
* lib/protocols.c (gftp_get_line) - fixed bug where the read function
was being called one extra time after the end of file was reached
* lib/rfc2068.c - fixes for chunked file transfers. All known issues with the
HTTP protocol should be (hopefully) fixed now
* lib/httpcommon.h (struct rfc2068_params_tag) - added eof variable
author | masneyb |
---|---|
date | Sat, 05 Jul 2003 17:30:14 +0000 |
parents | 0098dae654a5 |
children | a85a097bbb02 |
rev | line source |
---|---|
1 | 1 /*****************************************************************************/ |
2 /* rfc959.c - General purpose routines for the FTP protocol (RFC 959) */ | |
122 | 3 /* Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org> */ |
1 | 4 /* */ |
5 /* This program is free software; you can redistribute it and/or modify */ | |
6 /* it under the terms of the GNU General Public License as published by */ | |
7 /* the Free Software Foundation; either version 2 of the License, or */ | |
8 /* (at your option) any later version. */ | |
9 /* */ | |
10 /* This program is distributed in the hope that it will be useful, */ | |
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | |
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | |
13 /* GNU General Public License for more details. */ | |
14 /* */ | |
15 /* You should have received a copy of the GNU General Public License */ | |
16 /* along with this program; if not, write to the Free Software */ | |
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ | |
18 /*****************************************************************************/ | |
19 | |
20 #include "gftp.h" | |
33 | 21 static const char cvsid[] = "$Id$"; |
1 | 22 |
126 | 23 static gftp_textcomboedt_data gftp_proxy_type[] = { |
136 | 24 {N_("none"), "", 0}, |
25 {N_("SITE command"), "USER %pu\nPASS %pp\nSITE %hh\nUSER %hu\nPASS %hp\n", 0}, | |
26 {N_("user@host"), "USER %pu\nPASS %pp\nUSER %hu@%hh\nPASS %hp\n", 0}, | |
27 {N_("user@host:port"), "USER %hu@%hh:%ho\nPASS %hp\n", 0}, | |
28 {N_("AUTHENTICATE"), "USER %hu@%hh\nPASS %hp\nSITE AUTHENTICATE %pu\nSITE RESPONSE %pp\n", 0}, | |
29 {N_("user@host port"), "USER %hu@%hh %ho\nPASS %hp\n", 0}, | |
30 {N_("user@host NOAUTH"), "USER %hu@%hh\nPASS %hp\n", 0}, | |
31 {N_("HTTP Proxy"), "http", 0}, | |
32 {N_("Custom"), "", GFTP_TEXTCOMBOEDT_EDITABLE}, | |
126 | 33 {NULL, NULL} |
34 }; | |
35 | |
122 | 36 static gftp_config_vars config_vars[] = |
37 { | |
38 {"", N_("FTP"), gftp_option_type_notebook, NULL, NULL, 0, NULL, | |
39 GFTP_PORT_GTK, NULL}, | |
40 | |
41 {"email", N_("Email address:"), | |
42 gftp_option_type_text, "", NULL, 0, | |
43 N_("This is the password that will be used whenever you log into a remote FTP server as anonymous"), | |
44 GFTP_PORT_ALL, NULL}, | |
45 {"ftp_proxy_host", N_("Proxy hostname:"), | |
46 gftp_option_type_text, "", NULL, 0, | |
47 N_("Firewall hostname"), GFTP_PORT_ALL, NULL}, | |
48 {"ftp_proxy_port", N_("Proxy port:"), | |
49 gftp_option_type_int, GINT_TO_POINTER(21), NULL, 0, | |
50 N_("Port to connect to on the firewall"), GFTP_PORT_ALL, NULL}, | |
51 {"ftp_proxy_username", N_("Proxy username:"), | |
52 gftp_option_type_text, "", NULL, 0, | |
53 N_("Your firewall username"), GFTP_PORT_ALL, NULL}, | |
54 {"ftp_proxy_password", N_("Proxy password:"), | |
55 gftp_option_type_hidetext, "", NULL, 0, | |
56 N_("Your firewall password"), GFTP_PORT_ALL, NULL}, | |
57 {"ftp_proxy_account", N_("Proxy account:"), | |
58 gftp_option_type_text, "", NULL, 0, | |
59 N_("Your firewall account (optional)"), GFTP_PORT_ALL, NULL}, | |
60 | |
126 | 61 {"proxy_config", N_("Proxy server type:"), |
62 gftp_option_type_textcomboedt, "", gftp_proxy_type, 0, | |
149 | 63 /* xgettext:no-c-format */ |
126 | 64 N_("This specifies how your proxy server expects us to log in. You can specify a 2 character replacement string prefixed by a % that will be replaced with the proper data. The first character can be either p for proxy or h for the host of the FTP server. The second character can be u (user), p (pass), h (host), o (port) or a (account). For example, to specify the proxy user, you can you type in %pu"), |
65 GFTP_PORT_ALL, NULL}, | |
66 | |
136 | 67 {"passive_transfer", N_("Passive file transfers"), |
68 gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, 0, | |
69 N_("If this is enabled, then the remote FTP server will open up a port for the data connection. If you are behind a firewall, you will need to enable this. Generally, it is a good idea to keep this enabled unless you are connecting to an older FTP server that doesn't support this. If this is disabled, then gFTP will open up a port on the client side and the remote server will attempt to connect to it."), | |
70 GFTP_PORT_ALL, NULL}, | |
71 {"resolve_symlinks", N_("Resolve Remote Symlinks (LIST -L)"), | |
72 gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, 0, | |
73 N_("The remote FTP server will attempt to resolve symlinks in the directory listings. Generally, this is a good idea to leave enabled. The only time you will want to disable this is if the remote FTP server doesn't support the -L option to LIST"), | |
74 GFTP_PORT_ALL, NULL}, | |
75 {"ascii_transfers", N_("Transfer files in ASCII mode"), | |
76 gftp_option_type_checkbox, GINT_TO_POINTER(0), NULL, 0, | |
77 N_("If you are transfering a text file from Windows to UNIX box or vice versa, then you should enable this. Each system represents newlines differently for text files. If you are transfering from UNIX to UNIX, then it is safe to leave this off. If you are downloading binary data, you will want to disable this."), | |
78 GFTP_PORT_ALL, NULL}, | |
79 | |
122 | 80 {NULL, NULL, 0, NULL, NULL, 0, NULL, 0, NULL} |
81 }; | |
82 | |
83 | |
58 | 84 typedef struct rfc959_params_tag |
85 { | |
169 | 86 gftp_getline_buffer * datafd_rbuf, |
87 * dataconn_rbuf; | |
122 | 88 int is_ascii_transfer; |
169 | 89 int data_connection; |
58 | 90 } rfc959_parms; |
91 | |
92 | |
48 | 93 static int |
94 rfc959_read_response (gftp_request * request) | |
95 { | |
96 char tempstr[255], code[4]; | |
58 | 97 rfc959_parms * parms; |
98 ssize_t num_read; | |
48 | 99 |
84 | 100 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
101 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 102 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
48 | 103 |
104 *code = '\0'; | |
105 if (request->last_ftp_response) | |
106 { | |
107 g_free (request->last_ftp_response); | |
108 request->last_ftp_response = NULL; | |
109 } | |
110 | |
58 | 111 parms = request->protocol_data; |
112 | |
48 | 113 do |
114 { | |
169 | 115 if ((num_read = gftp_get_line (request, &parms->datafd_rbuf, tempstr, |
116 sizeof (tempstr), request->datafd)) <= 0) | |
48 | 117 break; |
58 | 118 |
48 | 119 if (isdigit ((int) *tempstr) && isdigit ((int) *(tempstr + 1)) |
120 && isdigit ((int) *(tempstr + 2))) | |
121 { | |
122 strncpy (code, tempstr, 3); | |
123 code[3] = ' '; | |
124 } | |
186 | 125 request->logging_function (gftp_logging_recv, request, |
48 | 126 "%s\n", tempstr); |
127 } | |
128 while (strncmp (code, tempstr, 4) != 0); | |
129 | |
58 | 130 if (num_read < 0) |
84 | 131 return ((int) num_read); |
48 | 132 |
105 | 133 request->last_ftp_response = g_strdup (tempstr); |
48 | 134 |
135 if (request->last_ftp_response[0] == '4' && | |
136 request->last_ftp_response[1] == '2') | |
137 gftp_disconnect (request); | |
138 | |
139 return (*request->last_ftp_response); | |
140 } | |
141 | |
142 | |
143 static int | |
144 rfc959_send_command (gftp_request * request, const char *command) | |
145 { | |
84 | 146 int ret; |
147 | |
148 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
149 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
150 g_return_val_if_fail (command != NULL, GFTP_EFATAL); | |
169 | 151 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
48 | 152 |
153 if (strncmp (command, "PASS", 4) == 0) | |
154 { | |
186 | 155 request->logging_function (gftp_logging_send, request, |
48 | 156 "PASS xxxx\n"); |
157 } | |
158 else if (strncmp (command, "ACCT", 4) == 0) | |
159 { | |
186 | 160 request->logging_function (gftp_logging_send, request, |
48 | 161 "ACCT xxxx\n"); |
162 } | |
163 else | |
164 { | |
186 | 165 request->logging_function (gftp_logging_send, request, "%s", |
48 | 166 command); |
167 } | |
168 | |
168 | 169 if ((ret = gftp_fd_write (request, command, strlen (command), |
169 | 170 request->datafd)) < 0) |
84 | 171 return (ret); |
48 | 172 |
173 return (rfc959_read_response (request)); | |
174 } | |
175 | |
176 | |
177 static char * | |
178 parse_ftp_proxy_string (gftp_request * request) | |
179 { | |
126 | 180 char *startpos, *endpos, *newstr, *newval, tempport[6], *proxy_config, |
181 savechar; | |
182 size_t len; | |
122 | 183 int tmp; |
48 | 184 |
185 g_return_val_if_fail (request != NULL, NULL); | |
186 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, NULL); | |
1 | 187 |
122 | 188 gftp_lookup_request_option (request, "proxy_config", &proxy_config); |
126 | 189 |
190 newstr = g_malloc0 (1); | |
191 len = 0; | |
122 | 192 startpos = endpos = proxy_config; |
48 | 193 while (*endpos != '\0') |
194 { | |
195 if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'p') | |
196 { | |
197 switch (tolower ((int) *(endpos + 2))) | |
198 { | |
199 case 'u': | |
124 | 200 gftp_lookup_request_option (request, "ftp_proxy_username", &newval); |
48 | 201 break; |
202 case 'p': | |
124 | 203 gftp_lookup_request_option (request, "ftp_proxy_password", &newval); |
48 | 204 break; |
205 case 'h': | |
124 | 206 gftp_lookup_request_option (request, "ftp_proxy_host", &newval); |
48 | 207 break; |
208 case 'o': | |
124 | 209 gftp_lookup_request_option (request, "ftp_proxy_port", &tmp); |
126 | 210 g_snprintf (tempport, sizeof (tempport), "%d", tmp); |
48 | 211 newval = tempport; |
212 break; | |
213 case 'a': | |
124 | 214 gftp_lookup_request_option (request, "ftp_proxy_account", &newval); |
48 | 215 break; |
216 default: | |
217 endpos++; | |
218 continue; | |
219 } | |
220 } | |
221 else if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'h') | |
222 { | |
223 switch (tolower ((int) *(endpos + 2))) | |
224 { | |
225 case 'u': | |
226 newval = request->username; | |
227 break; | |
228 case 'p': | |
229 newval = request->password; | |
230 break; | |
231 case 'h': | |
232 newval = request->hostname; | |
233 break; | |
234 case 'o': | |
126 | 235 g_snprintf (tempport, sizeof (tempport), "%d", request->port); |
48 | 236 newval = tempport; |
237 break; | |
238 case 'a': | |
239 newval = request->account; | |
240 break; | |
241 default: | |
242 endpos++; | |
243 continue; | |
244 } | |
245 } | |
246 else if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'n') | |
247 { | |
126 | 248 savechar = *endpos; |
249 *endpos = '\0'; | |
250 | |
251 len += strlen (startpos) + 2; | |
252 newstr = g_realloc (newstr, sizeof (char) * (len + 1)); | |
253 strcat (newstr, startpos); | |
254 strcat (newstr, "\r\n"); | |
255 | |
256 *endpos = savechar; | |
48 | 257 endpos += 2; |
258 startpos = endpos; | |
259 continue; | |
260 } | |
261 else | |
262 { | |
263 endpos++; | |
264 continue; | |
265 } | |
1 | 266 |
126 | 267 savechar = *endpos; |
48 | 268 *endpos = '\0'; |
126 | 269 len += strlen (startpos); |
48 | 270 if (!newval) |
126 | 271 { |
272 newstr = g_realloc (newstr, sizeof (char) * (len + 1)); | |
273 strcat (newstr, startpos); | |
274 } | |
48 | 275 else |
126 | 276 { |
277 len += strlen (newval); | |
278 newstr = g_realloc (newstr, sizeof (char) * (len + 1)); | |
279 strcat (newstr, startpos); | |
280 strcat (newstr, newval); | |
281 } | |
282 | |
283 *endpos = savechar; | |
48 | 284 endpos += 3; |
285 startpos = endpos; | |
286 } | |
126 | 287 |
48 | 288 return (newstr); |
289 } | |
290 | |
291 | |
292 static int | |
58 | 293 rfc959_getcwd (gftp_request * request) |
294 { | |
295 char *pos, *dir; | |
296 int ret; | |
297 | |
298 ret = rfc959_send_command (request, "PWD\r\n"); | |
299 if (ret < 0) | |
84 | 300 return (ret); |
58 | 301 else if (ret != '2') |
302 { | |
186 | 303 request->logging_function (gftp_logging_error, request, |
58 | 304 _("Received invalid response to PWD command: '%s'\n"), |
305 request->last_ftp_response); | |
306 gftp_disconnect (request); | |
84 | 307 return (GFTP_ERETRYABLE); |
58 | 308 } |
309 | |
310 if ((pos = strchr (request->last_ftp_response, '"')) == NULL) | |
311 { | |
186 | 312 request->logging_function (gftp_logging_error, request, |
58 | 313 _("Received invalid response to PWD command: '%s'\n"), |
314 request->last_ftp_response); | |
315 gftp_disconnect (request); | |
84 | 316 return (GFTP_EFATAL); |
58 | 317 } |
318 | |
319 dir = pos + 1; | |
320 | |
321 if ((pos = strchr (dir, '"')) == NULL) | |
322 { | |
186 | 323 request->logging_function (gftp_logging_error, request, |
58 | 324 _("Received invalid response to PWD command: '%s'\n"), |
325 request->last_ftp_response); | |
326 gftp_disconnect (request); | |
84 | 327 return (GFTP_EFATAL); |
58 | 328 } |
329 | |
330 *pos = '\0'; | |
331 | |
332 if (request->directory) | |
333 g_free (request->directory); | |
334 | |
105 | 335 request->directory = g_strdup (dir); |
58 | 336 return (0); |
337 } | |
338 | |
339 | |
340 static int | |
48 | 341 rfc959_chdir (gftp_request * request, const char *directory) |
342 { | |
58 | 343 char ret, *tempstr; |
84 | 344 int r; |
48 | 345 |
84 | 346 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
347 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
348 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
48 | 349 |
350 if (strcmp (directory, "..") == 0) | |
351 ret = rfc959_send_command (request, "CDUP\r\n"); | |
352 else | |
353 { | |
354 tempstr = g_strconcat ("CWD ", directory, "\r\n", NULL); | |
355 ret = rfc959_send_command (request, tempstr); | |
356 g_free (tempstr); | |
357 } | |
358 | |
359 if (ret != '2') | |
84 | 360 return (GFTP_ERETRYABLE); |
48 | 361 |
362 if (directory != request->directory) | |
363 { | |
84 | 364 if ((r = rfc959_getcwd (request)) < 0) |
365 return (r); | |
48 | 366 } |
367 | |
368 return (0); | |
1 | 369 } |
370 | |
371 | |
372 static int | |
91 | 373 rfc959_syst (gftp_request * request) |
374 { | |
375 char *stpos, *endpos; | |
376 int ret; | |
377 | |
378 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
379 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 380 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
91 | 381 |
382 ret = rfc959_send_command (request, "SYST\r\n"); | |
383 | |
384 if (ret < 0) | |
385 return (ret); | |
386 else if (ret != '2') | |
387 return (GFTP_ERETRYABLE); | |
388 | |
389 if ((stpos = strchr (request->last_ftp_response, ' ')) == NULL) | |
390 return (GFTP_ERETRYABLE); | |
391 | |
114 | 392 stpos++; |
393 | |
91 | 394 if ((endpos = strchr (stpos, ' ')) == NULL) |
395 return (GFTP_ERETRYABLE); | |
396 | |
397 *endpos = '\0'; | |
398 if (strcmp (stpos, "UNIX") == 0) | |
122 | 399 request->server_type = GFTP_DIRTYPE_UNIX; |
107 | 400 else if (strcmp (stpos, "VMS") == 0) |
122 | 401 request->server_type = GFTP_DIRTYPE_VMS; |
136 | 402 else if (strcmp (stpos, "CRAY") == 0) |
403 request->server_type = GFTP_DIRTYPE_CRAY; | |
91 | 404 else |
122 | 405 request->server_type = GFTP_DIRTYPE_OTHER; |
91 | 406 |
407 return (0); | |
408 } | |
409 | |
410 | |
411 static int | |
1 | 412 rfc959_connect (gftp_request * request) |
413 { | |
122 | 414 char tempchar, *startpos, *endpos, *tempstr, *email, *proxy_hostname; |
415 int ret, resp, ascii_transfers, proxy_port; | |
416 rfc959_parms * parms; | |
1 | 417 |
84 | 418 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
419 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
420 g_return_val_if_fail (request->hostname != NULL, GFTP_EFATAL); | |
1 | 421 |
169 | 422 if (request->datafd > 0) |
58 | 423 return (0); |
424 | |
122 | 425 parms = request->protocol_data; |
426 | |
427 gftp_lookup_request_option (request, "email", &email); | |
124 | 428 gftp_lookup_request_option (request, "ftp_proxy_host", &proxy_hostname); |
429 gftp_lookup_request_option (request, "ftp_proxy_port", &proxy_port); | |
122 | 430 |
7 | 431 if (request->username == NULL || *request->username == '\0') |
432 { | |
433 gftp_set_username (request, "anonymous"); | |
122 | 434 gftp_set_password (request, email); |
7 | 435 } |
436 else if (strcasecmp (request->username, "anonymous") == 0) | |
122 | 437 gftp_set_password (request, email); |
438 | |
177 | 439 if ((ret = gftp_connect_server (request, "ftp", proxy_hostname, proxy_port)) < 0) |
440 return (ret); | |
1 | 441 |
442 /* Get the banner */ | |
84 | 443 if ((ret = rfc959_read_response (request)) != '2') |
1 | 444 { |
445 gftp_disconnect (request); | |
84 | 446 return (ret); |
1 | 447 } |
448 | |
449 /* Login the proxy server if available */ | |
450 if (request->use_proxy) | |
451 { | |
452 resp = '3'; | |
453 startpos = endpos = tempstr = parse_ftp_proxy_string (request); | |
454 while ((resp == '3' || resp == '2') && *startpos != '\0') | |
455 { | |
456 if (*endpos == '\n' || *endpos == '\0') | |
457 { | |
458 tempchar = *(endpos + 1); | |
459 if (*endpos != '\0') | |
460 *(endpos + 1) = '\0'; | |
461 if ((resp = rfc959_send_command (request, startpos)) < 0) | |
84 | 462 return (resp); |
1 | 463 if (*endpos != '\0') |
464 *(endpos + 1) = tempchar; | |
465 else | |
466 break; | |
467 startpos = endpos + 1; | |
468 } | |
469 endpos++; | |
470 } | |
471 g_free (tempstr); | |
472 } | |
473 else | |
474 { | |
475 tempstr = g_strconcat ("USER ", request->username, "\r\n", NULL); | |
476 resp = rfc959_send_command (request, tempstr); | |
477 g_free (tempstr); | |
478 if (resp < 0) | |
84 | 479 return (GFTP_ERETRYABLE); |
1 | 480 if (resp == '3') |
481 { | |
482 tempstr = g_strconcat ("PASS ", request->password, "\r\n", NULL); | |
483 resp = rfc959_send_command (request, tempstr); | |
484 g_free (tempstr); | |
485 if (resp < 0) | |
84 | 486 return (GFTP_ERETRYABLE); |
1 | 487 } |
488 if (resp == '3' && request->account) | |
489 { | |
490 tempstr = g_strconcat ("ACCT ", request->account, "\r\n", NULL); | |
491 resp = rfc959_send_command (request, tempstr); | |
492 g_free (tempstr); | |
493 if (resp < 0) | |
84 | 494 return (GFTP_ERETRYABLE); |
1 | 495 } |
496 } | |
497 | |
498 if (resp != '2') | |
499 { | |
500 gftp_disconnect (request); | |
84 | 501 return (GFTP_EFATAL); |
1 | 502 } |
503 | |
169 | 504 if ((ret = rfc959_syst (request)) < 0 && request->datafd < 0) |
91 | 505 return (ret); |
506 | |
122 | 507 gftp_lookup_request_option (request, "ascii_transfers", &ascii_transfers); |
508 if (ascii_transfers) | |
509 { | |
510 tempstr = "TYPE A\r\n"; | |
511 parms->is_ascii_transfer = 1; | |
512 } | |
1 | 513 else |
122 | 514 { |
515 tempstr = "TYPE I\r\n"; | |
516 parms->is_ascii_transfer = 0; | |
517 } | |
1 | 518 |
84 | 519 if ((ret = rfc959_send_command (request, tempstr)) < 0) |
520 return (ret); | |
1 | 521 |
522 ret = -1; | |
523 if (request->directory != NULL && *request->directory != '\0') | |
524 { | |
525 ret = rfc959_chdir (request, request->directory); | |
169 | 526 if (request->datafd < 0) |
84 | 527 return (ret); |
1 | 528 } |
529 | |
530 if (ret != 0) | |
531 { | |
84 | 532 if ((ret = rfc959_getcwd (request)) < 0) |
533 return (ret); | |
1 | 534 } |
535 | |
169 | 536 if (request->datafd < 0) |
84 | 537 return (GFTP_EFATAL); |
1 | 538 |
539 return (0); | |
540 } | |
541 | |
542 | |
543 static void | |
544 rfc959_disconnect (gftp_request * request) | |
545 { | |
169 | 546 rfc959_parms * parms; |
547 | |
1 | 548 g_return_if_fail (request != NULL); |
549 g_return_if_fail (request->protonum == GFTP_FTP_NUM); | |
550 | |
169 | 551 parms = request->protocol_data; |
552 | |
553 if (request->datafd > 0) | |
1 | 554 { |
186 | 555 request->logging_function (gftp_logging_misc, request, |
1 | 556 _("Disconnecting from site %s\n"), |
557 request->hostname); | |
169 | 558 close (request->datafd); |
559 request->datafd = -1; | |
560 } | |
561 | |
562 if (parms->data_connection > 0) | |
563 { | |
564 close (parms->data_connection); | |
565 parms->data_connection = -1; | |
1 | 566 } |
567 } | |
568 | |
569 | |
48 | 570 static int |
146 | 571 rfc959_ipv4_data_connection_new (gftp_request * request) |
48 | 572 { |
573 char *pos, *pos1, resp, *command; | |
574 struct sockaddr_in data_addr; | |
122 | 575 int i, passive_transfer; |
169 | 576 rfc959_parms * parms; |
195 | 577 socklen_t data_addr_len; |
48 | 578 unsigned int temp[6]; |
579 unsigned char ad[6]; | |
580 | |
169 | 581 parms = request->protocol_data; |
582 | |
583 if ((parms->data_connection = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) | |
48 | 584 { |
186 | 585 request->logging_function (gftp_logging_error, request, |
48 | 586 _("Failed to create a socket: %s\n"), |
587 g_strerror (errno)); | |
588 gftp_disconnect (request); | |
84 | 589 return (GFTP_ERETRYABLE); |
48 | 590 } |
591 | |
182 | 592 if (fcntl (parms->data_connection, F_SETFD, 1) == -1) |
593 { | |
186 | 594 request->logging_function (gftp_logging_error, request, |
182 | 595 _("Error: Cannot set close on exec flag: %s\n"), |
596 g_strerror (errno)); | |
597 | |
598 return (GFTP_ERETRYABLE); | |
599 } | |
600 | |
48 | 601 data_addr_len = sizeof (data_addr); |
602 memset (&data_addr, 0, data_addr_len); | |
603 data_addr.sin_family = AF_INET; | |
604 | |
122 | 605 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); |
606 if (passive_transfer) | |
48 | 607 { |
608 if ((resp = rfc959_send_command (request, "PASV\r\n")) != '2') | |
609 { | |
169 | 610 if (request->datafd < 0) |
84 | 611 return (resp); |
48 | 612 |
122 | 613 gftp_set_request_option (request, "passive_transfer", GINT_TO_POINTER(0)); |
146 | 614 return (rfc959_ipv4_data_connection_new (request)); |
48 | 615 } |
58 | 616 |
48 | 617 pos = request->last_ftp_response + 4; |
618 while (!isdigit ((int) *pos) && *pos != '\0') | |
619 pos++; | |
58 | 620 |
48 | 621 if (*pos == '\0') |
622 { | |
186 | 623 request->logging_function (gftp_logging_error, request, |
58 | 624 _("Cannot find an IP address in PASV response '%s'\n"), |
625 request->last_ftp_response); | |
48 | 626 gftp_disconnect (request); |
84 | 627 return (GFTP_EFATAL); |
48 | 628 } |
58 | 629 |
48 | 630 if (sscanf (pos, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2], |
631 &temp[3], &temp[4], &temp[5]) != 6) | |
632 { | |
186 | 633 request->logging_function (gftp_logging_error, request, |
58 | 634 _("Cannot find an IP address in PASV response '%s'\n"), |
635 request->last_ftp_response); | |
48 | 636 gftp_disconnect (request); |
84 | 637 return (GFTP_EFATAL); |
48 | 638 } |
58 | 639 |
48 | 640 for (i = 0; i < 6; i++) |
641 ad[i] = (unsigned char) (temp[i] & 0xff); | |
642 | |
643 memcpy (&data_addr.sin_addr, &ad[0], 4); | |
644 memcpy (&data_addr.sin_port, &ad[4], 2); | |
169 | 645 if (connect (parms->data_connection, (struct sockaddr *) &data_addr, |
58 | 646 data_addr_len) == -1) |
48 | 647 { |
186 | 648 request->logging_function (gftp_logging_error, request, |
48 | 649 _("Cannot create a data connection: %s\n"), |
650 g_strerror (errno)); | |
651 gftp_disconnect (request); | |
84 | 652 return (GFTP_ERETRYABLE); |
48 | 653 } |
654 } | |
655 else | |
656 { | |
169 | 657 if (getsockname (request->datafd, (struct sockaddr *) &data_addr, |
58 | 658 &data_addr_len) == -1) |
659 { | |
186 | 660 request->logging_function (gftp_logging_error, request, |
58 | 661 _("Cannot get socket name: %s\n"), |
662 g_strerror (errno)); | |
663 gftp_disconnect (request); | |
84 | 664 return (GFTP_ERETRYABLE); |
58 | 665 } |
666 | |
48 | 667 data_addr.sin_port = 0; |
169 | 668 if (bind (parms->data_connection, (struct sockaddr *) &data_addr, |
58 | 669 data_addr_len) == -1) |
48 | 670 { |
186 | 671 request->logging_function (gftp_logging_error, request, |
48 | 672 _("Cannot bind a port: %s\n"), |
673 g_strerror (errno)); | |
674 gftp_disconnect (request); | |
84 | 675 return (GFTP_ERETRYABLE); |
48 | 676 } |
677 | |
169 | 678 if (getsockname (parms->data_connection, (struct sockaddr *) &data_addr, |
58 | 679 &data_addr_len) == -1) |
680 { | |
186 | 681 request->logging_function (gftp_logging_error, request, |
58 | 682 _("Cannot get socket name: %s\n"), |
683 g_strerror (errno)); | |
684 gftp_disconnect (request); | |
84 | 685 return (GFTP_ERETRYABLE); |
58 | 686 } |
687 | |
169 | 688 if (listen (parms->data_connection, 1) == -1) |
48 | 689 { |
186 | 690 request->logging_function (gftp_logging_error, request, |
48 | 691 _("Cannot listen on port %d: %s\n"), |
692 ntohs (data_addr.sin_port), | |
693 g_strerror (errno)); | |
694 gftp_disconnect (request); | |
84 | 695 return (GFTP_ERETRYABLE); |
48 | 696 } |
58 | 697 |
48 | 698 pos = (char *) &data_addr.sin_addr; |
699 pos1 = (char *) &data_addr.sin_port; | |
700 command = g_strdup_printf ("PORT %u,%u,%u,%u,%u,%u\r\n", | |
701 pos[0] & 0xff, pos[1] & 0xff, pos[2] & 0xff, | |
702 pos[3] & 0xff, pos1[0] & 0xff, | |
703 pos1[1] & 0xff); | |
704 resp = rfc959_send_command (request, command); | |
705 g_free (command); | |
706 if (resp != '2') | |
707 { | |
708 gftp_disconnect (request); | |
84 | 709 return (GFTP_ERETRYABLE); |
48 | 710 } |
711 } | |
712 | |
713 return (0); | |
714 } | |
715 | |
716 | |
146 | 717 #ifdef HAVE_IPV6 |
718 | |
719 static int | |
720 rfc959_ipv6_data_connection_new (gftp_request * request) | |
721 { | |
722 char *pos, resp, buf[64], *command; | |
723 struct sockaddr_in6 data_addr; | |
724 int passive_transfer; | |
195 | 725 socklen_t data_addr_len; |
169 | 726 rfc959_parms * parms; |
146 | 727 unsigned int port; |
728 | |
169 | 729 parms = request->protocol_data; |
730 if ((parms->data_connection = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) | |
146 | 731 { |
186 | 732 request->logging_function (gftp_logging_error, request, |
146 | 733 _("Failed to create a socket: %s\n"), |
734 g_strerror (errno)); | |
735 gftp_disconnect (request); | |
736 return (GFTP_ERETRYABLE); | |
737 } | |
738 | |
182 | 739 if (fcntl (parms->data_connection, F_SETFD, 1) == -1) |
740 { | |
186 | 741 request->logging_function (gftp_logging_error, request, |
182 | 742 _("Error: Cannot set close on exec flag: %s\n"), |
743 g_strerror (errno)); | |
744 | |
745 return (GFTP_ERETRYABLE); | |
746 } | |
747 | |
146 | 748 data_addr_len = sizeof (data_addr); |
749 /* This condition shouldn't happen. We better check anyway... */ | |
750 if (data_addr_len != request->hostp->ai_addrlen) | |
751 { | |
186 | 752 request->logging_function (gftp_logging_error, request, |
146 | 753 _("Error: It doesn't look like we are connected via IPv6. Aborting connection.\n")); |
754 gftp_disconnect (request); | |
755 return (GFTP_EFATAL); | |
756 } | |
757 | |
758 memset (&data_addr, 0, data_addr_len); | |
759 data_addr.sin6_family = AF_INET6; | |
760 | |
761 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); | |
762 if (passive_transfer) | |
763 { | |
764 if ((resp = rfc959_send_command (request, "EPSV\r\n")) != '2') | |
765 { | |
169 | 766 if (request->datafd < 0) |
146 | 767 return (resp); |
768 | |
769 gftp_set_request_option (request, "passive_transfer", | |
770 GINT_TO_POINTER(0)); | |
771 return (rfc959_ipv6_data_connection_new (request)); | |
772 } | |
773 | |
774 pos = request->last_ftp_response + 4; | |
775 while (*pos != '(' && *pos != '\0') | |
776 pos++; | |
777 pos++; | |
778 | |
779 if (*pos == '\0') | |
780 { | |
186 | 781 request->logging_function (gftp_logging_error, request, |
146 | 782 _("Invalid EPSV response '%s'\n"), |
783 request->last_ftp_response); | |
784 gftp_disconnect (request); | |
785 return (GFTP_EFATAL); | |
786 } | |
787 | |
788 if (sscanf (pos, "|||%d|", &port) != 1) | |
789 { | |
186 | 790 request->logging_function (gftp_logging_error, request, |
146 | 791 _("Invalid EPSV response '%s'\n"), |
792 request->last_ftp_response); | |
793 gftp_disconnect (request); | |
794 return (GFTP_EFATAL); | |
795 } | |
796 | |
797 memcpy (&data_addr, request->hostp->ai_addr, data_addr_len); | |
798 data_addr.sin6_port = htons (port); | |
799 | |
169 | 800 if (connect (parms->data_connection, (struct sockaddr *) &data_addr, |
146 | 801 data_addr_len) == -1) |
802 { | |
186 | 803 request->logging_function (gftp_logging_error, request, |
146 | 804 _("Cannot create a data connection: %s\n"), |
805 g_strerror (errno)); | |
806 gftp_disconnect (request); | |
807 return (GFTP_ERETRYABLE); | |
808 } | |
809 } | |
810 else | |
811 { | |
812 memcpy (&data_addr, request->hostp->ai_addr, data_addr_len); | |
813 data_addr.sin6_port = 0; | |
814 | |
169 | 815 if (bind (parms->data_connection, (struct sockaddr *) &data_addr, |
146 | 816 data_addr_len) == -1) |
817 { | |
186 | 818 request->logging_function (gftp_logging_error, request, |
146 | 819 _("Cannot bind a port: %s\n"), |
820 g_strerror (errno)); | |
821 gftp_disconnect (request); | |
822 return (GFTP_ERETRYABLE); | |
823 } | |
824 | |
169 | 825 if (getsockname (parms->data_connection, (struct sockaddr *) &data_addr, |
146 | 826 &data_addr_len) == -1) |
827 { | |
186 | 828 request->logging_function (gftp_logging_error, request, |
146 | 829 _("Cannot get socket name: %s\n"), |
830 g_strerror (errno)); | |
831 gftp_disconnect (request); | |
832 return (GFTP_ERETRYABLE); | |
833 } | |
834 | |
169 | 835 if (listen (parms->data_connection, 1) == -1) |
146 | 836 { |
186 | 837 request->logging_function (gftp_logging_error, request, |
146 | 838 _("Cannot listen on port %d: %s\n"), |
839 ntohs (data_addr.sin6_port), | |
840 g_strerror (errno)); | |
841 gftp_disconnect (request); | |
842 return (GFTP_ERETRYABLE); | |
843 } | |
844 | |
845 if (inet_ntop (AF_INET6, &data_addr.sin6_addr, buf, sizeof (buf)) == NULL) | |
846 { | |
186 | 847 request->logging_function (gftp_logging_error, request, |
146 | 848 _("Cannot get address of local socket: %s\n"), |
849 g_strerror (errno)); | |
850 gftp_disconnect (request); | |
851 return (GFTP_ERETRYABLE); | |
852 } | |
853 | |
854 command = g_strdup_printf ("EPRT |2|%s|%d|\n", buf, | |
855 ntohs (data_addr.sin6_port)); | |
856 | |
857 resp = rfc959_send_command (request, command); | |
858 g_free (command); | |
859 if (resp != '2') | |
860 { | |
861 gftp_disconnect (request); | |
862 return (GFTP_ERETRYABLE); | |
863 } | |
864 } | |
865 | |
866 return (0); | |
867 } | |
868 | |
869 #endif /* HAVE_IPV6 */ | |
870 | |
871 | |
872 static int | |
873 rfc959_data_connection_new (gftp_request * request) | |
874 { | |
875 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
876 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 877 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
146 | 878 |
879 #ifdef HAVE_IPV6 | |
151 | 880 if (GFTP_GET_AI_FAMILY(request) == AF_INET6) |
146 | 881 return (rfc959_ipv6_data_connection_new (request)); |
882 else | |
151 | 883 return (rfc959_ipv4_data_connection_new (request)); |
884 #else | |
885 return (rfc959_ipv4_data_connection_new (request)); | |
146 | 886 #endif |
887 } | |
888 | |
889 | |
48 | 890 static int |
891 rfc959_accept_active_connection (gftp_request * request) | |
892 { | |
122 | 893 int infd, ret, passive_transfer; |
169 | 894 rfc959_parms * parms; |
146 | 895 #ifdef HAVE_IPV6 |
48 | 896 struct sockaddr_in cli_addr; |
146 | 897 #else |
898 struct sockaddr_in6 cli_addr; | |
899 #endif | |
195 | 900 socklen_t cli_addr_len; |
48 | 901 |
169 | 902 parms = request->protocol_data; |
903 | |
84 | 904 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
905 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 906 g_return_val_if_fail (parms->data_connection > 0, GFTP_EFATAL); |
122 | 907 |
908 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); | |
909 g_return_val_if_fail (!passive_transfer, GFTP_EFATAL); | |
48 | 910 |
911 cli_addr_len = sizeof (cli_addr); | |
58 | 912 |
169 | 913 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 0)) < 0) |
84 | 914 return (ret); |
58 | 915 |
169 | 916 if ((infd = accept (parms->data_connection, (struct sockaddr *) &cli_addr, |
48 | 917 &cli_addr_len)) == -1) |
918 { | |
186 | 919 request->logging_function (gftp_logging_error, request, |
48 | 920 _("Cannot accept connection from server: %s\n"), |
921 g_strerror (errno)); | |
922 gftp_disconnect (request); | |
84 | 923 return (GFTP_ERETRYABLE); |
48 | 924 } |
925 | |
169 | 926 close (parms->data_connection); |
48 | 927 |
169 | 928 parms->data_connection = infd; |
929 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 1)) < 0) | |
84 | 930 return (ret); |
58 | 931 |
48 | 932 return (0); |
933 } | |
934 | |
935 | |
122 | 936 static int |
937 rfc959_is_ascii_transfer (const char *filename) | |
938 { | |
939 gftp_config_list_vars * tmplistvar; | |
940 gftp_file_extensions * tempext; | |
941 GList * templist; | |
942 int stlen, ret; | |
943 | |
944 gftp_lookup_global_option ("ext", &tmplistvar); | |
945 | |
946 ret = 0; | |
947 stlen = strlen (filename); | |
948 for (templist = tmplistvar->list; templist != NULL; templist = templist->next) | |
949 { | |
950 tempext = templist->data; | |
951 | |
952 if (stlen >= tempext->stlen && | |
953 strcmp (&filename[stlen - tempext->stlen], tempext->ext) == 0) | |
954 { | |
955 if (toupper (*tempext->ascii_binary == 'A')) | |
956 ret = 1; | |
957 break; | |
958 } | |
959 } | |
960 | |
961 return (ret); | |
962 } | |
963 | |
964 | |
965 static void | |
966 rfc959_set_data_type (gftp_request * request, const char *filename) | |
967 { | |
968 rfc959_parms * parms; | |
969 int new_ascii; | |
970 char *tempstr; | |
971 | |
972 g_return_if_fail (request != NULL); | |
973 g_return_if_fail (request->protonum == GFTP_FTP_NUM); | |
974 | |
975 parms = request->protocol_data; | |
976 new_ascii = rfc959_is_ascii_transfer (filename); | |
977 | |
169 | 978 if (request->datafd > 0 && new_ascii != parms->is_ascii_transfer) |
122 | 979 { |
980 if (new_ascii) | |
981 { | |
982 tempstr = "TYPE A\r\n"; | |
983 parms->is_ascii_transfer = 1; | |
984 } | |
985 else | |
986 { | |
987 tempstr = "TYPE I\r\n"; | |
988 parms->is_ascii_transfer = 1; | |
989 } | |
990 | |
991 rfc959_send_command (request, tempstr); | |
992 } | |
993 | |
994 return; | |
995 } | |
996 | |
997 | |
58 | 998 static off_t |
999 rfc959_get_file (gftp_request * request, const char *filename, int fd, | |
1 | 1000 off_t startsize) |
1001 { | |
1002 char *command, *tempstr, resp; | |
122 | 1003 int ret, passive_transfer; |
169 | 1004 rfc959_parms * parms; |
1 | 1005 |
84 | 1006 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1007 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1008 g_return_val_if_fail (filename != NULL, GFTP_EFATAL); | |
169 | 1009 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1010 |
169 | 1011 parms = request->protocol_data; |
58 | 1012 if (fd > 0) |
169 | 1013 parms->data_connection = fd; |
1 | 1014 |
122 | 1015 rfc959_set_data_type (request, filename); |
1016 | |
169 | 1017 if (parms->data_connection < 0 && |
1 | 1018 (ret = rfc959_data_connection_new (request)) < 0) |
1019 return (ret); | |
1020 | |
169 | 1021 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 1)) < 0) |
84 | 1022 return (ret); |
1 | 1023 |
1024 if (startsize > 0) | |
1025 { | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1026 #if defined (_LARGEFILE_SOURCE) |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1027 command = g_strdup_printf ("REST %lld\r\n", startsize); |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1028 #else |
1 | 1029 command = g_strdup_printf ("REST %ld\r\n", startsize); |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1030 #endif |
1 | 1031 resp = rfc959_send_command (request, command); |
1032 g_free (command); | |
1033 | |
1034 if (resp != '3') | |
1035 { | |
169 | 1036 close (parms->data_connection); |
1037 parms->data_connection = -1; | |
84 | 1038 return (GFTP_ERETRYABLE); |
1 | 1039 } |
1040 } | |
1041 | |
1042 tempstr = g_strconcat ("RETR ", filename, "\r\n", NULL); | |
1043 ret = rfc959_send_command (request, tempstr); | |
1044 g_free (tempstr); | |
1045 | |
1046 if (ret != '1') | |
58 | 1047 { |
169 | 1048 close (parms->data_connection); |
1049 parms->data_connection = -1; | |
84 | 1050 return (GFTP_ERETRYABLE); |
58 | 1051 } |
1 | 1052 |
122 | 1053 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); |
1054 if (!passive_transfer && | |
1 | 1055 (ret = rfc959_accept_active_connection (request)) < 0) |
1056 return (ret); | |
1057 | |
1058 if ((tempstr = strrchr (request->last_ftp_response, '(')) == NULL) | |
1059 { | |
1060 tempstr = request->last_ftp_response + 4; | |
1061 while (!isdigit ((int) *tempstr) && *tempstr != '\0') | |
1062 tempstr++; | |
1063 } | |
1064 else | |
1065 tempstr++; | |
1066 | |
1067 return (strtol (tempstr, NULL, 10) + startsize); | |
1068 } | |
1069 | |
1070 | |
1071 static int | |
58 | 1072 rfc959_put_file (gftp_request * request, const char *filename, int fd, |
1 | 1073 off_t startsize, off_t totalsize) |
1074 { | |
1075 char *command, *tempstr, resp; | |
122 | 1076 int ret, passive_transfer; |
169 | 1077 rfc959_parms * parms; |
1 | 1078 |
84 | 1079 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1080 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1081 g_return_val_if_fail (filename != NULL, GFTP_EFATAL); | |
169 | 1082 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1083 |
169 | 1084 parms = request->protocol_data; |
58 | 1085 if (fd > 0) |
169 | 1086 fd = parms->data_connection; |
1 | 1087 |
122 | 1088 rfc959_set_data_type (request, filename); |
1089 | |
169 | 1090 if (parms->data_connection < 0 && |
1 | 1091 (ret = rfc959_data_connection_new (request)) < 0) |
1092 return (ret); | |
1093 | |
169 | 1094 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 1)) < 0) |
84 | 1095 return (ret); |
1 | 1096 |
1097 if (startsize > 0) | |
1098 { | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1099 #if defined (_LARGEFILE_SOURCE) |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1100 command = g_strdup_printf ("REST %lld\r\n", startsize); |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1101 #else |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1102 command = g_strdup_printf ("REST %ld\r\n", startsize); |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1103 #endif |
1 | 1104 resp = rfc959_send_command (request, command); |
1105 g_free (command); | |
1106 if (resp != '3') | |
1107 { | |
169 | 1108 close (parms->data_connection); |
1109 parms->data_connection = -1; | |
84 | 1110 return (GFTP_ERETRYABLE); |
1 | 1111 } |
1112 } | |
1113 | |
1114 tempstr = g_strconcat ("STOR ", filename, "\r\n", NULL); | |
1115 ret = rfc959_send_command (request, tempstr); | |
1116 g_free (tempstr); | |
1117 if (ret != '1') | |
58 | 1118 { |
169 | 1119 close (parms->data_connection); |
1120 parms->data_connection = -1; | |
84 | 1121 return (GFTP_ERETRYABLE); |
58 | 1122 } |
1 | 1123 |
122 | 1124 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); |
1125 if (!passive_transfer && | |
1 | 1126 (ret = rfc959_accept_active_connection (request)) < 0) |
1127 return (ret); | |
1128 | |
1129 return (0); | |
1130 } | |
1131 | |
58 | 1132 |
1 | 1133 static long |
1134 rfc959_transfer_file (gftp_request *fromreq, const char *fromfile, | |
1135 off_t fromsize, gftp_request *toreq, | |
1136 const char *tofile, off_t tosize) | |
1137 { | |
1138 char *tempstr, *pos, *endpos; | |
84 | 1139 int ret; |
1 | 1140 |
84 | 1141 g_return_val_if_fail (fromreq != NULL, GFTP_EFATAL); |
1142 g_return_val_if_fail (fromfile != NULL, GFTP_EFATAL); | |
1143 g_return_val_if_fail (toreq != NULL, GFTP_EFATAL); | |
1144 g_return_val_if_fail (tofile != NULL, GFTP_EFATAL); | |
169 | 1145 g_return_val_if_fail (fromreq->datafd > 0, GFTP_EFATAL); |
1146 g_return_val_if_fail (toreq->datafd > 0, GFTP_EFATAL); | |
1 | 1147 |
122 | 1148 gftp_set_request_option (fromreq, "passive_transfer", GINT_TO_POINTER(1)); |
1149 gftp_set_request_option (toreq, "passive_transfer", GINT_TO_POINTER(0)); | |
1 | 1150 |
84 | 1151 if ((ret = rfc959_send_command (fromreq, "PASV\r\n")) != '2') |
1152 return (ret); | |
1 | 1153 |
1154 pos = fromreq->last_ftp_response + 4; | |
1155 while (!isdigit ((int) *pos) && *pos != '\0') | |
1156 pos++; | |
1157 if (*pos == '\0') | |
84 | 1158 return (GFTP_EFATAL); |
1 | 1159 |
1160 endpos = pos; | |
1161 while (*endpos != ')' && *endpos != '\0') | |
1162 endpos++; | |
1163 if (*endpos == ')') | |
1164 *endpos = '\0'; | |
1165 | |
1166 tempstr = g_strconcat ("PORT ", pos, "\r\n", NULL); | |
84 | 1167 if ((ret = rfc959_send_command (toreq, tempstr)) != '2') |
15
82fabd6ef1c4
FXP fixes (from Tobias Gruetzmacher <tobias@portfolio16.de>)
masneyb
parents:
14
diff
changeset
|
1168 { |
82fabd6ef1c4
FXP fixes (from Tobias Gruetzmacher <tobias@portfolio16.de>)
masneyb
parents:
14
diff
changeset
|
1169 g_free (tempstr); |
84 | 1170 return (ret); |
15
82fabd6ef1c4
FXP fixes (from Tobias Gruetzmacher <tobias@portfolio16.de>)
masneyb
parents:
14
diff
changeset
|
1171 } |
1 | 1172 g_free (tempstr); |
1173 | |
1174 tempstr = g_strconcat ("RETR ", fromfile, "\r\n", NULL); | |
168 | 1175 if ((ret = gftp_fd_write (fromreq, tempstr, strlen (tempstr), |
169 | 1176 fromreq->datafd)) < 0) |
58 | 1177 { |
1178 g_free (tempstr); | |
84 | 1179 return (ret); |
58 | 1180 } |
1 | 1181 g_free (tempstr); |
1182 | |
1183 tempstr = g_strconcat ("STOR ", tofile, "\r\n", NULL); | |
168 | 1184 if ((ret = gftp_fd_write (toreq, tempstr, strlen (tempstr), |
169 | 1185 toreq->datafd)) < 0) |
58 | 1186 { |
1187 g_free (tempstr); | |
84 | 1188 return (ret); |
58 | 1189 } |
1 | 1190 g_free (tempstr); |
1191 | |
84 | 1192 if ((ret = rfc959_read_response (fromreq)) < 0) |
1193 return (ret); | |
1194 | |
1195 if ((ret = rfc959_read_response (toreq)) < 0) | |
1196 return (ret); | |
1 | 1197 |
1198 return (0); | |
1199 } | |
1200 | |
1201 | |
1202 static int | |
1203 rfc959_end_transfer (gftp_request * request) | |
1204 { | |
169 | 1205 rfc959_parms * parms; |
84 | 1206 int ret; |
1207 | |
1208 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
1209 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 1210 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1211 |
169 | 1212 parms = request->protocol_data; |
1213 if (parms->data_connection > 0) | |
1 | 1214 { |
169 | 1215 close (parms->data_connection); |
1216 parms->data_connection = -1; | |
1 | 1217 } |
84 | 1218 |
1219 ret = rfc959_read_response (request); | |
1220 | |
1221 if (ret < 0) | |
1222 return (ret); | |
1223 else if (ret == '2') | |
1224 return (0); | |
1225 else | |
1226 return (GFTP_ERETRYABLE); | |
1 | 1227 } |
1228 | |
1229 | |
1230 static int | |
40 | 1231 rfc959_abort_transfer (gftp_request * request) |
1232 { | |
169 | 1233 rfc959_parms * parms; |
40 | 1234 int ret; |
1235 | |
84 | 1236 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1237 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 1238 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
40 | 1239 |
169 | 1240 parms = request->protocol_data; |
1241 if (parms->data_connection > 0) | |
40 | 1242 { |
169 | 1243 close (parms->data_connection); |
1244 parms->data_connection = -1; | |
40 | 1245 } |
1246 | |
1247 /* We need to read two lines of output. The first one is acknowleging | |
1248 the transfer and the second line acknowleges the ABOR command */ | |
84 | 1249 if ((ret = rfc959_send_command (request, "ABOR\r\n")) < 0) |
1250 return (ret); | |
40 | 1251 |
169 | 1252 if (request->datafd > 0) |
40 | 1253 { |
58 | 1254 if ((ret = rfc959_read_response (request)) < 0) |
40 | 1255 gftp_disconnect (request); |
1256 } | |
1257 | |
1258 return (0); | |
1259 } | |
1260 | |
1261 | |
1262 static int | |
1 | 1263 rfc959_list_files (gftp_request * request) |
1264 { | |
122 | 1265 int ret, show_hidden_files, resolve_symlinks, passive_transfer; |
1 | 1266 char *tempstr, parms[3]; |
1267 | |
84 | 1268 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1269 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 1270 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1271 |
1272 if ((ret = rfc959_data_connection_new (request)) < 0) | |
1273 return (ret); | |
1274 | |
122 | 1275 gftp_lookup_request_option (request, "show_hidden_files", &show_hidden_files); |
1276 gftp_lookup_request_option (request, "resolve_symlinks", &resolve_symlinks); | |
1277 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); | |
1278 | |
1 | 1279 *parms = '\0'; |
1280 strcat (parms, show_hidden_files ? "a" : ""); | |
1281 strcat (parms, resolve_symlinks ? "L" : ""); | |
1282 tempstr = g_strconcat ("LIST", *parms != '\0' ? " -" : "", parms, "\r\n", | |
1283 NULL); | |
1284 | |
1285 ret = rfc959_send_command (request, tempstr); | |
1286 g_free (tempstr); | |
1287 | |
1288 if (ret != '1') | |
84 | 1289 return (GFTP_ERETRYABLE); |
1 | 1290 |
1291 ret = 0; | |
122 | 1292 if (!passive_transfer) |
1 | 1293 ret = rfc959_accept_active_connection (request); |
1294 | |
1295 return (ret); | |
1296 } | |
1297 | |
1298 | |
122 | 1299 static ssize_t |
1300 rfc959_get_next_file_chunk (gftp_request * request, char *buf, size_t size) | |
1301 { | |
1302 int i, j, ascii_transfers; | |
169 | 1303 rfc959_parms * parms; |
122 | 1304 ssize_t num_read; |
1305 | |
169 | 1306 parms = request->protocol_data; |
1307 num_read = gftp_fd_read (request, buf, size, parms->data_connection); | |
122 | 1308 if (num_read < 0) |
1309 return (num_read); | |
1310 | |
1311 gftp_lookup_request_option (request, "ascii_transfers", &ascii_transfers); | |
1312 if (ascii_transfers) | |
1313 { | |
1314 for (i = 0, j = 0; i < num_read; i++) | |
1315 { | |
1316 if (buf[i] != '\r') | |
1317 buf[j++] = buf[i]; | |
1318 else | |
1319 num_read--; | |
1320 } | |
1321 } | |
1322 | |
1323 return (num_read); | |
1324 } | |
1325 | |
1326 | |
1327 static ssize_t | |
1328 rfc959_put_next_file_chunk (gftp_request * request, char *buf, size_t size) | |
1329 { | |
1330 int i, j, ascii_transfers; | |
169 | 1331 rfc959_parms * parms; |
122 | 1332 ssize_t num_wrote; |
1333 char *tempstr; | |
1334 size_t rsize; | |
1335 | |
1336 if (size == 0) | |
1337 return (0); | |
1338 | |
169 | 1339 parms = request->protocol_data; |
1340 | |
122 | 1341 gftp_lookup_request_option (request, "ascii_transfers", &ascii_transfers); |
1342 if (ascii_transfers) | |
1343 { | |
1344 rsize = 0; | |
1345 for (i = 0; i < size; i++) | |
1346 { | |
1347 rsize++; | |
1348 if (i > 0 && buf[i] == '\n' && buf[i - 1] != '\r') | |
1349 rsize++; | |
1350 } | |
1351 | |
1352 if (rsize != size) | |
1353 { | |
1354 tempstr = g_malloc (rsize); | |
1355 | |
1356 for (i = 0, j = 0; i < size; i++) | |
1357 { | |
1358 if (i > 0 && buf[i] == '\n' && buf[i - 1] != '\r') | |
1359 tempstr[j++] = '\r'; | |
1360 tempstr[j++] = buf[i]; | |
1361 } | |
1362 } | |
1363 else | |
1364 tempstr = buf; | |
1365 } | |
1366 else | |
1367 { | |
1368 rsize = size; | |
1369 tempstr = buf; | |
1370 } | |
1371 | |
169 | 1372 num_wrote = gftp_fd_write (request, tempstr, rsize, parms->data_connection); |
122 | 1373 |
1374 if (tempstr != buf) | |
1375 g_free (tempstr); | |
1376 | |
1377 return (num_wrote); | |
1378 } | |
1379 | |
1380 | |
1 | 1381 int |
58 | 1382 rfc959_get_next_file (gftp_request * request, gftp_file * fle, int fd) |
1 | 1383 { |
58 | 1384 rfc959_parms * parms; |
1 | 1385 char tempstr[255]; |
58 | 1386 ssize_t len; |
1 | 1387 |
84 | 1388 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1389 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1390 g_return_val_if_fail (fle != NULL, GFTP_EFATAL); | |
1391 g_return_val_if_fail (fd > 0, GFTP_EFATAL); | |
1 | 1392 |
1393 if (request->last_dir_entry) | |
1394 { | |
1395 g_free (request->last_dir_entry); | |
1396 request->last_dir_entry = NULL; | |
1397 } | |
58 | 1398 |
1399 parms = request->protocol_data; | |
1400 | |
169 | 1401 if (fd == request->datafd) |
1402 fd = parms->data_connection; | |
1403 | |
1 | 1404 do |
1405 { | |
169 | 1406 if ((len = gftp_get_line (request, &parms->dataconn_rbuf, |
60 | 1407 tempstr, sizeof (tempstr), fd)) <= 0) |
1 | 1408 { |
1409 gftp_file_destroy (fle); | |
58 | 1410 return ((int) len); |
1 | 1411 } |
1412 | |
91 | 1413 if (gftp_parse_ls (request, tempstr, fle) != 0) |
1 | 1414 { |
58 | 1415 if (strncmp (tempstr, "total", strlen ("total")) != 0 && |
1416 strncmp (tempstr, _("total"), strlen (_("total"))) != 0) | |
186 | 1417 request->logging_function (gftp_logging_error, request, |
1 | 1418 _("Warning: Cannot parse listing %s\n"), |
1419 tempstr); | |
1420 gftp_file_destroy (fle); | |
1421 continue; | |
1422 } | |
1423 else | |
1424 break; | |
1425 } | |
1426 while (1); | |
1427 | |
1428 len = strlen (tempstr); | |
1429 if (!request->cached) | |
1430 { | |
60 | 1431 request->last_dir_entry = g_strdup_printf ("%s\n", tempstr); |
168 | 1432 request->last_dir_entry_len = strlen (tempstr) + 1; |
1 | 1433 } |
1434 return (len); | |
1435 } | |
1436 | |
1437 | |
1438 static off_t | |
1439 rfc959_get_file_size (gftp_request * request, const char *filename) | |
1440 { | |
1441 char *tempstr; | |
1442 int ret; | |
1443 | |
1444 g_return_val_if_fail (request != NULL, 0); | |
84 | 1445 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); |
1 | 1446 g_return_val_if_fail (filename != NULL, 0); |
169 | 1447 g_return_val_if_fail (request->datafd > 0, 0); |
1 | 1448 |
1449 tempstr = g_strconcat ("SIZE ", filename, "\r\n", NULL); | |
1450 ret = rfc959_send_command (request, tempstr); | |
1451 g_free (tempstr); | |
1452 if (ret < 0) | |
84 | 1453 return (ret); |
1 | 1454 |
1455 if (*request->last_ftp_response != '2') | |
1456 return (0); | |
1457 return (strtol (request->last_ftp_response + 4, NULL, 10)); | |
1458 } | |
1459 | |
1460 | |
1461 static int | |
1462 rfc959_rmdir (gftp_request * request, const char *directory) | |
1463 { | |
1464 char *tempstr, ret; | |
1465 | |
84 | 1466 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1467 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1468 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
169 | 1469 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1470 |
1471 tempstr = g_strconcat ("RMD ", directory, "\r\n", NULL); | |
1472 ret = rfc959_send_command (request, tempstr); | |
1473 g_free (tempstr); | |
84 | 1474 |
1475 if (ret < 0) | |
1476 return (ret); | |
1477 else if (ret == '2') | |
1478 return (0); | |
1479 else | |
1480 return (GFTP_ERETRYABLE); | |
1 | 1481 } |
1482 | |
1483 | |
1484 static int | |
1485 rfc959_rmfile (gftp_request * request, const char *file) | |
1486 { | |
1487 char *tempstr, ret; | |
1488 | |
84 | 1489 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1490 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1491 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
169 | 1492 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1493 |
1494 tempstr = g_strconcat ("DELE ", file, "\r\n", NULL); | |
1495 ret = rfc959_send_command (request, tempstr); | |
1496 g_free (tempstr); | |
84 | 1497 |
1498 if (ret < 0) | |
1499 return (ret); | |
1500 else if (ret == '2') | |
1501 return (0); | |
1502 else | |
1503 return (GFTP_ERETRYABLE); | |
1 | 1504 } |
1505 | |
1506 | |
1507 static int | |
1508 rfc959_mkdir (gftp_request * request, const char *directory) | |
1509 { | |
1510 char *tempstr, ret; | |
1511 | |
84 | 1512 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1513 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1514 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
169 | 1515 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1516 |
1517 tempstr = g_strconcat ("MKD ", directory, "\r\n", NULL); | |
1518 ret = rfc959_send_command (request, tempstr); | |
1519 g_free (tempstr); | |
84 | 1520 |
1521 if (ret < 0) | |
1522 return (ret); | |
1523 else if (ret == '2') | |
1524 return (0); | |
1525 else | |
1526 return (GFTP_ERETRYABLE); | |
1 | 1527 } |
1528 | |
1529 | |
1530 static int | |
1531 rfc959_rename (gftp_request * request, const char *oldname, | |
1532 const char *newname) | |
1533 { | |
1534 char *tempstr, ret; | |
1535 | |
84 | 1536 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1537 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1538 g_return_val_if_fail (oldname != NULL, GFTP_EFATAL); | |
1539 g_return_val_if_fail (newname != NULL, GFTP_EFATAL); | |
169 | 1540 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1541 |
1542 tempstr = g_strconcat ("RNFR ", oldname, "\r\n", NULL); | |
1543 ret = rfc959_send_command (request, tempstr); | |
1544 g_free (tempstr); | |
84 | 1545 |
1546 if (ret < 0) | |
1547 return (ret); | |
1548 else if (ret != '2') | |
1549 return (GFTP_ERETRYABLE); | |
1 | 1550 |
1551 tempstr = g_strconcat ("RNTO ", newname, "\r\n", NULL); | |
1552 ret = rfc959_send_command (request, tempstr); | |
1553 g_free (tempstr); | |
84 | 1554 |
1555 if (ret < 0) | |
1556 return (ret); | |
1557 else if (ret == '2') | |
1558 return (0); | |
1559 else | |
1560 return (GFTP_ERETRYABLE); | |
1 | 1561 } |
1562 | |
1563 | |
1564 static int | |
1565 rfc959_chmod (gftp_request * request, const char *file, int mode) | |
1566 { | |
1567 char *tempstr, ret; | |
1568 | |
84 | 1569 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1570 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1571 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
169 | 1572 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1573 |
1574 tempstr = g_malloc (strlen (file) + (mode / 10) + 16); | |
1575 sprintf (tempstr, "SITE CHMOD %d %s\r\n", mode, file); | |
1576 ret = rfc959_send_command (request, tempstr); | |
1577 g_free (tempstr); | |
84 | 1578 |
1579 if (ret < 0) | |
1580 return (ret); | |
1581 else if (ret == '2') | |
1582 return (0); | |
1583 else | |
1584 return (GFTP_ERETRYABLE); | |
1 | 1585 } |
1586 | |
1587 | |
1588 static int | |
1589 rfc959_site (gftp_request * request, const char *command) | |
1590 { | |
1591 char *tempstr, ret; | |
1592 | |
84 | 1593 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1594 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1595 g_return_val_if_fail (command != NULL, GFTP_EFATAL); | |
169 | 1596 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1597 |
1598 tempstr = g_strconcat ("SITE ", command, "\r\n", NULL); | |
1599 ret = rfc959_send_command (request, tempstr); | |
1600 g_free (tempstr); | |
84 | 1601 |
1602 if (ret < 0) | |
1603 return (ret); | |
1604 else if (ret == '2') | |
1605 return (0); | |
1606 else | |
1607 return (GFTP_ERETRYABLE); | |
58 | 1608 } |
1609 | |
1610 | |
177 | 1611 static int |
58 | 1612 rfc959_set_config_options (gftp_request * request) |
1613 { | |
122 | 1614 char *proxy_config; |
177 | 1615 int ret; |
58 | 1616 |
122 | 1617 gftp_lookup_request_option (request, "proxy_config", &proxy_config); |
1618 if (strcmp (proxy_config, "http") == 0) | |
58 | 1619 { |
177 | 1620 if ((ret = gftp_protocols[GFTP_HTTP_NUM].init (request)) < 0) |
1621 return (ret); | |
173 | 1622 |
122 | 1623 gftp_set_request_option (request, "proxy_config", "ftp"); |
58 | 1624 } |
177 | 1625 |
1626 return (0); | |
122 | 1627 } |
58 | 1628 |
1629 | |
122 | 1630 void |
1631 rfc959_register_module (void) | |
1632 { | |
1633 struct hostent *hent; | |
1634 struct utsname unme; | |
1635 struct passwd *pw; | |
1636 char *tempstr; | |
1637 | |
1638 gftp_register_config_vars (config_vars); | |
1639 | |
1640 gftp_lookup_global_option ("email", &tempstr); | |
1641 if (tempstr == NULL || *tempstr == '\0') | |
1642 { | |
1643 /* If there is no email address specified, then we'll just use the | |
1644 currentuser@currenthost */ | |
1645 uname (&unme); | |
1646 pw = getpwuid (geteuid ()); | |
1647 hent = gethostbyname (unme.nodename); | |
1648 if (strchr (unme.nodename, '.') == NULL && hent != NULL) | |
1649 tempstr = g_strconcat (pw->pw_name, "@", hent->h_name, NULL); | |
1650 else | |
1651 tempstr = g_strconcat (pw->pw_name, "@", unme.nodename, NULL); | |
1652 gftp_set_global_option ("email", tempstr); | |
58 | 1653 } |
1 | 1654 } |
1655 | |
1656 | |
201 | 1657 void |
1658 rfc959_request_destroy (gftp_request * request) | |
1659 { | |
1660 rfc959_parms * parms; | |
1661 | |
1662 parms = request->protocol_data; | |
1663 | |
1664 if (parms->datafd_rbuf != NULL) | |
1665 gftp_free_getline_buffer (&parms->datafd_rbuf); | |
1666 | |
1667 if (parms->dataconn_rbuf != NULL) | |
1668 gftp_free_getline_buffer (&parms->dataconn_rbuf); | |
1669 } | |
1670 | |
1671 | |
173 | 1672 int |
48 | 1673 rfc959_init (gftp_request * request) |
1 | 1674 { |
169 | 1675 rfc959_parms * parms; |
1676 | |
173 | 1677 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1 | 1678 |
48 | 1679 request->protonum = GFTP_FTP_NUM; |
1680 request->init = rfc959_init; | |
201 | 1681 request->destroy = rfc959_request_destroy; |
168 | 1682 request->read_function = gftp_fd_read; |
1683 request->write_function = gftp_fd_write; | |
48 | 1684 request->connect = rfc959_connect; |
168 | 1685 request->post_connect = NULL; |
48 | 1686 request->disconnect = rfc959_disconnect; |
1687 request->get_file = rfc959_get_file; | |
1688 request->put_file = rfc959_put_file; | |
1689 request->transfer_file = rfc959_transfer_file; | |
122 | 1690 request->get_next_file_chunk = rfc959_get_next_file_chunk; |
1691 request->put_next_file_chunk = rfc959_put_next_file_chunk; | |
48 | 1692 request->end_transfer = rfc959_end_transfer; |
1693 request->abort_transfer = rfc959_abort_transfer; | |
1694 request->list_files = rfc959_list_files; | |
1695 request->get_next_file = rfc959_get_next_file; | |
1696 request->get_file_size = rfc959_get_file_size; | |
1697 request->chdir = rfc959_chdir; | |
1698 request->rmdir = rfc959_rmdir; | |
1699 request->rmfile = rfc959_rmfile; | |
1700 request->mkdir = rfc959_mkdir; | |
1701 request->rename = rfc959_rename; | |
1702 request->chmod = rfc959_chmod; | |
1703 request->set_file_time = NULL; | |
1704 request->site = rfc959_site; | |
1705 request->parse_url = NULL; | |
63 | 1706 request->swap_socks = NULL; |
58 | 1707 request->set_config_options = rfc959_set_config_options; |
48 | 1708 request->url_prefix = "ftp"; |
1709 request->need_hostport = 1; | |
1710 request->need_userpass = 1; | |
1711 request->use_cache = 1; | |
1712 request->use_threads = 1; | |
1713 request->always_connected = 0; | |
169 | 1714 |
58 | 1715 request->protocol_data = g_malloc0 (sizeof (rfc959_parms)); |
169 | 1716 parms = request->protocol_data; |
1717 parms->data_connection = -1; | |
1718 | |
177 | 1719 return (gftp_set_config_options (request)); |
1 | 1720 } |
1721 |