1 /* File Transfer Protocol support.
2 Copyright (C) 1996-2005 Free Software Foundation, Inc.
4 This file is part of GNU Wget.
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 GNU Wget is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables. You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL". If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so. If you do not wish to do
28 so, delete this exception statement from your version. */
49 #include "convert.h" /* for downloaded_file */
50 #include "recur.h" /* for INFINITE_RECURSION */
52 /* File where the "ls -al" listing will be saved. */
53 #define LIST_FILENAME ".listing"
57 int st; /* connection status */
58 int cmd; /* command code */
59 int csock; /* control connection socket */
60 double dltime; /* time of the download in msecs */
61 enum stype rs; /* remote system reported by ftp server */
62 char *id; /* initial directory */
63 char *target; /* target file name */
64 struct url *proxy; /* FTWK-style proxy */
68 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
69 the string S, and return the number converted to wgint, if found, 0
72 ftp_expected_bytes (const char *s)
78 while (*s && *s != '(')
82 ++s; /* skip the '(' */
83 res = str_to_wgint (s, (char **) &s, 10);
86 while (*s && ISSPACE (*s))
90 if (TOLOWER (*s) != 'b')
92 if (strncasecmp (s, "byte", 4))
102 * This function sets up a passive data connection with the FTP server.
103 * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv.
106 ftp_do_pasv (int csock, ip_address *addr, int *port)
110 /* We need to determine the address family and need to call
111 getpeername, so while we're at it, store the address to ADDR.
112 ftp_pasv and ftp_lpsv can simply override it. */
113 if (!socket_ip_address (csock, addr, ENDPOINT_PEER))
116 /* If our control connection is over IPv6, then we first try EPSV and then
117 * LPSV if the former is not supported. If the control connection is over
118 * IPv4, we simply issue the good old PASV request. */
122 if (!opt.server_response)
123 logputs (LOG_VERBOSE, "==> PASV ... ");
124 err = ftp_pasv (csock, addr, port);
127 if (!opt.server_response)
128 logputs (LOG_VERBOSE, "==> EPSV ... ");
129 err = ftp_epsv (csock, addr, port);
131 /* If EPSV is not supported try LPSV */
132 if (err == FTPNOPASV)
134 if (!opt.server_response)
135 logputs (LOG_VERBOSE, "==> LPSV ... ");
136 err = ftp_lpsv (csock, addr, port);
147 * This function sets up an active data connection with the FTP server.
148 * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port.
151 ftp_do_port (int csock, int *local_sock)
156 if (!socket_ip_address (csock, &cip, ENDPOINT_PEER))
159 /* If our control connection is over IPv6, then we first try EPRT and then
160 * LPRT if the former is not supported. If the control connection is over
161 * IPv4, we simply issue the good old PORT request. */
165 if (!opt.server_response)
166 logputs (LOG_VERBOSE, "==> PORT ... ");
167 err = ftp_port (csock, local_sock);
170 if (!opt.server_response)
171 logputs (LOG_VERBOSE, "==> EPRT ... ");
172 err = ftp_eprt (csock, local_sock);
174 /* If EPRT is not supported try LPRT */
175 if (err == FTPPORTERR)
177 if (!opt.server_response)
178 logputs (LOG_VERBOSE, "==> LPRT ... ");
179 err = ftp_lprt (csock, local_sock);
190 ftp_do_pasv (int csock, ip_address *addr, int *port)
192 if (!opt.server_response)
193 logputs (LOG_VERBOSE, "==> PASV ... ");
194 return ftp_pasv (csock, addr, port);
198 ftp_do_port (int csock, int *local_sock)
200 if (!opt.server_response)
201 logputs (LOG_VERBOSE, "==> PORT ... ");
202 return ftp_port (csock, local_sock);
207 print_length (wgint size, wgint start, bool authoritative)
209 logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
211 logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
215 logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
216 number_to_static_string (size - start),
217 human_readable (size - start));
219 logprintf (LOG_VERBOSE, _(", %s remaining"),
220 number_to_static_string (size - start));
222 logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
225 /* Retrieves a file with denoted parameters through opening an FTP
226 connection to the server. It always closes the data connection,
227 and closes the control connection in case of error. */
229 getftp (struct url *u, wgint *len, wgint restval, ccon *con)
231 int csock, dtsock, local_sock, res;
232 uerr_t err = RETROK; /* appease the compiler */
234 char *user, *passwd, *respline;
238 bool pasv_mode_open = false;
239 wgint expected_bytes = 0;
240 bool rest_failed = false;
244 assert (con != NULL);
245 assert (con->target != NULL);
247 /* Debug-check of the sanity of the request by making sure that LIST
248 and RETR are never both requested (since we can handle only one
250 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
251 /* Make sure that at least *something* is requested. */
252 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
256 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
257 user = user ? user : (opt.ftp_user ? opt.ftp_user : opt.user);
258 if (!user) user = "anonymous";
259 passwd = passwd ? passwd : (opt.ftp_passwd ? opt.ftp_passwd : opt.passwd);
260 if (!passwd) passwd = "-wget@";
266 if (!(cmd & DO_LOGIN))
268 else /* cmd & DO_LOGIN */
271 char *host = con->proxy ? con->proxy->host : u->host;
272 int port = con->proxy ? con->proxy->port : u->port;
273 char *logname = user;
277 /* If proxy is in use, log in as username@target-site. */
278 logname = concat_strings (user, "@", u->host, (char *) 0);
281 /* Login to the server: */
283 /* First: Establish the control connection. */
285 csock = connect_to_host (host, port);
289 return (retryable_socket_connect_error (errno)
290 ? CONERROR : CONIMPOSSIBLE);
292 if (cmd & LEAVE_PENDING)
297 /* Second: Login with proper USER/PASS sequence. */
298 logprintf (LOG_VERBOSE, _("Logging in as %s ... "), escnonprint (user));
299 if (opt.server_response)
300 logputs (LOG_ALWAYS, "\n");
301 err = ftp_login (csock, logname, passwd);
306 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
310 logputs (LOG_VERBOSE, "\n");
311 logputs (LOG_NOTQUIET, _("\
312 Error in server response, closing control connection.\n"));
317 logputs (LOG_VERBOSE, "\n");
318 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
323 logputs (LOG_VERBOSE, "\n");
324 logputs (LOG_NOTQUIET,
325 _("Write failed, closing control connection.\n"));
330 logputs (LOG_VERBOSE, "\n");
331 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
334 return FTPLOGREFUSED;
336 logputs (LOG_VERBOSE, "\n");
337 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
342 if (!opt.server_response)
343 logputs (LOG_VERBOSE, _("Logged in!\n"));
348 /* Third: Get the system type */
349 if (!opt.server_response)
350 logprintf (LOG_VERBOSE, "==> SYST ... ");
351 err = ftp_syst (csock, &con->rs);
356 logputs (LOG_VERBOSE, "\n");
357 logputs (LOG_NOTQUIET, _("\
358 Error in server response, closing control connection.\n"));
363 logputs (LOG_VERBOSE, "\n");
364 logputs (LOG_NOTQUIET,
365 _("Server error, can't determine system type.\n"));
368 /* Everything is OK. */
373 if (!opt.server_response && err != FTPSRVERR)
374 logputs (LOG_VERBOSE, _("done. "));
376 /* Fourth: Find the initial ftp directory */
378 if (!opt.server_response)
379 logprintf (LOG_VERBOSE, "==> PWD ... ");
380 err = ftp_pwd (csock, &con->id);
385 logputs (LOG_VERBOSE, "\n");
386 logputs (LOG_NOTQUIET, _("\
387 Error in server response, closing control connection.\n"));
392 /* PWD unsupported -- assume "/". */
393 xfree_null (con->id);
394 con->id = xstrdup ("/");
397 /* Everything is OK. */
402 /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
403 Convert it to "/INITIAL/FOLDER" */
404 if (con->rs == ST_VMS)
406 char *path = strchr (con->id, '[');
407 char *pathend = path ? strchr (path + 1, ']') : NULL;
408 if (!path || !pathend)
409 DEBUGP (("Initial VMS directory not in the form [...]!\n"));
412 char *idir = con->id;
413 DEBUGP (("Preprocessing the initial VMS directory\n"));
414 DEBUGP ((" old = '%s'\n", con->id));
415 /* We do the conversion in-place by copying the stuff
416 between [ and ] to the beginning, and changing dots
417 to slashes at the same time. */
419 for (++path; path < pathend; path++, idir++)
420 *idir = *path == '.' ? '/' : *path;
422 DEBUGP ((" new = '%s'\n\n", con->id));
425 if (!opt.server_response)
426 logputs (LOG_VERBOSE, _("done.\n"));
428 /* Fifth: Set the FTP type. */
429 type_char = ftp_process_type (u->params);
430 if (!opt.server_response)
431 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);
432 err = ftp_type (csock, type_char);
433 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
437 logputs (LOG_VERBOSE, "\n");
438 logputs (LOG_NOTQUIET, _("\
439 Error in server response, closing control connection.\n"));
444 logputs (LOG_VERBOSE, "\n");
445 logputs (LOG_NOTQUIET,
446 _("Write failed, closing control connection.\n"));
451 logputs (LOG_VERBOSE, "\n");
452 logprintf (LOG_NOTQUIET,
453 _("Unknown type `%c', closing control connection.\n"),
459 /* Everything is OK. */
464 if (!opt.server_response)
465 logputs (LOG_VERBOSE, _("done. "));
471 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
474 char *target = u->dir;
476 DEBUGP (("changing working directory\n"));
478 /* Change working directory. To change to a non-absolute
479 Unix directory, we need to prepend initial directory
480 (con->id) to it. Absolute directories "just work".
482 A relative directory is one that does not begin with '/'
483 and, on non-Unix OS'es, one that doesn't begin with
486 This is not done for OS400, which doesn't use
487 "/"-delimited directories, nor does it support directory
488 hierarchies. "CWD foo" followed by "CWD bar" leaves us
489 in "bar", not in "foo/bar", as would be customary
493 && !(con->rs != ST_UNIX
494 && ISALPHA (target[0])
496 && con->rs != ST_OS400)
498 int idlen = strlen (con->id);
501 /* Strip trailing slash(es) from con->id. */
502 while (idlen > 0 && con->id[idlen - 1] == '/')
504 p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
505 memcpy (p, con->id, idlen);
510 DEBUGP (("Prepended initial PWD to relative path:\n"));
511 DEBUGP ((" pwd: '%s'\n old: '%s'\n new: '%s'\n",
512 con->id, target, ntarget));
516 /* If the FTP host runs VMS, we will have to convert the absolute
517 directory path in UNIX notation to absolute directory path in
518 VMS notation as VMS FTP servers do not like UNIX notation of
519 absolute paths. "VMS notation" is [dir.subdir.subsubdir]. */
521 if (con->rs == ST_VMS)
524 char *ntarget = (char *)alloca (strlen (target) + 2);
525 /* We use a converted initial dir, so directories in
526 TARGET will be separated with slashes, something like
527 "/INITIAL/FOLDER/DIR/SUBDIR". Convert that to
528 "[INITIAL.FOLDER.DIR.SUBDIR]". */
529 strcpy (ntarget, target);
530 assert (*ntarget == '/');
532 for (tmpp = ntarget + 1; *tmpp; tmpp++)
537 DEBUGP (("Changed file name to VMS syntax:\n"));
538 DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget));
542 if (!opt.server_response)
543 logprintf (LOG_VERBOSE, "==> CWD %s ... ", escnonprint (target));
544 err = ftp_cwd (csock, target);
545 /* FTPRERR, WRITEFAILED, FTPNSFOD */
549 logputs (LOG_VERBOSE, "\n");
550 logputs (LOG_NOTQUIET, _("\
551 Error in server response, closing control connection.\n"));
556 logputs (LOG_VERBOSE, "\n");
557 logputs (LOG_NOTQUIET,
558 _("Write failed, closing control connection.\n"));
563 logputs (LOG_VERBOSE, "\n");
564 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
565 escnonprint (u->dir));
574 if (!opt.server_response)
575 logputs (LOG_VERBOSE, _("done.\n"));
578 else /* do not CWD */
579 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
581 if ((cmd & DO_RETR) && *len == 0)
585 if (!opt.server_response)
586 logprintf (LOG_VERBOSE, "==> SIZE %s ... ", escnonprint (u->file));
589 err = ftp_size (csock, u->file, len);
595 logputs (LOG_VERBOSE, "\n");
596 logputs (LOG_NOTQUIET, _("\
597 Error in server response, closing control connection.\n"));
602 /* Everything is OK. */
607 if (!opt.server_response)
608 logprintf (LOG_VERBOSE, *len ? "%s\n" : _("done.\n"),
609 number_to_static_string (*len));
612 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
613 if (cmd & (DO_LIST | DO_RETR))
617 ip_address passive_addr;
619 err = ftp_do_pasv (csock, &passive_addr, &passive_port);
620 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
624 logputs (LOG_VERBOSE, "\n");
625 logputs (LOG_NOTQUIET, _("\
626 Error in server response, closing control connection.\n"));
631 logputs (LOG_VERBOSE, "\n");
632 logputs (LOG_NOTQUIET,
633 _("Write failed, closing control connection.\n"));
638 logputs (LOG_VERBOSE, "\n");
639 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
642 logputs (LOG_VERBOSE, "\n");
643 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
652 DEBUGP (("trying to connect to %s port %d\n",
653 print_address (&passive_addr), passive_port));
654 dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
657 int save_errno = errno;
660 logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
661 print_address (&passive_addr), passive_port,
662 strerror (save_errno));
663 return (retryable_socket_connect_error (save_errno)
664 ? CONERROR : CONIMPOSSIBLE);
667 pasv_mode_open = true; /* Flag to avoid accept port */
668 if (!opt.server_response)
669 logputs (LOG_VERBOSE, _("done. "));
673 if (!pasv_mode_open) /* Try to use a port command if PASV failed */
675 err = ftp_do_port (csock, &local_sock);
676 /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,
681 logputs (LOG_VERBOSE, "\n");
682 logputs (LOG_NOTQUIET, _("\
683 Error in server response, closing control connection.\n"));
687 fd_close (local_sock);
690 logputs (LOG_VERBOSE, "\n");
691 logputs (LOG_NOTQUIET,
692 _("Write failed, closing control connection.\n"));
696 fd_close (local_sock);
699 logputs (LOG_VERBOSE, "\n");
700 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
704 fd_close (local_sock);
707 logputs (LOG_VERBOSE, "\n");
708 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
713 logputs (LOG_VERBOSE, "\n");
714 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
718 fd_close (local_sock);
725 if (!opt.server_response)
726 logputs (LOG_VERBOSE, _("done. "));
728 } /* cmd & (DO_LIST | DO_RETR) */
730 /* Restart if needed. */
731 if (restval && (cmd & DO_RETR))
733 if (!opt.server_response)
734 logprintf (LOG_VERBOSE, "==> REST %s ... ",
735 number_to_static_string (restval));
736 err = ftp_rest (csock, restval);
738 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
742 logputs (LOG_VERBOSE, "\n");
743 logputs (LOG_NOTQUIET, _("\
744 Error in server response, closing control connection.\n"));
748 fd_close (local_sock);
751 logputs (LOG_VERBOSE, "\n");
752 logputs (LOG_NOTQUIET,
753 _("Write failed, closing control connection.\n"));
757 fd_close (local_sock);
760 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
768 if (err != FTPRESTFAIL && !opt.server_response)
769 logputs (LOG_VERBOSE, _("done. "));
770 } /* restval && cmd & DO_RETR */
774 /* If we're in spider mode, don't really retrieve anything. The
775 fact that we got to this point should be proof enough that
776 the file exists, vaguely akin to HTTP's concept of a "HEAD"
783 fd_close (local_sock);
789 if (!opt.server_response)
792 logputs (LOG_VERBOSE, "\n");
793 logprintf (LOG_VERBOSE, "==> RETR %s ... ", escnonprint (u->file));
797 err = ftp_retr (csock, u->file);
798 /* FTPRERR, WRITEFAILED, FTPNSFOD */
802 logputs (LOG_VERBOSE, "\n");
803 logputs (LOG_NOTQUIET, _("\
804 Error in server response, closing control connection.\n"));
808 fd_close (local_sock);
811 logputs (LOG_VERBOSE, "\n");
812 logputs (LOG_NOTQUIET,
813 _("Write failed, closing control connection.\n"));
817 fd_close (local_sock);
820 logputs (LOG_VERBOSE, "\n");
821 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"),
822 escnonprint (u->file));
824 fd_close (local_sock);
832 if (!opt.server_response)
833 logputs (LOG_VERBOSE, _("done.\n"));
834 expected_bytes = ftp_expected_bytes (ftp_last_respline);
839 if (!opt.server_response)
840 logputs (LOG_VERBOSE, "==> LIST ... ");
841 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
842 without arguments is better than `LIST .'; confirmed by
844 err = ftp_list (csock, NULL);
845 /* FTPRERR, WRITEFAILED */
849 logputs (LOG_VERBOSE, "\n");
850 logputs (LOG_NOTQUIET, _("\
851 Error in server response, closing control connection.\n"));
855 fd_close (local_sock);
858 logputs (LOG_VERBOSE, "\n");
859 logputs (LOG_NOTQUIET,
860 _("Write failed, closing control connection.\n"));
864 fd_close (local_sock);
867 logputs (LOG_VERBOSE, "\n");
868 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
871 fd_close (local_sock);
878 if (!opt.server_response)
879 logputs (LOG_VERBOSE, _("done.\n"));
880 expected_bytes = ftp_expected_bytes (ftp_last_respline);
881 } /* cmd & DO_LIST */
883 if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
886 /* Some FTP servers return the total length of file after REST
887 command, others just return the remaining size. */
888 if (*len && restval && expected_bytes
889 && (expected_bytes == *len - restval))
891 DEBUGP (("Lying FTP server found, adjusting.\n"));
892 expected_bytes = *len;
895 /* If no transmission was required, then everything is OK. */
896 if (!pasv_mode_open) /* we are not using pasive mode so we need
899 /* Wait for the server to connect to the address we're waiting
901 dtsock = accept_connection (local_sock);
904 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
909 /* Open the file -- if output_stream is set, use it instead. */
910 if (!output_stream || con->cmd & DO_LIST)
912 mkalldirs (con->target);
914 rotate_backups (con->target);
917 fp = fopen (con->target, "ab");
918 else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
919 || opt.output_document)
920 fp = fopen (con->target, "wb");
923 fp = fopen_excl (con->target, true);
924 if (!fp && errno == EEXIST)
926 /* We cannot just invent a new name and use it (which is
927 what functions like unique_create typically do)
928 because we told the user we'd use this name.
929 Instead, return and retry the download. */
930 logprintf (LOG_NOTQUIET, _("%s has sprung into existence.\n"),
935 fd_close (local_sock);
936 return FOPEN_EXCL_ERR;
941 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
945 fd_close (local_sock);
954 print_length (*len, restval, true);
955 expected_bytes = *len; /* for get_contents/show_progress */
957 else if (expected_bytes)
958 print_length (expected_bytes, restval, false);
960 /* Get the contents of the document. */
962 if (restval && rest_failed)
963 flags |= rb_skip_startpos;
966 res = fd_read_body (dtsock, fp,
967 expected_bytes ? expected_bytes - restval : 0,
968 restval, &rd_size, len, &con->dltime, flags);
970 tms = time_str (NULL);
971 tmrate = retr_rate (rd_size, con->dltime);
972 total_download_time += con->dltime;
974 /* Close data connection socket. */
976 fd_close (local_sock);
977 /* Close the local file. */
979 /* Close or flush the file. We have to be careful to check for
980 error here. Checking the result of fwrite() is not enough --
981 errors could go unnoticed! */
983 if (!output_stream || con->cmd & DO_LIST)
984 flush_res = fclose (fp);
986 flush_res = fflush (fp);
987 if (flush_res == EOF)
991 /* If get_contents couldn't write to fp, bail out. */
994 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
995 con->target, strerror (errno));
1002 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
1003 tms, tmrate, strerror (errno));
1004 if (opt.server_response)
1005 logputs (LOG_ALWAYS, "\n");
1008 /* Get the server to tell us if everything is retrieved. */
1009 err = ftp_response (csock, &respline);
1013 /* The control connection is decidedly closed. Print the time
1014 only if it hasn't already been printed. */
1016 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1017 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
1018 /* If there is an error on the control connection, close it, but
1019 return FTPRETRINT, since there is a possibility that the
1020 whole file was retrieved nevertheless (but that is for
1021 ftp_loop_internal to decide). */
1025 } /* err != FTPOK */
1026 /* If retrieval failed for any reason, return FTPRETRINT, but do not
1027 close socket, since the control connection is still alive. If
1028 there is something wrong with the control connection, it will
1029 become apparent later. */
1030 if (*respline != '2')
1034 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1035 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
1042 /* What now? The data connection was erroneous, whereas the
1043 response says everything is OK. We shall play it safe. */
1047 if (!(cmd & LEAVE_PENDING))
1049 /* Closing the socket is faster than sending 'QUIT' and the
1050 effect is the same. */
1054 /* If it was a listing, and opt.server_response is true,
1056 if (opt.server_response && (con->cmd & DO_LIST))
1058 mkalldirs (con->target);
1059 fp = fopen (con->target, "r");
1061 logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
1065 /* The lines are being read with read_whole_line because of
1066 no-buffering on opt.lfile. */
1067 while ((line = read_whole_line (fp)) != NULL)
1069 char *p = strchr (line, '\0');
1070 while (p > line && (p[-1] == '\n' || p[-1] == '\r'))
1072 logprintf (LOG_ALWAYS, "%s\n", escnonprint (line));
1077 } /* con->cmd & DO_LIST && server_response */
1079 return RETRFINISHED;
1082 /* A one-file FTP loop. This is the part where FTP retrieval is
1083 retried, and retried, and retried, and...
1085 This loop either gets commands from con, or (if ON_YOUR_OWN is
1086 set), makes them up to retrieve the file given by the URL. */
1088 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
1091 wgint restval, len = 0;
1093 const char *tmrate = NULL;
1098 con->target = url_file_name (u);
1100 if (opt.noclobber && file_exists_p (con->target))
1102 logprintf (LOG_VERBOSE,
1103 _("File `%s' already there; not retrieving.\n"), con->target);
1104 /* If the file is there, we suppose it's retrieved OK. */
1108 /* Remove it if it's a link. */
1109 remove_link (con->target);
1110 if (!opt.output_document)
1113 locf = opt.output_document;
1117 if (con->st & ON_YOUR_OWN)
1118 con->st = ON_YOUR_OWN;
1120 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1125 /* Increment the pass counter. */
1127 sleep_between_retrievals (count);
1128 if (con->st & ON_YOUR_OWN)
1131 con->cmd |= (DO_RETR | LEAVE_PENDING);
1132 if (con->csock != -1)
1133 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1135 con->cmd |= (DO_LOGIN | DO_CWD);
1137 else /* not on your own */
1139 if (con->csock != -1)
1140 con->cmd &= ~DO_LOGIN;
1142 con->cmd |= DO_LOGIN;
1143 if (con->st & DONE_CWD)
1144 con->cmd &= ~DO_CWD;
1149 /* Decide whether or not to restart. */
1151 && stat (locf, &st) == 0
1152 && S_ISREG (st.st_mode))
1153 /* When -c is used, continue from on-disk size. (Can't use
1154 hstat.len even if count>1 because we don't want a failed
1155 first attempt to clobber existing data.) */
1156 restval = st.st_size;
1158 restval = len; /* start where the previous run left off */
1162 /* Get the current time string. */
1163 tms = time_str (NULL);
1164 /* Print fetch message, if opt.verbose. */
1167 char *hurl = url_string (u, true);
1171 sprintf (tmp, _("(try:%2d)"), count);
1172 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1173 tms, hurl, tmp, locf);
1175 ws_changetitle (hurl);
1179 /* Send getftp the proper length, if fileinfo was provided. */
1184 err = getftp (u, &len, restval, con);
1186 if (con->csock != -1)
1187 con->st &= ~DONE_CWD;
1189 con->st |= DONE_CWD;
1193 case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1194 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1195 /* Fatal errors, give up. */
1197 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1198 case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1199 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1200 case FOPEN_EXCL_ERR:
1201 printwhat (count, opt.ntry);
1202 /* non-fatal errors */
1203 if (err == FOPEN_EXCL_ERR)
1205 /* Re-determine the file name. */
1206 xfree_null (con->target);
1207 con->target = url_file_name (u);
1212 /* If the control connection was closed, the retrieval
1213 will be considered OK if f->size == len. */
1214 if (!f || len != f->size)
1216 printwhat (count, opt.ntry);
1227 tms = time_str (NULL);
1229 tmrate = retr_rate (len - restval, con->dltime);
1231 /* If we get out of the switch above without continue'ing, we've
1232 successfully downloaded a file. Remember this fact. */
1233 downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1235 if (con->st & ON_YOUR_OWN)
1237 fd_close (con->csock);
1241 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%s]\n\n"),
1242 tms, tmrate, locf, number_to_static_string (len));
1243 if (!opt.verbose && !opt.quiet)
1245 /* Need to hide the password from the URL. The `if' is here
1246 so that we don't do the needless allocation every
1248 char *hurl = url_string (u, true);
1249 logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
1250 tms, hurl, number_to_static_string (len), locf, count);
1254 if ((con->cmd & DO_LIST))
1255 /* This is a directory listing file. */
1257 if (!opt.remove_listing)
1258 /* --dont-remove-listing was specified, so do count this towards the
1259 number of bytes and files downloaded. */
1261 total_downloaded_bytes += len;
1265 /* Deletion of listing files is not controlled by --delete-after, but
1266 by the more specific option --dont-remove-listing, and the code
1267 to do this deletion is in another function. */
1269 else if (!opt.spider)
1270 /* This is not a directory listing file. */
1272 /* Unlike directory listing files, don't pretend normal files weren't
1273 downloaded if they're going to be deleted. People seeding proxies,
1274 for instance, may want to know how many bytes and files they've
1275 downloaded through it. */
1276 total_downloaded_bytes += len;
1279 if (opt.delete_after)
1282 Removing file due to --delete-after in ftp_loop_internal():\n"));
1283 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1285 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1289 /* Restore the original leave-pendingness. */
1291 con->cmd |= LEAVE_PENDING;
1293 con->cmd &= ~LEAVE_PENDING;
1295 } while (!opt.ntry || (count < opt.ntry));
1297 if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1299 fd_close (con->csock);
1305 /* Return the directory listing in a reusable format. The directory
1306 is specifed in u->dir. */
1308 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1311 char *uf; /* url file name */
1312 char *lf; /* list file name */
1313 char *old_target = con->target;
1315 con->st &= ~ON_YOUR_OWN;
1316 con->cmd |= (DO_LIST | LEAVE_PENDING);
1317 con->cmd &= ~DO_RETR;
1319 /* Find the listing file name. We do it by taking the file name of
1320 the URL and replacing the last component with the listing file
1322 uf = url_file_name (u);
1323 lf = file_merge (uf, LIST_FILENAME);
1325 DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
1328 err = ftp_loop_internal (u, NULL, con);
1329 con->target = old_target;
1332 *f = ftp_parse_ls (lf, con->rs);
1335 if (opt.remove_listing)
1338 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1340 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), lf);
1343 con->cmd &= ~DO_LIST;
1347 static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
1348 static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
1349 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
1350 static void freefileinfo (struct fileinfo *f);
1352 /* Retrieve a list of files given in struct fileinfo linked list. If
1353 a file is a symbolic link, do not retrieve it, but rather try to
1354 set up a similar link on the local disk, if the symlinks are
1357 If opt.recursive is set, after all files have been retrieved,
1358 ftp_retrieve_dirs will be called to retrieve the directories. */
1360 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1362 static int depth = 0;
1364 struct fileinfo *orig;
1369 /* Increase the depth. */
1371 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1373 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1374 depth, opt.reclevel));
1382 con->st &= ~ON_YOUR_OWN;
1383 if (!(con->st & DONE_CWD))
1386 con->cmd &= ~DO_CWD;
1387 con->cmd |= (DO_RETR | LEAVE_PENDING);
1390 con->cmd |= DO_LOGIN;
1392 con->cmd &= ~DO_LOGIN;
1394 err = RETROK; /* in case it's not used */
1398 char *old_target, *ofile;
1400 if (opt.quota && total_downloaded_bytes > opt.quota)
1405 old_target = con->target;
1407 ofile = xstrdup (u->file);
1408 url_set_file (u, f->name);
1410 con->target = url_file_name (u);
1414 if (opt.timestamping && f->type == FT_PLAINFILE)
1417 /* If conversion of HTML files retrieved via FTP is ever implemented,
1418 we'll need to stat() <file>.orig here when -K has been specified.
1419 I'm not implementing it now since files on an FTP server are much
1420 more likely than files on an HTTP server to legitimately have a
1422 if (!stat (con->target, &st))
1426 /* Else, get it from the file. */
1427 local_size = st.st_size;
1430 /* Modification time granularity is 2 seconds for Windows, so
1431 increase local time by 1 second for later comparison. */
1434 /* Compare file sizes only for servers that tell us correct
1435 values. Assumme sizes being equal for servers that lie
1437 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1438 eq_size = cor_val ? (local_size == f->size) : true;
1439 if (f->tstamp <= tml && eq_size)
1441 /* Remote file is older, file sizes can be compared and
1443 logprintf (LOG_VERBOSE, _("\
1444 Remote file no newer than local file `%s' -- not retrieving.\n"), con->target);
1449 /* Remote file is newer or sizes cannot be matched */
1450 logprintf (LOG_VERBOSE, _("\
1451 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1456 /* Sizes do not match */
1457 logprintf (LOG_VERBOSE, _("\
1458 The sizes do not match (local %s) -- retrieving.\n\n"),
1459 number_to_static_string (local_size));
1462 } /* opt.timestamping && f->type == FT_PLAINFILE */
1466 /* If opt.retr_symlinks is defined, we treat symlinks as
1467 if they were normal files. There is currently no way
1468 to distinguish whether they might be directories, and
1470 if (!opt.retr_symlinks)
1474 logputs (LOG_NOTQUIET,
1475 _("Invalid name of the symlink, skipping.\n"));
1479 /* Check whether we already have the correct
1481 int rc = lstat (con->target, &st);
1484 size_t len = strlen (f->linkto) + 1;
1485 if (S_ISLNK (st.st_mode))
1487 char *link_target = (char *)alloca (len);
1488 size_t n = readlink (con->target, link_target, len);
1490 && (memcmp (link_target, f->linkto, n) == 0))
1492 logprintf (LOG_VERBOSE, _("\
1493 Already have correct symlink %s -> %s\n\n"),
1494 con->target, escnonprint (f->linkto));
1500 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1501 con->target, escnonprint (f->linkto));
1502 /* Unlink before creating symlink! */
1503 unlink (con->target);
1504 if (symlink (f->linkto, con->target) == -1)
1505 logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno));
1506 logputs (LOG_VERBOSE, "\n");
1507 } /* have f->linkto */
1508 #else /* not HAVE_SYMLINK */
1509 logprintf (LOG_NOTQUIET,
1510 _("Symlinks not supported, skipping symlink `%s'.\n"),
1512 #endif /* not HAVE_SYMLINK */
1514 else /* opt.retr_symlinks */
1517 err = ftp_loop_internal (u, f, con);
1518 } /* opt.retr_symlinks */
1522 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1523 escnonprint (f->name));
1526 /* Call the retrieve loop. */
1528 err = ftp_loop_internal (u, f, con);
1531 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1532 escnonprint (f->name));
1536 /* Set the time-stamp information to the local file. Symlinks
1537 are not to be stamped because it sets the stamp on the
1539 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1542 && file_exists_p (con->target))
1544 /* #### This code repeats in http.c and ftp.c. Move it to a
1546 const char *fl = NULL;
1547 if (opt.output_document)
1549 if (output_stream_regular)
1550 fl = opt.output_document;
1555 touch (fl, f->tstamp);
1557 else if (f->tstamp == -1)
1558 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), con->target);
1560 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1562 if (opt.preserve_perm)
1563 chmod (con->target, f->perms);
1566 DEBUGP (("Unrecognized permissions for %s.\n", con->target));
1568 xfree (con->target);
1569 con->target = old_target;
1571 url_set_file (u, ofile);
1574 /* Break on fatals. */
1575 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1577 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1581 /* We do not want to call ftp_retrieve_dirs here */
1582 if (opt.recursive &&
1583 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1584 err = ftp_retrieve_dirs (u, orig, con);
1585 else if (opt.recursive)
1586 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1587 depth, opt.reclevel));
1592 /* Retrieve the directories given in a file list. This function works
1593 by simply going through the linked list and calling
1594 ftp_retrieve_glob on each directory entry. The function knows
1595 about excluded directories. */
1597 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
1599 char *container = NULL;
1600 int container_size = 0;
1602 for (; f; f = f->next)
1605 char *odir, *newdir;
1607 if (opt.quota && total_downloaded_bytes > opt.quota)
1609 if (f->type != FT_DIRECTORY)
1612 /* Allocate u->dir off stack, but reallocate only if a larger
1613 string is needed. It's a pity there's no "realloca" for an
1614 item on the bottom of the stack. */
1615 size = strlen (u->dir) + 1 + strlen (f->name) + 1;
1616 if (size > container_size)
1617 container = (char *)alloca (size);
1622 || (*odir == '/' && *(odir + 1) == '\0'))
1623 /* If ODIR is empty or just "/", simply append f->name to
1624 ODIR. (In the former case, to preserve u->dir being
1625 relative; in the latter case, to avoid double slash.) */
1626 sprintf (newdir, "%s%s", odir, f->name);
1628 /* Else, use a separator. */
1629 sprintf (newdir, "%s/%s", odir, f->name);
1631 DEBUGP (("Composing new CWD relative to the initial directory.\n"));
1632 DEBUGP ((" odir = '%s'\n f->name = '%s'\n newdir = '%s'\n\n",
1633 odir, f->name, newdir));
1634 if (!accdir (newdir, ALLABS))
1636 logprintf (LOG_VERBOSE, _("\
1637 Not descending to `%s' as it is excluded/not-included.\n"),
1638 escnonprint (newdir));
1642 con->st &= ~DONE_CWD;
1644 odir = xstrdup (u->dir); /* because url_set_dir will free
1646 url_set_dir (u, newdir);
1647 ftp_retrieve_glob (u, con, GLOB_GETALL);
1648 url_set_dir (u, odir);
1651 /* Set the time-stamp? */
1654 if (opt.quota && total_downloaded_bytes > opt.quota)
1660 /* Return true if S has a leading '/' or contains '../' */
1662 has_insecure_name_p (const char *s)
1667 if (strstr (s, "../") != 0)
1673 /* A near-top-level function to retrieve the files in a directory.
1674 The function calls ftp_get_listing, to get a linked list of files.
1675 Then it weeds out the file names that do not match the pattern.
1676 ftp_retrieve_list is called with this updated list as an argument.
1678 If the argument ACTION is GLOB_GETONE, just download the file (but
1679 first get the listing, so that the time-stamp is heeded); if it's
1680 GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
1683 ftp_retrieve_glob (struct url *u, ccon *con, int action)
1685 struct fileinfo *f, *start;
1688 con->cmd |= LEAVE_PENDING;
1690 res = ftp_get_listing (u, con, &start);
1693 /* First: weed out that do not conform the global rules given in
1694 opt.accepts and opt.rejects. */
1695 if (opt.accepts || opt.rejects)
1700 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1702 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
1703 escnonprint (f->name));
1704 f = delelement (f, &start);
1710 /* Remove all files with possible harmful names */
1714 if (has_insecure_name_p (f->name))
1716 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
1717 escnonprint (f->name));
1718 f = delelement (f, &start);
1723 /* Now weed out the files that do not match our globbing pattern.
1724 If we are dealing with a globbing pattern, that is. */
1725 if (*u->file && (action == GLOB_GLOBALL || action == GLOB_GETONE))
1732 matchres = fnmatch (u->file, f->name, 0);
1735 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
1739 if (matchres == FNM_NOMATCH)
1740 f = delelement (f, &start); /* delete the element from the list */
1742 f = f->next; /* leave the element in the list */
1746 freefileinfo (start);
1747 return RETRBADPATTERN;
1752 /* Just get everything. */
1753 ftp_retrieve_list (u, start, con);
1757 if (action == GLOB_GLOBALL)
1760 /* #### This message SUCKS. We should see what was the
1761 reason that nothing was retrieved. */
1762 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"),
1763 escnonprint (u->file));
1765 else /* GLOB_GETONE or GLOB_GETALL */
1767 /* Let's try retrieving it anyway. */
1768 con->st |= ON_YOUR_OWN;
1769 res = ftp_loop_internal (u, NULL, con);
1773 freefileinfo (start);
1774 if (opt.quota && total_downloaded_bytes > opt.quota)
1777 /* #### Should we return `res' here? */
1781 /* The wrapper that calls an appropriate routine according to contents
1782 of URL. Inherently, its capabilities are limited on what can be
1783 encoded into a URL. */
1785 ftp_loop (struct url *u, int *dt, struct url *proxy)
1787 ccon con; /* FTP connection */
1795 con.st = ON_YOUR_OWN;
1800 /* If the file name is empty, the user probably wants a directory
1801 index. We'll provide one, properly HTML-ized. Unless
1802 opt.htmlify is 0, of course. :-) */
1803 if (!*u->file && !opt.recursive)
1806 res = ftp_get_listing (u, &con, &f);
1810 if (opt.htmlify && !opt.spider)
1812 char *filename = (opt.output_document
1813 ? xstrdup (opt.output_document)
1814 : (con.target ? xstrdup (con.target)
1815 : url_file_name (u)));
1816 res = ftp_index (filename, u, f);
1817 if (res == FTPOK && opt.verbose)
1819 if (!opt.output_document)
1823 if (stat (filename, &st) == 0)
1827 logprintf (LOG_NOTQUIET,
1828 _("Wrote HTML-ized index to `%s' [%s].\n"),
1829 filename, number_to_static_string (sz));
1832 logprintf (LOG_NOTQUIET,
1833 _("Wrote HTML-ized index to `%s'.\n"),
1843 bool ispattern = false;
1846 /* Treat the URL as a pattern if the file name part of the
1847 URL path contains wildcards. (Don't check for u->file
1848 because it is unescaped and therefore doesn't leave users
1849 the option to escape literal '*' as %2A.) */
1850 char *file_part = strrchr (u->path, '/');
1852 file_part = u->path;
1853 ispattern = has_wildcards_p (file_part);
1855 if (ispattern || opt.recursive || opt.timestamping)
1857 /* ftp_retrieve_glob is a catch-all function that gets called
1858 if we need globbing, time-stamping or recursion. Its
1859 third argument is just what we really need. */
1860 res = ftp_retrieve_glob (u, &con,
1861 ispattern ? GLOB_GLOBALL : GLOB_GETONE);
1864 res = ftp_loop_internal (u, NULL, &con);
1870 /* If a connection was left, quench it. */
1871 if (con.csock != -1)
1872 fd_close (con.csock);
1873 xfree_null (con.id);
1875 xfree_null (con.target);
1880 /* Delete an element from the fileinfo linked list. Returns the
1881 address of the next element, or NULL if the list is exhausted. It
1882 can modify the start of the list. */
1883 static struct fileinfo *
1884 delelement (struct fileinfo *f, struct fileinfo **start)
1886 struct fileinfo *prev = f->prev;
1887 struct fileinfo *next = f->next;
1890 xfree_null (f->linkto);
1902 /* Free the fileinfo linked list of files. */
1904 freefileinfo (struct fileinfo *f)
1908 struct fileinfo *next = f->next;