1 /* File Transfer Protocol support.
2 Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001
3 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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 In addition, as a special exception, the Free Software Foundation
22 gives permission to link the code of its release of Wget with the
23 OpenSSL project's "OpenSSL" library (or with modified versions of it
24 that use the same license as the "OpenSSL" library), and distribute
25 the linked executables. You must obey the GNU General Public License
26 in all respects for all of the code used other than "OpenSSL". If you
27 modify this file, you may extend this exception to your version of the
28 file, but you are not obligated to do so. If you do not wish to do
29 so, delete this exception statement from your version. */
50 #include "convert.h" /* for downloaded_file */
51 #include "recur.h" /* for INFINITE_RECURSION */
53 /* File where the "ls -al" listing will be saved. */
54 #define LIST_FILENAME ".listing"
58 int st; /* connection status */
59 int cmd; /* command code */
60 int csock; /* control connection socket */
61 double dltime; /* time of the download in msecs */
62 enum stype rs; /* remote system reported by ftp server */
63 char *id; /* initial directory */
64 char *target; /* target file name */
65 struct url *proxy; /* FTWK-style proxy */
69 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
70 the string S, and return the number converted to wgint, if found, 0
73 ftp_expected_bytes (const char *s)
79 while (*s && *s != '(')
83 ++s; /* skip the '(' */
84 res = str_to_wgint (s, (char **) &s, 10);
87 while (*s && ISSPACE (*s))
91 if (TOLOWER (*s) != 'b')
93 if (strncasecmp (s, "byte", 4))
103 * This function sets up a passive data connection with the FTP server.
104 * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv.
107 ftp_do_pasv (int csock, ip_address *addr, int *port)
111 /* We need to determine the address family and need to call
112 getpeername, so while we're at it, store the address to ADDR.
113 ftp_pasv and ftp_lpsv can simply override it. */
114 if (!socket_ip_address (csock, addr, ENDPOINT_PEER))
117 /* If our control connection is over IPv6, then we first try EPSV and then
118 * LPSV if the former is not supported. If the control connection is over
119 * IPv4, we simply issue the good old PASV request. */
123 if (!opt.server_response)
124 logputs (LOG_VERBOSE, "==> PASV ... ");
125 err = ftp_pasv (csock, addr, port);
128 if (!opt.server_response)
129 logputs (LOG_VERBOSE, "==> EPSV ... ");
130 err = ftp_epsv (csock, addr, port);
132 /* If EPSV is not supported try LPSV */
133 if (err == FTPNOPASV)
135 if (!opt.server_response)
136 logputs (LOG_VERBOSE, "==> LPSV ... ");
137 err = ftp_lpsv (csock, addr, port);
148 * This function sets up an active data connection with the FTP server.
149 * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port.
152 ftp_do_port (int csock, int *local_sock)
157 if (!socket_ip_address (csock, &cip, ENDPOINT_PEER))
160 /* If our control connection is over IPv6, then we first try EPRT and then
161 * LPRT if the former is not supported. If the control connection is over
162 * IPv4, we simply issue the good old PORT request. */
166 if (!opt.server_response)
167 logputs (LOG_VERBOSE, "==> PORT ... ");
168 err = ftp_port (csock, local_sock);
171 if (!opt.server_response)
172 logputs (LOG_VERBOSE, "==> EPRT ... ");
173 err = ftp_eprt (csock, local_sock);
175 /* If EPRT is not supported try LPRT */
176 if (err == FTPPORTERR)
178 if (!opt.server_response)
179 logputs (LOG_VERBOSE, "==> LPRT ... ");
180 err = ftp_lprt (csock, local_sock);
191 ftp_do_pasv (int csock, ip_address *addr, int *port)
193 if (!opt.server_response)
194 logputs (LOG_VERBOSE, "==> PASV ... ");
195 return ftp_pasv (csock, addr, port);
199 ftp_do_port (int csock, int *local_sock)
201 if (!opt.server_response)
202 logputs (LOG_VERBOSE, "==> PORT ... ");
203 return ftp_port (csock, local_sock);
208 print_length (wgint size, wgint start, bool authoritative)
210 logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
212 logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
216 logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
217 number_to_static_string (size - start),
218 human_readable (size - start));
220 logprintf (LOG_VERBOSE, _(", %s remaining"),
221 number_to_static_string (size - start));
223 logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
226 /* Retrieves a file with denoted parameters through opening an FTP
227 connection to the server. It always closes the data connection,
228 and closes the control connection in case of error. */
230 getftp (struct url *u, wgint *len, wgint restval, ccon *con)
232 int csock, dtsock, local_sock, res;
233 uerr_t err = RETROK; /* appease the compiler */
235 char *user, *passwd, *respline;
239 bool pasv_mode_open = false;
240 wgint expected_bytes = 0;
241 bool rest_failed = false;
245 assert (con != NULL);
246 assert (con->target != NULL);
248 /* Debug-check of the sanity of the request by making sure that LIST
249 and RETR are never both requested (since we can handle only one
251 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
252 /* Make sure that at least *something* is requested. */
253 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
257 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
258 user = user ? user : (opt.ftp_user ? opt.ftp_user : opt.user);
259 if (!user) user = "anonymous";
260 passwd = passwd ? passwd : (opt.ftp_passwd ? opt.ftp_passwd : opt.passwd);
261 if (!passwd) passwd = "-wget@";
267 if (!(cmd & DO_LOGIN))
269 else /* cmd & DO_LOGIN */
272 char *host = con->proxy ? con->proxy->host : u->host;
273 int port = con->proxy ? con->proxy->port : u->port;
274 char *logname = user;
278 /* If proxy is in use, log in as username@target-site. */
279 logname = concat_strings (user, "@", u->host, (char *) 0);
282 /* Login to the server: */
284 /* First: Establish the control connection. */
286 csock = connect_to_host (host, port);
290 return (retryable_socket_connect_error (errno)
291 ? CONERROR : CONIMPOSSIBLE);
293 if (cmd & LEAVE_PENDING)
298 /* Second: Login with proper USER/PASS sequence. */
299 logprintf (LOG_VERBOSE, _("Logging in as %s ... "), escnonprint (user));
300 if (opt.server_response)
301 logputs (LOG_ALWAYS, "\n");
302 err = ftp_login (csock, logname, passwd);
307 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
311 logputs (LOG_VERBOSE, "\n");
312 logputs (LOG_NOTQUIET, _("\
313 Error in server response, closing control connection.\n"));
318 logputs (LOG_VERBOSE, "\n");
319 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
324 logputs (LOG_VERBOSE, "\n");
325 logputs (LOG_NOTQUIET,
326 _("Write failed, closing control connection.\n"));
331 logputs (LOG_VERBOSE, "\n");
332 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
335 return FTPLOGREFUSED;
337 logputs (LOG_VERBOSE, "\n");
338 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
343 if (!opt.server_response)
344 logputs (LOG_VERBOSE, _("Logged in!\n"));
349 /* Third: Get the system type */
350 if (!opt.server_response)
351 logprintf (LOG_VERBOSE, "==> SYST ... ");
352 err = ftp_syst (csock, &con->rs);
357 logputs (LOG_VERBOSE, "\n");
358 logputs (LOG_NOTQUIET, _("\
359 Error in server response, closing control connection.\n"));
364 logputs (LOG_VERBOSE, "\n");
365 logputs (LOG_NOTQUIET,
366 _("Server error, can't determine system type.\n"));
369 /* Everything is OK. */
374 if (!opt.server_response && err != FTPSRVERR)
375 logputs (LOG_VERBOSE, _("done. "));
377 /* Fourth: Find the initial ftp directory */
379 if (!opt.server_response)
380 logprintf (LOG_VERBOSE, "==> PWD ... ");
381 err = ftp_pwd (csock, &con->id);
386 logputs (LOG_VERBOSE, "\n");
387 logputs (LOG_NOTQUIET, _("\
388 Error in server response, closing control connection.\n"));
393 /* PWD unsupported -- assume "/". */
394 xfree_null (con->id);
395 con->id = xstrdup ("/");
398 /* Everything is OK. */
403 /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
404 Convert it to "/INITIAL/FOLDER" */
405 if (con->rs == ST_VMS)
407 char *path = strchr (con->id, '[');
408 char *pathend = path ? strchr (path + 1, ']') : NULL;
409 if (!path || !pathend)
410 DEBUGP (("Initial VMS directory not in the form [...]!\n"));
413 char *idir = con->id;
414 DEBUGP (("Preprocessing the initial VMS directory\n"));
415 DEBUGP ((" old = '%s'\n", con->id));
416 /* We do the conversion in-place by copying the stuff
417 between [ and ] to the beginning, and changing dots
418 to slashes at the same time. */
420 for (++path; path < pathend; path++, idir++)
421 *idir = *path == '.' ? '/' : *path;
423 DEBUGP ((" new = '%s'\n\n", con->id));
426 if (!opt.server_response)
427 logputs (LOG_VERBOSE, _("done.\n"));
429 /* Fifth: Set the FTP type. */
430 type_char = ftp_process_type (u->params);
431 if (!opt.server_response)
432 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);
433 err = ftp_type (csock, type_char);
434 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
438 logputs (LOG_VERBOSE, "\n");
439 logputs (LOG_NOTQUIET, _("\
440 Error in server response, closing control connection.\n"));
445 logputs (LOG_VERBOSE, "\n");
446 logputs (LOG_NOTQUIET,
447 _("Write failed, closing control connection.\n"));
452 logputs (LOG_VERBOSE, "\n");
453 logprintf (LOG_NOTQUIET,
454 _("Unknown type `%c', closing control connection.\n"),
460 /* Everything is OK. */
465 if (!opt.server_response)
466 logputs (LOG_VERBOSE, _("done. "));
472 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
475 char *target = u->dir;
477 DEBUGP (("changing working directory\n"));
479 /* Change working directory. To change to a non-absolute
480 Unix directory, we need to prepend initial directory
481 (con->id) to it. Absolute directories "just work".
483 A relative directory is one that does not begin with '/'
484 and, on non-Unix OS'es, one that doesn't begin with
487 This is not done for OS400, which doesn't use
488 "/"-delimited directories, nor does it support directory
489 hierarchies. "CWD foo" followed by "CWD bar" leaves us
490 in "bar", not in "foo/bar", as would be customary
494 && !(con->rs != ST_UNIX
495 && ISALPHA (target[0])
497 && con->rs != ST_OS400)
499 int idlen = strlen (con->id);
502 /* Strip trailing slash(es) from con->id. */
503 while (idlen > 0 && con->id[idlen - 1] == '/')
505 p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
506 memcpy (p, con->id, idlen);
511 DEBUGP (("Prepended initial PWD to relative path:\n"));
512 DEBUGP ((" pwd: '%s'\n old: '%s'\n new: '%s'\n",
513 con->id, target, ntarget));
517 /* If the FTP host runs VMS, we will have to convert the absolute
518 directory path in UNIX notation to absolute directory path in
519 VMS notation as VMS FTP servers do not like UNIX notation of
520 absolute paths. "VMS notation" is [dir.subdir.subsubdir]. */
522 if (con->rs == ST_VMS)
525 char *ntarget = (char *)alloca (strlen (target) + 2);
526 /* We use a converted initial dir, so directories in
527 TARGET will be separated with slashes, something like
528 "/INITIAL/FOLDER/DIR/SUBDIR". Convert that to
529 "[INITIAL.FOLDER.DIR.SUBDIR]". */
530 strcpy (ntarget, target);
531 assert (*ntarget == '/');
533 for (tmpp = ntarget + 1; *tmpp; tmpp++)
538 DEBUGP (("Changed file name to VMS syntax:\n"));
539 DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget));
543 if (!opt.server_response)
544 logprintf (LOG_VERBOSE, "==> CWD %s ... ", escnonprint (target));
545 err = ftp_cwd (csock, target);
546 /* FTPRERR, WRITEFAILED, FTPNSFOD */
550 logputs (LOG_VERBOSE, "\n");
551 logputs (LOG_NOTQUIET, _("\
552 Error in server response, closing control connection.\n"));
557 logputs (LOG_VERBOSE, "\n");
558 logputs (LOG_NOTQUIET,
559 _("Write failed, closing control connection.\n"));
564 logputs (LOG_VERBOSE, "\n");
565 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
566 escnonprint (u->dir));
575 if (!opt.server_response)
576 logputs (LOG_VERBOSE, _("done.\n"));
579 else /* do not CWD */
580 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
582 if ((cmd & DO_RETR) && *len == 0)
586 if (!opt.server_response)
587 logprintf (LOG_VERBOSE, "==> SIZE %s ... ", escnonprint (u->file));
590 err = ftp_size (csock, u->file, len);
596 logputs (LOG_VERBOSE, "\n");
597 logputs (LOG_NOTQUIET, _("\
598 Error in server response, closing control connection.\n"));
603 /* Everything is OK. */
608 if (!opt.server_response)
609 logprintf (LOG_VERBOSE, *len ? "%s\n" : _("done.\n"),
610 number_to_static_string (*len));
613 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
614 if (cmd & (DO_LIST | DO_RETR))
618 ip_address passive_addr;
620 err = ftp_do_pasv (csock, &passive_addr, &passive_port);
621 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
625 logputs (LOG_VERBOSE, "\n");
626 logputs (LOG_NOTQUIET, _("\
627 Error in server response, closing control connection.\n"));
632 logputs (LOG_VERBOSE, "\n");
633 logputs (LOG_NOTQUIET,
634 _("Write failed, closing control connection.\n"));
639 logputs (LOG_VERBOSE, "\n");
640 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
643 logputs (LOG_VERBOSE, "\n");
644 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
653 DEBUGP (("trying to connect to %s port %d\n",
654 pretty_print_address (&passive_addr),
656 dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
659 int save_errno = errno;
662 logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
663 pretty_print_address (&passive_addr), passive_port,
664 strerror (save_errno));
665 return (retryable_socket_connect_error (save_errno)
666 ? CONERROR : CONIMPOSSIBLE);
669 pasv_mode_open = true; /* Flag to avoid accept port */
670 if (!opt.server_response)
671 logputs (LOG_VERBOSE, _("done. "));
675 if (!pasv_mode_open) /* Try to use a port command if PASV failed */
677 err = ftp_do_port (csock, &local_sock);
678 /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,
683 logputs (LOG_VERBOSE, "\n");
684 logputs (LOG_NOTQUIET, _("\
685 Error in server response, closing control connection.\n"));
689 fd_close (local_sock);
692 logputs (LOG_VERBOSE, "\n");
693 logputs (LOG_NOTQUIET,
694 _("Write failed, closing control connection.\n"));
698 fd_close (local_sock);
701 logputs (LOG_VERBOSE, "\n");
702 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
706 fd_close (local_sock);
709 logputs (LOG_VERBOSE, "\n");
710 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
715 logputs (LOG_VERBOSE, "\n");
716 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
720 fd_close (local_sock);
727 if (!opt.server_response)
728 logputs (LOG_VERBOSE, _("done. "));
730 } /* cmd & (DO_LIST | DO_RETR) */
732 /* Restart if needed. */
733 if (restval && (cmd & DO_RETR))
735 if (!opt.server_response)
736 logprintf (LOG_VERBOSE, "==> REST %s ... ",
737 number_to_static_string (restval));
738 err = ftp_rest (csock, restval);
740 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
744 logputs (LOG_VERBOSE, "\n");
745 logputs (LOG_NOTQUIET, _("\
746 Error in server response, closing control connection.\n"));
750 fd_close (local_sock);
753 logputs (LOG_VERBOSE, "\n");
754 logputs (LOG_NOTQUIET,
755 _("Write failed, closing control connection.\n"));
759 fd_close (local_sock);
762 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
770 if (err != FTPRESTFAIL && !opt.server_response)
771 logputs (LOG_VERBOSE, _("done. "));
772 } /* restval && cmd & DO_RETR */
776 /* If we're in spider mode, don't really retrieve anything. The
777 fact that we got to this point should be proof enough that
778 the file exists, vaguely akin to HTTP's concept of a "HEAD"
785 fd_close (local_sock);
791 if (!opt.server_response)
794 logputs (LOG_VERBOSE, "\n");
795 logprintf (LOG_VERBOSE, "==> RETR %s ... ", escnonprint (u->file));
799 err = ftp_retr (csock, u->file);
800 /* FTPRERR, WRITEFAILED, FTPNSFOD */
804 logputs (LOG_VERBOSE, "\n");
805 logputs (LOG_NOTQUIET, _("\
806 Error in server response, closing control connection.\n"));
810 fd_close (local_sock);
813 logputs (LOG_VERBOSE, "\n");
814 logputs (LOG_NOTQUIET,
815 _("Write failed, closing control connection.\n"));
819 fd_close (local_sock);
822 logputs (LOG_VERBOSE, "\n");
823 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"),
824 escnonprint (u->file));
826 fd_close (local_sock);
834 if (!opt.server_response)
835 logputs (LOG_VERBOSE, _("done.\n"));
836 expected_bytes = ftp_expected_bytes (ftp_last_respline);
841 if (!opt.server_response)
842 logputs (LOG_VERBOSE, "==> LIST ... ");
843 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
844 without arguments is better than `LIST .'; confirmed by
846 err = ftp_list (csock, NULL);
847 /* FTPRERR, WRITEFAILED */
851 logputs (LOG_VERBOSE, "\n");
852 logputs (LOG_NOTQUIET, _("\
853 Error in server response, closing control connection.\n"));
857 fd_close (local_sock);
860 logputs (LOG_VERBOSE, "\n");
861 logputs (LOG_NOTQUIET,
862 _("Write failed, closing control connection.\n"));
866 fd_close (local_sock);
869 logputs (LOG_VERBOSE, "\n");
870 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
873 fd_close (local_sock);
880 if (!opt.server_response)
881 logputs (LOG_VERBOSE, _("done.\n"));
882 expected_bytes = ftp_expected_bytes (ftp_last_respline);
883 } /* cmd & DO_LIST */
885 if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
888 /* Some FTP servers return the total length of file after REST
889 command, others just return the remaining size. */
890 if (*len && restval && expected_bytes
891 && (expected_bytes == *len - restval))
893 DEBUGP (("Lying FTP server found, adjusting.\n"));
894 expected_bytes = *len;
897 /* If no transmission was required, then everything is OK. */
898 if (!pasv_mode_open) /* we are not using pasive mode so we need
901 /* Wait for the server to connect to the address we're waiting
903 dtsock = accept_connection (local_sock);
906 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
911 /* Open the file -- if output_stream is set, use it instead. */
912 if (!output_stream || con->cmd & DO_LIST)
914 mkalldirs (con->target);
916 rotate_backups (con->target);
919 fp = fopen (con->target, "ab");
920 else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
921 || opt.output_document)
922 fp = fopen (con->target, "wb");
925 fp = fopen_excl (con->target, true);
926 if (!fp && errno == EEXIST)
928 /* We cannot just invent a new name and use it (which is
929 what functions like unique_create typically do)
930 because we told the user we'd use this name.
931 Instead, return and retry the download. */
932 logprintf (LOG_NOTQUIET, _("%s has sprung into existence.\n"),
937 fd_close (local_sock);
938 return FOPEN_EXCL_ERR;
943 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
947 fd_close (local_sock);
956 print_length (*len, restval, true);
957 expected_bytes = *len; /* for get_contents/show_progress */
959 else if (expected_bytes)
960 print_length (expected_bytes, restval, false);
962 /* Get the contents of the document. */
964 if (restval && rest_failed)
965 flags |= rb_skip_startpos;
968 res = fd_read_body (dtsock, fp,
969 expected_bytes ? expected_bytes - restval : 0,
970 restval, &rd_size, len, &con->dltime, flags);
972 tms = time_str (NULL);
973 tmrate = retr_rate (rd_size, con->dltime);
974 total_download_time += con->dltime;
976 /* Close data connection socket. */
978 fd_close (local_sock);
979 /* Close the local file. */
981 /* Close or flush the file. We have to be careful to check for
982 error here. Checking the result of fwrite() is not enough --
983 errors could go unnoticed! */
985 if (!output_stream || con->cmd & DO_LIST)
986 flush_res = fclose (fp);
988 flush_res = fflush (fp);
989 if (flush_res == EOF)
993 /* If get_contents couldn't write to fp, bail out. */
996 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
997 con->target, strerror (errno));
1004 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
1005 tms, tmrate, strerror (errno));
1006 if (opt.server_response)
1007 logputs (LOG_ALWAYS, "\n");
1010 /* Get the server to tell us if everything is retrieved. */
1011 err = ftp_response (csock, &respline);
1015 /* The control connection is decidedly closed. Print the time
1016 only if it hasn't already been printed. */
1018 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1019 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
1020 /* If there is an error on the control connection, close it, but
1021 return FTPRETRINT, since there is a possibility that the
1022 whole file was retrieved nevertheless (but that is for
1023 ftp_loop_internal to decide). */
1027 } /* err != FTPOK */
1028 /* If retrieval failed for any reason, return FTPRETRINT, but do not
1029 close socket, since the control connection is still alive. If
1030 there is something wrong with the control connection, it will
1031 become apparent later. */
1032 if (*respline != '2')
1036 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1037 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
1044 /* What now? The data connection was erroneous, whereas the
1045 response says everything is OK. We shall play it safe. */
1049 if (!(cmd & LEAVE_PENDING))
1051 /* Closing the socket is faster than sending 'QUIT' and the
1052 effect is the same. */
1056 /* If it was a listing, and opt.server_response is true,
1058 if (opt.server_response && (con->cmd & DO_LIST))
1060 mkalldirs (con->target);
1061 fp = fopen (con->target, "r");
1063 logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
1067 /* The lines are being read with read_whole_line because of
1068 no-buffering on opt.lfile. */
1069 while ((line = read_whole_line (fp)) != NULL)
1071 logprintf (LOG_ALWAYS, "%s\n", escnonprint (line));
1076 } /* con->cmd & DO_LIST && server_response */
1078 return RETRFINISHED;
1081 /* A one-file FTP loop. This is the part where FTP retrieval is
1082 retried, and retried, and retried, and...
1084 This loop either gets commands from con, or (if ON_YOUR_OWN is
1085 set), makes them up to retrieve the file given by the URL. */
1087 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
1090 wgint restval, len = 0;
1092 const char *tmrate = NULL;
1097 con->target = url_file_name (u);
1099 if (opt.noclobber && file_exists_p (con->target))
1101 logprintf (LOG_VERBOSE,
1102 _("File `%s' already there; not retrieving.\n"), con->target);
1103 /* If the file is there, we suppose it's retrieved OK. */
1107 /* Remove it if it's a link. */
1108 remove_link (con->target);
1109 if (!opt.output_document)
1112 locf = opt.output_document;
1116 if (con->st & ON_YOUR_OWN)
1117 con->st = ON_YOUR_OWN;
1119 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1124 /* Increment the pass counter. */
1126 sleep_between_retrievals (count);
1127 if (con->st & ON_YOUR_OWN)
1130 con->cmd |= (DO_RETR | LEAVE_PENDING);
1131 if (con->csock != -1)
1132 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1134 con->cmd |= (DO_LOGIN | DO_CWD);
1136 else /* not on your own */
1138 if (con->csock != -1)
1139 con->cmd &= ~DO_LOGIN;
1141 con->cmd |= DO_LOGIN;
1142 if (con->st & DONE_CWD)
1143 con->cmd &= ~DO_CWD;
1148 /* Decide whether or not to restart. */
1150 && stat (locf, &st) == 0
1151 && S_ISREG (st.st_mode))
1152 /* When -c is used, continue from on-disk size. (Can't use
1153 hstat.len even if count>1 because we don't want a failed
1154 first attempt to clobber existing data.) */
1155 restval = st.st_size;
1157 restval = len; /* start where the previous run left off */
1161 /* Get the current time string. */
1162 tms = time_str (NULL);
1163 /* Print fetch message, if opt.verbose. */
1166 char *hurl = url_string (u, true);
1170 sprintf (tmp, _("(try:%2d)"), count);
1171 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1172 tms, hurl, tmp, locf);
1174 ws_changetitle (hurl);
1178 /* Send getftp the proper length, if fileinfo was provided. */
1183 err = getftp (u, &len, restval, con);
1185 if (con->csock != -1)
1186 con->st &= ~DONE_CWD;
1188 con->st |= DONE_CWD;
1192 case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1193 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1194 /* Fatal errors, give up. */
1196 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1197 case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1198 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1199 case FOPEN_EXCL_ERR:
1200 printwhat (count, opt.ntry);
1201 /* non-fatal errors */
1202 if (err == FOPEN_EXCL_ERR)
1204 /* Re-determine the file name. */
1205 xfree_null (con->target);
1206 con->target = url_file_name (u);
1211 /* If the control connection was closed, the retrieval
1212 will be considered OK if f->size == len. */
1213 if (!f || len != f->size)
1215 printwhat (count, opt.ntry);
1226 tms = time_str (NULL);
1228 tmrate = retr_rate (len - restval, con->dltime);
1230 /* If we get out of the switch above without continue'ing, we've
1231 successfully downloaded a file. Remember this fact. */
1232 downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1234 if (con->st & ON_YOUR_OWN)
1236 fd_close (con->csock);
1240 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%s]\n\n"),
1241 tms, tmrate, locf, number_to_static_string (len));
1242 if (!opt.verbose && !opt.quiet)
1244 /* Need to hide the password from the URL. The `if' is here
1245 so that we don't do the needless allocation every
1247 char *hurl = url_string (u, true);
1248 logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
1249 tms, hurl, number_to_static_string (len), locf, count);
1253 if ((con->cmd & DO_LIST))
1254 /* This is a directory listing file. */
1256 if (!opt.remove_listing)
1257 /* --dont-remove-listing was specified, so do count this towards the
1258 number of bytes and files downloaded. */
1260 total_downloaded_bytes += len;
1264 /* Deletion of listing files is not controlled by --delete-after, but
1265 by the more specific option --dont-remove-listing, and the code
1266 to do this deletion is in another function. */
1268 else if (!opt.spider)
1269 /* This is not a directory listing file. */
1271 /* Unlike directory listing files, don't pretend normal files weren't
1272 downloaded if they're going to be deleted. People seeding proxies,
1273 for instance, may want to know how many bytes and files they've
1274 downloaded through it. */
1275 total_downloaded_bytes += len;
1278 if (opt.delete_after)
1281 Removing file due to --delete-after in ftp_loop_internal():\n"));
1282 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1284 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1288 /* Restore the original leave-pendingness. */
1290 con->cmd |= LEAVE_PENDING;
1292 con->cmd &= ~LEAVE_PENDING;
1294 } while (!opt.ntry || (count < opt.ntry));
1296 if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1298 fd_close (con->csock);
1304 /* Return the directory listing in a reusable format. The directory
1305 is specifed in u->dir. */
1307 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1310 char *uf; /* url file name */
1311 char *lf; /* list file name */
1312 char *old_target = con->target;
1314 con->st &= ~ON_YOUR_OWN;
1315 con->cmd |= (DO_LIST | LEAVE_PENDING);
1316 con->cmd &= ~DO_RETR;
1318 /* Find the listing file name. We do it by taking the file name of
1319 the URL and replacing the last component with the listing file
1321 uf = url_file_name (u);
1322 lf = file_merge (uf, LIST_FILENAME);
1324 DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
1327 err = ftp_loop_internal (u, NULL, con);
1328 con->target = old_target;
1331 *f = ftp_parse_ls (lf, con->rs);
1334 if (opt.remove_listing)
1337 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1339 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), lf);
1342 con->cmd &= ~DO_LIST;
1346 static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
1347 static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
1348 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
1349 static void freefileinfo (struct fileinfo *f);
1351 /* Retrieve a list of files given in struct fileinfo linked list. If
1352 a file is a symbolic link, do not retrieve it, but rather try to
1353 set up a similar link on the local disk, if the symlinks are
1356 If opt.recursive is set, after all files have been retrieved,
1357 ftp_retrieve_dirs will be called to retrieve the directories. */
1359 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1361 static int depth = 0;
1363 struct fileinfo *orig;
1368 /* Increase the depth. */
1370 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1372 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1373 depth, opt.reclevel));
1381 con->st &= ~ON_YOUR_OWN;
1382 if (!(con->st & DONE_CWD))
1385 con->cmd &= ~DO_CWD;
1386 con->cmd |= (DO_RETR | LEAVE_PENDING);
1389 con->cmd |= DO_LOGIN;
1391 con->cmd &= ~DO_LOGIN;
1393 err = RETROK; /* in case it's not used */
1397 char *old_target, *ofile;
1399 if (opt.quota && total_downloaded_bytes > opt.quota)
1404 old_target = con->target;
1406 ofile = xstrdup (u->file);
1407 url_set_file (u, f->name);
1409 con->target = url_file_name (u);
1413 if (opt.timestamping && f->type == FT_PLAINFILE)
1416 /* If conversion of HTML files retrieved via FTP is ever implemented,
1417 we'll need to stat() <file>.orig here when -K has been specified.
1418 I'm not implementing it now since files on an FTP server are much
1419 more likely than files on an HTTP server to legitimately have a
1421 if (!stat (con->target, &st))
1425 /* Else, get it from the file. */
1426 local_size = st.st_size;
1429 /* Modification time granularity is 2 seconds for Windows, so
1430 increase local time by 1 second for later comparison. */
1433 /* Compare file sizes only for servers that tell us correct
1434 values. Assumme sizes being equal for servers that lie
1436 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1437 eq_size = cor_val ? (local_size == f->size) : true;
1438 if (f->tstamp <= tml && eq_size)
1440 /* Remote file is older, file sizes can be compared and
1442 logprintf (LOG_VERBOSE, _("\
1443 Remote file no newer than local file `%s' -- not retrieving.\n"), con->target);
1448 /* Remote file is newer or sizes cannot be matched */
1449 logprintf (LOG_VERBOSE, _("\
1450 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1455 /* Sizes do not match */
1456 logprintf (LOG_VERBOSE, _("\
1457 The sizes do not match (local %s) -- retrieving.\n\n"),
1458 number_to_static_string (local_size));
1461 } /* opt.timestamping && f->type == FT_PLAINFILE */
1465 /* If opt.retr_symlinks is defined, we treat symlinks as
1466 if they were normal files. There is currently no way
1467 to distinguish whether they might be directories, and
1469 if (!opt.retr_symlinks)
1473 logputs (LOG_NOTQUIET,
1474 _("Invalid name of the symlink, skipping.\n"));
1478 /* Check whether we already have the correct
1480 int rc = lstat (con->target, &st);
1483 size_t len = strlen (f->linkto) + 1;
1484 if (S_ISLNK (st.st_mode))
1486 char *link_target = (char *)alloca (len);
1487 size_t n = readlink (con->target, link_target, len);
1489 && (memcmp (link_target, f->linkto, n) == 0))
1491 logprintf (LOG_VERBOSE, _("\
1492 Already have correct symlink %s -> %s\n\n"),
1493 con->target, escnonprint (f->linkto));
1499 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1500 con->target, escnonprint (f->linkto));
1501 /* Unlink before creating symlink! */
1502 unlink (con->target);
1503 if (symlink (f->linkto, con->target) == -1)
1504 logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno));
1505 logputs (LOG_VERBOSE, "\n");
1506 } /* have f->linkto */
1507 #else /* not HAVE_SYMLINK */
1508 logprintf (LOG_NOTQUIET,
1509 _("Symlinks not supported, skipping symlink `%s'.\n"),
1511 #endif /* not HAVE_SYMLINK */
1513 else /* opt.retr_symlinks */
1516 err = ftp_loop_internal (u, f, con);
1517 } /* opt.retr_symlinks */
1521 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1522 escnonprint (f->name));
1525 /* Call the retrieve loop. */
1527 err = ftp_loop_internal (u, f, con);
1530 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1531 escnonprint (f->name));
1535 /* Set the time-stamp information to the local file. Symlinks
1536 are not to be stamped because it sets the stamp on the
1538 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1541 && file_exists_p (con->target))
1543 /* #### This code repeats in http.c and ftp.c. Move it to a
1545 const char *fl = NULL;
1546 if (opt.output_document)
1548 if (output_stream_regular)
1549 fl = opt.output_document;
1554 touch (fl, f->tstamp);
1556 else if (f->tstamp == -1)
1557 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), con->target);
1559 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1561 if (opt.preserve_perm)
1562 chmod (con->target, f->perms);
1565 DEBUGP (("Unrecognized permissions for %s.\n", con->target));
1567 xfree (con->target);
1568 con->target = old_target;
1570 url_set_file (u, ofile);
1573 /* Break on fatals. */
1574 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1576 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1580 /* We do not want to call ftp_retrieve_dirs here */
1581 if (opt.recursive &&
1582 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1583 err = ftp_retrieve_dirs (u, orig, con);
1584 else if (opt.recursive)
1585 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1586 depth, opt.reclevel));
1591 /* Retrieve the directories given in a file list. This function works
1592 by simply going through the linked list and calling
1593 ftp_retrieve_glob on each directory entry. The function knows
1594 about excluded directories. */
1596 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
1598 char *container = NULL;
1599 int container_size = 0;
1601 for (; f; f = f->next)
1604 char *odir, *newdir;
1606 if (opt.quota && total_downloaded_bytes > opt.quota)
1608 if (f->type != FT_DIRECTORY)
1611 /* Allocate u->dir off stack, but reallocate only if a larger
1612 string is needed. It's a pity there's no "realloca" for an
1613 item on the bottom of the stack. */
1614 size = strlen (u->dir) + 1 + strlen (f->name) + 1;
1615 if (size > container_size)
1616 container = (char *)alloca (size);
1621 || (*odir == '/' && *(odir + 1) == '\0'))
1622 /* If ODIR is empty or just "/", simply append f->name to
1623 ODIR. (In the former case, to preserve u->dir being
1624 relative; in the latter case, to avoid double slash.) */
1625 sprintf (newdir, "%s%s", odir, f->name);
1627 /* Else, use a separator. */
1628 sprintf (newdir, "%s/%s", odir, f->name);
1630 DEBUGP (("Composing new CWD relative to the initial directory.\n"));
1631 DEBUGP ((" odir = '%s'\n f->name = '%s'\n newdir = '%s'\n\n",
1632 odir, f->name, newdir));
1633 if (!accdir (newdir, ALLABS))
1635 logprintf (LOG_VERBOSE, _("\
1636 Not descending to `%s' as it is excluded/not-included.\n"),
1637 escnonprint (newdir));
1641 con->st &= ~DONE_CWD;
1643 odir = xstrdup (u->dir); /* because url_set_dir will free
1645 url_set_dir (u, newdir);
1646 ftp_retrieve_glob (u, con, GLOB_GETALL);
1647 url_set_dir (u, odir);
1650 /* Set the time-stamp? */
1653 if (opt.quota && total_downloaded_bytes > opt.quota)
1659 /* Return true if S has a leading '/' or contains '../' */
1661 has_insecure_name_p (const char *s)
1666 if (strstr (s, "../") != 0)
1672 /* A near-top-level function to retrieve the files in a directory.
1673 The function calls ftp_get_listing, to get a linked list of files.
1674 Then it weeds out the file names that do not match the pattern.
1675 ftp_retrieve_list is called with this updated list as an argument.
1677 If the argument ACTION is GLOB_GETONE, just download the file (but
1678 first get the listing, so that the time-stamp is heeded); if it's
1679 GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
1682 ftp_retrieve_glob (struct url *u, ccon *con, int action)
1684 struct fileinfo *f, *start;
1687 con->cmd |= LEAVE_PENDING;
1689 res = ftp_get_listing (u, con, &start);
1692 /* First: weed out that do not conform the global rules given in
1693 opt.accepts and opt.rejects. */
1694 if (opt.accepts || opt.rejects)
1699 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1701 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
1702 escnonprint (f->name));
1703 f = delelement (f, &start);
1709 /* Remove all files with possible harmful names */
1713 if (has_insecure_name_p (f->name))
1715 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
1716 escnonprint (f->name));
1717 f = delelement (f, &start);
1722 /* Now weed out the files that do not match our globbing pattern.
1723 If we are dealing with a globbing pattern, that is. */
1724 if (*u->file && (action == GLOB_GLOBALL || action == GLOB_GETONE))
1731 matchres = fnmatch (u->file, f->name, 0);
1734 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
1738 if (matchres == FNM_NOMATCH)
1739 f = delelement (f, &start); /* delete the element from the list */
1741 f = f->next; /* leave the element in the list */
1745 freefileinfo (start);
1746 return RETRBADPATTERN;
1751 /* Just get everything. */
1752 ftp_retrieve_list (u, start, con);
1756 if (action == GLOB_GLOBALL)
1759 /* #### This message SUCKS. We should see what was the
1760 reason that nothing was retrieved. */
1761 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"),
1762 escnonprint (u->file));
1764 else /* GLOB_GETONE or GLOB_GETALL */
1766 /* Let's try retrieving it anyway. */
1767 con->st |= ON_YOUR_OWN;
1768 res = ftp_loop_internal (u, NULL, con);
1772 freefileinfo (start);
1773 if (opt.quota && total_downloaded_bytes > opt.quota)
1776 /* #### Should we return `res' here? */
1780 /* The wrapper that calls an appropriate routine according to contents
1781 of URL. Inherently, its capabilities are limited on what can be
1782 encoded into a URL. */
1784 ftp_loop (struct url *u, int *dt, struct url *proxy)
1786 ccon con; /* FTP connection */
1794 con.st = ON_YOUR_OWN;
1799 /* If the file name is empty, the user probably wants a directory
1800 index. We'll provide one, properly HTML-ized. Unless
1801 opt.htmlify is 0, of course. :-) */
1802 if (!*u->file && !opt.recursive)
1805 res = ftp_get_listing (u, &con, &f);
1809 if (opt.htmlify && !opt.spider)
1811 char *filename = (opt.output_document
1812 ? xstrdup (opt.output_document)
1813 : (con.target ? xstrdup (con.target)
1814 : url_file_name (u)));
1815 res = ftp_index (filename, u, f);
1816 if (res == FTPOK && opt.verbose)
1818 if (!opt.output_document)
1822 if (stat (filename, &st) == 0)
1826 logprintf (LOG_NOTQUIET,
1827 _("Wrote HTML-ized index to `%s' [%s].\n"),
1828 filename, number_to_static_string (sz));
1831 logprintf (LOG_NOTQUIET,
1832 _("Wrote HTML-ized index to `%s'.\n"),
1842 bool ispattern = false;
1845 /* Treat the URL as a pattern if the file name part of the
1846 URL path contains wildcards. (Don't check for u->file
1847 because it is unescaped and therefore doesn't leave users
1848 the option to escape literal '*' as %2A.) */
1849 char *file_part = strrchr (u->path, '/');
1851 file_part = u->path;
1852 ispattern = has_wildcards_p (file_part);
1854 if (ispattern || opt.recursive || opt.timestamping)
1856 /* ftp_retrieve_glob is a catch-all function that gets called
1857 if we need globbing, time-stamping or recursion. Its
1858 third argument is just what we really need. */
1859 res = ftp_retrieve_glob (u, &con,
1860 ispattern ? GLOB_GLOBALL : GLOB_GETONE);
1863 res = ftp_loop_internal (u, NULL, &con);
1869 /* If a connection was left, quench it. */
1870 if (con.csock != -1)
1871 fd_close (con.csock);
1872 xfree_null (con.id);
1874 xfree_null (con.target);
1879 /* Delete an element from the fileinfo linked list. Returns the
1880 address of the next element, or NULL if the list is exhausted. It
1881 can modify the start of the list. */
1882 static struct fileinfo *
1883 delelement (struct fileinfo *f, struct fileinfo **start)
1885 struct fileinfo *prev = f->prev;
1886 struct fileinfo *next = f->next;
1889 xfree_null (f->linkto);
1901 /* Free the fileinfo linked list of files. */
1903 freefileinfo (struct fileinfo *f)
1907 struct fileinfo *next = f->next;