1 /* File Transfer Protocol support.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GNU Wget.
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Wget. If not, see <http://www.gnu.org/licenses/>.
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. */
54 #define LIST_FILENAME "_listing"
56 #define LIST_FILENAME ".listing"
61 int st; /* connection status */
62 int cmd; /* command code */
63 int csock; /* control connection socket */
64 double dltime; /* time of the download in msecs */
65 enum stype rs; /* remote system reported by ftp server */
66 char *id; /* initial directory */
67 char *target; /* target file name */
68 struct url *proxy; /* FTWK-style proxy */
72 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
73 the string S, and return the number converted to wgint, if found, 0
76 ftp_expected_bytes (const char *s)
82 while (*s && *s != '(')
86 ++s; /* skip the '(' */
87 res = str_to_wgint (s, (char **) &s, 10);
90 while (*s && c_isspace (*s))
94 if (c_tolower (*s) != 'b')
96 if (strncasecmp (s, "byte", 4))
106 * This function sets up a passive data connection with the FTP server.
107 * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv.
110 ftp_do_pasv (int csock, ip_address *addr, int *port)
114 /* We need to determine the address family and need to call
115 getpeername, so while we're at it, store the address to ADDR.
116 ftp_pasv and ftp_lpsv can simply override it. */
117 if (!socket_ip_address (csock, addr, ENDPOINT_PEER))
120 /* If our control connection is over IPv6, then we first try EPSV and then
121 * LPSV if the former is not supported. If the control connection is over
122 * IPv4, we simply issue the good old PASV request. */
123 switch (addr->family)
126 if (!opt.server_response)
127 logputs (LOG_VERBOSE, "==> PASV ... ");
128 err = ftp_pasv (csock, addr, port);
131 if (!opt.server_response)
132 logputs (LOG_VERBOSE, "==> EPSV ... ");
133 err = ftp_epsv (csock, addr, port);
135 /* If EPSV is not supported try LPSV */
136 if (err == FTPNOPASV)
138 if (!opt.server_response)
139 logputs (LOG_VERBOSE, "==> LPSV ... ");
140 err = ftp_lpsv (csock, addr, port);
151 * This function sets up an active data connection with the FTP server.
152 * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port.
155 ftp_do_port (int csock, int *local_sock)
160 if (!socket_ip_address (csock, &cip, ENDPOINT_PEER))
163 /* If our control connection is over IPv6, then we first try EPRT and then
164 * LPRT if the former is not supported. If the control connection is over
165 * IPv4, we simply issue the good old PORT request. */
169 if (!opt.server_response)
170 logputs (LOG_VERBOSE, "==> PORT ... ");
171 err = ftp_port (csock, local_sock);
174 if (!opt.server_response)
175 logputs (LOG_VERBOSE, "==> EPRT ... ");
176 err = ftp_eprt (csock, local_sock);
178 /* If EPRT is not supported try LPRT */
179 if (err == FTPPORTERR)
181 if (!opt.server_response)
182 logputs (LOG_VERBOSE, "==> LPRT ... ");
183 err = ftp_lprt (csock, local_sock);
194 ftp_do_pasv (int csock, ip_address *addr, int *port)
196 if (!opt.server_response)
197 logputs (LOG_VERBOSE, "==> PASV ... ");
198 return ftp_pasv (csock, addr, port);
202 ftp_do_port (int csock, int *local_sock)
204 if (!opt.server_response)
205 logputs (LOG_VERBOSE, "==> PORT ... ");
206 return ftp_port (csock, local_sock);
211 print_length (wgint size, wgint start, bool authoritative)
213 logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
215 logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
219 logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
220 number_to_static_string (size - start),
221 human_readable (size - start));
223 logprintf (LOG_VERBOSE, _(", %s remaining"),
224 number_to_static_string (size - start));
226 logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
229 /* Retrieves a file with denoted parameters through opening an FTP
230 connection to the server. It always closes the data connection,
231 and closes the control connection in case of error. */
233 getftp (struct url *u, wgint *len, wgint restval, ccon *con)
235 int csock, dtsock, local_sock, res;
236 uerr_t err = RETROK; /* appease the compiler */
238 char *user, *passwd, *respline;
242 bool pasv_mode_open = false;
243 wgint expected_bytes = 0;
244 bool rest_failed = false;
248 assert (con != NULL);
249 assert (con->target != NULL);
251 /* Debug-check of the sanity of the request by making sure that LIST
252 and RETR are never both requested (since we can handle only one
254 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
255 /* Make sure that at least *something* is requested. */
256 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
260 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
261 user = user ? user : (opt.ftp_user ? opt.ftp_user : opt.user);
262 if (!user) user = "anonymous";
263 passwd = passwd ? passwd : (opt.ftp_passwd ? opt.ftp_passwd : opt.passwd);
264 if (!passwd) passwd = "-wget@";
270 if (!(cmd & DO_LOGIN))
272 else /* cmd & DO_LOGIN */
275 char *host = con->proxy ? con->proxy->host : u->host;
276 int port = con->proxy ? con->proxy->port : u->port;
277 char *logname = user;
281 /* If proxy is in use, log in as username@target-site. */
282 logname = concat_strings (user, "@", u->host, (char *) 0);
285 /* Login to the server: */
287 /* First: Establish the control connection. */
289 csock = connect_to_host (host, port);
293 return (retryable_socket_connect_error (errno)
294 ? CONERROR : CONIMPOSSIBLE);
296 if (cmd & LEAVE_PENDING)
301 /* Second: Login with proper USER/PASS sequence. */
302 logprintf (LOG_VERBOSE, _("Logging in as %s ... "), escnonprint (user));
303 if (opt.server_response)
304 logputs (LOG_ALWAYS, "\n");
305 err = ftp_login (csock, logname, passwd);
310 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
314 logputs (LOG_VERBOSE, "\n");
315 logputs (LOG_NOTQUIET, _("\
316 Error in server response, closing control connection.\n"));
321 logputs (LOG_VERBOSE, "\n");
322 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
327 logputs (LOG_VERBOSE, "\n");
328 logputs (LOG_NOTQUIET,
329 _("Write failed, closing control connection.\n"));
334 logputs (LOG_VERBOSE, "\n");
335 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
338 return FTPLOGREFUSED;
340 logputs (LOG_VERBOSE, "\n");
341 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
346 if (!opt.server_response)
347 logputs (LOG_VERBOSE, _("Logged in!\n"));
352 /* Third: Get the system type */
353 if (!opt.server_response)
354 logprintf (LOG_VERBOSE, "==> SYST ... ");
355 err = ftp_syst (csock, &con->rs);
360 logputs (LOG_VERBOSE, "\n");
361 logputs (LOG_NOTQUIET, _("\
362 Error in server response, closing control connection.\n"));
367 logputs (LOG_VERBOSE, "\n");
368 logputs (LOG_NOTQUIET,
369 _("Server error, can't determine system type.\n"));
372 /* Everything is OK. */
377 if (!opt.server_response && err != FTPSRVERR)
378 logputs (LOG_VERBOSE, _("done. "));
380 /* Fourth: Find the initial ftp directory */
382 if (!opt.server_response)
383 logprintf (LOG_VERBOSE, "==> PWD ... ");
384 err = ftp_pwd (csock, &con->id);
389 logputs (LOG_VERBOSE, "\n");
390 logputs (LOG_NOTQUIET, _("\
391 Error in server response, closing control connection.\n"));
396 /* PWD unsupported -- assume "/". */
397 xfree_null (con->id);
398 con->id = xstrdup ("/");
401 /* Everything is OK. */
406 /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
407 Convert it to "/INITIAL/FOLDER" */
408 if (con->rs == ST_VMS)
410 char *path = strchr (con->id, '[');
411 char *pathend = path ? strchr (path + 1, ']') : NULL;
412 if (!path || !pathend)
413 DEBUGP (("Initial VMS directory not in the form [...]!\n"));
416 char *idir = con->id;
417 DEBUGP (("Preprocessing the initial VMS directory\n"));
418 DEBUGP ((" old = '%s'\n", con->id));
419 /* We do the conversion in-place by copying the stuff
420 between [ and ] to the beginning, and changing dots
421 to slashes at the same time. */
423 for (++path; path < pathend; path++, idir++)
424 *idir = *path == '.' ? '/' : *path;
426 DEBUGP ((" new = '%s'\n\n", con->id));
429 if (!opt.server_response)
430 logputs (LOG_VERBOSE, _("done.\n"));
432 /* Fifth: Set the FTP type. */
433 type_char = ftp_process_type (u->params);
434 if (!opt.server_response)
435 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);
436 err = ftp_type (csock, type_char);
437 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
441 logputs (LOG_VERBOSE, "\n");
442 logputs (LOG_NOTQUIET, _("\
443 Error in server response, closing control connection.\n"));
448 logputs (LOG_VERBOSE, "\n");
449 logputs (LOG_NOTQUIET,
450 _("Write failed, closing control connection.\n"));
455 logputs (LOG_VERBOSE, "\n");
456 logprintf (LOG_NOTQUIET,
457 _("Unknown type `%c', closing control connection.\n"),
463 /* Everything is OK. */
468 if (!opt.server_response)
469 logputs (LOG_VERBOSE, _("done. "));
475 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
478 char *target = u->dir;
480 DEBUGP (("changing working directory\n"));
482 /* Change working directory. To change to a non-absolute
483 Unix directory, we need to prepend initial directory
484 (con->id) to it. Absolute directories "just work".
486 A relative directory is one that does not begin with '/'
487 and, on non-Unix OS'es, one that doesn't begin with
490 This is not done for OS400, which doesn't use
491 "/"-delimited directories, nor does it support directory
492 hierarchies. "CWD foo" followed by "CWD bar" leaves us
493 in "bar", not in "foo/bar", as would be customary
497 && !(con->rs != ST_UNIX
498 && c_isalpha (target[0])
500 && con->rs != ST_OS400)
502 int idlen = strlen (con->id);
505 /* Strip trailing slash(es) from con->id. */
506 while (idlen > 0 && con->id[idlen - 1] == '/')
508 p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
509 memcpy (p, con->id, idlen);
514 DEBUGP (("Prepended initial PWD to relative path:\n"));
515 DEBUGP ((" pwd: '%s'\n old: '%s'\n new: '%s'\n",
516 con->id, target, ntarget));
520 /* If the FTP host runs VMS, we will have to convert the absolute
521 directory path in UNIX notation to absolute directory path in
522 VMS notation as VMS FTP servers do not like UNIX notation of
523 absolute paths. "VMS notation" is [dir.subdir.subsubdir]. */
525 if (con->rs == ST_VMS)
528 char *ntarget = (char *)alloca (strlen (target) + 2);
529 /* We use a converted initial dir, so directories in
530 TARGET will be separated with slashes, something like
531 "/INITIAL/FOLDER/DIR/SUBDIR". Convert that to
532 "[INITIAL.FOLDER.DIR.SUBDIR]". */
533 strcpy (ntarget, target);
534 assert (*ntarget == '/');
536 for (tmpp = ntarget + 1; *tmpp; tmpp++)
541 DEBUGP (("Changed file name to VMS syntax:\n"));
542 DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget));
546 if (!opt.server_response)
547 logprintf (LOG_VERBOSE, "==> CWD %s ... ", escnonprint (target));
548 err = ftp_cwd (csock, target);
549 /* FTPRERR, WRITEFAILED, FTPNSFOD */
553 logputs (LOG_VERBOSE, "\n");
554 logputs (LOG_NOTQUIET, _("\
555 Error in server response, closing control connection.\n"));
560 logputs (LOG_VERBOSE, "\n");
561 logputs (LOG_NOTQUIET,
562 _("Write failed, closing control connection.\n"));
567 logputs (LOG_VERBOSE, "\n");
568 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
569 escnonprint (u->dir));
578 if (!opt.server_response)
579 logputs (LOG_VERBOSE, _("done.\n"));
582 else /* do not CWD */
583 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
585 if ((cmd & DO_RETR) && *len == 0)
589 if (!opt.server_response)
590 logprintf (LOG_VERBOSE, "==> SIZE %s ... ", escnonprint (u->file));
593 err = ftp_size (csock, u->file, len);
599 logputs (LOG_VERBOSE, "\n");
600 logputs (LOG_NOTQUIET, _("\
601 Error in server response, closing control connection.\n"));
606 /* Everything is OK. */
611 if (!opt.server_response)
612 logprintf (LOG_VERBOSE, *len ? "%s\n" : _("done.\n"),
613 number_to_static_string (*len));
616 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
617 if (cmd & (DO_LIST | DO_RETR))
621 ip_address passive_addr;
623 err = ftp_do_pasv (csock, &passive_addr, &passive_port);
624 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
628 logputs (LOG_VERBOSE, "\n");
629 logputs (LOG_NOTQUIET, _("\
630 Error in server response, closing control connection.\n"));
635 logputs (LOG_VERBOSE, "\n");
636 logputs (LOG_NOTQUIET,
637 _("Write failed, closing control connection.\n"));
642 logputs (LOG_VERBOSE, "\n");
643 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
646 logputs (LOG_VERBOSE, "\n");
647 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
656 DEBUGP (("trying to connect to %s port %d\n",
657 print_address (&passive_addr), passive_port));
658 dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
661 int save_errno = errno;
664 logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
665 print_address (&passive_addr), passive_port,
666 strerror (save_errno));
667 return (retryable_socket_connect_error (save_errno)
668 ? CONERROR : CONIMPOSSIBLE);
671 pasv_mode_open = true; /* Flag to avoid accept port */
672 if (!opt.server_response)
673 logputs (LOG_VERBOSE, _("done. "));
677 if (!pasv_mode_open) /* Try to use a port command if PASV failed */
679 err = ftp_do_port (csock, &local_sock);
680 /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,
685 logputs (LOG_VERBOSE, "\n");
686 logputs (LOG_NOTQUIET, _("\
687 Error in server response, closing control connection.\n"));
691 fd_close (local_sock);
694 logputs (LOG_VERBOSE, "\n");
695 logputs (LOG_NOTQUIET,
696 _("Write failed, closing control connection.\n"));
700 fd_close (local_sock);
703 logputs (LOG_VERBOSE, "\n");
704 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
708 fd_close (local_sock);
711 logputs (LOG_VERBOSE, "\n");
712 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
717 logputs (LOG_VERBOSE, "\n");
718 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
722 fd_close (local_sock);
729 if (!opt.server_response)
730 logputs (LOG_VERBOSE, _("done. "));
732 } /* cmd & (DO_LIST | DO_RETR) */
734 /* Restart if needed. */
735 if (restval && (cmd & DO_RETR))
737 if (!opt.server_response)
738 logprintf (LOG_VERBOSE, "==> REST %s ... ",
739 number_to_static_string (restval));
740 err = ftp_rest (csock, restval);
742 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
746 logputs (LOG_VERBOSE, "\n");
747 logputs (LOG_NOTQUIET, _("\
748 Error in server response, closing control connection.\n"));
752 fd_close (local_sock);
755 logputs (LOG_VERBOSE, "\n");
756 logputs (LOG_NOTQUIET,
757 _("Write failed, closing control connection.\n"));
761 fd_close (local_sock);
764 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
772 if (err != FTPRESTFAIL && !opt.server_response)
773 logputs (LOG_VERBOSE, _("done. "));
774 } /* restval && cmd & DO_RETR */
778 /* If we're in spider mode, don't really retrieve anything. The
779 fact that we got to this point should be proof enough that
780 the file exists, vaguely akin to HTTP's concept of a "HEAD"
787 fd_close (local_sock);
793 if (!opt.server_response)
796 logputs (LOG_VERBOSE, "\n");
797 logprintf (LOG_VERBOSE, "==> RETR %s ... ", escnonprint (u->file));
801 err = ftp_retr (csock, u->file);
802 /* FTPRERR, WRITEFAILED, FTPNSFOD */
806 logputs (LOG_VERBOSE, "\n");
807 logputs (LOG_NOTQUIET, _("\
808 Error in server response, closing control connection.\n"));
812 fd_close (local_sock);
815 logputs (LOG_VERBOSE, "\n");
816 logputs (LOG_NOTQUIET,
817 _("Write failed, closing control connection.\n"));
821 fd_close (local_sock);
824 logputs (LOG_VERBOSE, "\n");
825 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"),
826 escnonprint (u->file));
828 fd_close (local_sock);
836 if (!opt.server_response)
837 logputs (LOG_VERBOSE, _("done.\n"));
838 expected_bytes = ftp_expected_bytes (ftp_last_respline);
843 if (!opt.server_response)
844 logputs (LOG_VERBOSE, "==> LIST ... ");
845 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
846 without arguments is better than `LIST .'; confirmed by
848 err = ftp_list (csock, NULL);
849 /* FTPRERR, WRITEFAILED */
853 logputs (LOG_VERBOSE, "\n");
854 logputs (LOG_NOTQUIET, _("\
855 Error in server response, closing control connection.\n"));
859 fd_close (local_sock);
862 logputs (LOG_VERBOSE, "\n");
863 logputs (LOG_NOTQUIET,
864 _("Write failed, closing control connection.\n"));
868 fd_close (local_sock);
871 logputs (LOG_VERBOSE, "\n");
872 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
875 fd_close (local_sock);
882 if (!opt.server_response)
883 logputs (LOG_VERBOSE, _("done.\n"));
884 expected_bytes = ftp_expected_bytes (ftp_last_respline);
885 } /* cmd & DO_LIST */
887 if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
890 /* Some FTP servers return the total length of file after REST
891 command, others just return the remaining size. */
892 if (*len && restval && expected_bytes
893 && (expected_bytes == *len - restval))
895 DEBUGP (("Lying FTP server found, adjusting.\n"));
896 expected_bytes = *len;
899 /* If no transmission was required, then everything is OK. */
900 if (!pasv_mode_open) /* we are not using pasive mode so we need
903 /* Wait for the server to connect to the address we're waiting
905 dtsock = accept_connection (local_sock);
908 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
913 /* Open the file -- if output_stream is set, use it instead. */
914 if (!output_stream || con->cmd & DO_LIST)
916 mkalldirs (con->target);
918 rotate_backups (con->target);
921 fp = fopen (con->target, "ab");
922 else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
923 || opt.output_document)
924 fp = fopen (con->target, "wb");
927 fp = fopen_excl (con->target, true);
928 if (!fp && errno == EEXIST)
930 /* We cannot just invent a new name and use it (which is
931 what functions like unique_create typically do)
932 because we told the user we'd use this name.
933 Instead, return and retry the download. */
934 logprintf (LOG_NOTQUIET, _("%s has sprung into existence.\n"),
939 fd_close (local_sock);
940 return FOPEN_EXCL_ERR;
945 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
949 fd_close (local_sock);
958 print_length (*len, restval, true);
959 expected_bytes = *len; /* for fd_read_body's progress bar */
961 else if (expected_bytes)
962 print_length (expected_bytes, restval, false);
964 /* Get the contents of the document. */
966 if (restval && rest_failed)
967 flags |= rb_skip_startpos;
970 res = fd_read_body (dtsock, fp,
971 expected_bytes ? expected_bytes - restval : 0,
972 restval, &rd_size, len, &con->dltime, flags);
974 tms = datetime_str (time (NULL));
975 tmrate = retr_rate (rd_size, con->dltime);
976 total_download_time += con->dltime;
978 fd_close (local_sock);
979 /* Close the local file. */
980 if (!output_stream || con->cmd & DO_LIST)
983 /* If fd_read_body couldn't write to fp, bail out. */
986 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
987 con->target, strerror (errno));
995 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
996 tms, tmrate, fd_errstr (dtsock));
997 if (opt.server_response)
998 logputs (LOG_ALWAYS, "\n");
1002 /* Get the server to tell us if everything is retrieved. */
1003 err = ftp_response (csock, &respline);
1006 /* The control connection is decidedly closed. Print the time
1007 only if it hasn't already been printed. */
1009 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1010 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
1011 /* If there is an error on the control connection, close it, but
1012 return FTPRETRINT, since there is a possibility that the
1013 whole file was retrieved nevertheless (but that is for
1014 ftp_loop_internal to decide). */
1018 } /* err != FTPOK */
1019 /* If retrieval failed for any reason, return FTPRETRINT, but do not
1020 close socket, since the control connection is still alive. If
1021 there is something wrong with the control connection, it will
1022 become apparent later. */
1023 if (*respline != '2')
1027 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1028 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
1035 /* What now? The data connection was erroneous, whereas the
1036 response says everything is OK. We shall play it safe. */
1040 if (!(cmd & LEAVE_PENDING))
1042 /* Closing the socket is faster than sending 'QUIT' and the
1043 effect is the same. */
1047 /* If it was a listing, and opt.server_response is true,
1049 if (opt.server_response && (con->cmd & DO_LIST))
1051 mkalldirs (con->target);
1052 fp = fopen (con->target, "r");
1054 logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
1058 /* The lines are being read with read_whole_line because of
1059 no-buffering on opt.lfile. */
1060 while ((line = read_whole_line (fp)) != NULL)
1062 char *p = strchr (line, '\0');
1063 while (p > line && (p[-1] == '\n' || p[-1] == '\r'))
1065 logprintf (LOG_ALWAYS, "%s\n", escnonprint (line));
1070 } /* con->cmd & DO_LIST && server_response */
1072 return RETRFINISHED;
1075 /* A one-file FTP loop. This is the part where FTP retrieval is
1076 retried, and retried, and retried, and...
1078 This loop either gets commands from con, or (if ON_YOUR_OWN is
1079 set), makes them up to retrieve the file given by the URL. */
1081 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
1084 wgint restval, len = 0;
1086 const char *tmrate = NULL;
1091 con->target = url_file_name (u);
1093 if (opt.noclobber && file_exists_p (con->target))
1095 logprintf (LOG_VERBOSE,
1096 _("File `%s' already there; not retrieving.\n"), con->target);
1097 /* If the file is there, we suppose it's retrieved OK. */
1101 /* Remove it if it's a link. */
1102 remove_link (con->target);
1103 if (!opt.output_document)
1106 locf = opt.output_document;
1110 if (con->st & ON_YOUR_OWN)
1111 con->st = ON_YOUR_OWN;
1113 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1118 /* Increment the pass counter. */
1120 sleep_between_retrievals (count);
1121 if (con->st & ON_YOUR_OWN)
1124 con->cmd |= (DO_RETR | LEAVE_PENDING);
1125 if (con->csock != -1)
1126 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1128 con->cmd |= (DO_LOGIN | DO_CWD);
1130 else /* not on your own */
1132 if (con->csock != -1)
1133 con->cmd &= ~DO_LOGIN;
1135 con->cmd |= DO_LOGIN;
1136 if (con->st & DONE_CWD)
1137 con->cmd &= ~DO_CWD;
1142 /* Decide whether or not to restart. */
1144 && stat (locf, &st) == 0
1145 && S_ISREG (st.st_mode))
1146 /* When -c is used, continue from on-disk size. (Can't use
1147 hstat.len even if count>1 because we don't want a failed
1148 first attempt to clobber existing data.) */
1149 restval = st.st_size;
1151 restval = len; /* start where the previous run left off */
1155 /* Get the current time string. */
1156 tms = datetime_str (time (NULL));
1157 /* Print fetch message, if opt.verbose. */
1160 char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1164 sprintf (tmp, _("(try:%2d)"), count);
1165 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1166 tms, hurl, tmp, locf);
1168 ws_changetitle (hurl);
1172 /* Send getftp the proper length, if fileinfo was provided. */
1177 err = getftp (u, &len, restval, con);
1179 if (con->csock == -1)
1180 con->st &= ~DONE_CWD;
1182 con->st |= DONE_CWD;
1186 case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1187 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1188 /* Fatal errors, give up. */
1190 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1191 case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1192 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1193 case FOPEN_EXCL_ERR:
1194 printwhat (count, opt.ntry);
1195 /* non-fatal errors */
1196 if (err == FOPEN_EXCL_ERR)
1198 /* Re-determine the file name. */
1199 xfree_null (con->target);
1200 con->target = url_file_name (u);
1205 /* If the control connection was closed, the retrieval
1206 will be considered OK if f->size == len. */
1207 if (!f || len != f->size)
1209 printwhat (count, opt.ntry);
1220 tms = datetime_str (time (NULL));
1222 tmrate = retr_rate (len - restval, con->dltime);
1224 /* If we get out of the switch above without continue'ing, we've
1225 successfully downloaded a file. Remember this fact. */
1226 downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1228 if (con->st & ON_YOUR_OWN)
1230 fd_close (con->csock);
1234 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%s]\n\n"),
1235 tms, tmrate, locf, number_to_static_string (len));
1236 if (!opt.verbose && !opt.quiet)
1238 /* Need to hide the password from the URL. The `if' is here
1239 so that we don't do the needless allocation every
1241 char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
1242 logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
1243 tms, hurl, number_to_static_string (len), locf, count);
1247 if ((con->cmd & DO_LIST))
1248 /* This is a directory listing file. */
1250 if (!opt.remove_listing)
1251 /* --dont-remove-listing was specified, so do count this towards the
1252 number of bytes and files downloaded. */
1254 total_downloaded_bytes += len;
1258 /* Deletion of listing files is not controlled by --delete-after, but
1259 by the more specific option --dont-remove-listing, and the code
1260 to do this deletion is in another function. */
1262 else if (!opt.spider)
1263 /* This is not a directory listing file. */
1265 /* Unlike directory listing files, don't pretend normal files weren't
1266 downloaded if they're going to be deleted. People seeding proxies,
1267 for instance, may want to know how many bytes and files they've
1268 downloaded through it. */
1269 total_downloaded_bytes += len;
1272 if (opt.delete_after)
1275 Removing file due to --delete-after in ftp_loop_internal():\n"));
1276 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1278 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1282 /* Restore the original leave-pendingness. */
1284 con->cmd |= LEAVE_PENDING;
1286 con->cmd &= ~LEAVE_PENDING;
1288 } while (!opt.ntry || (count < opt.ntry));
1290 if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1292 fd_close (con->csock);
1298 /* Return the directory listing in a reusable format. The directory
1299 is specifed in u->dir. */
1301 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1304 char *uf; /* url file name */
1305 char *lf; /* list file name */
1306 char *old_target = con->target;
1308 con->st &= ~ON_YOUR_OWN;
1309 con->cmd |= (DO_LIST | LEAVE_PENDING);
1310 con->cmd &= ~DO_RETR;
1312 /* Find the listing file name. We do it by taking the file name of
1313 the URL and replacing the last component with the listing file
1315 uf = url_file_name (u);
1316 lf = file_merge (uf, LIST_FILENAME);
1318 DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
1321 err = ftp_loop_internal (u, NULL, con);
1322 con->target = old_target;
1325 *f = ftp_parse_ls (lf, con->rs);
1328 if (opt.remove_listing)
1331 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1333 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), lf);
1336 con->cmd &= ~DO_LIST;
1340 static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
1341 static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
1342 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
1343 static void freefileinfo (struct fileinfo *f);
1345 /* Retrieve a list of files given in struct fileinfo linked list. If
1346 a file is a symbolic link, do not retrieve it, but rather try to
1347 set up a similar link on the local disk, if the symlinks are
1350 If opt.recursive is set, after all files have been retrieved,
1351 ftp_retrieve_dirs will be called to retrieve the directories. */
1353 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1355 static int depth = 0;
1357 struct fileinfo *orig;
1362 /* Increase the depth. */
1364 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1366 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1367 depth, opt.reclevel));
1375 con->st &= ~ON_YOUR_OWN;
1376 if (!(con->st & DONE_CWD))
1379 con->cmd &= ~DO_CWD;
1380 con->cmd |= (DO_RETR | LEAVE_PENDING);
1383 con->cmd |= DO_LOGIN;
1385 con->cmd &= ~DO_LOGIN;
1387 err = RETROK; /* in case it's not used */
1391 char *old_target, *ofile;
1393 if (opt.quota && total_downloaded_bytes > opt.quota)
1398 old_target = con->target;
1400 ofile = xstrdup (u->file);
1401 url_set_file (u, f->name);
1403 con->target = url_file_name (u);
1407 if (opt.timestamping && f->type == FT_PLAINFILE)
1410 /* If conversion of HTML files retrieved via FTP is ever implemented,
1411 we'll need to stat() <file>.orig here when -K has been specified.
1412 I'm not implementing it now since files on an FTP server are much
1413 more likely than files on an HTTP server to legitimately have a
1415 if (!stat (con->target, &st))
1419 /* Else, get it from the file. */
1420 local_size = st.st_size;
1423 /* Modification time granularity is 2 seconds for Windows, so
1424 increase local time by 1 second for later comparison. */
1427 /* Compare file sizes only for servers that tell us correct
1428 values. Assume sizes being equal for servers that lie
1430 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1431 eq_size = cor_val ? (local_size == f->size) : true;
1432 if (f->tstamp <= tml && eq_size)
1434 /* Remote file is older, file sizes can be compared and
1436 logprintf (LOG_VERBOSE, _("\
1437 Remote file no newer than local file `%s' -- not retrieving.\n"), con->target);
1442 /* Remote file is newer or sizes cannot be matched */
1443 logprintf (LOG_VERBOSE, _("\
1444 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1449 /* Sizes do not match */
1450 logprintf (LOG_VERBOSE, _("\
1451 The sizes do not match (local %s) -- retrieving.\n\n"),
1452 number_to_static_string (local_size));
1455 } /* opt.timestamping && f->type == FT_PLAINFILE */
1459 /* If opt.retr_symlinks is defined, we treat symlinks as
1460 if they were normal files. There is currently no way
1461 to distinguish whether they might be directories, and
1463 if (!opt.retr_symlinks)
1467 logputs (LOG_NOTQUIET,
1468 _("Invalid name of the symlink, skipping.\n"));
1472 /* Check whether we already have the correct
1474 int rc = lstat (con->target, &st);
1477 size_t len = strlen (f->linkto) + 1;
1478 if (S_ISLNK (st.st_mode))
1480 char *link_target = (char *)alloca (len);
1481 size_t n = readlink (con->target, link_target, len);
1483 && (memcmp (link_target, f->linkto, n) == 0))
1485 logprintf (LOG_VERBOSE, _("\
1486 Already have correct symlink %s -> %s\n\n"),
1487 con->target, escnonprint (f->linkto));
1493 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1494 con->target, escnonprint (f->linkto));
1495 /* Unlink before creating symlink! */
1496 unlink (con->target);
1497 if (symlink (f->linkto, con->target) == -1)
1498 logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno));
1499 logputs (LOG_VERBOSE, "\n");
1500 } /* have f->linkto */
1501 #else /* not HAVE_SYMLINK */
1502 logprintf (LOG_NOTQUIET,
1503 _("Symlinks not supported, skipping symlink `%s'.\n"),
1505 #endif /* not HAVE_SYMLINK */
1507 else /* opt.retr_symlinks */
1510 err = ftp_loop_internal (u, f, con);
1511 } /* opt.retr_symlinks */
1515 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1516 escnonprint (f->name));
1519 /* Call the retrieve loop. */
1521 err = ftp_loop_internal (u, f, con);
1524 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1525 escnonprint (f->name));
1529 /* Set the time-stamp information to the local file. Symlinks
1530 are not to be stamped because it sets the stamp on the
1532 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1535 && file_exists_p (con->target))
1537 /* #### This code repeats in http.c and ftp.c. Move it to a
1539 const char *fl = NULL;
1540 if (opt.output_document)
1542 if (output_stream_regular)
1543 fl = opt.output_document;
1548 touch (fl, f->tstamp);
1550 else if (f->tstamp == -1)
1551 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), con->target);
1553 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1555 if (opt.preserve_perm)
1556 chmod (con->target, f->perms);
1559 DEBUGP (("Unrecognized permissions for %s.\n", con->target));
1561 xfree (con->target);
1562 con->target = old_target;
1564 url_set_file (u, ofile);
1567 /* Break on fatals. */
1568 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1570 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1574 /* We do not want to call ftp_retrieve_dirs here */
1575 if (opt.recursive &&
1576 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1577 err = ftp_retrieve_dirs (u, orig, con);
1578 else if (opt.recursive)
1579 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1580 depth, opt.reclevel));
1585 /* Retrieve the directories given in a file list. This function works
1586 by simply going through the linked list and calling
1587 ftp_retrieve_glob on each directory entry. The function knows
1588 about excluded directories. */
1590 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
1592 char *container = NULL;
1593 int container_size = 0;
1595 for (; f; f = f->next)
1598 char *odir, *newdir;
1600 if (opt.quota && total_downloaded_bytes > opt.quota)
1602 if (f->type != FT_DIRECTORY)
1605 /* Allocate u->dir off stack, but reallocate only if a larger
1606 string is needed. It's a pity there's no "realloca" for an
1607 item on the bottom of the stack. */
1608 size = strlen (u->dir) + 1 + strlen (f->name) + 1;
1609 if (size > container_size)
1610 container = (char *)alloca (size);
1615 || (*odir == '/' && *(odir + 1) == '\0'))
1616 /* If ODIR is empty or just "/", simply append f->name to
1617 ODIR. (In the former case, to preserve u->dir being
1618 relative; in the latter case, to avoid double slash.) */
1619 sprintf (newdir, "%s%s", odir, f->name);
1621 /* Else, use a separator. */
1622 sprintf (newdir, "%s/%s", odir, f->name);
1624 DEBUGP (("Composing new CWD relative to the initial directory.\n"));
1625 DEBUGP ((" odir = '%s'\n f->name = '%s'\n newdir = '%s'\n\n",
1626 odir, f->name, newdir));
1627 if (!accdir (newdir))
1629 logprintf (LOG_VERBOSE, _("\
1630 Not descending to `%s' as it is excluded/not-included.\n"),
1631 escnonprint (newdir));
1635 con->st &= ~DONE_CWD;
1637 odir = xstrdup (u->dir); /* because url_set_dir will free
1639 url_set_dir (u, newdir);
1640 ftp_retrieve_glob (u, con, GLOB_GETALL);
1641 url_set_dir (u, odir);
1644 /* Set the time-stamp? */
1647 if (opt.quota && total_downloaded_bytes > opt.quota)
1653 /* Return true if S has a leading '/' or contains '../' */
1655 has_insecure_name_p (const char *s)
1660 if (strstr (s, "../") != 0)
1666 /* A near-top-level function to retrieve the files in a directory.
1667 The function calls ftp_get_listing, to get a linked list of files.
1668 Then it weeds out the file names that do not match the pattern.
1669 ftp_retrieve_list is called with this updated list as an argument.
1671 If the argument ACTION is GLOB_GETONE, just download the file (but
1672 first get the listing, so that the time-stamp is heeded); if it's
1673 GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
1676 ftp_retrieve_glob (struct url *u, ccon *con, int action)
1678 struct fileinfo *f, *start;
1681 con->cmd |= LEAVE_PENDING;
1683 res = ftp_get_listing (u, con, &start);
1686 /* First: weed out that do not conform the global rules given in
1687 opt.accepts and opt.rejects. */
1688 if (opt.accepts || opt.rejects)
1693 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1695 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
1696 escnonprint (f->name));
1697 f = delelement (f, &start);
1703 /* Remove all files with possible harmful names */
1707 if (has_insecure_name_p (f->name))
1709 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
1710 escnonprint (f->name));
1711 f = delelement (f, &start);
1716 /* Now weed out the files that do not match our globbing pattern.
1717 If we are dealing with a globbing pattern, that is. */
1718 if (*u->file && (action == GLOB_GLOBALL || action == GLOB_GETONE))
1720 int (*matcher) (const char *, const char *, int)
1721 = opt.ignore_case ? fnmatch_nocase : fnmatch;
1727 matchres = matcher (u->file, f->name, 0);
1730 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
1734 if (matchres == FNM_NOMATCH)
1735 f = delelement (f, &start); /* delete the element from the list */
1737 f = f->next; /* leave the element in the list */
1741 freefileinfo (start);
1742 return RETRBADPATTERN;
1747 /* Just get everything. */
1748 ftp_retrieve_list (u, start, con);
1752 if (action == GLOB_GLOBALL)
1755 /* #### This message SUCKS. We should see what was the
1756 reason that nothing was retrieved. */
1757 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"),
1758 escnonprint (u->file));
1760 else /* GLOB_GETONE or GLOB_GETALL */
1762 /* Let's try retrieving it anyway. */
1763 con->st |= ON_YOUR_OWN;
1764 res = ftp_loop_internal (u, NULL, con);
1768 freefileinfo (start);
1769 if (opt.quota && total_downloaded_bytes > opt.quota)
1772 /* #### Should we return `res' here? */
1776 /* The wrapper that calls an appropriate routine according to contents
1777 of URL. Inherently, its capabilities are limited on what can be
1778 encoded into a URL. */
1780 ftp_loop (struct url *u, int *dt, struct url *proxy, bool recursive, bool glob)
1782 ccon con; /* FTP connection */
1790 con.st = ON_YOUR_OWN;
1795 /* If the file name is empty, the user probably wants a directory
1796 index. We'll provide one, properly HTML-ized. Unless
1797 opt.htmlify is 0, of course. :-) */
1798 if (!*u->file && !recursive)
1801 res = ftp_get_listing (u, &con, &f);
1805 if (opt.htmlify && !opt.spider)
1807 char *filename = (opt.output_document
1808 ? xstrdup (opt.output_document)
1809 : (con.target ? xstrdup (con.target)
1810 : url_file_name (u)));
1811 res = ftp_index (filename, u, f);
1812 if (res == FTPOK && opt.verbose)
1814 if (!opt.output_document)
1818 if (stat (filename, &st) == 0)
1822 logprintf (LOG_NOTQUIET,
1823 _("Wrote HTML-ized index to `%s' [%s].\n"),
1824 filename, number_to_static_string (sz));
1827 logprintf (LOG_NOTQUIET,
1828 _("Wrote HTML-ized index to `%s'.\n"),
1838 bool ispattern = false;
1841 /* Treat the URL as a pattern if the file name part of the
1842 URL path contains wildcards. (Don't check for u->file
1843 because it is unescaped and therefore doesn't leave users
1844 the option to escape literal '*' as %2A.) */
1845 char *file_part = strrchr (u->path, '/');
1847 file_part = u->path;
1848 ispattern = has_wildcards_p (file_part);
1850 if (ispattern || recursive || opt.timestamping)
1852 /* ftp_retrieve_glob is a catch-all function that gets called
1853 if we need globbing, time-stamping or recursion. Its
1854 third argument is just what we really need. */
1855 res = ftp_retrieve_glob (u, &con,
1856 ispattern ? GLOB_GLOBALL : GLOB_GETONE);
1859 res = ftp_loop_internal (u, NULL, &con);
1865 /* If a connection was left, quench it. */
1866 if (con.csock != -1)
1867 fd_close (con.csock);
1868 xfree_null (con.id);
1870 xfree_null (con.target);
1875 /* Delete an element from the fileinfo linked list. Returns the
1876 address of the next element, or NULL if the list is exhausted. It
1877 can modify the start of the list. */
1878 static struct fileinfo *
1879 delelement (struct fileinfo *f, struct fileinfo **start)
1881 struct fileinfo *prev = f->prev;
1882 struct fileinfo *next = f->next;
1885 xfree_null (f->linkto);
1897 /* Free the fileinfo linked list of files. */
1899 freefileinfo (struct fileinfo *f)
1903 struct fileinfo *next = f->next;