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