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