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[];
69 extern FILE *output_stream;
70 extern int output_stream_regular;
74 int st; /* connection status */
75 int cmd; /* command code */
76 int csock; /* control connection socket */
77 double dltime; /* time of the download in msecs */
78 enum stype rs; /* remote system reported by ftp server */
79 char *id; /* initial directory */
80 char *target; /* target file name */
81 struct url *proxy; /* FTWK-style proxy */
85 /* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
86 the string S, and return the number converted to wgint, if found, 0
89 ftp_expected_bytes (const char *s)
95 while (*s && *s != '(')
99 res = str_to_wgint (s, (char **) &s, 10);
102 while (*s && ISSPACE (*s))
106 if (TOLOWER (*s) != 'b')
108 if (strncasecmp (s, "byte", 4))
118 * This function sets up a passive data connection with the FTP server.
119 * It is merely a wrapper around ftp_epsv, ftp_lpsv and ftp_pasv.
122 ftp_do_pasv (int csock, ip_address *addr, int *port)
126 /* We need to determine the address family and need to call
127 getpeername, so while we're at it, store the address to ADDR.
128 ftp_pasv and ftp_lpsv can simply override it. */
129 if (!socket_ip_address (csock, addr, ENDPOINT_PEER))
132 /* If our control connection is over IPv6, then we first try EPSV and then
133 * LPSV if the former is not supported. If the control connection is over
134 * IPv4, we simply issue the good old PASV request. */
138 if (!opt.server_response)
139 logputs (LOG_VERBOSE, "==> PASV ... ");
140 err = ftp_pasv (csock, addr, port);
143 if (!opt.server_response)
144 logputs (LOG_VERBOSE, "==> EPSV ... ");
145 err = ftp_epsv (csock, addr, port);
147 /* If EPSV is not supported try LPSV */
148 if (err == FTPNOPASV)
150 if (!opt.server_response)
151 logputs (LOG_VERBOSE, "==> LPSV ... ");
152 err = ftp_lpsv (csock, addr, port);
163 * This function sets up an active data connection with the FTP server.
164 * It is merely a wrapper around ftp_eprt, ftp_lprt and ftp_port.
167 ftp_do_port (int csock, int *local_sock)
172 if (!socket_ip_address (csock, &cip, ENDPOINT_PEER))
175 /* If our control connection is over IPv6, then we first try EPRT and then
176 * LPRT if the former is not supported. If the control connection is over
177 * IPv4, we simply issue the good old PORT request. */
181 if (!opt.server_response)
182 logputs (LOG_VERBOSE, "==> PORT ... ");
183 err = ftp_port (csock, local_sock);
186 if (!opt.server_response)
187 logputs (LOG_VERBOSE, "==> EPRT ... ");
188 err = ftp_eprt (csock, local_sock);
190 /* If EPRT is not supported try LPRT */
191 if (err == FTPPORTERR)
193 if (!opt.server_response)
194 logputs (LOG_VERBOSE, "==> LPRT ... ");
195 err = ftp_lprt (csock, local_sock);
206 ftp_do_pasv (int csock, ip_address *addr, int *port)
208 if (!opt.server_response)
209 logputs (LOG_VERBOSE, "==> PASV ... ");
210 return ftp_pasv (csock, addr, port);
214 ftp_do_port (int csock, int *local_sock)
216 if (!opt.server_response)
217 logputs (LOG_VERBOSE, "==> PORT ... ");
218 return ftp_port (csock, local_sock);
222 /* Retrieves a file with denoted parameters through opening an FTP
223 connection to the server. It always closes the data connection,
224 and closes the control connection in case of error. */
226 getftp (struct url *u, wgint *len, wgint restval, ccon *con)
228 int csock, dtsock, local_sock, res;
231 char *user, *passwd, *respline;
234 int pasv_mode_open = 0;
235 wgint expected_bytes = 0L;
240 assert (con != NULL);
241 assert (con->target != NULL);
243 /* Debug-check of the sanity of the request by making sure that LIST
244 and RETR are never both requested (since we can handle only one
246 assert (!((cmd & DO_LIST) && (cmd & DO_RETR)));
247 /* Make sure that at least *something* is requested. */
248 assert ((cmd & (DO_LIST | DO_CWD | DO_RETR | DO_LOGIN)) != 0);
252 search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
253 user = user ? user : opt.ftp_acc;
254 passwd = passwd ? passwd : opt.ftp_pass;
255 assert (user && passwd);
261 if (!(cmd & DO_LOGIN))
263 else /* cmd & DO_LOGIN */
266 char *host = con->proxy ? con->proxy->host : u->host;
267 int port = con->proxy ? con->proxy->port : u->port;
268 char *logname = user;
272 /* If proxy is in use, log in as username@target-site. */
273 logname = xmalloc (strlen (user) + 1 + strlen (u->host) + 1);
274 sprintf (logname, "%s@%s", user, u->host);
277 /* Login to the server: */
279 /* First: Establish the control connection. */
281 csock = connect_to_host (host, port);
285 return (retryable_socket_connect_error (errno)
286 ? CONERROR : CONIMPOSSIBLE);
288 if (cmd & LEAVE_PENDING)
293 /* Second: Login with proper USER/PASS sequence. */
294 logprintf (LOG_VERBOSE, _("Logging in as %s ... "), user);
295 if (opt.server_response)
296 logputs (LOG_ALWAYS, "\n");
297 err = ftp_login (csock, logname, passwd);
302 /* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
306 logputs (LOG_VERBOSE, "\n");
307 logputs (LOG_NOTQUIET, _("\
308 Error in server response, closing control connection.\n"));
314 logputs (LOG_VERBOSE, "\n");
315 logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
321 logputs (LOG_VERBOSE, "\n");
322 logputs (LOG_NOTQUIET,
323 _("Write failed, closing control connection.\n"));
329 logputs (LOG_VERBOSE, "\n");
330 logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
333 return FTPLOGREFUSED;
336 logputs (LOG_VERBOSE, "\n");
337 logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
343 if (!opt.server_response)
344 logputs (LOG_VERBOSE, _("Logged in!\n"));
351 /* Third: Get the system type */
352 if (!opt.server_response)
353 logprintf (LOG_VERBOSE, "==> SYST ... ");
354 err = ftp_syst (csock, &con->rs);
359 logputs (LOG_VERBOSE, "\n");
360 logputs (LOG_NOTQUIET, _("\
361 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. */
378 if (!opt.server_response && err != FTPSRVERR)
379 logputs (LOG_VERBOSE, _("done. "));
381 /* Fourth: Find the initial ftp directory */
383 if (!opt.server_response)
384 logprintf (LOG_VERBOSE, "==> PWD ... ");
385 err = ftp_pwd (csock, &con->id);
390 logputs (LOG_VERBOSE, "\n");
391 logputs (LOG_NOTQUIET, _("\
392 Error in server response, closing control connection.\n"));
398 /* PWD unsupported -- assume "/". */
399 xfree_null (con->id);
400 con->id = xstrdup ("/");
403 /* Everything is OK. */
409 /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
410 Convert it to "/INITIAL/FOLDER" */
411 if (con->rs == ST_VMS)
413 char *path = strchr (con->id, '[');
414 char *pathend = path ? strchr (path + 1, ']') : NULL;
415 if (!path || !pathend)
416 DEBUGP (("Initial VMS directory not in the form [...]!\n"));
419 char *idir = con->id;
420 DEBUGP (("Preprocessing the initial VMS directory\n"));
421 DEBUGP ((" old = '%s'\n", con->id));
422 /* We do the conversion in-place by copying the stuff
423 between [ and ] to the beginning, and changing dots
424 to slashes at the same time. */
426 for (++path; path < pathend; path++, idir++)
427 *idir = *path == '.' ? '/' : *path;
429 DEBUGP ((" new = '%s'\n\n", con->id));
432 if (!opt.server_response)
433 logputs (LOG_VERBOSE, _("done.\n"));
435 /* Fifth: Set the FTP type. */
436 type_char = ftp_process_type (u->params);
437 if (!opt.server_response)
438 logprintf (LOG_VERBOSE, "==> TYPE %c ... ", type_char);
439 err = ftp_type (csock, type_char);
440 /* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
444 logputs (LOG_VERBOSE, "\n");
445 logputs (LOG_NOTQUIET, _("\
446 Error in server response, closing control connection.\n"));
452 logputs (LOG_VERBOSE, "\n");
453 logputs (LOG_NOTQUIET,
454 _("Write failed, closing control connection.\n"));
460 logputs (LOG_VERBOSE, "\n");
461 logprintf (LOG_NOTQUIET,
462 _("Unknown type `%c', closing control connection.\n"),
468 /* Everything is OK. */
474 if (!opt.server_response)
475 logputs (LOG_VERBOSE, _("done. "));
481 logputs (LOG_VERBOSE, _("==> CWD not needed.\n"));
484 char *target = u->dir;
486 DEBUGP (("changing working directory\n"));
488 /* Change working directory. To change to a non-absolute
489 Unix directory, we need to prepend initial directory
490 (con->id) to it. Absolute directories "just work".
492 A relative directory is one that does not begin with '/'
493 and, on non-Unix OS'es, one that doesn't begin with
496 This is not done for OS400, which doesn't use
497 "/"-delimited directories, nor does it support directory
498 hierarchies. "CWD foo" followed by "CWD bar" leaves us
499 in "bar", not in "foo/bar", as would be customary
503 && !(con->rs != ST_UNIX
504 && ISALPHA (target[0])
506 && con->rs != ST_OS400)
508 int idlen = strlen (con->id);
511 /* Strip trailing slash(es) from con->id. */
512 while (idlen > 0 && con->id[idlen - 1] == '/')
514 p = ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
515 memcpy (p, con->id, idlen);
520 DEBUGP (("Prepended initial PWD to relative path:\n"));
521 DEBUGP ((" pwd: '%s'\n old: '%s'\n new: '%s'\n",
522 con->id, target, ntarget));
526 /* If the FTP host runs VMS, we will have to convert the absolute
527 directory path in UNIX notation to absolute directory path in
528 VMS notation as VMS FTP servers do not like UNIX notation of
529 absolute paths. "VMS notation" is [dir.subdir.subsubdir]. */
531 if (con->rs == ST_VMS)
534 char *ntarget = (char *)alloca (strlen (target) + 2);
535 /* We use a converted initial dir, so directories in
536 TARGET will be separated with slashes, something like
537 "/INITIAL/FOLDER/DIR/SUBDIR". Convert that to
538 "[INITIAL.FOLDER.DIR.SUBDIR]". */
539 strcpy (ntarget, target);
540 assert (*ntarget == '/');
542 for (tmpp = ntarget + 1; *tmpp; tmpp++)
547 DEBUGP (("Changed file name to VMS syntax:\n"));
548 DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget));
552 if (!opt.server_response)
553 logprintf (LOG_VERBOSE, "==> CWD %s ... ", target);
554 err = ftp_cwd (csock, target);
555 /* FTPRERR, WRITEFAILED, FTPNSFOD */
559 logputs (LOG_VERBOSE, "\n");
560 logputs (LOG_NOTQUIET, _("\
561 Error in server response, closing control connection.\n"));
567 logputs (LOG_VERBOSE, "\n");
568 logputs (LOG_NOTQUIET,
569 _("Write failed, closing control connection.\n"));
575 logputs (LOG_VERBOSE, "\n");
576 logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
589 if (!opt.server_response)
590 logputs (LOG_VERBOSE, _("done.\n"));
593 else /* do not CWD */
594 logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
596 if ((cmd & DO_RETR) && restval && *len == 0)
600 if (!opt.server_response)
601 logprintf (LOG_VERBOSE, "==> SIZE %s ... ", u->file);
604 err = ftp_size (csock, u->file, len);
610 logputs (LOG_VERBOSE, "\n");
611 logputs (LOG_NOTQUIET, _("\
612 Error in server response, closing control connection.\n"));
618 /* Everything is OK. */
624 if (!opt.server_response)
625 logputs (LOG_VERBOSE, _("done.\n"));
628 /* If anything is to be retrieved, PORT (or PASV) must be sent. */
629 if (cmd & (DO_LIST | DO_RETR))
631 if (opt.ftp_pasv > 0)
633 ip_address passive_addr;
635 err = ftp_do_pasv (csock, &passive_addr, &passive_port);
636 /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
640 logputs (LOG_VERBOSE, "\n");
641 logputs (LOG_NOTQUIET, _("\
642 Error in server response, closing control connection.\n"));
648 logputs (LOG_VERBOSE, "\n");
649 logputs (LOG_NOTQUIET,
650 _("Write failed, closing control connection.\n"));
656 logputs (LOG_VERBOSE, "\n");
657 logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
660 logputs (LOG_VERBOSE, "\n");
661 logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
672 DEBUGP (("trying to connect to %s port %d\n",
673 pretty_print_address (&passive_addr),
675 dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
678 int save_errno = errno;
681 logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
682 pretty_print_address (&passive_addr), passive_port,
683 strerror (save_errno));
684 return (retryable_socket_connect_error (save_errno)
685 ? CONERROR : CONIMPOSSIBLE);
688 pasv_mode_open = 1; /* Flag to avoid accept port */
689 if (!opt.server_response)
690 logputs (LOG_VERBOSE, _("done. "));
694 if (!pasv_mode_open) /* Try to use a port command if PASV failed */
696 err = ftp_do_port (csock, &local_sock);
697 /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR,
702 logputs (LOG_VERBOSE, "\n");
703 logputs (LOG_NOTQUIET, _("\
704 Error in server response, closing control connection.\n"));
708 fd_close (local_sock);
712 logputs (LOG_VERBOSE, "\n");
713 logputs (LOG_NOTQUIET,
714 _("Write failed, closing control connection.\n"));
718 fd_close (local_sock);
722 logputs (LOG_VERBOSE, "\n");
723 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
727 fd_close (local_sock);
731 logputs (LOG_VERBOSE, "\n");
732 logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
738 logputs (LOG_VERBOSE, "\n");
739 logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
743 fd_close (local_sock);
753 if (!opt.server_response)
754 logputs (LOG_VERBOSE, _("done. "));
756 } /* cmd & (DO_LIST | DO_RETR) */
758 /* Restart if needed. */
759 if (restval && (cmd & DO_RETR))
761 if (!opt.server_response)
762 logprintf (LOG_VERBOSE, "==> REST %s ... ", number_to_static_string (restval));
763 err = ftp_rest (csock, restval);
765 /* FTPRERR, WRITEFAILED, FTPRESTFAIL */
769 logputs (LOG_VERBOSE, "\n");
770 logputs (LOG_NOTQUIET, _("\
771 Error in server response, closing control connection.\n"));
775 fd_close (local_sock);
779 logputs (LOG_VERBOSE, "\n");
780 logputs (LOG_NOTQUIET,
781 _("Write failed, closing control connection.\n"));
785 fd_close (local_sock);
789 logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
799 if (err != FTPRESTFAIL && !opt.server_response)
800 logputs (LOG_VERBOSE, _("done. "));
801 } /* restval && cmd & DO_RETR */
805 /* If we're in spider mode, don't really retrieve anything. The
806 fact that we got to this point should be proof enough that
807 the file exists, vaguely akin to HTTP's concept of a "HEAD"
814 fd_close (local_sock);
820 if (!opt.server_response)
823 logputs (LOG_VERBOSE, "\n");
824 logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
828 err = ftp_retr (csock, u->file);
829 /* FTPRERR, WRITEFAILED, FTPNSFOD */
833 logputs (LOG_VERBOSE, "\n");
834 logputs (LOG_NOTQUIET, _("\
835 Error in server response, closing control connection.\n"));
839 fd_close (local_sock);
843 logputs (LOG_VERBOSE, "\n");
844 logputs (LOG_NOTQUIET,
845 _("Write failed, closing control connection.\n"));
849 fd_close (local_sock);
853 logputs (LOG_VERBOSE, "\n");
854 logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
856 fd_close (local_sock);
867 if (!opt.server_response)
868 logputs (LOG_VERBOSE, _("done.\n"));
869 expected_bytes = ftp_expected_bytes (ftp_last_respline);
874 if (!opt.server_response)
875 logputs (LOG_VERBOSE, "==> LIST ... ");
876 /* As Maciej W. Rozycki (macro@ds2.pg.gda.pl) says, `LIST'
877 without arguments is better than `LIST .'; confirmed by
879 err = ftp_list (csock, NULL);
880 /* FTPRERR, WRITEFAILED */
884 logputs (LOG_VERBOSE, "\n");
885 logputs (LOG_NOTQUIET, _("\
886 Error in server response, closing control connection.\n"));
890 fd_close (local_sock);
894 logputs (LOG_VERBOSE, "\n");
895 logputs (LOG_NOTQUIET,
896 _("Write failed, closing control connection.\n"));
900 fd_close (local_sock);
904 logputs (LOG_VERBOSE, "\n");
905 logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
908 fd_close (local_sock);
918 if (!opt.server_response)
919 logputs (LOG_VERBOSE, _("done.\n"));
920 expected_bytes = ftp_expected_bytes (ftp_last_respline);
921 } /* cmd & DO_LIST */
923 if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
926 /* Some FTP servers return the total length of file after REST
927 command, others just return the remaining size. */
928 if (*len && restval && expected_bytes
929 && (expected_bytes == *len - restval))
931 DEBUGP (("Lying FTP server found, adjusting.\n"));
932 expected_bytes = *len;
935 /* If no transmission was required, then everything is OK. */
936 if (!pasv_mode_open) /* we are not using pasive mode so we need
939 /* Wait for the server to connect to the address we're waiting
941 dtsock = accept_connection (local_sock);
944 logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno));
949 /* Open the file -- if output_stream is set, use it instead. */
950 if (!output_stream || con->cmd & DO_LIST)
952 mkalldirs (con->target);
954 rotate_backups (con->target);
955 /* #### Is this correct? */
956 chmod (con->target, 0600);
958 fp = fopen (con->target, restval ? "ab" : "wb");
961 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
965 fd_close (local_sock);
974 logprintf (LOG_VERBOSE, _("Length: %s"), legible (*len));
976 logprintf (LOG_VERBOSE, _(" [%s to go]"), legible (*len - restval));
977 logputs (LOG_VERBOSE, "\n");
978 expected_bytes = *len; /* for get_contents/show_progress */
980 else if (expected_bytes)
982 logprintf (LOG_VERBOSE, _("Length: %s"), legible (expected_bytes));
984 logprintf (LOG_VERBOSE, _(" [%s to go]"),
985 legible (expected_bytes - restval));
986 logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
989 /* Get the contents of the document. */
991 if (restval && rest_failed)
992 flags |= rb_skip_startpos;
995 res = fd_read_body (dtsock, fp,
996 expected_bytes ? expected_bytes - restval : 0,
997 restval, &rd_size, len, &con->dltime, flags);
999 tms = time_str (NULL);
1000 tmrate = retr_rate (rd_size, con->dltime, 0);
1001 /* Close data connection socket. */
1003 fd_close (local_sock);
1004 /* Close the local file. */
1006 /* Close or flush the file. We have to be careful to check for
1007 error here. Checking the result of fwrite() is not enough --
1008 errors could go unnoticed! */
1010 if (!output_stream || con->cmd & DO_LIST)
1011 flush_res = fclose (fp);
1013 flush_res = fflush (fp);
1014 if (flush_res == EOF)
1018 /* If get_contents couldn't write to fp, bail out. */
1021 logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
1022 con->target, strerror (errno));
1029 logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
1030 tms, tmrate, strerror (errno));
1031 if (opt.server_response)
1032 logputs (LOG_ALWAYS, "\n");
1035 /* Get the server to tell us if everything is retrieved. */
1036 err = ftp_response (csock, &respline);
1040 /* The control connection is decidedly closed. Print the time
1041 only if it hasn't already been printed. */
1043 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1044 logputs (LOG_NOTQUIET, _("Control connection closed.\n"));
1045 /* If there is an error on the control connection, close it, but
1046 return FTPRETRINT, since there is a possibility that the
1047 whole file was retrieved nevertheless (but that is for
1048 ftp_loop_internal to decide). */
1052 } /* err != FTPOK */
1053 /* If retrieval failed for any reason, return FTPRETRINT, but do not
1054 close socket, since the control connection is still alive. If
1055 there is something wrong with the control connection, it will
1056 become apparent later. */
1057 if (*respline != '2')
1061 logprintf (LOG_NOTQUIET, "%s (%s) - ", tms, tmrate);
1062 logputs (LOG_NOTQUIET, _("Data transfer aborted.\n"));
1069 /* What now? The data connection was erroneous, whereas the
1070 response says everything is OK. We shall play it safe. */
1074 if (!(cmd & LEAVE_PENDING))
1076 /* Closing the socket is faster than sending 'QUIT' and the
1077 effect is the same. */
1081 /* If it was a listing, and opt.server_response is true,
1083 if (opt.server_response && (con->cmd & DO_LIST))
1085 mkalldirs (con->target);
1086 fp = fopen (con->target, "r");
1088 logprintf (LOG_ALWAYS, "%s: %s\n", con->target, strerror (errno));
1092 /* The lines are being read with read_whole_line because of
1093 no-buffering on opt.lfile. */
1094 while ((line = read_whole_line (fp)))
1096 logprintf (LOG_ALWAYS, "%s\n", line);
1101 } /* con->cmd & DO_LIST && server_response */
1103 return RETRFINISHED;
1106 /* A one-file FTP loop. This is the part where FTP retrieval is
1107 retried, and retried, and retried, and...
1109 This loop either gets commands from con, or (if ON_YOUR_OWN is
1110 set), makes them up to retrieve the file given by the URL. */
1112 ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
1115 wgint restval, len = 0;
1117 char *tmrate = NULL;
1122 con->target = url_file_name (u);
1124 if (opt.noclobber && file_exists_p (con->target))
1126 logprintf (LOG_VERBOSE,
1127 _("File `%s' already there, not retrieving.\n"), con->target);
1128 /* If the file is there, we suppose it's retrieved OK. */
1132 /* Remove it if it's a link. */
1133 remove_link (con->target);
1134 if (!opt.output_document)
1137 locf = opt.output_document;
1141 if (con->st & ON_YOUR_OWN)
1142 con->st = ON_YOUR_OWN;
1144 orig_lp = con->cmd & LEAVE_PENDING ? 1 : 0;
1149 /* Increment the pass counter. */
1151 sleep_between_retrievals (count);
1152 if (con->st & ON_YOUR_OWN)
1155 con->cmd |= (DO_RETR | LEAVE_PENDING);
1156 if (con->csock != -1)
1157 con->cmd &= ~ (DO_LOGIN | DO_CWD);
1159 con->cmd |= (DO_LOGIN | DO_CWD);
1161 else /* not on your own */
1163 if (con->csock != -1)
1164 con->cmd &= ~DO_LOGIN;
1166 con->cmd |= DO_LOGIN;
1167 if (con->st & DONE_CWD)
1168 con->cmd &= ~DO_CWD;
1173 /* Decide whether or not to restart. */
1176 restval = len; /* start where the previous run left off */
1177 else if (opt.always_rest
1178 && stat (locf, &st) == 0
1179 && S_ISREG (st.st_mode))
1180 restval = st.st_size;
1182 /* Get the current time string. */
1183 tms = time_str (NULL);
1184 /* Print fetch message, if opt.verbose. */
1187 char *hurl = url_string (u, 1);
1191 sprintf (tmp, _("(try:%2d)"), count);
1192 logprintf (LOG_VERBOSE, "--%s-- %s\n %s => `%s'\n",
1193 tms, hurl, tmp, locf);
1195 ws_changetitle (hurl);
1199 /* Send getftp the proper length, if fileinfo was provided. */
1204 err = getftp (u, &len, restval, con);
1206 if (con->csock != -1)
1207 con->st &= ~DONE_CWD;
1209 con->st |= DONE_CWD;
1213 case HOSTERR: case CONIMPOSSIBLE: case FWRITEERR: case FOPENERR:
1214 case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
1215 /* Fatal errors, give up. */
1218 case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
1219 case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
1220 case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
1221 printwhat (count, opt.ntry);
1222 /* non-fatal errors */
1226 /* If the control connection was closed, the retrieval
1227 will be considered OK if f->size == len. */
1228 if (!f || len != f->size)
1230 printwhat (count, opt.ntry);
1241 tms = time_str (NULL);
1243 tmrate = retr_rate (len - restval, con->dltime, 0);
1245 /* If we get out of the switch above without continue'ing, we've
1246 successfully downloaded a file. Remember this fact. */
1247 downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
1249 if (con->st & ON_YOUR_OWN)
1251 fd_close (con->csock);
1255 logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%s]\n\n"),
1256 tms, tmrate, locf, number_to_static_string (len));
1257 if (!opt.verbose && !opt.quiet)
1259 /* Need to hide the password from the URL. The `if' is here
1260 so that we don't do the needless allocation every
1262 char *hurl = url_string (u, 1);
1263 logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
1264 tms, hurl, number_to_static_string (len), locf, count);
1268 if ((con->cmd & DO_LIST))
1269 /* This is a directory listing file. */
1271 if (!opt.remove_listing)
1272 /* --dont-remove-listing was specified, so do count this towards the
1273 number of bytes and files downloaded. */
1275 total_downloaded_bytes += len;
1279 /* Deletion of listing files is not controlled by --delete-after, but
1280 by the more specific option --dont-remove-listing, and the code
1281 to do this deletion is in another function. */
1283 else if (!opt.spider)
1284 /* This is not a directory listing file. */
1286 /* Unlike directory listing files, don't pretend normal files weren't
1287 downloaded if they're going to be deleted. People seeding proxies,
1288 for instance, may want to know how many bytes and files they've
1289 downloaded through it. */
1290 total_downloaded_bytes += len;
1293 if (opt.delete_after)
1295 DEBUGP (("Removing file due to --delete-after in"
1296 " ftp_loop_internal():\n"));
1297 logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
1299 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1303 /* Restore the original leave-pendingness. */
1305 con->cmd |= LEAVE_PENDING;
1307 con->cmd &= ~LEAVE_PENDING;
1309 } while (!opt.ntry || (count < opt.ntry));
1311 if (con->csock != -1 && (con->st & ON_YOUR_OWN))
1313 fd_close (con->csock);
1319 /* Return the directory listing in a reusable format. The directory
1320 is specifed in u->dir. */
1322 ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
1325 char *uf; /* url file name */
1326 char *lf; /* list file name */
1327 char *old_target = con->target;
1329 con->st &= ~ON_YOUR_OWN;
1330 con->cmd |= (DO_LIST | LEAVE_PENDING);
1331 con->cmd &= ~DO_RETR;
1333 /* Find the listing file name. We do it by taking the file name of
1334 the URL and replacing the last component with the listing file
1336 uf = url_file_name (u);
1337 lf = file_merge (uf, LIST_FILENAME);
1339 DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
1342 err = ftp_loop_internal (u, NULL, con);
1343 con->target = old_target;
1346 *f = ftp_parse_ls (lf, con->rs);
1349 if (opt.remove_listing)
1352 logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
1354 logprintf (LOG_VERBOSE, _("Removed `%s'.\n"), lf);
1357 con->cmd &= ~DO_LIST;
1361 static uerr_t ftp_retrieve_dirs PARAMS ((struct url *, struct fileinfo *,
1363 static uerr_t ftp_retrieve_glob PARAMS ((struct url *, ccon *, int));
1364 static struct fileinfo *delelement PARAMS ((struct fileinfo *,
1365 struct fileinfo **));
1366 static void freefileinfo PARAMS ((struct fileinfo *f));
1368 /* Retrieve a list of files given in struct fileinfo linked list. If
1369 a file is a symbolic link, do not retrieve it, but rather try to
1370 set up a similar link on the local disk, if the symlinks are
1373 If opt.recursive is set, after all files have been retrieved,
1374 ftp_retrieve_dirs will be called to retrieve the directories. */
1376 ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
1378 static int depth = 0;
1380 struct fileinfo *orig;
1385 /* Increase the depth. */
1387 if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
1389 DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
1390 depth, opt.reclevel));
1398 con->st &= ~ON_YOUR_OWN;
1399 if (!(con->st & DONE_CWD))
1402 con->cmd &= ~DO_CWD;
1403 con->cmd |= (DO_RETR | LEAVE_PENDING);
1406 con->cmd |= DO_LOGIN;
1408 con->cmd &= ~DO_LOGIN;
1410 err = RETROK; /* in case it's not used */
1414 char *old_target, *ofile;
1416 if (opt.quota && total_downloaded_bytes > opt.quota)
1421 old_target = con->target;
1423 ofile = xstrdup (u->file);
1424 url_set_file (u, f->name);
1426 con->target = url_file_name (u);
1430 if (opt.timestamping && f->type == FT_PLAINFILE)
1433 /* If conversion of HTML files retrieved via FTP is ever implemented,
1434 we'll need to stat() <file>.orig here when -K has been specified.
1435 I'm not implementing it now since files on an FTP server are much
1436 more likely than files on an HTTP server to legitimately have a
1438 if (!stat (con->target, &st))
1442 /* Else, get it from the file. */
1443 local_size = st.st_size;
1446 /* Modification time granularity is 2 seconds for Windows, so
1447 increase local time by 1 second for later comparison. */
1450 /* Compare file sizes only for servers that tell us correct
1451 values. Assumme sizes being equal for servers that lie
1453 cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
1454 eq_size = cor_val ? (local_size == f->size) : 1 ;
1455 if (f->tstamp <= tml && eq_size)
1457 /* Remote file is older, file sizes can be compared and
1459 logprintf (LOG_VERBOSE, _("\
1460 Remote file no newer than local file `%s' -- not retrieving.\n"), con->target);
1465 /* Remote file is newer or sizes cannot be matched */
1466 logprintf (LOG_VERBOSE, _("\
1467 Remote file is newer than local file `%s' -- retrieving.\n\n"),
1472 /* Sizes do not match */
1473 logprintf (LOG_VERBOSE, _("\
1474 The sizes do not match (local %s) -- retrieving.\n\n"),
1475 number_to_static_string (local_size));
1478 } /* opt.timestamping && f->type == FT_PLAINFILE */
1482 /* If opt.retr_symlinks is defined, we treat symlinks as
1483 if they were normal files. There is currently no way
1484 to distinguish whether they might be directories, and
1486 if (!opt.retr_symlinks)
1490 logputs (LOG_NOTQUIET,
1491 _("Invalid name of the symlink, skipping.\n"));
1495 /* Check whether we already have the correct
1497 int rc = lstat (con->target, &st);
1500 size_t len = strlen (f->linkto) + 1;
1501 if (S_ISLNK (st.st_mode))
1503 char *link_target = (char *)alloca (len);
1504 size_t n = readlink (con->target, link_target, len);
1506 && (memcmp (link_target, f->linkto, n) == 0))
1508 logprintf (LOG_VERBOSE, _("\
1509 Already have correct symlink %s -> %s\n\n"),
1510 con->target, f->linkto);
1516 logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
1517 con->target, f->linkto);
1518 /* Unlink before creating symlink! */
1519 unlink (con->target);
1520 if (symlink (f->linkto, con->target) == -1)
1521 logprintf (LOG_NOTQUIET, "symlink: %s\n",
1523 logputs (LOG_VERBOSE, "\n");
1524 } /* have f->linkto */
1525 #else /* not HAVE_SYMLINK */
1526 logprintf (LOG_NOTQUIET,
1527 _("Symlinks not supported, skipping symlink `%s'.\n"),
1529 #endif /* not HAVE_SYMLINK */
1531 else /* opt.retr_symlinks */
1534 err = ftp_loop_internal (u, f, con);
1535 } /* opt.retr_symlinks */
1539 logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
1543 /* Call the retrieve loop. */
1545 err = ftp_loop_internal (u, f, con);
1548 logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
1553 /* Set the time-stamp information to the local file. Symlinks
1554 are not to be stamped because it sets the stamp on the
1556 if (!(f->type == FT_SYMLINK && !opt.retr_symlinks)
1559 && file_exists_p (con->target))
1561 /* #### This code repeats in http.c and ftp.c. Move it to a
1563 const char *fl = NULL;
1564 if (opt.output_document)
1566 if (output_stream_regular)
1567 fl = opt.output_document;
1572 touch (fl, f->tstamp);
1574 else if (f->tstamp == -1)
1575 logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), con->target);
1577 if (f->perms && f->type == FT_PLAINFILE && dlthis)
1579 if (opt.preserve_perm)
1580 chmod (con->target, f->perms);
1583 DEBUGP (("Unrecognized permissions for %s.\n", con->target));
1585 xfree (con->target);
1586 con->target = old_target;
1588 url_set_file (u, ofile);
1591 /* Break on fatals. */
1592 if (err == QUOTEXC || err == HOSTERR || err == FWRITEERR)
1594 con->cmd &= ~ (DO_CWD | DO_LOGIN);
1598 /* We do not want to call ftp_retrieve_dirs here */
1599 if (opt.recursive &&
1600 !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
1601 err = ftp_retrieve_dirs (u, orig, con);
1602 else if (opt.recursive)
1603 DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
1604 depth, opt.reclevel));
1609 /* Retrieve the directories given in a file list. This function works
1610 by simply going through the linked list and calling
1611 ftp_retrieve_glob on each directory entry. The function knows
1612 about excluded directories. */
1614 ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
1616 char *container = NULL;
1617 int container_size = 0;
1619 for (; f; f = f->next)
1622 char *odir, *newdir;
1624 if (opt.quota && total_downloaded_bytes > opt.quota)
1626 if (f->type != FT_DIRECTORY)
1629 /* Allocate u->dir off stack, but reallocate only if a larger
1630 string is needed. It's a pity there's no "realloca" for an
1631 item on the bottom of the stack. */
1632 size = strlen (u->dir) + 1 + strlen (f->name) + 1;
1633 if (size > container_size)
1634 container = (char *)alloca (size);
1639 || (*odir == '/' && *(odir + 1) == '\0'))
1640 /* If ODIR is empty or just "/", simply append f->name to
1641 ODIR. (In the former case, to preserve u->dir being
1642 relative; in the latter case, to avoid double slash.) */
1643 sprintf (newdir, "%s%s", odir, f->name);
1645 /* Else, use a separator. */
1646 sprintf (newdir, "%s/%s", odir, f->name);
1648 DEBUGP (("Composing new CWD relative to the initial directory.\n"));
1649 DEBUGP ((" odir = '%s'\n f->name = '%s'\n newdir = '%s'\n\n",
1650 odir, f->name, newdir));
1651 if (!accdir (newdir, ALLABS))
1653 logprintf (LOG_VERBOSE, _("\
1654 Not descending to `%s' as it is excluded/not-included.\n"), newdir);
1658 con->st &= ~DONE_CWD;
1660 odir = xstrdup (u->dir); /* because url_set_dir will free
1662 url_set_dir (u, newdir);
1663 ftp_retrieve_glob (u, con, GETALL);
1664 url_set_dir (u, odir);
1667 /* Set the time-stamp? */
1670 if (opt.quota && total_downloaded_bytes > opt.quota)
1676 /* Return non-zero if S has a leading '/' or contains '../' */
1678 has_insecure_name_p (const char *s)
1683 if (strstr (s, "../") != 0)
1689 /* A near-top-level function to retrieve the files in a directory.
1690 The function calls ftp_get_listing, to get a linked list of files.
1691 Then it weeds out the file names that do not match the pattern.
1692 ftp_retrieve_list is called with this updated list as an argument.
1694 If the argument ACTION is GETONE, just download the file (but first
1695 get the listing, so that the time-stamp is heeded); if it's GLOBALL,
1696 use globbing; if it's GETALL, download the whole directory. */
1698 ftp_retrieve_glob (struct url *u, ccon *con, int action)
1700 struct fileinfo *f, *start;
1703 con->cmd |= LEAVE_PENDING;
1705 res = ftp_get_listing (u, con, &start);
1708 /* First: weed out that do not conform the global rules given in
1709 opt.accepts and opt.rejects. */
1710 if (opt.accepts || opt.rejects)
1715 if (f->type != FT_DIRECTORY && !acceptable (f->name))
1717 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1718 f = delelement (f, &start);
1724 /* Remove all files with possible harmful names */
1728 if (has_insecure_name_p (f->name))
1730 logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
1731 f = delelement (f, &start);
1736 /* Now weed out the files that do not match our globbing pattern.
1737 If we are dealing with a globbing pattern, that is. */
1738 if (*u->file && (action == GLOBALL || action == GETONE))
1745 matchres = fnmatch (u->file, f->name, 0);
1748 logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
1752 if (matchres == FNM_NOMATCH)
1753 f = delelement (f, &start); /* delete the element from the list */
1755 f = f->next; /* leave the element in the list */
1759 freefileinfo (start);
1760 return RETRBADPATTERN;
1766 /* Just get everything. */
1767 ftp_retrieve_list (u, start, con);
1771 if (action == GLOBALL)
1774 /* #### This message SUCKS. We should see what was the
1775 reason that nothing was retrieved. */
1776 logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
1778 else /* GETONE or GETALL */
1780 /* Let's try retrieving it anyway. */
1781 con->st |= ON_YOUR_OWN;
1782 res = ftp_loop_internal (u, NULL, con);
1786 freefileinfo (start);
1787 if (opt.quota && total_downloaded_bytes > opt.quota)
1790 /* #### Should we return `res' here? */
1794 /* The wrapper that calls an appropriate routine according to contents
1795 of URL. Inherently, its capabilities are limited on what can be
1796 encoded into a URL. */
1798 ftp_loop (struct url *u, int *dt, struct url *proxy)
1800 ccon con; /* FTP connection */
1805 memset (&con, 0, sizeof (con));
1808 con.st = ON_YOUR_OWN;
1812 res = RETROK; /* in case it's not used */
1814 /* If the file name is empty, the user probably wants a directory
1815 index. We'll provide one, properly HTML-ized. Unless
1816 opt.htmlify is 0, of course. :-) */
1817 if (!*u->file && !opt.recursive)
1820 res = ftp_get_listing (u, &con, &f);
1824 if (opt.htmlify && !opt.spider)
1826 char *filename = (opt.output_document
1827 ? xstrdup (opt.output_document)
1828 : (con.target ? xstrdup (con.target)
1829 : url_file_name (u)));
1830 res = ftp_index (filename, u, f);
1831 if (res == FTPOK && opt.verbose)
1833 if (!opt.output_document)
1837 if (stat (filename, &st) == 0)
1841 logprintf (LOG_NOTQUIET,
1842 _("Wrote HTML-ized index to `%s' [%s].\n"),
1843 filename, number_to_static_string (sz));
1846 logprintf (LOG_NOTQUIET,
1847 _("Wrote HTML-ized index to `%s'.\n"),
1857 int wild = has_wildcards_p (u->file);
1858 if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
1860 /* ftp_retrieve_glob is a catch-all function that gets called
1861 if we need globbing, time-stamping or recursion. Its
1862 third argument is just what we really need. */
1863 res = ftp_retrieve_glob (u, &con,
1864 (opt.ftp_glob && wild) ? GLOBALL : GETONE);
1867 res = ftp_loop_internal (u, NULL, &con);
1873 /* If a connection was left, quench it. */
1874 if (con.csock != -1)
1875 fd_close (con.csock);
1876 xfree_null (con.id);
1878 xfree_null (con.target);
1883 /* Delete an element from the fileinfo linked list. Returns the
1884 address of the next element, or NULL if the list is exhausted. It
1885 can modify the start of the list. */
1886 static struct fileinfo *
1887 delelement (struct fileinfo *f, struct fileinfo **start)
1889 struct fileinfo *prev = f->prev;
1890 struct fileinfo *next = f->next;
1893 xfree_null (f->linkto);
1905 /* Free the fileinfo linked list of files. */
1907 freefileinfo (struct fileinfo *f)
1911 struct fileinfo *next = f->next;