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. */
43 #include <sys/types.h>
55 #include "convert.h" /* for downloaded_file */
56 #include "recur.h" /* for INFINITE_RECURSION */
62 extern LARGE_INT total_downloaded_bytes;
64 /* File where the "ls -al" listing will be saved. */
65 #define LIST_FILENAME ".listing"
67 extern char ftp_last_respline[];
71 int st; /* connection status */
72 int cmd; /* command code */
73 int csock; /* control connection socket */
74 double dltime; /* time of the download in msecs */
75 enum stype rs; /* remote system reported by ftp server */
76 char *id; /* initial directory */
77 char *target; /* target file name */
78 struct url *proxy; /* FTWK-style proxy */
82 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
83 the string S, and return the number converted to long, if found, 0
86 ftp_expected_bytes (const char *s)
92 while (*s && *s != '(')
96 for (++s; *s && ISSPACE (*s); s++);
104 res = (*s - '0') + 10 * res;
107 while (*s && ISDIGIT (*s));
110 while (*s && ISSPACE (*s))
114 if (TOLOWER (*s) != 'b')
116 if (strncasecmp (s, "byte", 4))
126 * This function sets up a passive data connection with the FTP server.
127 * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv.
130 ftp_do_pasv (int csock, ip_address *addr, int *port)
134 /* We need to determine the address family and need to call
135 getpeername, so while we're at it, store the address to ADDR.
136 ftp_pasv and ftp_lpsv can simply override it. */
137 if (!socket_ip_address (csock, addr, ENDPOINT_PEER))
140 /* If our control connection is over IPv6, then we first try EPSV and then
141 * LPSV if the former is not supported. If the control connection is over
142 * IPv4, we simply issue the good old PASV request. */
146 if (!opt.server_response)
147 logputs (LOG_VERBOSE, "==> PASV ... ");
148 err = ftp_pasv (csock, addr, port);
151 if (!opt.server_response)
152 logputs (LOG_VERBOSE, "==> EPSV ... ");
153 err = ftp_epsv (csock, addr, port);
155 /* If EPSV is not supported try LPSV */
156 if (err == FTPNOPASV)
158 if (!opt.server_response)
159 logputs (LOG_VERBOSE, "==> LPSV ... ");
160 err = ftp_lpsv (csock, addr, port);
171 * This function sets up an active data connection with the FTP server.
172 * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port.
175 ftp_do_port (int csock, int *local_sock)
180 if (!socket_ip_address (csock, &cip, ENDPOINT_PEER))
183 /* If our control connection is over IPv6, then we first try EPRT and then
184 * LPRT if the former is not supported. If the control connection is over
185 * IPv4, we simply issue the good old PORT request. */
189 if (!opt.server_response)
190 logputs (LOG_VERBOSE, "==> PORT ... ");
191 err = ftp_port (csock, local_sock);
194 if (!opt.server_response)
195 logputs (LOG_VERBOSE, "==> EPRT ... ");
196 err = ftp_eprt (csock, local_sock);
198 /* If EPRT is not supported try LPRT */
199 if (err == FTPPORTERR)
201 if (!opt.server_response)
202 logputs (LOG_VERBOSE, "==> LPRT ... ");
203 err = ftp_lprt (csock, local_sock);
214 ftp_do_pasv (int csock, ip_address *addr, int *port)
216 if (!opt.server_response)
217 logputs (LOG_VERBOSE, "==> PASV ... ");
218 return ftp_pasv (csock, addr, port);
222 ftp_do_port (int csock, int *local_sock)
224 if (!opt.server_response)
225 logputs (LOG_VERBOSE, "==> PORT ... ");
226 return ftp_port (csock, local_sock);
230 /* Retrieves a file with denoted parameters through opening an FTP
231 connection to the server. It always closes the data connection,
232 and closes the control connection in case of error. */
234 getftp (struct url *u, long *len, long restval, ccon *con)
236 int csock, dtsock, local_sock, res;
239 char *user, *passwd, *respline;
242 int pasv_mode_open = 0;
243 long expected_bytes = 0L;
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_acc;
259 passwd = passwd ? passwd : opt.ftp_pass;
260 assert (user && passwd);
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 = xmalloc (strlen (user) + 1 + strlen (u->host) + 1);
279 sprintf (logname, "%s@%s", user, u->host);
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 ... "), 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"));
319 logputs (LOG_VERBOSE, "\n");
320 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
326 logputs (LOG_VERBOSE, "\n");
327 logputs (LOG_NOTQUIET,
328 _("Write failed, closing control connection.\n"));
334 logputs (LOG_VERBOSE, "\n");
335 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
338 return FTPLOGREFUSED;
341 logputs (LOG_VERBOSE, "\n");
342 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
348 if (!opt.server_response)
349 logputs (LOG_VERBOSE, _("Logged in!\n"));
356 /* Third: Get the system type */
357 if (!opt.server_response)
358 logprintf (LOG_VERBOSE, "==> SYST ... ");
359 err = ftp_syst (csock, &con->rs);
364 logputs (LOG_VERBOSE, "\n");
365 logputs (LOG_NOTQUIET, _("\
366 Error in server response, closing control connection.\n"));
372 logputs (LOG_VERBOSE, "\n");
373 logputs (LOG_NOTQUIET,
374 _("Server error, can't determine system type.\n"));
377 /* Everything is OK. */
383 if (!opt.server_response && err != FTPSRVERR)
384 logputs (LOG_VERBOSE, _("done. "));
386 /* Fourth: Find the initial ftp directory */
388 if (!opt.server_response)
389 logprintf (LOG_VERBOSE, "==> PWD ... ");
390 err = ftp_pwd (csock, &con->id);
395 logputs (LOG_VERBOSE, "\n");
396 logputs (LOG_NOTQUIET, _("\
397 Error in server response, closing control connection.\n"));
403 /* PWD unsupported -- assume "/". */
404 xfree_null (con->id);
405 con->id = xstrdup ("/");
408 /* Everything is OK. */
414 /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
415 Convert it to "/INITIAL/FOLDER" */
416 if (con->rs == ST_VMS)
418 char *path = strchr (con->id, '[');
419 char *pathend = path ? strchr (path + 1, ']') : NULL;
420 if (!path || !pathend)
421 DEBUGP (("Initial VMS directory not in the form [...]!\n"));
424 char *idir = con->id;
425 DEBUGP (("Preprocessing the initial VMS directory\n"));
426 DEBUGP ((" old = '%s'\n", con->id));
427 /* We do the conversion in-place by copying the stuff
428 between [ and ] to the beginning, and changing dots
429 to slashes at the same time. */
431 for (++path; path < pathend; path++, idir++)
432 *idir = *path == '.' ? '/' : *path;
434 DEBUGP ((" new = '%s'\n\n", con->id));
437 if (!opt.server_response)
438 logputs (LOG_VERBOSE, _("done.\n"));
440 /* Fifth: Set the FTP type. */
441 type_char = ftp_process_type (u->params);
442 if (!opt.server_response)
443 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);
444 err = ftp_type (csock, type_char);
445 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
449 logputs (LOG_VERBOSE, "\n");
450 logputs (LOG_NOTQUIET, _("\
451 Error in server response, closing control connection.\n"));
457 logputs (LOG_VERBOSE, "\n");
458 logputs (LOG_NOTQUIET,
459 _("Write failed, closing control connection.\n"));
465 logputs (LOG_VERBOSE, "\n");
466 logprintf (LOG_NOTQUIET,
467 _("Unknown type `%c', closing control connection.\n"),
473 /* Everything is OK. */
479 if (!opt.server_response)
480 logputs (LOG_VERBOSE, _("done. "));
486 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
489 char *target = u->dir;
491 DEBUGP (("changing working directory\n"));
493 /* Change working directory. To change to a non-absolute
494 Unix directory, we need to prepend initial directory
495 (con->id) to it. Absolute directories "just work".
497 A relative directory is one that does not begin with '/'
498 and, on non-Unix OS'es, one that doesn't begin with
501 This is not done for OS400, which doesn't use
502 "/"-delimited directories, nor does it support directory
503 hierarchies. "CWD foo" followed by "CWD bar" leaves us
504 in "bar", not in "foo/bar", as would be customary
508 && !(con->rs != ST_UNIX
509 && ISALPHA (target[0])
511 && con->rs != ST_OS400)
513 int idlen = strlen (con->id);
516 /* Strip trailing slash(es) from con->id. */
517 while (idlen > 0 && con->id[idlen - 1] == '/')
519 p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
520 memcpy (p, con->id, idlen);
525 DEBUGP (("Prepended initial PWD to relative path:\n"));
526 DEBUGP ((" pwd: '%s'\n old: '%s'\n new: '%s'\n",
527 con->id, target, ntarget));
531 /* If the FTP host runs VMS, we will have to convert the absolute
532 directory path in UNIX notation to absolute directory path in
533 VMS notation as VMS FTP servers do not like UNIX notation of
534 absolute paths. "VMS notation" is [dir.subdir.subsubdir]. */
536 if (con->rs == ST_VMS)
539 char *ntarget = (char *)alloca (strlen (target) + 2);
540 /* We use a converted initial dir, so directories in
541 TARGET will be separated with slashes, something like
542 "/INITIAL/FOLDER/DIR/SUBDIR". Convert that to
543 "[INITIAL.FOLDER.DIR.SUBDIR]". */
544 strcpy (ntarget, target);
545 assert (*ntarget == '/');
547 for (tmpp = ntarget + 1; *tmpp; tmpp++)
552 DEBUGP (("Changed file name to VMS syntax:\n"));
553 DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget));
557 if (!opt.server_response)
558 logprintf (LOG_VERBOSE, "==> CWD %s ... ", target);
559 err = ftp_cwd (csock, target);
560 /* FTPRERR, WRITEFAILED, FTPNSFOD */
564 logputs (LOG_VERBOSE, "\n");
565 logputs (LOG_NOTQUIET, _("\
566 Error in server response, closing control connection.\n"));
572 logputs (LOG_VERBOSE, "\n");
573 logputs (LOG_NOTQUIET,
574 _("Write failed, closing control connection.\n"));
580 logputs (LOG_VERBOSE, "\n");
581 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
594 if (!opt.server_response)
595 logputs (LOG_VERBOSE, _("done.\n"));
598 else /* do not CWD */
599 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
601 if ((cmd & DO_RETR) && restval && *len == 0)
605 if (!opt.server_response)
606 logprintf (LOG_VERBOSE, "==> SIZE %s ... ", u->file);
609 err = ftp_size (csock, u->file, len);
615 logputs (LOG_VERBOSE, "\n");
616 logputs (LOG_NOTQUIET, _("\
617 Error in server response, closing control connection.\n"));
623 /* Everything is OK. */
629 if (!opt.server_response)
630 logputs (LOG_VERBOSE, _("done.\n"));
633 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
634 if (cmd & (DO_LIST | DO_RETR))
636 if (opt.ftp_pasv > 0)
638 ip_address passive_addr;
640 err = ftp_do_pasv (csock, &passive_addr, &passive_port);
641 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
645 logputs (LOG_VERBOSE, "\n");
646 logputs (LOG_NOTQUIET, _("\
647 Error in server response, closing control connection.\n"));
653 logputs (LOG_VERBOSE, "\n");
654 logputs (LOG_NOTQUIET,
655 _("Write failed, closing control connection.\n"));
661 logputs (LOG_VERBOSE, "\n");
662 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
665 logputs (LOG_VERBOSE, "\n");
666 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
677 DEBUGP (("trying to connect to %s port %d\n",
678 pretty_print_address (&passive_addr),
680 dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
683 int save_errno = errno;
686 logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
687 pretty_print_address (&passive_addr), passive_port,
688 strerror (save_errno));
689 return (retryable_socket_connect_error (save_errno)
690 ? CONERROR : CONIMPOSSIBLE);
693 pasv_mode_open = 1; /* Flag to avoid accept port */
694 if (!opt.server_response)
695 logputs (LOG_VERBOSE, _("done. "));
699 if (!pasv_mode_open) /* Try to use a port command if PASV failed */
701 err = ftp_do_port (csock, &local_sock);
702 /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,
707 logputs (LOG_VERBOSE, "\n");
708 logputs (LOG_NOTQUIET, _("\
709 Error in server response, closing control connection.\n"));
713 fd_close (local_sock);
717 logputs (LOG_VERBOSE, "\n");
718 logputs (LOG_NOTQUIET,
719 _("Write failed, closing control connection.\n"));
723 fd_close (local_sock);
727 logputs (LOG_VERBOSE, "\n");
728 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
732 fd_close (local_sock);
736 logputs (LOG_VERBOSE, "\n");
737 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
743 logputs (LOG_VERBOSE, "\n");
744 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
748 fd_close (local_sock);
758 if (!opt.server_response)
759 logputs (LOG_VERBOSE, _("done. "));
761 } /* cmd & (DO_LIST | DO_RETR) */
763 /* Restart if needed. */
764 if (restval && (cmd & DO_RETR))
766 if (!opt.server_response)
767 logprintf (LOG_VERBOSE, "==> REST %ld ... ", restval);
768 err = ftp_rest (csock, restval);
770 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
774 logputs (LOG_VERBOSE, "\n");
775 logputs (LOG_NOTQUIET, _("\
776 Error in server response, closing control connection.\n"));
780 fd_close (local_sock);
784 logputs (LOG_VERBOSE, "\n");
785 logputs (LOG_NOTQUIET,
786 _("Write failed, closing control connection.\n"));
790 fd_close (local_sock);
794 /* If `-c' is specified and the file already existed when
795 Wget was started, it would be a bad idea for us to start
796 downloading it from scratch, effectively truncating it. */
797 if (opt.always_rest && (cmd & NO_TRUNCATE))
799 logprintf (LOG_NOTQUIET,
800 _("\nREST failed; will not truncate `%s'.\n"),
805 fd_close (local_sock);
806 return CONTNOTSUPPORTED;
808 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
818 if (err != FTPRESTFAIL && !opt.server_response)
819 logputs (LOG_VERBOSE, _("done. "));
820 } /* restval && cmd & DO_RETR */
824 /* If we're in spider mode, don't really retrieve anything. The
825 fact that we got to this point should be proof enough that
826 the file exists, vaguely akin to HTTP's concept of a "HEAD"
833 fd_close (local_sock);
839 if (!opt.server_response)
842 logputs (LOG_VERBOSE, "\n");
843 logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
847 err = ftp_retr (csock, u->file);
848 /* FTPRERR, WRITEFAILED, FTPNSFOD */
852 logputs (LOG_VERBOSE, "\n");
853 logputs (LOG_NOTQUIET, _("\
854 Error in server response, closing control connection.\n"));
858 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);
872 logputs (LOG_VERBOSE, "\n");
873 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
875 fd_close (local_sock);
886 if (!opt.server_response)
887 logputs (LOG_VERBOSE, _("done.\n"));
888 expected_bytes = ftp_expected_bytes (ftp_last_respline);
893 if (!opt.server_response)
894 logputs (LOG_VERBOSE, "==> LIST ... ");
895 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
896 without arguments is better than `LIST .'; confirmed by
898 err = ftp_list (csock, NULL);
899 /* FTPRERR, WRITEFAILED */
903 logputs (LOG_VERBOSE, "\n");
904 logputs (LOG_NOTQUIET, _("\
905 Error in server response, closing control connection.\n"));
909 fd_close (local_sock);
913 logputs (LOG_VERBOSE, "\n");
914 logputs (LOG_NOTQUIET,
915 _("Write failed, closing control connection.\n"));
919 fd_close (local_sock);
923 logputs (LOG_VERBOSE, "\n");
924 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
927 fd_close (local_sock);
937 if (!opt.server_response)
938 logputs (LOG_VERBOSE, _("done.\n"));
939 expected_bytes = ftp_expected_bytes (ftp_last_respline);
940 } /* cmd & DO_LIST */
942 if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
945 /* Some FTP servers return the total length of file after REST
946 command, others just return the remaining size. */
947 if (*len && restval && expected_bytes
948 && (expected_bytes == *len - restval))
950 DEBUGP (("Lying FTP server found, adjusting.\n"));
951 expected_bytes = *len;
954 /* If no transmission was required, then everything is OK. */
955 if (!pasv_mode_open) /* we are not using pasive mode so we need
958 /* Wait for the server to connect to the address we're waiting
960 dtsock = accept_connection (local_sock);
963 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
968 /* Open the file -- if opt.dfp is set, use it instead. */
969 if (!opt.dfp || con->cmd & DO_LIST)
971 mkalldirs (con->target);
973 rotate_backups (con->target);
974 /* #### Is this correct? */
975 chmod (con->target, 0600);
977 fp = fopen (con->target, restval ? "ab" : "wb");
980 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
984 fd_close (local_sock);
990 extern int global_download_count;
993 /* Rewind the output document if the download starts over and if
994 this is the first download. See gethttp() for a longer
996 if (!restval && global_download_count == 0 && opt.dfp != stdout)
998 /* This will silently fail for streams that don't correspond
999 to regular files, but that's OK. */
1001 /* ftruncate is needed because opt.dfp is opened in append
1002 mode if opt.always_rest is set. */
1003 ftruncate (fileno (fp), 0);
1010 logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
1012 logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
1013 logputs (LOG_VERBOSE, "\n");
1014 expected_bytes = *len; /* for get_contents/show_progress */
1016 else if (expected_bytes)
1018 logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
1020 logprintf (LOG_VERBOSE, _(" [%s to go]"),
1021 legible (expected_bytes - restval));
1022 logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
1025 /* Get the contents of the document. */
1026 res = fd_read_body (dtsock, fp,
1027 expected_bytes ? expected_bytes - restval : 0,
1028 0, restval, len, &con->dltime);
1031 tms = time_str (NULL);
1032 tmrate = retr_rate (*len - restval, con->dltime, 0);
1033 /* Close data connection socket. */
1035 fd_close (local_sock);
1036 /* Close the local file. */
1038 /* Close or flush the file. We have to be careful to check for
1039 error here. Checking the result of fwrite() is not enough --
1040 errors could go unnoticed! */
1042 if (!opt.dfp || con->cmd & DO_LIST)
1043 flush_res = fclose (fp);
1045 flush_res = fflush (fp);
1046 if (flush_res == EOF)
1050 /* If get_contents couldn't write to fp, bail out. */
1053 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
1054 con->target, strerror (errno));
1061 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
1062 tms, tmrate, strerror (errno));
1063 if (opt.server_response)
1064 logputs (LOG_ALWAYS, "\n");
1067 /* Get the server to tell us if everything is retrieved. */
1068 err = ftp_response (csock, &respline);
1072 /* The control connection is decidedly closed. Print the time
1073 only if it hasn't already been printed. */
1075 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1076 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
1077 /* If there is an error on the control connection, close it, but
1078 return FTPRETRINT, since there is a possibility that the
1079 whole file was retrieved nevertheless (but that is for
1080 ftp_loop_internal to decide). */
1084 } /* err != FTPOK */
1085 /* If retrieval failed for any reason, return FTPRETRINT, but do not
1086 close socket, since the control connection is still alive. If
1087 there is something wrong with the control connection, it will
1088 become apparent later. */
1089 if (*respline != '2')
1093 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1094 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
1101 /* What now? The data connection was erroneous, whereas the
1102 response says everything is OK. We shall play it safe. */
1106 if (!(cmd & LEAVE_PENDING))
1108 /* I should probably send 'QUIT' and check for a reply, but this
1109 is faster. #### Is it OK, though? */
1113 /* If it was a listing, and opt.server_response is true,
1115 if (opt.server_response && (con->cmd & DO_LIST))
1117 mkalldirs (con->target);
1118 fp = fopen (con->target, "r");
1120 logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
1124 /* The lines are being read with read_whole_line because of
1125 no-buffering on opt.lfile. */
1126 while ((line = read_whole_line (fp)))
1128 logprintf (LOG_ALWAYS, "%s\n", line);
1133 } /* con->cmd & DO_LIST && server_response */
1135 return RETRFINISHED;
1138 /* A one-file FTP loop. This is the part where FTP retrieval is
1139 retried, and retried, and retried, and...
1141 This loop either gets commands from con, or (if ON_YOUR_OWN is
1142 set), makes them up to retrieve the file given by the URL. */
1144 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
1149 char *tmrate = NULL;
1154 con->target = url_file_name (u);
1156 if (opt.noclobber && file_exists_p (con->target))
1158 logprintf (LOG_VERBOSE,
1159 _("File `%s' already there, not retrieving.\n"), con->target);
1160 /* If the file is there, we suppose it's retrieved OK. */
1164 /* Remove it if it's a link. */
1165 remove_link (con->target);
1166 if (!opt.output_document)
1169 locf = opt.output_document;
1173 if (con->st & ON_YOUR_OWN)
1174 con->st = ON_YOUR_OWN;
1176 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1181 /* Increment the pass counter. */
1183 sleep_between_retrievals (count);
1184 if (con->st & ON_YOUR_OWN)
1187 con->cmd |= (DO_RETR | LEAVE_PENDING);
1188 if (con->csock != -1)
1189 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1191 con->cmd |= (DO_LOGIN | DO_CWD);
1193 else /* not on your own */
1195 if (con->csock != -1)
1196 con->cmd &= ~DO_LOGIN;
1198 con->cmd |= DO_LOGIN;
1199 if (con->st & DONE_CWD)
1200 con->cmd &= ~DO_CWD;
1205 /* Assume no restarting. */
1207 if ((count > 1 || opt.always_rest)
1208 && !(con->cmd & DO_LIST)
1209 && file_exists_p (locf))
1210 if (stat (locf, &st) == 0 && S_ISREG (st.st_mode))
1211 restval = st.st_size;
1213 /* In `-c' is used, check whether the file we're writing to
1214 exists and is of non-zero length. If so, we'll refuse to
1215 truncate it if the server doesn't support continued
1217 if (opt.always_rest && restval > 0)
1218 con->cmd |= NO_TRUNCATE;
1220 /* Get the current time string. */
1221 tms = time_str (NULL);
1222 /* Print fetch message, if opt.verbose. */
1225 char *hurl = url_string (u, 1);
1229 sprintf (tmp, _("(try:%2d)"), count);
1230 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1231 tms, hurl, tmp, locf);
1233 ws_changetitle (hurl, 1);
1237 /* Send getftp the proper length, if fileinfo was provided. */
1242 err = getftp (u, &len, restval, con);
1244 if (con->csock != -1)
1245 con->st &= ~DONE_CWD;
1247 con->st |= DONE_CWD;
1251 case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1252 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1253 /* Fatal errors, give up. */
1256 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1257 case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1258 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1259 printwhat (count, opt.ntry);
1260 /* non-fatal errors */
1264 /* If the control connection was closed, the retrieval
1265 will be considered OK if f->size == len. */
1266 if (!f || len != f->size)
1268 printwhat (count, opt.ntry);
1280 tms = time_str (NULL);
1282 tmrate = retr_rate (len - restval, con->dltime, 0);
1284 /* If we get out of the switch above without continue'ing, we've
1285 successfully downloaded a file. Remember this fact. */
1286 downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1288 if (con->st & ON_YOUR_OWN)
1290 fd_close (con->csock);
1294 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
1295 tms, tmrate, locf, len);
1296 if (!opt.verbose && !opt.quiet)
1298 /* Need to hide the password from the URL. The `if' is here
1299 so that we don't do the needless allocation every
1301 char *hurl = url_string (u, 1);
1302 logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
1303 tms, hurl, len, locf, count);
1307 if ((con->cmd & DO_LIST))
1308 /* This is a directory listing file. */
1310 if (!opt.remove_listing)
1311 /* --dont-remove-listing was specified, so do count this towards the
1312 number of bytes and files downloaded. */
1314 total_downloaded_bytes += len;
1318 /* Deletion of listing files is not controlled by --delete-after, but
1319 by the more specific option --dont-remove-listing, and the code
1320 to do this deletion is in another function. */
1322 else if (!opt.spider)
1323 /* This is not a directory listing file. */
1325 /* Unlike directory listing files, don't pretend normal files weren't
1326 downloaded if they're going to be deleted. People seeding proxies,
1327 for instance, may want to know how many bytes and files they've
1328 downloaded through it. */
1329 total_downloaded_bytes += len;
1332 if (opt.delete_after)
1334 DEBUGP (("Removing file due to --delete-after in"
1335 " ftp_loop_internal():\n"));
1336 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1338 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1342 /* Restore the original leave-pendingness. */
1344 con->cmd |= LEAVE_PENDING;
1346 con->cmd &= ~LEAVE_PENDING;
1348 } while (!opt.ntry || (count < opt.ntry));
1350 if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1352 fd_close (con->csock);
1358 /* Return the directory listing in a reusable format. The directory
1359 is specifed in u->dir. */
1361 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1364 char *uf; /* url file name */
1365 char *lf; /* list file name */
1366 char *old_target = con->target;
1368 con->st &= ~ON_YOUR_OWN;
1369 con->cmd |= (DO_LIST | LEAVE_PENDING);
1370 con->cmd &= ~DO_RETR;
1372 /* Find the listing file name. We do it by taking the file name of
1373 the URL and replacing the last component with the listing file
1375 uf = url_file_name (u);
1376 lf = file_merge (uf, LIST_FILENAME);
1378 DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
1381 err = ftp_loop_internal (u, NULL, con);
1382 con->target = old_target;
1385 *f = ftp_parse_ls (lf, con->rs);
1388 if (opt.remove_listing)
1391 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1393 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), lf);
1396 con->cmd &= ~DO_LIST;
1400 static uerr_t ftp_retrieve_dirs PARAMS ((struct url *, struct fileinfo *,
1402 static uerr_t ftp_retrieve_glob PARAMS ((struct url *, ccon *, int));
1403 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1404 struct fileinfo **));
1405 static void freefileinfo PARAMS ((struct fileinfo *f));
1407 /* Retrieve a list of files given in struct fileinfo linked list. If
1408 a file is a symbolic link, do not retrieve it, but rather try to
1409 set up a similar link on the local disk, if the symlinks are
1412 If opt.recursive is set, after all files have been retrieved,
1413 ftp_retrieve_dirs will be called to retrieve the directories. */
1415 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1417 static int depth = 0;
1419 struct fileinfo *orig;
1424 /* Increase the depth. */
1426 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1428 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1429 depth, opt.reclevel));
1437 con->st &= ~ON_YOUR_OWN;
1438 if (!(con->st & DONE_CWD))
1441 con->cmd &= ~DO_CWD;
1442 con->cmd |= (DO_RETR | LEAVE_PENDING);
1445 con->cmd |= DO_LOGIN;
1447 con->cmd &= ~DO_LOGIN;
1449 err = RETROK; /* in case it's not used */
1453 char *old_target, *ofile;
1455 if (opt.quota && total_downloaded_bytes > opt.quota)
1460 old_target = con->target;
1462 ofile = xstrdup (u->file);
1463 url_set_file (u, f->name);
1465 con->target = url_file_name (u);
1469 if (opt.timestamping && f->type == FT_PLAINFILE)
1472 /* If conversion of HTML files retrieved via FTP is ever implemented,
1473 we'll need to stat() <file>.orig here when -K has been specified.
1474 I'm not implementing it now since files on an FTP server are much
1475 more likely than files on an HTTP server to legitimately have a
1477 if (!stat (con->target, &st))
1481 /* Else, get it from the file. */
1482 local_size = st.st_size;
1485 /* Modification time granularity is 2 seconds for Windows, so
1486 increase local time by 1 second for later comparison. */
1489 /* Compare file sizes only for servers that tell us correct
1490 values. Assumme sizes being equal for servers that lie
1492 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1493 eq_size = cor_val ? (local_size == f->size) : 1 ;
1494 if (f->tstamp <= tml && eq_size)
1496 /* Remote file is older, file sizes can be compared and
1498 logprintf (LOG_VERBOSE, _("\
1499 Remote file no newer than local file `%s' -- not retrieving.\n"), con->target);
1504 /* Remote file is newer or sizes cannot be matched */
1505 logprintf (LOG_VERBOSE, _("\
1506 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1511 /* Sizes do not match */
1512 logprintf (LOG_VERBOSE, _("\
1513 The sizes do not match (local %ld) -- retrieving.\n\n"), local_size);
1516 } /* opt.timestamping && f->type == FT_PLAINFILE */
1520 /* If opt.retr_symlinks is defined, we treat symlinks as
1521 if they were normal files. There is currently no way
1522 to distinguish whether they might be directories, and
1524 if (!opt.retr_symlinks)
1528 logputs (LOG_NOTQUIET,
1529 _("Invalid name of the symlink, skipping.\n"));
1533 /* Check whether we already have the correct
1535 int rc = lstat (con->target, &st);
1538 size_t len = strlen (f->linkto) + 1;
1539 if (S_ISLNK (st.st_mode))
1541 char *link_target = (char *)alloca (len);
1542 size_t n = readlink (con->target, link_target, len);
1544 && (memcmp (link_target, f->linkto, n) == 0))
1546 logprintf (LOG_VERBOSE, _("\
1547 Already have correct symlink %s -> %s\n\n"),
1548 con->target, f->linkto);
1554 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1555 con->target, f->linkto);
1556 /* Unlink before creating symlink! */
1557 unlink (con->target);
1558 if (symlink (f->linkto, con->target) == -1)
1559 logprintf (LOG_NOTQUIET, "symlink: %s\n",
1561 logputs (LOG_VERBOSE, "\n");
1562 } /* have f->linkto */
1563 #else /* not HAVE_SYMLINK */
1564 logprintf (LOG_NOTQUIET,
1565 _("Symlinks not supported, skipping symlink `%s'.\n"),
1567 #endif /* not HAVE_SYMLINK */
1569 else /* opt.retr_symlinks */
1572 err = ftp_loop_internal (u, f, con);
1573 } /* opt.retr_symlinks */
1577 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1581 /* Call the retrieve loop. */
1583 err = ftp_loop_internal (u, f, con);
1586 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1591 /* Set the time-stamp information to the local file. Symlinks
1592 are not to be stamped because it sets the stamp on the
1594 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1597 && file_exists_p (con->target))
1599 /* #### This code repeats in http.c and ftp.c. Move it to a
1601 const char *fl = NULL;
1602 if (opt.output_document)
1604 if (opt.od_known_regular)
1605 fl = opt.output_document;
1610 touch (fl, f->tstamp);
1612 else if (f->tstamp == -1)
1613 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), con->target);
1615 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1617 if (opt.preserve_perm)
1618 chmod (con->target, f->perms);
1621 DEBUGP (("Unrecognized permissions for %s.\n", con->target));
1623 xfree (con->target);
1624 con->target = old_target;
1626 url_set_file (u, ofile);
1629 /* Break on fatals. */
1630 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1632 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1636 /* We do not want to call ftp_retrieve_dirs here */
1637 if (opt.recursive &&
1638 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1639 err = ftp_retrieve_dirs (u, orig, con);
1640 else if (opt.recursive)
1641 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1642 depth, opt.reclevel));
1647 /* Retrieve the directories given in a file list. This function works
1648 by simply going through the linked list and calling
1649 ftp_retrieve_glob on each directory entry. The function knows
1650 about excluded directories. */
1652 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
1654 char *container = NULL;
1655 int container_size = 0;
1657 for (; f; f = f->next)
1660 char *odir, *newdir;
1662 if (opt.quota && total_downloaded_bytes > opt.quota)
1664 if (f->type != FT_DIRECTORY)
1667 /* Allocate u->dir off stack, but reallocate only if a larger
1668 string is needed. It's a pity there's no "realloca" for an
1669 item on the bottom of the stack. */
1670 size = strlen (u->dir) + 1 + strlen (f->name) + 1;
1671 if (size > container_size)
1672 container = (char *)alloca (size);
1677 || (*odir == '/' && *(odir + 1) == '\0'))
1678 /* If ODIR is empty or just "/", simply append f->name to
1679 ODIR. (In the former case, to preserve u->dir being
1680 relative; in the latter case, to avoid double slash.) */
1681 sprintf (newdir, "%s%s", odir, f->name);
1683 /* Else, use a separator. */
1684 sprintf (newdir, "%s/%s", odir, f->name);
1686 DEBUGP (("Composing new CWD relative to the initial directory.\n"));
1687 DEBUGP ((" odir = '%s'\n f->name = '%s'\n newdir = '%s'\n\n",
1688 odir, f->name, newdir));
1689 if (!accdir (newdir, ALLABS))
1691 logprintf (LOG_VERBOSE, _("\
1692 Not descending to `%s' as it is excluded/not-included.\n"), newdir);
1696 con->st &= ~DONE_CWD;
1698 odir = xstrdup (u->dir); /* because url_set_dir will free
1700 url_set_dir (u, newdir);
1701 ftp_retrieve_glob (u, con, GETALL);
1702 url_set_dir (u, odir);
1705 /* Set the time-stamp? */
1708 if (opt.quota && total_downloaded_bytes > opt.quota)
1714 /* Return non-zero if S has a leading '/' or contains '../' */
1716 has_insecure_name_p (const char *s)
1721 if (strstr (s, "../") != 0)
1727 /* A near-top-level function to retrieve the files in a directory.
1728 The function calls ftp_get_listing, to get a linked list of files.
1729 Then it weeds out the file names that do not match the pattern.
1730 ftp_retrieve_list is called with this updated list as an argument.
1732 If the argument ACTION is GETONE, just download the file (but first
1733 get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1734 use globbing; if it's GETALL, download the whole directory. */
1736 ftp_retrieve_glob (struct url *u, ccon *con, int action)
1738 struct fileinfo *f, *start;
1741 con->cmd |= LEAVE_PENDING;
1743 res = ftp_get_listing (u, con, &start);
1746 /* First: weed out that do not conform the global rules given in
1747 opt.accepts and opt.rejects. */
1748 if (opt.accepts || opt.rejects)
1753 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1755 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1756 f = delelement (f, &start);
1762 /* Remove all files with possible harmful names */
1766 if (has_insecure_name_p (f->name))
1768 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1769 f = delelement (f, &start);
1774 /* Now weed out the files that do not match our globbing pattern.
1775 If we are dealing with a globbing pattern, that is. */
1776 if (*u->file && (action == GLOBALL || action == GETONE))
1783 matchres = fnmatch (u->file, f->name, 0);
1786 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
1790 if (matchres == FNM_NOMATCH)
1791 f = delelement (f, &start); /* delete the element from the list */
1793 f = f->next; /* leave the element in the list */
1797 freefileinfo (start);
1798 return RETRBADPATTERN;
1804 /* Just get everything. */
1805 ftp_retrieve_list (u, start, con);
1809 if (action == GLOBALL)
1812 /* #### This message SUCKS. We should see what was the
1813 reason that nothing was retrieved. */
1814 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1816 else /* GETONE or GETALL */
1818 /* Let's try retrieving it anyway. */
1819 con->st |= ON_YOUR_OWN;
1820 res = ftp_loop_internal (u, NULL, con);
1824 freefileinfo (start);
1825 if (opt.quota && total_downloaded_bytes > opt.quota)
1828 /* #### Should we return `res' here? */
1832 /* The wrapper that calls an appropriate routine according to contents
1833 of URL. Inherently, its capabilities are limited on what can be
1834 encoded into a URL. */
1836 ftp_loop (struct url *u, int *dt, struct url *proxy)
1838 ccon con; /* FTP connection */
1843 memset (&con, 0, sizeof (con));
1846 con.st = ON_YOUR_OWN;
1850 res = RETROK; /* in case it's not used */
1852 /* If the file name is empty, the user probably wants a directory
1853 index. We'll provide one, properly HTML-ized. Unless
1854 opt.htmlify is 0, of course. :-) */
1855 if (!*u->file && !opt.recursive)
1858 res = ftp_get_listing (u, &con, &f);
1862 if (opt.htmlify && !opt.spider)
1864 char *filename = (opt.output_document
1865 ? xstrdup (opt.output_document)
1866 : (con.target ? xstrdup (con.target)
1867 : url_file_name (u)));
1868 res = ftp_index (filename, u, f);
1869 if (res == FTPOK && opt.verbose)
1871 if (!opt.output_document)
1875 if (stat (filename, &st) == 0)
1879 logprintf (LOG_NOTQUIET,
1880 _("Wrote HTML-ized index to `%s' [%ld].\n"),
1884 logprintf (LOG_NOTQUIET,
1885 _("Wrote HTML-ized index to `%s'.\n"),
1895 int wild = has_wildcards_p (u->file);
1896 if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1898 /* ftp_retrieve_glob is a catch-all function that gets called
1899 if we need globbing, time-stamping or recursion. Its
1900 third argument is just what we really need. */
1901 res = ftp_retrieve_glob (u, &con,
1902 (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1905 res = ftp_loop_internal (u, NULL, &con);
1911 /* If a connection was left, quench it. */
1912 if (con.csock != -1)
1913 fd_close (con.csock);
1914 xfree_null (con.id);
1916 xfree_null (con.target);
1921 /* Delete an element from the fileinfo linked list. Returns the
1922 address of the next element, or NULL if the list is exhausted. It
1923 can modify the start of the list. */
1924 static struct fileinfo *
1925 delelement (struct fileinfo *f, struct fileinfo **start)
1927 struct fileinfo *prev = f->prev;
1928 struct fileinfo *next = f->next;
1931 xfree_null (f->linkto);
1943 /* Free the fileinfo linked list of files. */
1945 freefileinfo (struct fileinfo *f)
1949 struct fileinfo *next = f->next;