Mercurial > gftp.yaz
annotate lib/rfc959.c @ 512:2c8a42a63a31
2004-7-25 Brian Masney <masneyb@gftp.org>
* lib/protocols.c (gftp_get_transfer_status) - don't force the user to
wait to reconnect if the connection to the server timed out
author | masneyb |
---|---|
date | Sun, 25 Jul 2004 14:25:27 +0000 |
parents | 93d7d3b9a477 |
children | cb882efd4d6d |
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 | |
485 | 1460 static ssize_t |
1461 rfc959_get_next_dirlist_line (gftp_request * request, int fd, | |
1462 char *buf, size_t buflen) | |
1463 { | |
1464 ssize_t (*oldread_func) (gftp_request * request, void *ptr, size_t size, | |
1465 int fd); | |
1466 rfc959_parms * parms; | |
1467 ssize_t len; | |
1468 | |
1469 parms = request->protocol_data; | |
1470 | |
1471 oldread_func = request->read_function; | |
1472 request->read_function = parms->data_conn_read; | |
1473 len = gftp_get_line (request, &parms->dataconn_rbuf, buf, buflen, fd); | |
1474 request->read_function = oldread_func; | |
1475 | |
1476 return (len); | |
1477 } | |
1478 | |
1479 | |
1 | 1480 int |
58 | 1481 rfc959_get_next_file (gftp_request * request, gftp_file * fle, int fd) |
1 | 1482 { |
58 | 1483 rfc959_parms * parms; |
249 | 1484 char tempstr[1024]; |
58 | 1485 ssize_t len; |
1 | 1486 |
84 | 1487 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1488 g_return_val_if_fail (fle != NULL, GFTP_EFATAL); | |
1489 g_return_val_if_fail (fd > 0, GFTP_EFATAL); | |
1 | 1490 |
1491 if (request->last_dir_entry) | |
1492 { | |
1493 g_free (request->last_dir_entry); | |
1494 request->last_dir_entry = NULL; | |
1495 } | |
58 | 1496 |
1497 parms = request->protocol_data; | |
1498 | |
169 | 1499 if (fd == request->datafd) |
1500 fd = parms->data_connection; | |
1501 | |
1 | 1502 do |
1503 { | |
485 | 1504 len = rfc959_get_next_dirlist_line (request, fd, tempstr, |
1505 sizeof (tempstr)); | |
389 | 1506 if (len <= 0) |
1 | 1507 { |
1508 gftp_file_destroy (fle); | |
58 | 1509 return ((int) len); |
1 | 1510 } |
1511 | |
485 | 1512 if (gftp_parse_ls (request, tempstr, fle, fd) != 0) |
1 | 1513 { |
58 | 1514 if (strncmp (tempstr, "total", strlen ("total")) != 0 && |
1515 strncmp (tempstr, _("total"), strlen (_("total"))) != 0) | |
186 | 1516 request->logging_function (gftp_logging_error, request, |
1 | 1517 _("Warning: Cannot parse listing %s\n"), |
1518 tempstr); | |
1519 gftp_file_destroy (fle); | |
1520 continue; | |
1521 } | |
1522 else | |
1523 break; | |
1524 } | |
1525 while (1); | |
1526 | |
1527 len = strlen (tempstr); | |
1528 if (!request->cached) | |
1529 { | |
60 | 1530 request->last_dir_entry = g_strdup_printf ("%s\n", tempstr); |
460 | 1531 request->last_dir_entry_len = len + 1; |
1 | 1532 } |
1533 return (len); | |
1534 } | |
1535 | |
1536 | |
1537 static off_t | |
1538 rfc959_get_file_size (gftp_request * request, const char *filename) | |
1539 { | |
1540 char *tempstr; | |
1541 int ret; | |
1542 | |
1543 g_return_val_if_fail (request != NULL, 0); | |
1544 g_return_val_if_fail (filename != NULL, 0); | |
169 | 1545 g_return_val_if_fail (request->datafd > 0, 0); |
1 | 1546 |
1547 tempstr = g_strconcat ("SIZE ", filename, "\r\n", NULL); | |
292 | 1548 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1549 g_free (tempstr); |
1550 if (ret < 0) | |
84 | 1551 return (ret); |
1 | 1552 |
1553 if (*request->last_ftp_response != '2') | |
1554 return (0); | |
1555 return (strtol (request->last_ftp_response + 4, NULL, 10)); | |
1556 } | |
1557 | |
1558 | |
1559 static int | |
1560 rfc959_rmdir (gftp_request * request, const char *directory) | |
1561 { | |
1562 char *tempstr, ret; | |
1563 | |
84 | 1564 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1565 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
169 | 1566 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1567 |
1568 tempstr = g_strconcat ("RMD ", directory, "\r\n", NULL); | |
292 | 1569 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1570 g_free (tempstr); |
84 | 1571 |
1572 if (ret < 0) | |
1573 return (ret); | |
1574 else if (ret == '2') | |
1575 return (0); | |
1576 else | |
1577 return (GFTP_ERETRYABLE); | |
1 | 1578 } |
1579 | |
1580 | |
1581 static int | |
1582 rfc959_rmfile (gftp_request * request, const char *file) | |
1583 { | |
1584 char *tempstr, ret; | |
1585 | |
84 | 1586 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1587 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
169 | 1588 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1589 |
1590 tempstr = g_strconcat ("DELE ", file, "\r\n", NULL); | |
292 | 1591 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1592 g_free (tempstr); |
84 | 1593 |
1594 if (ret < 0) | |
1595 return (ret); | |
1596 else if (ret == '2') | |
1597 return (0); | |
1598 else | |
1599 return (GFTP_ERETRYABLE); | |
1 | 1600 } |
1601 | |
1602 | |
1603 static int | |
1604 rfc959_mkdir (gftp_request * request, const char *directory) | |
1605 { | |
1606 char *tempstr, ret; | |
1607 | |
84 | 1608 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1609 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
169 | 1610 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1611 |
1612 tempstr = g_strconcat ("MKD ", directory, "\r\n", NULL); | |
292 | 1613 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1614 g_free (tempstr); |
84 | 1615 |
1616 if (ret < 0) | |
1617 return (ret); | |
1618 else if (ret == '2') | |
1619 return (0); | |
1620 else | |
1621 return (GFTP_ERETRYABLE); | |
1 | 1622 } |
1623 | |
1624 | |
1625 static int | |
1626 rfc959_rename (gftp_request * request, const char *oldname, | |
1627 const char *newname) | |
1628 { | |
1629 char *tempstr, ret; | |
1630 | |
84 | 1631 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1632 g_return_val_if_fail (oldname != NULL, GFTP_EFATAL); | |
1633 g_return_val_if_fail (newname != NULL, GFTP_EFATAL); | |
169 | 1634 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1635 |
1636 tempstr = g_strconcat ("RNFR ", oldname, "\r\n", NULL); | |
292 | 1637 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1638 g_free (tempstr); |
84 | 1639 |
1640 if (ret < 0) | |
1641 return (ret); | |
278 | 1642 else if (ret != '3') |
84 | 1643 return (GFTP_ERETRYABLE); |
1 | 1644 |
1645 tempstr = g_strconcat ("RNTO ", newname, "\r\n", NULL); | |
292 | 1646 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1647 g_free (tempstr); |
84 | 1648 |
1649 if (ret < 0) | |
1650 return (ret); | |
1651 else if (ret == '2') | |
1652 return (0); | |
1653 else | |
1654 return (GFTP_ERETRYABLE); | |
1 | 1655 } |
1656 | |
1657 | |
1658 static int | |
499 | 1659 rfc959_chmod (gftp_request * request, const char *file, mode_t mode) |
1 | 1660 { |
1661 char *tempstr, ret; | |
504 | 1662 size_t len; |
1 | 1663 |
84 | 1664 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1665 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
169 | 1666 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1667 |
504 | 1668 len = strlen (file) + (mode / 10) + 20; |
1669 tempstr = g_malloc (len); | |
1670 snprintf (tempstr, len, "SITE CHMOD %o %s\r\n", mode, file); | |
292 | 1671 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1672 g_free (tempstr); |
84 | 1673 |
1674 if (ret < 0) | |
1675 return (ret); | |
1676 else if (ret == '2') | |
1677 return (0); | |
1678 else | |
1679 return (GFTP_ERETRYABLE); | |
1 | 1680 } |
1681 | |
1682 | |
1683 static int | |
478 | 1684 rfc959_site (gftp_request * request, int specify_site, const char *command) |
1 | 1685 { |
1686 char *tempstr, ret; | |
1687 | |
84 | 1688 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1689 g_return_val_if_fail (command != NULL, GFTP_EFATAL); | |
169 | 1690 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1691 |
478 | 1692 if (specify_site) |
1693 tempstr = g_strconcat ("SITE ", command, "\r\n", NULL); | |
1694 else | |
1695 tempstr = g_strconcat (command, "\r\n", NULL); | |
1696 | |
292 | 1697 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1698 g_free (tempstr); |
84 | 1699 |
1700 if (ret < 0) | |
1701 return (ret); | |
1702 else if (ret == '2') | |
1703 return (0); | |
1704 else | |
1705 return (GFTP_ERETRYABLE); | |
58 | 1706 } |
1707 | |
1708 | |
177 | 1709 static int |
58 | 1710 rfc959_set_config_options (gftp_request * request) |
1711 { | |
122 | 1712 char *proxy_config; |
177 | 1713 int ret; |
58 | 1714 |
122 | 1715 gftp_lookup_request_option (request, "proxy_config", &proxy_config); |
1716 if (strcmp (proxy_config, "http") == 0) | |
58 | 1717 { |
177 | 1718 if ((ret = gftp_protocols[GFTP_HTTP_NUM].init (request)) < 0) |
1719 return (ret); | |
173 | 1720 |
122 | 1721 gftp_set_request_option (request, "proxy_config", "ftp"); |
58 | 1722 } |
177 | 1723 |
1724 return (0); | |
122 | 1725 } |
58 | 1726 |
1727 | |
122 | 1728 void |
1729 rfc959_register_module (void) | |
1730 { | |
1731 gftp_register_config_vars (config_vars); | |
1 | 1732 } |
1733 | |
1734 | |
201 | 1735 void |
1736 rfc959_request_destroy (gftp_request * request) | |
1737 { | |
1738 rfc959_parms * parms; | |
1739 | |
1740 parms = request->protocol_data; | |
1741 | |
1742 if (parms->datafd_rbuf != NULL) | |
1743 gftp_free_getline_buffer (&parms->datafd_rbuf); | |
1744 | |
1745 if (parms->dataconn_rbuf != NULL) | |
1746 gftp_free_getline_buffer (&parms->dataconn_rbuf); | |
1747 } | |
1748 | |
1749 | |
309 | 1750 void |
1751 rfc959_copy_param_options (gftp_request * dest_request, | |
1752 gftp_request * src_request) | |
1753 { | |
1754 rfc959_parms * dparms, * sparms; | |
1755 | |
1756 dparms = dest_request->protocol_data; | |
1757 sparms = src_request->protocol_data; | |
1758 | |
432 | 1759 dparms->data_connection = -1; |
309 | 1760 dparms->is_ascii_transfer = sparms->is_ascii_transfer; |
432 | 1761 dparms->is_fxp_transfer = sparms->is_fxp_transfer; |
1762 dparms->auth_tls_start = sparms->auth_tls_start; | |
1763 dparms->data_conn_read = sparms->data_conn_read; | |
1764 dparms->data_conn_write = sparms->data_conn_write; | |
1765 | |
1766 dest_request->read_function = src_request->read_function; | |
1767 dest_request->write_function = src_request->write_function; | |
309 | 1768 } |
1769 | |
1770 | |
173 | 1771 int |
48 | 1772 rfc959_init (gftp_request * request) |
1 | 1773 { |
169 | 1774 rfc959_parms * parms; |
227 | 1775 struct hostent *hent; |
1776 struct utsname unme; | |
1777 struct passwd *pw; | |
1778 char *tempstr; | |
169 | 1779 |
173 | 1780 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1 | 1781 |
227 | 1782 gftp_lookup_global_option ("email", &tempstr); |
1783 if (tempstr == NULL || *tempstr == '\0') | |
1784 { | |
1785 /* If there is no email address specified, then we'll just use the | |
1786 currentuser@currenthost */ | |
1787 uname (&unme); | |
1788 pw = getpwuid (geteuid ()); | |
1789 hent = gethostbyname (unme.nodename); | |
1790 if (strchr (unme.nodename, '.') == NULL && hent != NULL) | |
1791 tempstr = g_strconcat (pw->pw_name, "@", hent->h_name, NULL); | |
1792 else | |
1793 tempstr = g_strconcat (pw->pw_name, "@", unme.nodename, NULL); | |
1794 gftp_set_global_option ("email", tempstr); | |
1795 g_free (tempstr); | |
1796 } | |
1797 | |
48 | 1798 request->protonum = GFTP_FTP_NUM; |
1799 request->init = rfc959_init; | |
309 | 1800 request->copy_param_options = rfc959_copy_param_options; |
201 | 1801 request->destroy = rfc959_request_destroy; |
168 | 1802 request->read_function = gftp_fd_read; |
1803 request->write_function = gftp_fd_write; | |
48 | 1804 request->connect = rfc959_connect; |
168 | 1805 request->post_connect = NULL; |
48 | 1806 request->disconnect = rfc959_disconnect; |
1807 request->get_file = rfc959_get_file; | |
1808 request->put_file = rfc959_put_file; | |
1809 request->transfer_file = rfc959_transfer_file; | |
122 | 1810 request->get_next_file_chunk = rfc959_get_next_file_chunk; |
1811 request->put_next_file_chunk = rfc959_put_next_file_chunk; | |
48 | 1812 request->end_transfer = rfc959_end_transfer; |
1813 request->abort_transfer = rfc959_abort_transfer; | |
500 | 1814 request->stat_filename = NULL; |
48 | 1815 request->list_files = rfc959_list_files; |
1816 request->get_next_file = rfc959_get_next_file; | |
485 | 1817 request->get_next_dirlist_line = rfc959_get_next_dirlist_line; |
48 | 1818 request->get_file_size = rfc959_get_file_size; |
1819 request->chdir = rfc959_chdir; | |
1820 request->rmdir = rfc959_rmdir; | |
1821 request->rmfile = rfc959_rmfile; | |
1822 request->mkdir = rfc959_mkdir; | |
1823 request->rename = rfc959_rename; | |
1824 request->chmod = rfc959_chmod; | |
1825 request->set_file_time = NULL; | |
1826 request->site = rfc959_site; | |
1827 request->parse_url = NULL; | |
63 | 1828 request->swap_socks = NULL; |
58 | 1829 request->set_config_options = rfc959_set_config_options; |
48 | 1830 request->url_prefix = "ftp"; |
1831 request->need_hostport = 1; | |
1832 request->need_userpass = 1; | |
1833 request->use_cache = 1; | |
1834 request->always_connected = 0; | |
169 | 1835 |
58 | 1836 request->protocol_data = g_malloc0 (sizeof (rfc959_parms)); |
169 | 1837 parms = request->protocol_data; |
1838 parms->data_connection = -1; | |
389 | 1839 parms->auth_tls_start = NULL; |
390 | 1840 parms->data_conn_read = gftp_fd_read; |
1841 parms->data_conn_write = gftp_fd_write; | |
169 | 1842 |
177 | 1843 return (gftp_set_config_options (request)); |
1 | 1844 } |
1845 |